// File: /workspace/github_cpp_makefile_star2_O1/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 0x27fae
leaq 0xe68e(%rip), %rdx      # 0x36400
movslq (%rdx,%rcx,4), %rsi
addq %rdx, %rsi
jmpq *%rsi
movzbl %cl, %esi
movq %rbx, %rdi
addq $0x18, %rsp
popq %rbx
popq %rbp
jmp 0x28624
movzbl %cl, %esi
movq %rbx, %rdi
addq $0x18, %rsp
popq %rbx
popq %rbp
jmp 0x280cc
movq %rbx, %rdi
addq $0x18, %rsp
popq %rbx
popq %rbp
jmp 0x29462
movq %rbx, %rdi
addq $0x18, %rsp
popq %rbx
popq %rbp
jmp 0x2a596
movq %rbx, %rdi
addq $0x18, %rsp
popq %rbx
popq %rbp
jmp 0x2a60a
movq %rbx, %rdi
addq $0x18, %rsp
popq %rbx
popq %rbp
jmp 0x29dd8
movq %rbx, %rdi
addq $0x18, %rsp
popq %rbx
popq %rbp
jmp 0x28b5c
movq %rbx, %rdi
addq $0x18, %rsp
popq %rbx
popq %rbp
jmp 0x28cfe
cmpl $0x1, 0x484(%rbx)
ja 0x27f27
movl $0x2, 0x7c(%rbx)
movb $0x1, %al
jmp 0x27fcb
movq %rbx, %rdi
movl $0x1, %esi
jmp 0x27e90
leaq 0xc(%rsp), %rsi
movl $0x3a, (%rsi)
movb $0x0, 0x4(%rsi)
movw $0x1, 0x1(%rsi)
movw $0x5, 0x3(%rsi)
movq %rbx, %rdi
movl $0x5, %edx
callq 0x27fd2
testb %al, %al
je 0x27fcb
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 0x27fcb
movq %rbx, %rdi
addq $0x18, %rsp
popq %rbx
popq %rbp
jmp 0x28a2c
movq %rbx, %rdi
addq $0x18, %rsp
popq %rbx
popq %rbp
jmp 0x28efa
movq %rbx, %rdi
xorl %esi, %esi
addq $0x18, %rsp
popq %rbx
popq %rbp
jmp 0x29602
movq %rbx, %rdi
addq $0x18, %rsp
popq %rbx
popq %rbp
jmp 0x290dc
movq %rbx, %rdi
addq $0x18, %rsp
popq %rbx
popq %rbp
jmp 0x2a3ec
movq %rbx, %rdi
addq $0x18, %rsp
popq %rbx
popq %rbp
jmp 0x29b62
movq %rbx, %rdi
addq $0x18, %rsp
popq %rbx
popq %rbp
jmp 0x2a01c
movq %rbx, %rdi
addq $0x18, %rsp
popq %rbx
popq %rbp
jmp 0x2a7b0
movq %rbx, %rdi
addq $0x18, %rsp
popq %rbx
popq %rbp
jmp 0x2a9aa
movq %rbx, %rdi
addq $0x18, %rsp
popq %rbx
popq %rbp
jmp 0x2a1b8
movq %rbx, %rdi
addq $0x18, %rsp
popq %rbx
popq %rbp
jmp 0x292be
movq %rbx, %rdi
addq $0x18, %rsp
popq %rbx
popq %rbp
jmp 0x2ab98
movq %rbx, %rdi
addq $0x18, %rsp
popq %rbx
popq %rbp
jmp 0x2845c
leaq 0x12(%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 0x28eaf
testb %al, %al
je 0x27fae
movq 0x70(%rbx), %rdi
movl %ebp, %esi
callq 0xd98c
leaq 0xb(%rsp), %rsi
movb $0x32, (%rsi)
movq %rbx, %rdi
movl $0x1, %edx
callq 0x27fd2
testb %al, %al
je 0x27fcb
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 0x27fcb
leaq 0xa(%rsp), %rsi
movb $0x34, (%rsi)
movq %rbx, %rdi
movl $0x1, %edx
callq 0x27fd2
testb %al, %al
je 0x27fcb
movb $0x1, 0x78(%rbx)
addq $0x18, %rsp
popq %rbx
popq %rbp
retq