// File: /workspace/github_cpp_makefile_star2_O1/davmac314[P]dinit/src/shutdown.cc
// Function: main
int main(int argc, char **argv)
{
    using namespace std;
    
    bool show_help = false;
    bool sys_shutdown = false;
    bool use_passed_cfd = false;
    
    auto shutdown_type = shutdown_type_t::POWEROFF;

    const char *execname = base_name(argv[0]);
    if (strcmp(execname, reboot_execname) == 0) {
        shutdown_type = shutdown_type_t::REBOOT;
    }
    else if (strcmp(execname, soft_reboot_execname) == 0) {
        shutdown_type = shutdown_type_t::SOFTREBOOT;
    }
        
    for (int i = 1; i < argc; i++) {
        if (argv[i][0] == '-') {
            if (strcmp(argv[i], "--help") == 0) {
                show_help = true;
                break;
            }
            
            if (strcmp(argv[i], "--system") == 0) {
                sys_shutdown = true;
            }
            else if (strcmp(argv[i], "-r") == 0) {
                shutdown_type = shutdown_type_t::REBOOT;
            }
            else if (strcmp(argv[i], "-h") == 0) {
                shutdown_type = shutdown_type_t::HALT;
            }
            else if (strcmp(argv[i], "-p") == 0) {
                shutdown_type = shutdown_type_t::POWEROFF;
            }
            else if (strcmp(argv[i], "-s") == 0) {
                shutdown_type = shutdown_type_t::SOFTREBOOT;
            }
            else if (strcmp(argv[i], "-k") == 0) {
                shutdown_type = shutdown_type_t::KEXEC;
            }
            else if (strcmp(argv[i], "--use-passed-cfd") == 0) {
                use_passed_cfd = true;
            }
            else {
                cerr << "Unrecognized command-line parameter: " << argv[i] << endl;
                return 1;
            }
        }
        else {
            // time argument? TODO
            show_help = true;
        }
    }

    if (show_help) {
        cout << execname << " :   shutdown the system\n"
                "  --help           : show this help\n"
                "  -r               : reboot\n"
                "  -s               : soft-reboot (restart dinit with same boot-time arguments)\n"
#if defined(RB_HALT_SYSTEM) || defined(RB_HALT)
                "  -h               : halt system\n"
#endif
#ifdef RB_POWER_OFF
                "  -p               : power down (default)\n"
#endif
#ifdef RB_KEXEC
                "  -k               : stop dinit and reboot directly into kernel loaded with kexec\n"
#endif
                "  --use-passed-cfd : use the socket file descriptor identified by the DINIT_CS_FD\n"
                "                     environment variable to communicate with the init daemon.\n"
                "  --system         : perform shutdown immediately, instead of issuing shutdown\n"
                "                     command to the init program. Not recommended for use\n"
                "                     by users.\n";
        return 1;
    }
    
    if (sys_shutdown) {
        do_system_shutdown(shutdown_type);
        return 1; // likely to cause panic; the above shouldn't return
    }

    if (reboot_cmd_unsupported(shutdown_type)) {
        cerr << "Unsupported shutdown type\n";
        return 1;
    }

    signal(SIGPIPE, SIG_IGN);
    
    int socknum = -1;
    
    if (use_passed_cfd) {
        socknum = get_passed_cfd();
        if (socknum == -1) {
            use_passed_cfd = false;
        }
    }
    
    if (!use_passed_cfd) {
        socknum = socket(AF_UNIX, SOCK_STREAM, 0);
        if (socknum == -1) {
            perror("socket");
            return 1;
        }
        
        const char *naddr = SYSCONTROLSOCKET;
        
        struct sockaddr_un name;
        name.sun_family = AF_UNIX;
        strcpy(name.sun_path, naddr);
        int sunlen = offsetof(struct sockaddr_un, sun_path) + strlen(naddr) + 1; // family, (string), nul
        
        int connr = connect(socknum, (struct sockaddr *) &name, sunlen);
        if (connr == -1) {
            perror("connect");
            return 1;
        }
    }

    try {
        cpbuffer_t rbuffer;
    
        check_protocol_version(min_cp_version, max_cp_version, rbuffer, socknum);

        // Build buffer;
        constexpr int bufsize = 2;
        char buf[bufsize];

        buf[0] = (dinit_cptypes::cp_cmd_t)cp_cmd::SHUTDOWN;
        buf[1] = static_cast<char>(shutdown_type);

        cout << "Issuing shutdown command..." << endl;

        write_all_x(socknum, buf, bufsize);

        // Wait for ACK/NACK
    
        wait_for_reply(rbuffer, socknum);
        
        if (rbuffer[0] != (dinit_cptypes::cp_rply_t)cp_rply::ACK) {
            cerr << "shutdown: control socket protocol error" << endl;
            return 1;
        }
    }
    catch (cp_old_client_exception &e) {
        std::cerr << "shutdown: too old (server reports newer protocol version)" << std::endl;
        return 1;
    }
    catch (cp_old_server_exception &e) {
        std::cerr << "shutdown: server too old or protocol error" << std::endl;
        return 1;
    }
    catch (cp_read_exception &e) {
        cerr << "shutdown: control socket read failure or protocol error" << endl;
        return 1;
    }
    catch (cp_write_exception &e) {
        cerr << "shutdown: control socket write error: " << std::strerror(e.errcode) << endl;
        return 1;
    }

    while (true) {
        pause();
    }
    
    return 0;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x418, %rsp            # imm = 0x418
movq %rsi, %r14
movl %edi, %ebp
movq (%rsi), %rbx
leaq 0x1(%rbx), %rax
movzbl -0x1(%rax), %ecx
cmpl $0x2f, %ecx
je 0x3688
testl %ecx, %ecx
jne 0x368b
jmp 0x3690
movq %rax, %rbx
incq %rax
jmp 0x3679
leaq 0x5999(%rip), %rsi      # 0x9030
movq %rbx, %rdi
callq 0x3370
testl %eax, %eax
je 0x36c1
leaq 0x598d(%rip), %rsi      # 0x9037
movq %rbx, %rdi
callq 0x3370
testl %eax, %eax
sete %r13b
addb %r13b, %r13b
addb $0x3, %r13b
jmp 0x36c4
movb $0x4, %r13b
cmpl $0x2, %ebp
jl 0x3803
movb %r13b, 0x1(%rsp)
movl %ebp, %r13d
movl $0x1, %r15d
movl $0x0, 0xc(%rsp)
movl $0x0, 0x8(%rsp)
movl $0x0, 0x4(%rsp)
movq (%r14,%r15,8), %rbp
movb $0x1, %r12b
cmpb $0x2d, (%rbp)
jne 0x37b0
movq %rbp, %rdi
leaq 0x5c46(%rip), %rsi      # 0x9354
callq 0x3370
testl %eax, %eax
je 0x3811
movq %rbp, %rdi
leaq 0x5c36(%rip), %rsi      # 0x935b
callq 0x3370
testl %eax, %eax
je 0x37b8
movq %rbp, %rdi
leaq 0x5c28(%rip), %rsi      # 0x9364
callq 0x3370
testl %eax, %eax
je 0x37c0
movq %rbp, %rdi
leaq 0x5c18(%rip), %rsi      # 0x9367
callq 0x3370
testl %eax, %eax
je 0x37c7
movq %rbp, %rdi
leaq 0x5c08(%rip), %rsi      # 0x936a
callq 0x3370
testl %eax, %eax
je 0x37ce
movq %rbp, %rdi
leaq 0x5bf8(%rip), %rsi      # 0x936d
callq 0x3370
testl %eax, %eax
je 0x37d5
movq %rbp, %rdi
leaq 0x5be8(%rip), %rsi      # 0x9370
callq 0x3370
testl %eax, %eax
je 0x37dc
movq %rbp, %rdi
leaq 0x5bd8(%rip), %rsi      # 0x9373
callq 0x3370
testl %eax, %eax
jne 0x3b44
movb $0x1, %al
movl %eax, 0x4(%rsp)
jmp 0x37e1
movb $0x1, %al
movl %eax, 0xc(%rsp)
jmp 0x37e1
movb $0x1, %al
movl %eax, 0x8(%rsp)
jmp 0x37e1
movb $0x4, 0x1(%rsp)
jmp 0x37e1
movb $0x2, 0x1(%rsp)
jmp 0x37e1
movb $0x3, 0x1(%rsp)
jmp 0x37e1
movb $0x5, 0x1(%rsp)
jmp 0x37e1
movb $0x6, 0x1(%rsp)
incq %r15
cmpq %r15, %r13
jne 0x36f3
xorl %r15d, %r15d
movb 0x1(%rsp), %r13b
movl 0x4(%rsp), %ebp
movl 0x8(%rsp), %eax
movl 0xc(%rsp), %ecx
jmp 0x3826
xorl %ebp, %ebp
movb $0x1, %r12b
xorl %eax, %eax
xorl %ecx, %ecx
xorl %r15d, %r15d
jmp 0x3826
xorl %r15d, %r15d
movb $0x1, %r12b
movb $0x1, %cl
movb 0x1(%rsp), %r13b
movl 0x4(%rsp), %ebp
movl 0x8(%rsp), %eax
testb %r12b, %r12b
je 0x3858
testb $0x1, %cl
je 0x3860
testq %rbx, %rbx
je 0x390f
movq %rbx, %rdi
callq 0x30f0
movq 0xa770(%rip), %rdi      # 0xdfb8
movq %rbx, %rsi
movq %rax, %rdx
callq 0x32c0
jmp 0x392d
movl %r15d, %ebp
jmp 0x394a
testb $0x1, %al
je 0x3872
movsbl %r13b, %edi
callq 0x3d09
jmp 0x3945
movl $0x1, %esi
movl $0xd, %edi
callq 0x32d0
movl $0xffffffff, %ebx       # imm = 0xFFFFFFFF
testb $0x1, %bpl
je 0x396f
leaq 0x6045(%rip), %rdi      # 0x98dc
callq 0x32e0
testq %rax, %rax
je 0x395e
movq %rax, %rbx
leaq 0x10(%rsp), %r12
movq %rax, %rdi
movq %r12, %rsi
movl $0xa, %edx
callq 0x3380
cmpq %rbx, (%r12)
je 0x395e
movq %rax, %r14
callq 0x3040
movq %rax, %r12
movl $0x0, (%rax)
xorl %ebx, %ebx
movl %r14d, %edi
movl $0x3, %esi
xorl %edx, %edx
xorl %eax, %eax
callq 0x3170
cmpl $-0x1, %eax
je 0x3b81
andl $0xfffff7ff, %eax       # imm = 0xFFFFF7FF
movl %r14d, %edi
movl $0x4, %esi
movl %eax, %edx
xorl %eax, %eax
callq 0x3170
movl %r14d, %ebx
jmp 0x3963
movq 0xa6a2(%rip), %rax      # 0xdfb8
movq (%rax), %rcx
movq -0x18(%rcx), %rcx
leaq (%rax,%rcx), %rdi
movl 0x20(%rax,%rcx), %esi
orl $0x1, %esi
callq 0x3420
movq 0xa684(%rip), %rdi      # 0xdfb8
leaq 0x5a6f(%rip), %rsi      # 0x93aa
movl $0x29e, %edx            # imm = 0x29E
callq 0x32c0
movl $0x1, %ebp
movl %ebp, %eax
addq $0x418, %rsp            # imm = 0x418
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movl $0xffffffff, %ebx       # imm = 0xFFFFFFFF
xorl %eax, %eax
cmpl $-0x1, %ebx
movzbl %bpl, %ebp
cmovel %eax, %ebp
testb $0x1, %bpl
jne 0x39e1
movl $0x1, %ebp
movl $0x1, %edi
movl $0x1, %esi
xorl %edx, %edx
callq 0x3060
cmpl $-0x1, %eax
je 0x3b91
movl %eax, %ebx
leaq 0x10(%rsp), %rsi
movw $0x1, (%rsi)
movabsq $0x6e69642f6e75722f, %rax # imm = 0x6E69642F6E75722F
movq %rax, 0x2(%rsi)
movabsq $0x6c746374696e69, %rax # imm = 0x6C746374696E69
movq %rax, 0x8(%rsi)
movl %ebx, %edi
movl $0x10, %edx
callq 0x3200
movl %eax, %r14d
cmpl $-0x1, %eax
je 0x3ba2
movl %r15d, %ebp
cmpl $-0x1, %r14d
je 0x394a
leaq 0x10(%rsp), %rdx
movq $0x0, 0x400(%rdx)
movl $0x1, %edi
movl $0x5, %esi
movl %ebx, %ecx
callq 0x44b8
movb $0xa, 0x2(%rsp)
movb %r13b, 0x3(%rsp)
movq 0xa5a5(%rip), %r14      # 0xdfb8
leaq 0x5c4c(%rip), %rsi      # 0x9666
movl $0x1b, %edx
movq %r14, %rdi
callq 0x32c0
movq (%r14), %rax
addq -0x18(%rax), %r14
movq %r14, %rdi
movl $0xa, %esi
callq 0x3280
movsbl %al, %esi
movq 0xa573(%rip), %rdi      # 0xdfb8
callq 0x3030
movq %rax, %rdi
callq 0x31a0
movl $0x2, %r12d
leaq 0x2(%rsp), %r14
xorl %ebp, %ebp
movl %r12d, %edx
movl %ebx, %edi
movq %r14, %rsi
callq 0x30c0
cmpl $-0x1, %eax
je 0x3a80
addl %eax, %ebp
movslq %eax, %rcx
addq %rcx, %r14
subl %eax, %r12d
xorl %ecx, %ecx
jmp 0x3aa0
callq 0x3040
movl $0x2, %ecx
cmpl $0x4, (%rax)
je 0x3aa0
testl %ebp, %ebp
movl $0xffffffff, %r13d      # imm = 0xFFFFFFFF
cmovgl %ebp, %r13d
movl $0x1, %ecx
testb $0x1, %cl
jne 0x3aac
testl %r12d, %r12d
jg 0x3a5f
jmp 0x3aaf
movl %r13d, %ebp
cmpl $-0x1, %ebp
je 0x3bb9
leaq 0x10(%rsp), %rdi
movl %ebx, %esi
callq 0x4754
movl 0x410(%rsp), %eax
leal -0x400(%rax), %ecx
cmpl $0x400, %eax            # imm = 0x400
cmovbl %eax, %ecx
movb 0x10(%rsp,%rcx), %r14b
cmpb $0x32, %r14b
je 0x3b30
movq 0xa4fd(%rip), %rbx      # 0xdfe8
leaq 0x5b90(%rip), %rsi      # 0x9682
movl $0x27, %edx
movq %rbx, %rdi
callq 0x32c0
movq (%rbx), %rax
addq -0x18(%rax), %rbx
movq %rbx, %rdi
movl $0xa, %esi
callq 0x3280
movsbl %al, %esi
movq 0xa4cb(%rip), %rdi      # 0xdfe8
callq 0x3030
movl $0x1, %r15d
movq %rax, %rdi
callq 0x31a0
movl %r15d, %ebp
cmpb $0x32, %r14b
jne 0x394a
callq 0x3050
jmp 0x3b3d
movq 0xa49d(%rip), %r12      # 0xdfe8
leaq 0x5832(%rip), %rsi      # 0x9384
movl $0x25, %edx
movq %r12, %rdi
callq 0x32c0
movq (%r14,%r15,8), %rsi
movq %r12, %rdi
callq 0x3290
movq %rax, %rdi
callq 0x3120
movl $0x1, %r15d
xorl %r12d, %r12d
jmp 0x37f0
cmpl $0x0, (%r12)
jne 0x3963
jmp 0x38f4
leaq 0x5ab1(%rip), %rdi      # 0x9649
callq 0x3210
jmp 0x394a
leaq 0x5ab5(%rip), %rdi      # 0x965e
callq 0x3210
movl $0x1, %r15d
jmp 0x39d4
movl $0x4, %edi
callq 0x3130
movq %rax, %rbx
callq 0x3040
movl (%rax), %eax
movl %eax, (%rbx)
leaq 0x9e5a(%rip), %rsi      # 0xda30
movq %rbx, %rdi
xorl %edx, %edx
callq 0x3430
jmp 0x3be4
jmp 0x3be4
movq %rax, %rbx
cmpl $0x4, %edx
jne 0x3c1d
movq %rbx, %rdi
callq 0x30e0
movq 0xa3ed(%rip), %rdi      # 0xdfe8
leaq 0x5b32(%rip), %rsi      # 0x9734
movl $0x39, %edx
callq 0x32c0
movq 0xa3d5(%rip), %rdi      # 0xdfe8
callq 0x3120
jmp 0x3cc9
cmpl $0x3, %edx
jne 0x3c50
movq %rbx, %rdi
callq 0x30e0
movq 0xa3b7(%rip), %rdi      # 0xdfe8
leaq 0x5ad1(%rip), %rsi      # 0x9709
movl $0x2a, %edx
callq 0x32c0
movq 0xa39f(%rip), %rdi      # 0xdfe8
callq 0x3120
jmp 0x3cc9
cmpl $0x2, %edx
jne 0x3c83
movq %rbx, %rdi
callq 0x30e0
movq 0xa384(%rip), %rdi      # 0xdfe8
leaq 0x5a66(%rip), %rsi      # 0x96d1
movl $0x37, %edx
callq 0x32c0
movq 0xa36c(%rip), %rdi      # 0xdfe8
callq 0x3120
jmp 0x3cc9
cmpl $0x1, %edx
jne 0x3cf9
movq %rbx, %rdi
callq 0x30e0
movq %rax, %rbx
movq 0xa34e(%rip), %rdi      # 0xdfe8
leaq 0x5a09(%rip), %rsi      # 0x96aa
movl $0x26, %edx
callq 0x32c0
movl (%rbx), %edi
callq 0x30b0
movq 0xa32f(%rip), %rdi      # 0xdfe8
movq %rax, %rsi
callq 0x3290
movq %rax, %rdi
callq 0x3120
callq 0x3400
jmp 0x3945
movq %rax, %rbx
callq 0x3400
jmp 0x3cf9
movq %rax, %rbx
callq 0x3400
jmp 0x3cf9
movq %rax, %rbx
callq 0x3400
jmp 0x3cf9
movq %rax, %rbx
callq 0x3400
movq %rbx, %rdi
callq 0x3440
movq %rax, %rdi
callq 0x4904