// File: /workspace/github_cpp_makefile_star2_O3/davmac314[P]dinit/src/control.cc
// Function: control_conn_t::process_packet()
bool control_conn_t::process_packet()
{
    using std::string;
    
    // Note that where we call queue_packet, we must generally check the return value. If it
    // returns false it has either deleted the connection or marked it for deletion; we
    // shouldn't touch instance members after that point.

    cp_cmd pkt_type = (cp_cmd)rbuf[0];

    switch (pkt_type) {
        case cp_cmd::QUERYVERSION:
        {
            // Responds with:
            // cp_rply::CPVERSION, (2 byte) minimum compatible version, (2 byte) actual version
            char replyBuf[] = { (char)cp_rply::CPVERSION, 0, 0, 0, 0 };
            memcpy(replyBuf + 1, &min_compat_version, 2);
            memcpy(replyBuf + 3, &cp_version, 2);
            if (!queue_packet(replyBuf, sizeof(replyBuf))) return false;
            rbuf.consume(1);
            return true;
        }
        case cp_cmd::FINDSERVICE:
        case cp_cmd::LOADSERVICE:
            return process_find_load(pkt_type);
        case cp_cmd::CLOSEHANDLE:
            return process_close_handle();
        case cp_cmd::STARTSERVICE:
        case cp_cmd::STOPSERVICE:
        case cp_cmd::WAKESERVICE:
        case cp_cmd::RELEASESERVICE:
            return process_start_stop(pkt_type);
        case cp_cmd::UNPINSERVICE:
            return process_unpin_service();
        case cp_cmd::UNLOADSERVICE:
            return process_unload_service();
        case cp_cmd::RELOADSERVICE:
            return process_reload_service();
        case cp_cmd::SHUTDOWN:
            // Shutdown/reboot
            if (rbuf.get_length() < 2) {
                chklen = 2;
                return true;
            }

            if (contains({shutdown_type_t::REMAIN, shutdown_type_t::HALT,
                    shutdown_type_t::POWEROFF, shutdown_type_t::REBOOT,
                    shutdown_type_t::SOFTREBOOT, shutdown_type_t::KEXEC}, rbuf[1])) {
                auto sd_type = static_cast<shutdown_type_t>(rbuf[1]);

                services->stop_all_services(sd_type);
                char ackBuf[] = { (char)cp_rply::ACK };
                if (! queue_packet(ackBuf, 1)) return false;

                // Clear the packet from the buffer
                rbuf.consume(2);
                chklen = 0;
                return true;
            }

            break;
        case cp_cmd::LISTSERVICES:
            return list_services();
        case cp_cmd::LISTSERVICES5:
            return list_services5();
        case cp_cmd::SERVICESTATUS:
            return process_service_status();
        case cp_cmd::SERVICESTATUS5:
            return process_service_status5();
        case cp_cmd::ADD_DEP:
            return add_service_dep();
        case cp_cmd::REM_DEP:
            return rm_service_dep();
        case cp_cmd::QUERY_LOAD_MECH:
            return query_load_mech();
        case cp_cmd::ENABLESERVICE:
            return add_service_dep(true);
        case cp_cmd::QUERYSERVICENAME:
            return process_query_name();
        case cp_cmd::SETENV:
            return process_setenv();
        case cp_cmd::GETALLENV:
            return process_getallenv();
        case cp_cmd::LISTENENV:
            return process_listenenv();
        case cp_cmd::SETTRIGGER:
            return process_set_trigger();
        case cp_cmd::CATLOG:
            return process_catlog();
        case cp_cmd::SIGNAL:
            return process_signal();
        case cp_cmd::QUERYSERVICEDSCDIR:
            return process_query_dsc_dir();
        default:
            break;
    }

    // Unrecognized: give error response
    char outbuf[] = { (char)cp_rply::BADREQ };
    if (!queue_packet(outbuf, 1)) return false;
    bad_conn_close = true;
    return true;
}

// Assembly:
pushq %rbp
pushq %rbx
subq $0x18, %rsp
movq %rdi, %rbx
movl 0x480(%rdi), %eax
leal -0x400(%rax), %ecx
cmpl $0x400, %eax            # imm = 0x400
cmovbl %eax, %ecx
movzbl 0x80(%rdi,%rcx), %ecx
cmpq $0x1b, %rcx
ja 0x28012
leaq 0xe5d6(%rip), %rdx      # 0x363b8
movslq (%rdx,%rcx,4), %rsi
addq %rdx, %rsi
jmpq *%rsi
movzbl %cl, %esi
movq %rbx, %rdi
addq $0x18, %rsp
popq %rbx
popq %rbp
jmp 0x28670
movzbl %cl, %esi
movq %rbx, %rdi
addq $0x18, %rsp
popq %rbx
popq %rbp
jmp 0x2812c
movq %rbx, %rdi
addq $0x18, %rsp
popq %rbx
popq %rbp
jmp 0x29414
movq %rbx, %rdi
addq $0x18, %rsp
popq %rbx
popq %rbp
jmp 0x2a464
movq %rbx, %rdi
addq $0x18, %rsp
popq %rbx
popq %rbp
jmp 0x2a4d8
movq %rbx, %rdi
addq $0x18, %rsp
popq %rbx
popq %rbp
jmp 0x29cb8
movq %rbx, %rdi
addq $0x18, %rsp
popq %rbx
popq %rbp
jmp 0x28b40
movq %rbx, %rdi
addq $0x18, %rsp
popq %rbx
popq %rbp
jmp 0x28ce2
cmpl $0x1, 0x484(%rbx)
ja 0x27f8b
movl $0x2, 0x7c(%rbx)
movb $0x1, %al
jmp 0x2802f
movq %rbx, %rdi
movl $0x1, %esi
jmp 0x27ef4
leaq 0xb(%rsp), %rsi
movb $0x3a, (%rsi)
movl $0x50001, 0x1(%rsi)     # imm = 0x50001
movq %rbx, %rdi
movl $0x5, %edx
callq 0x28036
testb %al, %al
je 0x2802f
movl 0x480(%rbx), %ecx
leal 0x1(%rcx), %edx
addl $0xfffffc01, %ecx       # imm = 0xFFFFFC01
cmpl $0x400, %edx            # imm = 0x400
cmovbl %edx, %ecx
movl %ecx, 0x480(%rbx)
decl 0x484(%rbx)
jmp 0x2802f
movq %rbx, %rdi
addq $0x18, %rsp
popq %rbx
popq %rbp
jmp 0x28a10
movq %rbx, %rdi
addq $0x18, %rsp
popq %rbx
popq %rbp
jmp 0x28ede
movq %rbx, %rdi
xorl %esi, %esi
addq $0x18, %rsp
popq %rbx
popq %rbp
jmp 0x295a4
movq %rbx, %rdi
addq $0x18, %rsp
popq %rbx
popq %rbp
jmp 0x290ae
movq %rbx, %rdi
addq $0x18, %rsp
popq %rbx
popq %rbp
jmp 0x2a2ba
movq %rbx, %rdi
addq $0x18, %rsp
popq %rbx
popq %rbp
jmp 0x29a72
movq %rbx, %rdi
addq $0x18, %rsp
popq %rbx
popq %rbp
jmp 0x29eea
movq %rbx, %rdi
addq $0x18, %rsp
popq %rbx
popq %rbp
jmp 0x2a678
movq %rbx, %rdi
addq $0x18, %rsp
popq %rbx
popq %rbp
jmp 0x2a8b0
movq %rbx, %rdi
addq $0x18, %rsp
popq %rbx
popq %rbp
jmp 0x2a08c
movq %rbx, %rdi
addq $0x18, %rsp
popq %rbx
popq %rbp
jmp 0x2927e
movq %rbx, %rdi
addq $0x18, %rsp
popq %rbx
popq %rbp
jmp 0x2aa9c
movq %rbx, %rdi
addq $0x18, %rsp
popq %rbx
popq %rbp
jmp 0x284c4
leaq 0x10(%rsp), %rdi
movl $0x4030201, (%rdi)      # imm = 0x4030201
movw $0x605, 0x4(%rdi)       # imm = 0x605
leal 0x1(%rax), %ecx
addl $0xfffffc01, %eax       # imm = 0xFFFFFC01
cmpl $0x400, %ecx            # imm = 0x400
cmovbl %ecx, %eax
movsbl 0x80(%rbx,%rax), %ebp
movl %ebp, %esi
callq 0x28e92
testb %al, %al
je 0x28012
movq 0x70(%rbx), %rdi
movl %ebp, %esi
callq 0xd442
leaq 0xa(%rsp), %rsi
movb $0x32, (%rsi)
movq %rbx, %rdi
movl $0x1, %edx
callq 0x28036
testb %al, %al
je 0x2802f
movl 0x480(%rbx), %ecx
leal 0x2(%rcx), %edx
addl $0xfffffc02, %ecx       # imm = 0xFFFFFC02
cmpl $0x400, %edx            # imm = 0x400
cmovbl %edx, %ecx
movl %ecx, 0x480(%rbx)
addl $-0x2, 0x484(%rbx)
movl $0x0, 0x7c(%rbx)
jmp 0x2802f
leaq 0x9(%rsp), %rsi
movb $0x34, (%rsi)
movq %rbx, %rdi
movl $0x1, %edx
callq 0x28036
testb %al, %al
je 0x2802f
movb $0x1, 0x78(%rbx)
addq $0x18, %rsp
popq %rbx
popq %rbp
retq