// File: davmac314[P]dinit/src/dinitctl.cc
// Function: do_setenv(int, cpbuffer<1024u>&, std::vector<char const*, std::allocator<char const*>>&, bool)
static int do_setenv(int socknum, cpbuffer_t &rbuffer, std::vector<const char *> &env_names, bool unset)
{
    using namespace std;

    string buf;

    for (const char *envp : env_names) {
        envvar_len_t envvar_len;
        buf.clear();
        buf.reserve(6);
        // protocol message and size space
        buf.push_back((char)cp_cmd::SETENV);
        buf.append(sizeof(envvar_len), 0);
        const unsigned hdr_len = 1 + sizeof(envvar_len);
        // either full var or name
        auto elen = strlen(envp);
        buf.append(envp, elen);
        // if '=' not found, get value from environment, except for unset
        auto eq = memchr(envp, '=', elen);
        if (!eq && !unset) {
            buf.push_back('=');
            auto *envv = getenv(envp);
            if (envv) {
                buf.append(envv);
            }
        }
        else if (eq && unset) {
            cerr << "dinitctl: environment variable '" << envp << "' must not contain the '=' sign." << endl;
            return 1;
        }
        envvar_len = buf.size() - hdr_len;
        // sanitize length early on
        if (buf.size() > cpbuffer_t::get_size()) {
            auto eq = buf.find('=', hdr_len);
            auto name = buf.substr(hdr_len, eq - hdr_len);
            cerr << "dinitctl: environment variable '" << name << "' too long." << endl;
            return 1;
        }
        // set size in protocol message
        memcpy(&buf[1], &envvar_len, sizeof(envvar_len));
        // send
        write_all_x(socknum, buf.data(), buf.size());
        wait_for_reply(rbuffer, socknum);
        if (rbuffer[0] == (char)cp_rply::BADREQ) {
            cerr << "dinitctl: failed to export environment." << endl;
            return 1;
        } else if (rbuffer[0] != (char)cp_rply::ACK) {
            throw dinit_protocol_error();
        }
        rbuffer.consume(1);
    }

    return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x150, %rsp            # imm = 0x150
movb %cl, %al
movl %edi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
andb $0x1, %al
movb %al, -0x19(%rbp)
leaq -0x40(%rbp), %rdi
callq 0x55c0
movq -0x18(%rbp), %rax
movq %rax, -0x48(%rbp)
movq -0x48(%rbp), %rdi
callq 0x1c9c0
movq %rax, -0x50(%rbp)
movq -0x48(%rbp), %rdi
callq 0x1c9f0
movq %rax, -0x58(%rbp)
leaq -0x50(%rbp), %rdi
leaq -0x58(%rbp), %rsi
callq 0x1ca20
testb $0x1, %al
jne 0xb16e
jmp 0xb55b
leaq -0x50(%rbp), %rdi
callq 0x1ca60
movq (%rax), %rax
movq %rax, -0x60(%rbp)
leaq -0x40(%rbp), %rdi
movq %rdi, -0xc8(%rbp)
callq 0x5550
movq -0xc8(%rbp), %rdi
movl $0x6, %esi
callq 0x5640
jmp 0xb1a1
leaq -0x40(%rbp), %rdi
movl $0x11, %esi
callq 0x5370
jmp 0xb1b1
leaq -0x40(%rbp), %rdi
movl $0x2, %esi
xorl %edx, %edx
callq 0x5430
jmp 0xb1c3
movl $0x3, -0x78(%rbp)
movq -0x60(%rbp), %rdi
callq 0x5190
movq %rax, -0x80(%rbp)
movq -0x60(%rbp), %rsi
movq -0x80(%rbp), %rdx
leaq -0x40(%rbp), %rdi
callq 0x5080
jmp 0xb1ea
movq -0x60(%rbp), %rdi
movq -0x80(%rbp), %rdx
movl $0x3d, %esi
callq 0x5470
movq %rax, -0x88(%rbp)
cmpq $0x0, -0x88(%rbp)
jne 0xb267
testb $0x1, -0x19(%rbp)
jne 0xb267
leaq -0x40(%rbp), %rdi
movl $0x3d, %esi
callq 0x5370
jmp 0xb223
movq -0x60(%rbp), %rdi
callq 0x54f0
movq %rax, -0x90(%rbp)
cmpq $0x0, -0x90(%rbp)
je 0xb262
movq -0x90(%rbp), %rsi
leaq -0x40(%rbp), %rdi
callq 0x5740
jmp 0xb24f
jmp 0xb262
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
jmp 0xb581
jmp 0xb2f9
cmpq $0x0, -0x88(%rbp)
je 0xb2f7
testb $0x1, -0x19(%rbp)
je 0xb2f7
movq 0x26d66(%rip), %rdi     # 0x31fe8
leaq 0x19e50(%rip), %rsi     # 0x250d9
callq 0x53d0
movq %rax, -0xd0(%rbp)
jmp 0xb297
movq -0xd0(%rbp), %rdi
movq -0x60(%rbp), %rsi
callq 0x53d0
movq %rax, -0xd8(%rbp)
jmp 0xb2b0
movq -0xd8(%rbp), %rdi
leaq 0x19e3c(%rip), %rsi     # 0x250fa
callq 0x53d0
movq %rax, -0xe0(%rbp)
jmp 0xb2cc
movq -0xe0(%rbp), %rdi
movq 0x26c8e(%rip), %rsi     # 0x31f68
callq 0x5410
jmp 0xb2e1
movl $0x1, -0x4(%rbp)
movl $0x1, -0x94(%rbp)
jmp 0xb56c
jmp 0xb2f9
leaq -0x40(%rbp), %rdi
movq %rdi, -0xf8(%rbp)
callq 0x52c0
movq -0xf8(%rbp), %rdi
addl $-0x3, %eax
movw %ax, -0x62(%rbp)
callq 0x52c0
movq %rax, -0xf0(%rbp)
callq 0x1ca80
movl %eax, -0xe4(%rbp)
jmp 0xb330
movq -0xf0(%rbp), %rax
movl -0xe4(%rbp), %ecx
movl %ecx, %ecx
cmpq %rcx, %rax
jbe 0xb43f
leaq -0x40(%rbp), %rdi
movq %rdi, -0x108(%rbp)
movl $0x3d, %esi
movl $0x3, %edx
movq %rdx, -0x100(%rbp)
callq 0x5540
movq -0x108(%rbp), %rsi
movq -0x100(%rbp), %rdx
movq %rax, -0xa0(%rbp)
movq -0xa0(%rbp), %rcx
addq $-0x3, %rcx
leaq -0xc0(%rbp), %rdi
callq 0x5400
jmp 0xb397
movq 0x26c4a(%rip), %rdi     # 0x31fe8
leaq 0x19d34(%rip), %rsi     # 0x250d9
callq 0x53d0
movq %rax, -0x110(%rbp)
jmp 0xb3b3
movq -0x110(%rbp), %rdi
leaq -0xc0(%rbp), %rsi
callq 0x53a0
movq %rax, -0x118(%rbp)
jmp 0xb3cf
movq -0x118(%rbp), %rdi
leaq 0x19d3e(%rip), %rsi     # 0x2511b
callq 0x53d0
movq %rax, -0x120(%rbp)
jmp 0xb3eb
movq -0x120(%rbp), %rdi
movq 0x26b6f(%rip), %rsi     # 0x31f68
callq 0x5410
jmp 0xb400
movl $0x1, -0x4(%rbp)
movl $0x1, -0x94(%rbp)
leaq -0xc0(%rbp), %rdi
callq 0x5280
jmp 0xb56c
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
leaq -0xc0(%rbp), %rdi
callq 0x5280
jmp 0xb581
leaq -0x40(%rbp), %rdi
movl $0x1, %esi
callq 0x57a0
movq %rax, -0x128(%rbp)
jmp 0xb456
movq -0x128(%rbp), %rax
movw -0x62(%rbp), %cx
movw %cx, (%rax)
movl -0x8(%rbp), %eax
movl %eax, -0x134(%rbp)
leaq -0x40(%rbp), %rdi
movq %rdi, -0x140(%rbp)
callq 0x5230
movq -0x140(%rbp), %rdi
movq %rax, -0x130(%rbp)
callq 0x52c0
movl -0x134(%rbp), %edi
movq -0x130(%rbp), %rsi
movl %eax, %edx
callq 0x112c0
jmp 0xb4a6
movq -0x10(%rbp), %rdi
movl -0x8(%rbp), %esi
callq 0x11350
jmp 0xb4b4
movq -0x10(%rbp), %rdi
xorl %esi, %esi
callq 0x113e0
movsbl %al, %eax
cmpl $0x34, %eax
jne 0xb50b
movq 0x26b1a(%rip), %rdi     # 0x31fe8
leaq 0x19c52(%rip), %rsi     # 0x25127
callq 0x53d0
movq %rax, -0x148(%rbp)
jmp 0xb4e3
movq -0x148(%rbp), %rdi
movq 0x26a77(%rip), %rsi     # 0x31f68
callq 0x5410
jmp 0xb4f8
movl $0x1, -0x4(%rbp)
movl $0x1, -0x94(%rbp)
jmp 0xb56c
movq -0x10(%rbp), %rdi
xorl %esi, %esi
callq 0x113e0
movsbl %al, %eax
cmpl $0x32, %eax
je 0xb53d
movl $0x1, %edi
callq 0x51c0
movq %rax, %rdi
leaq 0x265ae(%rip), %rsi     # 0x31ae0
xorl %eax, %eax
movl %eax, %edx
callq 0x56b0
jmp 0xb593
jmp 0xb53f
movq -0x10(%rbp), %rdi
movl $0x1, %esi
callq 0x115f0
leaq -0x50(%rbp), %rdi
callq 0x1ca90
jmp 0xb158
movl $0x0, -0x4(%rbp)
movl $0x1, -0x94(%rbp)
leaq -0x40(%rbp), %rdi
callq 0x5280
movl -0x4(%rbp), %eax
addq $0x150, %rsp            # imm = 0x150
popq %rbp
retq
leaq -0x40(%rbp), %rdi
callq 0x5280
movq -0x70(%rbp), %rdi
callq 0x56f0
nopw %cs:(%rax,%rax)