// File: davmac314[P]dinit/src/dinitctl.cc
// Function: cat_service_log(int, cpbuffer<1024u>&, char const*, bool)
static int cat_service_log(int socknum, cpbuffer_t &rbuffer, const char *service_name, bool do_clear)
{
    using namespace std;

    handle_t handle;
    if (!load_service(socknum, rbuffer, service_name, &handle, nullptr, true)) {
        return 1;
    }

    char flags = do_clear ? 1 : 0;

    // Issue CATLOG
    auto m = membuf()
             .append((char)cp_cmd::CATLOG)
             .append<char>(flags)
             .append(handle);
    write_all_x(socknum, m);

    wait_for_reply(rbuffer, socknum);
    if (rbuffer[0] == (char)cp_rply::NAK) {
        cerr << "dinitctl: cannot cat log for service not configured to buffer output.\n";
        return 1;
    }
    if (rbuffer[0] != (char)cp_rply::SERVICE_LOG) {
        cerr << "dinitctl: protocol error.\n";
        return 1;
    }

    fill_buffer_to(rbuffer, socknum, 2 + sizeof(unsigned));
    unsigned bufsize;
    rbuffer.extract(&bufsize, 2, sizeof(unsigned));
    rbuffer.consume(2 + sizeof(unsigned));

    // output the log
    if (bufsize > 0) {
        cout << flush;

        bool trailing_nl = false;
        char output_buf[cpbuffer_t::get_size()];
        while (bufsize > 0) {
            unsigned l = rbuffer.get_length();
            if (l == 0) {
                fill_buffer_to(rbuffer, socknum, 1);
            }
            l = std::min(rbuffer.get_length(), bufsize);
            rbuffer.extract(output_buf, 0, l);
            write(STDOUT_FILENO, output_buf, l);
            rbuffer.consume(l);
            bufsize -= l;
            trailing_nl = (output_buf[l - 1] == '\n');
        }

        if (!trailing_nl) {
            cout << "\n(last line is truncated or incomplete)\n";
        }
    }

    return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x450, %rsp            # imm = 0x450
movb %cl, %al
movl %edi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
andb $0x1, %al
movb %al, -0x19(%rbp)
movl -0x8(%rbp), %edi
movq -0x10(%rbp), %rsi
movq -0x18(%rbp), %rdx
leaq -0x20(%rbp), %rcx
xorl %eax, %eax
movl %eax, %r8d
movl $0x1, %r9d
callq 0xc5e0
testb $0x1, %al
jne 0xb71c
movl $0x1, -0x4(%rbp)
jmp 0xb923
movb -0x19(%rbp), %al
andb $0x1, %al
movb %al, -0x21(%rbp)
movb $0x14, -0x2c(%rbp)
leaq -0x2b(%rbp), %rdi
leaq -0x2c(%rbp), %rsi
callq 0x11b60
movb %al, -0x2a(%rbp)
leaq -0x2a(%rbp), %rdi
leaq -0x21(%rbp), %rsi
callq 0x11b90
movw %ax, -0x29(%rbp)
leaq -0x29(%rbp), %rdi
leaq -0x20(%rbp), %rsi
callq 0x11bc0
movl %eax, %ecx
movl %ecx, -0x27(%rbp)
shrq $0x20, %rax
movw %ax, -0x23(%rbp)
movl -0x8(%rbp), %edi
leaq -0x27(%rbp), %rsi
callq 0x11c10
movq -0x10(%rbp), %rdi
movl -0x8(%rbp), %esi
callq 0x11350
movq -0x10(%rbp), %rdi
xorl %esi, %esi
callq 0x113e0
movsbl %al, %eax
cmpl $0x33, %eax
jne 0xb7ad
movq 0x26853(%rip), %rdi     # 0x31fe8
leaq 0x19b28(%rip), %rsi     # 0x252c4
callq 0x53d0
movl $0x1, -0x4(%rbp)
jmp 0xb923
movq -0x10(%rbp), %rdi
xorl %esi, %esi
callq 0x113e0
movsbl %al, %eax
cmpl $0x49, %eax
je 0xb7df
movq 0x26821(%rip), %rdi     # 0x31fe8
leaq 0x199c6(%rip), %rsi     # 0x25194
callq 0x53d0
movl $0x1, -0x4(%rbp)
jmp 0xb923
movq -0x10(%rbp), %rdi
movl -0x8(%rbp), %esi
movl $0x6, %edx
callq 0x11440
movq -0x10(%rbp), %rdi
leaq -0x30(%rbp), %rsi
movl $0x2, %edx
movl $0x4, %ecx
callq 0x11540
movq -0x10(%rbp), %rdi
movl $0x6, %esi
callq 0x115f0
cmpl $0x0, -0x30(%rbp)
jbe 0xb91c
movq 0x26772(%rip), %rdi     # 0x31f98
movq 0x2677b(%rip), %rsi     # 0x31fa8
callq 0x5410
movb $0x0, -0x31(%rbp)
cmpl $0x0, -0x30(%rbp)
jbe 0xb901
movq -0x10(%rbp), %rdi
callq 0x12f00
movl %eax, -0x444(%rbp)
cmpl $0x0, -0x444(%rbp)
jne 0xb869
movq -0x10(%rbp), %rdi
movl -0x8(%rbp), %esi
movl $0x1, %edx
callq 0x11440
movq -0x10(%rbp), %rdi
callq 0x12f00
movl %eax, -0x448(%rbp)
leaq -0x448(%rbp), %rdi
leaq -0x30(%rbp), %rsi
callq 0x11840
movl (%rax), %eax
movl %eax, -0x444(%rbp)
movq -0x10(%rbp), %rdi
leaq -0x440(%rbp), %rsi
movl -0x444(%rbp), %ecx
xorl %edx, %edx
callq 0x11540
leaq -0x440(%rbp), %rsi
movl -0x444(%rbp), %eax
movl %eax, %edx
movl $0x1, %edi
callq 0x5110
movq -0x10(%rbp), %rdi
movl -0x444(%rbp), %esi
callq 0x115f0
movl -0x444(%rbp), %ecx
movl -0x30(%rbp), %eax
subl %ecx, %eax
movl %eax, -0x30(%rbp)
movl -0x444(%rbp), %eax
subl $0x1, %eax
movl %eax, %eax
movsbl -0x440(%rbp,%rax), %eax
cmpl $0xa, %eax
sete %al
andb $0x1, %al
movb %al, -0x31(%rbp)
jmp 0xb836
testb $0x1, -0x31(%rbp)
jne 0xb91a
movq 0x2668a(%rip), %rdi     # 0x31f98
leaq 0x199f6(%rip), %rsi     # 0x2530b
callq 0x53d0
jmp 0xb91c
movl $0x0, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x450, %rsp            # imm = 0x450
popq %rbp
retq
nop