// File: /workspace/github_cpp_makefile_star2_O2/davmac314[P]dinit/src/control.cc
// Function: control_conn_t::query_load_mech()
bool control_conn_t::query_load_mech()
{
    rbuf.consume(1);
    chklen = 0;

    if (services->get_set_type_id() == SSET_TYPE_DIRLOAD) {
        dirload_service_set *dss = static_cast<dirload_service_set *>(services);
        std::vector<char> reppkt;
        reppkt.resize(2 + sizeof(uint32_t) * 2);  // packet type, loader type, packet size, # dirs
        reppkt[0] = (char)cp_rply::LOADER_MECH;
        reppkt[1] = SSET_TYPE_DIRLOAD;

        // Number of directories in load path:
        uint32_t sdirs = dss->get_service_dir_count();
        std::memcpy(reppkt.data() + 2 + sizeof(uint32_t), &sdirs, sizeof(sdirs));

        // Our current working directory, which above are relative to:
        // leave sizeof(uint32_t) for size, which we'll fill in afterwards:
        std::size_t curpos = reppkt.size() + sizeof(uint32_t);
#ifdef PATH_MAX
        uint32_t try_path_size = PATH_MAX;
#else
        uint32_t try_path_size = 2048;
#endif
        char *wd;
        while (true) {
            std::size_t total_size = curpos + std::size_t(try_path_size);
            if (total_size < curpos) {
                // Overflow. In theory we could now limit to size_t max, but the size must already
                // be crazy long; let's abort.
                char ack_rep[] = { (char)cp_rply::NAK };
                if (! queue_packet(ack_rep, 1)) return false;
                return true;
            }
            reppkt.resize(total_size);
            wd = getcwd(reppkt.data() + curpos, try_path_size);
            if (wd != nullptr) break;

            // Keep doubling the path size we try until it's big enough, or we get numeric overflow
            uint32_t new_try_path_size = try_path_size * uint32_t(2u);
            if (new_try_path_size < try_path_size) {
                // Overflow.
                char ack_rep[] = { (char)cp_rply::NAK };
                return queue_packet(ack_rep, 1);
            }
            try_path_size = new_try_path_size;
        }

        uint32_t wd_len = std::strlen(reppkt.data() + curpos);
        reppkt.resize(curpos + std::size_t(wd_len));
        std::memcpy(reppkt.data() + curpos - sizeof(uint32_t), &wd_len, sizeof(wd_len));

        // Each directory in the load path:
        for (int i = 0; uint32_t(i) < sdirs; i++) {
            const char *sdir = dss->get_service_dir(i);
            uint32_t dlen = std::strlen(sdir);
            auto cursize = reppkt.size();
            reppkt.resize(cursize + sizeof(dlen) + dlen);
            std::memcpy(reppkt.data() + cursize, &dlen, sizeof(dlen));
            std::memcpy(reppkt.data() + cursize + sizeof(dlen), sdir, dlen);
        }

        // Total packet size:
        uint32_t fsize = reppkt.size();
        std::memcpy(reppkt.data() + 2, &fsize, sizeof(fsize));

        if (! queue_packet(std::move(reppkt))) return false;
        return true;
    }
    else {
        // If we don't know how to deal with the service set type, send a NAK reply:
        char ack_rep[] = { (char)cp_rply::NAK };
        return queue_packet(ack_rep, 1);
    }
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x38, %rsp
movq %rdi, %rbx
addq $0x80, %rdi
pushq $0x1
popq %rsi
callq 0x25df2
andl $0x0, 0x7c(%rbx)
movq 0x70(%rbx), %rdi
movq (%rdi), %rax
callq *0x20(%rax)
cmpl $0x1, %eax
jne 0x249ed
movq 0x70(%rbx), %rbp
xorps %xmm0, %xmm0
leaq 0x10(%rsp), %rdi
movaps %xmm0, (%rdi)
andq $0x0, 0x10(%rdi)
pushq $0xa
popq %rsi
callq 0x17940
leaq 0x10(%rsp), %r14
movq (%r14), %rax
movb $0x40, (%rax)
movq (%r14), %rax
movb $0x1, 0x1(%rax)
movq 0x50(%rbp), %r12
subq 0x48(%rbp), %r12
shrq $0x4, %r12
movq (%r14), %rax
movl %r12d, 0x6(%rax)
movq 0x8(%r14), %r13
subq (%r14), %r13
addq $0x4, %r13
movl $0x1000, %eax           # imm = 0x1000
movl %eax, %r15d
movq %r13, %rsi
addq %r15, %rsi
jb 0x249d5
movq %r14, %rdi
callq 0x17940
movq 0x10(%rsp), %rdi
addq %r13, %rdi
movq %r15, %rsi
callq 0x8300
testq %rax, %rax
jne 0x24a07
leal (%r15,%r15), %eax
testl %r15d, %r15d
jns 0x249a4
leaq 0xf(%rsp), %rsi
movb $0x33, (%rsi)
pushq $0x1
popq %rdx
movq %rbx, %rdi
callq 0x234ec
jmp 0x24ac9
leaq 0x10(%rsp), %rsi
movb $0x33, (%rsi)
pushq $0x1
popq %rdx
movq %rbx, %rdi
callq 0x234ec
movl %eax, %ebx
jmp 0x24ad5
movq %rbx, 0x28(%rsp)
leaq 0x10(%rsp), %r14
movq (%r14), %rdi
addq %r13, %rdi
callq 0x8220
movq %rax, %r15
movl %r15d, %esi
addq %r13, %rsi
movq %r14, %rdi
callq 0x17940
leaq 0x10(%rsp), %rax
movq (%rax), %rax
movl %r15d, -0x4(%rax,%r13)
movl %r12d, %eax
shlq $0x4, %rax
movq %rax, 0x30(%rsp)
xorl %r14d, %r14d
cmpq %r14, 0x30(%rsp)
je 0x24aaf
movq %rbp, %rbx
movq 0x48(%rbp), %rax
movq (%rax,%r14), %r15
movq %r15, %rdi
callq 0x8220
movq %rax, %r13
movq 0x18(%rsp), %rbp
subq 0x10(%rsp), %rbp
movl %r13d, %r12d
leaq (%r12,%rbp), %rsi
addq $0x4, %rsi
leaq 0x10(%rsp), %rdi
callq 0x17940
movq 0x10(%rsp), %rax
movl %r13d, (%rax,%rbp)
movq 0x10(%rsp), %rax
leaq (%rax,%rbp), %rdi
addq $0x4, %rdi
movq %r15, %rsi
movq %r12, %rdx
callq 0x84d0
addq $0x10, %r14
movq %rbx, %rbp
jmp 0x24a49
leaq 0x10(%rsp), %rsi
movl 0x8(%rsi), %eax
movq (%rsi), %rcx
subl %ecx, %eax
movl %eax, 0x2(%rcx)
movq 0x28(%rsp), %rdi
callq 0x253ac
movl %eax, %ebx
leaq 0x10(%rsp), %rdi
callq 0xc3e8
movl %ebx, %eax
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0x24aec
jmp 0x24aec
jmp 0x24aec
movq %rax, %rbx
leaq 0x10(%rsp), %rdi
callq 0xc3e8
movq %rbx, %rdi
callq 0x8a90
nop