// File: davmac314[P]dinit/src/dinit.cc
// Function: setup_external_log()
void setup_external_log() noexcept
{
    if (!external_log_open) {
        if (log_is_syslog) {
            const char * saddrname = log_path;
            size_t saddrname_len = strlen(saddrname);
            uint sockaddr_size = offsetof(struct sockaddr_un, sun_path) + saddrname_len + 1;

            struct sockaddr_un * name = static_cast<sockaddr_un *>(malloc(sockaddr_size));
            if (name == nullptr) {
                log(loglevel_t::ERROR, "Connecting to log socket: out of memory");
                return;
            }

            name->sun_family = AF_UNIX;
            memcpy(name->sun_path, saddrname, saddrname_len + 1);

            int sockfd = dinit_socket(AF_UNIX, SOCK_DGRAM, 0, SOCK_NONBLOCK | SOCK_CLOEXEC);
            if (sockfd == -1) {
                log(loglevel_t::ERROR, "Error creating log socket: ", strerror(errno));
                free(name);
                return;
            }

            if (connect(sockfd, (struct sockaddr *) name, sockaddr_size) == 0 || errno == EINPROGRESS) {
                // For EINPROGRESS, connection is still being established; however, we can select on
                // the file descriptor so we will be notified when it's ready. In other words we can
                // basically use it anyway.
                try {
                    setup_main_log(sockfd);
                    external_log_open = true;
                }
                catch (std::exception &e) {
                    log(loglevel_t::ERROR, "Setting up log failed: ", e.what());
                    close(sockfd);
                }
            }
            else {
                // Note if connect fails, we haven't warned at all, because the syslog server might not
                // have started yet.
                close(sockfd);
            }

            free(name);
        }
        else {
            // log to file:
            int log_fd = open(log_path, O_WRONLY | O_CREAT | O_APPEND | O_NONBLOCK | O_CLOEXEC, 0644);
            if (log_fd >= 0) {
                try {
                    setup_main_log(log_fd);
                    external_log_open = true;
                }
                catch (std::exception &e) {
                    log(loglevel_t::ERROR, "Setting up log failed: ", e.what());
                    close(log_fd);
                }
            }
            else {
                // log failure to log? It makes more sense than first appears, because we also log
                // to console:
                log(loglevel_t::ERROR, "Opening log file failed: ", strerror(errno));
            }
        }
    }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x80, %rsp
testb $0x1, 0x9b576(%rip)     # 0xa8cc8
jne 0xd9b2
testb $0x1, 0x9afb9(%rip)     # 0xa8718
je 0xd8e9
movq 0x9afb4(%rip), %rax     # 0xa8720
movq %rax, -0x8(%rbp)
movq -0x8(%rbp), %rdi
callq 0xa280
movq %rax, -0x10(%rbp)
movq -0x10(%rbp), %rax
addq $0x2, %rax
addq $0x1, %rax
movl %eax, -0x14(%rbp)
movl -0x14(%rbp), %eax
movl %eax, %edi
callq 0xa9e0
movq %rax, -0x20(%rbp)
cmpq $0x0, -0x20(%rbp)
jne 0xd7b7
movl $0x3, %edi
leaq 0x68a15(%rip), %rsi     # 0x761c2
callq 0x6b540
jmp 0xd9b2
movq -0x20(%rbp), %rax
movw $0x1, (%rax)
movq -0x20(%rbp), %rdi
addq $0x2, %rdi
movq -0x8(%rbp), %rsi
movq -0x10(%rbp), %rdx
incq %rdx
callq 0xa5b0
movl $0x1, %edi
movl $0x2, %esi
xorl %edx, %edx
movl $0x80800, %ecx          # imm = 0x80800
callq 0xdf80
movl %eax, -0x74(%rbp)
jmp 0xd7f3
movl -0x74(%rbp), %eax
movl %eax, -0x24(%rbp)
cmpl $-0x1, -0x24(%rbp)
jne 0xd832
callq 0xa060
movl (%rax), %edi
callq 0xa1f0
movq %rax, -0x30(%rbp)
movl $0x3, %edi
leaq 0x689cf(%rip), %rsi     # 0x761ea
leaq -0x30(%rbp), %rdx
callq 0xdfb0
movq -0x20(%rbp), %rdi
callq 0xa890
jmp 0xd9b2
movl -0x24(%rbp), %edi
movq -0x20(%rbp), %rsi
movl -0x14(%rbp), %edx
callq 0xa5d0
movl %eax, -0x78(%rbp)
jmp 0xd846
movl -0x78(%rbp), %eax
cmpl $0x0, %eax
je 0xd858
callq 0xa060
cmpl $0x73, (%rax)
jne 0xd8cf
movl -0x24(%rbp), %edi
callq 0x6b330
jmp 0xd862
movb $0x1, 0x9b45f(%rip)     # 0xa8cc8
jmp 0xd8cd
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x38(%rbp)
movl %eax, -0x3c(%rbp)
movl -0x3c(%rbp), %eax
movl $0x2, %ecx
cmpl %ecx, %eax
jne 0xd9c3
movq -0x38(%rbp), %rdi
callq 0xa240
movq %rax, -0x48(%rbp)
movq -0x48(%rbp), %rdi
movq (%rdi), %rax
movq 0x10(%rax), %rax
callq *%rax
movq %rax, -0x50(%rbp)
leaq 0x6895a(%rip), %rsi     # 0x76206
movl $0x3, %edi
leaq -0x50(%rbp), %rdx
callq 0xdfe0
movl -0x24(%rbp), %edi
callq 0xad80
jmp 0xd8c4
callq 0xac30
jmp 0xd8cb
jmp 0xd8cd
jmp 0xd8db
movl -0x24(%rbp), %edi
callq 0xad80
jmp 0xd8d9
jmp 0xd8db
movq -0x20(%rbp), %rdi
callq 0xa890
jmp 0xd9b0
movq 0x9ae30(%rip), %rdi     # 0xa8720
xorl %eax, %eax
movl $0x80c41, %esi          # imm = 0x80C41
movl $0x1a4, %edx            # imm = 0x1A4
callq 0xa520
movl %eax, -0x7c(%rbp)
jmp 0xd906
movl -0x7c(%rbp), %eax
movl %eax, -0x54(%rbp)
cmpl $0x0, -0x54(%rbp)
jl 0xd989
movl -0x54(%rbp), %edi
callq 0x6b330
jmp 0xd91c
movb $0x1, 0x9b3a5(%rip)     # 0xa8cc8
jmp 0xd987
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x38(%rbp)
movl %eax, -0x3c(%rbp)
movl -0x3c(%rbp), %eax
movl $0x2, %ecx
cmpl %ecx, %eax
jne 0xd9c3
movq -0x38(%rbp), %rdi
callq 0xa240
movq %rax, -0x60(%rbp)
movq -0x60(%rbp), %rdi
movq (%rdi), %rax
movq 0x10(%rax), %rax
callq *%rax
movq %rax, -0x68(%rbp)
leaq 0x688a0(%rip), %rsi     # 0x76206
movl $0x3, %edi
leaq -0x68(%rbp), %rdx
callq 0xdfe0
movl -0x54(%rbp), %edi
callq 0xad80
jmp 0xd97e
callq 0xac30
jmp 0xd985
jmp 0xd987
jmp 0xd9ae
callq 0xa060
movl (%rax), %edi
callq 0xa1f0
movq %rax, -0x70(%rbp)
movl $0x3, %edi
leaq 0x68879(%rip), %rsi     # 0x7621e
leaq -0x70(%rbp), %rdx
callq 0xe010
jmp 0xd9b0
jmp 0xd9b2
addq $0x80, %rsp
popq %rbp
retq
movq %rax, %rdi
callq 0xfa30
movq -0x38(%rbp), %rdi
callq 0xfa30
nopl (%rax)