// File: davmac314[P]dinit/src/dinitcheck.cc
// Function: get_remote_env(int, cpbuffer<1024u>&)
static void get_remote_env(int csfd, cpbuffer_t &rbuffer)
{
    char buf[2] = { (char)cp_cmd::GETALLENV, 0 };
    write_all_x(csfd, buf, 2);

    wait_for_reply(rbuffer, csfd);

    if (rbuffer[0] != (char)cp_rply::ALLENV) {
        throw dinit_protocol_error();
    }

    // 1-byte packet header, then size_t data size
    constexpr size_t allenv_hdr_size = 1 + sizeof(size_t);
    rbuffer.fill_to(csfd, allenv_hdr_size);

    size_t data_size;
    rbuffer.extract(&data_size, 1, sizeof(data_size));
    rbuffer.consume(allenv_hdr_size);

    if (data_size == 0) return;

    if (rbuffer.get_length() == 0) {
        fill_some(rbuffer, csfd);
    }

    std::string env_var;

    while (data_size > 0) {
        // look for a nul terminator
        get_var:
        unsigned contig_len = rbuffer.get_contiguous_length(rbuffer.get_ptr(0));
        unsigned check_len = std::min((size_t) contig_len, data_size);
        for (unsigned i = 0; i < check_len; ++i) {
            if (rbuffer[i] == '\0') {
                // append the last portion
                env_var.append(rbuffer.get_ptr(0), rbuffer.get_ptr(0) + i);
                rbuffer.consume(i + 1);
                data_size -= (i + 1);

                menv.set_var(std::move(env_var));
                env_var.clear();

                if (data_size == 0) {
                    // that's the last one
                    return;
                }

                goto get_var;
            }
        }

        // copy what we have so far to the string, and fill some more
        env_var.append(rbuffer.get_ptr(0), rbuffer.get_ptr(0) + check_len);
        rbuffer.consume(check_len);
        data_size -= check_len;

        if (data_size == 0) {
            // This shouldn't happen, we didn't find the nul terminator at the end
            throw dinit_protocol_error();
        }

        if (rbuffer.get_length() == 0) {
            fill_some(rbuffer, csfd);
        }
    }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xa0, %rsp
movl %edi, -0x4(%rbp)
movq %rsi, -0x10(%rbp)
movw 0x30e4c(%rip), %ax      # 0x39a55
movw %ax, -0x12(%rbp)
movl -0x4(%rbp), %edi
leaq -0x12(%rbp), %rsi
movl $0x2, %edx
callq 0x18ab0
movq -0x10(%rbp), %rdi
movl -0x4(%rbp), %esi
callq 0x18b40
movq -0x10(%rbp), %rdi
xorl %esi, %esi
callq 0x18bd0
movsbl %al, %eax
cmpl $0x4e, %eax
je 0x8c5a
movl $0x1, %edi
callq 0x5220
movq %rax, %rdi
leaq 0x47ebf(%rip), %rsi     # 0x50b10
xorl %eax, %eax
movl %eax, %edx
callq 0x5840
movq $0x9, -0x20(%rbp)
movq -0x10(%rbp), %rdi
movl -0x4(%rbp), %esi
movl $0x9, %edx
callq 0x18f00
movq -0x10(%rbp), %rdi
leaq -0x28(%rbp), %rsi
movl $0x1, %edx
movl $0x8, %ecx
callq 0x18d30
movq -0x10(%rbp), %rdi
movl $0x9, %esi
callq 0x18de0
cmpq $0x0, -0x28(%rbp)
jne 0x8ca4
jmp 0x8eb7
movq -0x10(%rbp), %rdi
callq 0x191c0
cmpl $0x0, %eax
jne 0x8cbe
movq -0x10(%rbp), %rdi
movl -0x4(%rbp), %esi
callq 0x193e0
leaq -0x48(%rbp), %rdi
callq 0x5700
cmpq $0x0, -0x28(%rbp)
jbe 0x8ea7
jmp 0x8cd4
movq -0x10(%rbp), %rdi
movq %rdi, -0x80(%rbp)
xorl %esi, %esi
callq 0x194d0
movq -0x80(%rbp), %rdi
movq %rax, %rsi
callq 0x1a740
movl %eax, -0x74(%rbp)
jmp 0x8cf4
movl -0x74(%rbp), %eax
movl %eax, -0x4c(%rbp)
movl -0x4c(%rbp), %eax
movq %rax, -0x68(%rbp)
leaq -0x68(%rbp), %rdi
leaq -0x28(%rbp), %rsi
callq 0x18640
movq (%rax), %rax
movl %eax, -0x60(%rbp)
movl $0x0, -0x6c(%rbp)
movl -0x6c(%rbp), %eax
cmpl -0x60(%rbp), %eax
jae 0x8e00
movq -0x10(%rbp), %rdi
movl -0x6c(%rbp), %esi
callq 0x18bd0
movsbl %al, %eax
cmpl $0x0, %eax
jne 0x8df0
movq -0x10(%rbp), %rdi
xorl %esi, %esi
movl %esi, -0x8c(%rbp)
callq 0x194d0
movl -0x8c(%rbp), %esi
movq %rax, -0x88(%rbp)
movq -0x10(%rbp), %rdi
callq 0x194d0
movq -0x88(%rbp), %rsi
movq %rax, %rdx
movl -0x6c(%rbp), %eax
addq %rax, %rdx
leaq -0x48(%rbp), %rdi
callq 0x1a7d0
jmp 0x8d81
movq -0x10(%rbp), %rdi
movl -0x6c(%rbp), %esi
incl %esi
callq 0x18de0
movl -0x6c(%rbp), %eax
incl %eax
movl %eax, %ecx
movq -0x28(%rbp), %rax
subq %rcx, %rax
movq %rax, -0x28(%rbp)
leaq 0x48ac0(%rip), %rdi     # 0x51868
leaq -0x48(%rbp), %rsi
xorl %edx, %edx
callq 0x162b0
jmp 0x8db5
leaq -0x48(%rbp), %rdi
callq 0x5680
cmpq $0x0, -0x28(%rbp)
jne 0x8deb
movl $0x1, -0x70(%rbp)
jmp 0x8eae
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
leaq -0x48(%rbp), %rdi
callq 0x5320
jmp 0x8ec0
jmp 0x8cd4
jmp 0x8df2
movl -0x6c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x6c(%rbp)
jmp 0x8d1b
movq -0x10(%rbp), %rdi
xorl %esi, %esi
movl %esi, -0x9c(%rbp)
callq 0x194d0
movl -0x9c(%rbp), %esi
movq %rax, -0x98(%rbp)
movq -0x10(%rbp), %rdi
callq 0x194d0
movq -0x98(%rbp), %rsi
movq %rax, %rdx
movl -0x60(%rbp), %eax
addq %rax, %rdx
leaq -0x48(%rbp), %rdi
callq 0x1a7d0
jmp 0x8e42
movq -0x10(%rbp), %rdi
movl -0x60(%rbp), %esi
callq 0x18de0
movl -0x60(%rbp), %eax
movl %eax, %ecx
movq -0x28(%rbp), %rax
subq %rcx, %rax
movq %rax, -0x28(%rbp)
cmpq $0x0, -0x28(%rbp)
jne 0x8e84
movl $0x1, %edi
callq 0x5220
movq %rax, %rdi
leaq 0x47c97(%rip), %rsi     # 0x50b10
xorl %eax, %eax
movl %eax, %edx
callq 0x5840
jmp 0x8ec9
movq -0x10(%rbp), %rdi
callq 0x191c0
cmpl $0x0, %eax
jne 0x8ea2
movq -0x10(%rbp), %rdi
movl -0x4(%rbp), %esi
callq 0x193e0
jmp 0x8ea0
jmp 0x8ea2
jmp 0x8cc7
movl $0x0, -0x70(%rbp)
leaq -0x48(%rbp), %rdi
callq 0x5320
addq $0xa0, %rsp
popq %rbp
retq
movq -0x58(%rbp), %rdi
callq 0x5870
nopl (%rax)