// File: davmac314[P]dinit/src/control.cc
// Function: control_conn_t::process_unload_service()
bool control_conn_t::process_unload_service()
{
    using std::string;

    constexpr int pkt_size = 1 + sizeof(handle_t);

    if (rbuf.get_length() < pkt_size) {
        chklen = pkt_size;
        return true;
    }

    // 1 byte: packet type
    // 4 bytes: service handle

    handle_t handle;
    rbuf.extract((char *) &handle, 1, sizeof(handle));

    service_record *service = find_service_for_key(handle);
    if (service == nullptr) {
        // Service handle is bad
        char badreq_rep[] = { (char)cp_rply::BADREQ };
        if (! queue_packet(badreq_rep, 1)) return false;
        bad_conn_close = true;
        return true;
    }

    if (!service->has_lone_ref() || service->get_state() != service_state_t::STOPPED) {
        // Cannot unload: has other references
        char nak_rep[] = { (char)cp_rply::NAK };
        if (!queue_packet(nak_rep, 1)) return false;
    }
    else {
        // unload (this may fail with bad_alloc)
        services->unload_service(service);

        // drop handle
        service_key_map.erase(service);
        key_service_map.erase(handle);

        // send ack
        char ack_buf[] = { (char) cp_rply::ACK };
        if (!queue_packet(ack_buf, 1)) return false;
    }

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

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x30, %rsp
movq %rdi, -0x10(%rbp)
movq -0x10(%rbp), %rdi
movq %rdi, -0x30(%rbp)
movl $0x5, -0x14(%rbp)
addq $0x80, %rdi
callq 0x5e200
cmpl $0x5, %eax
jae 0x59330
movq -0x30(%rbp), %rax
movl $0x5, 0x7c(%rax)
movb $0x1, -0x1(%rbp)
jmp 0x5946d
movq -0x30(%rbp), %rdi
addq $0x80, %rdi
leaq -0x18(%rbp), %rsi
movl $0x1, %edx
movl $0x4, %ecx
callq 0x5e220
movq -0x30(%rbp), %rdi
movl -0x18(%rbp), %esi
callq 0x5e970
movq %rax, -0x20(%rbp)
cmpq $0x0, -0x20(%rbp)
jne 0x5939e
movq -0x30(%rbp), %rdi
movb 0x200d4(%rip), %al      # 0x79443
movb %al, -0x21(%rbp)
leaq -0x21(%rbp), %rsi
movl $0x1, %edx
callq 0x58340
testb $0x1, %al
jne 0x5938d
movb $0x0, -0x1(%rbp)
jmp 0x5946d
movq -0x30(%rbp), %rax
movb $0x1, 0x78(%rax)
movb $0x1, -0x1(%rbp)
jmp 0x5946d
movq -0x20(%rbp), %rdi
movl $0x1, %esi
callq 0x5ea80
testb $0x1, %al
jne 0x593b2
jmp 0x593bf
movq -0x20(%rbp), %rdi
callq 0x2f0d0
cmpb $0x0, %al
je 0x593e9
movq -0x30(%rbp), %rdi
movb 0x2007b(%rip), %al      # 0x79444
movb %al, -0x22(%rbp)
leaq -0x22(%rbp), %rsi
movl $0x1, %edx
callq 0x58340
testb $0x1, %al
jne 0x593e7
movb $0x0, -0x1(%rbp)
jmp 0x5946d
jmp 0x59449
movq -0x30(%rbp), %rax
movq 0x70(%rax), %rdi
movq -0x20(%rbp), %rsi
callq 0x5ebb0
movq -0x30(%rbp), %rdi
addq $0x488, %rdi            # imm = 0x488
leaq -0x20(%rbp), %rsi
callq 0x5eeb0
movq -0x30(%rbp), %rdi
addq $0x4c0, %rdi            # imm = 0x4C0
leaq -0x18(%rbp), %rsi
callq 0x5eee0
movq -0x30(%rbp), %rdi
movb 0x20019(%rip), %al      # 0x79445
movb %al, -0x23(%rbp)
leaq -0x23(%rbp), %rsi
movl $0x1, %edx
callq 0x58340
testb $0x1, %al
jne 0x59447
movb $0x0, -0x1(%rbp)
jmp 0x5946d
jmp 0x59449
movq -0x30(%rbp), %rdi
addq $0x80, %rdi
movl $0x5, %esi
callq 0x5e1a0
movq -0x30(%rbp), %rax
movl $0x0, 0x7c(%rax)
movb $0x1, -0x1(%rbp)
movb -0x1(%rbp), %al
andb $0x1, %al
addq $0x30, %rsp
popq %rbp
retq
nopl (%rax,%rax)