// File: davmac314[P]dinit/src/dinitctl.cc
// Function: add_remove_dependency(int, cpbuffer<1024u>&, bool, char const*, char const*, dependency_type, bool)
static int add_remove_dependency(int socknum, cpbuffer_t &rbuffer, bool add,
        const char *service_from, const char *service_to, dependency_type dep_type, bool verbose)
{
    using namespace std;

    handle_t from_handle;
    handle_t to_handle;

    if (! load_service(socknum, rbuffer, service_from, &from_handle, nullptr)
            || ! load_service(socknum, rbuffer, service_to, &to_handle, nullptr)) {
        return 1;
    }

    if (from_handle == to_handle) {
        cerr << "dinitctl: can not add/remove a dependency from a service to itself" << endl;
        return 1;
    }

    auto m = membuf()
            .append<char>(add ? (char)cp_cmd::ADD_DEP : (char)cp_cmd::REM_DEP)
            .append(static_cast<char>(dep_type))
            .append(from_handle)
            .append(to_handle);
    write_all_x(socknum, m);

    wait_for_reply(rbuffer, socknum);

    // check reply
    if (rbuffer[0] == (char)cp_rply::NAK) {
        if (add) {
            cerr << "dinitctl: could not add dependency: circular dependency or wrong state" << endl;
        }
        else {
            cerr << "dinitctl: no such dependency to remove" << endl;
        }
        return 1;
    }
    if (rbuffer[0] != (char)cp_rply::ACK) {
        cerr << "dinitctl: control socket protocol error" << endl;
        return 1;
    }

    if (verbose) {
        std::cout << "Service '" << service_from << "': dependency '" << service_to << "' " << (add ? "added" : "removed") << endl;
    }

    return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x60, %rsp
movb 0x10(%rbp), %al
movl %edi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
andb $0x1, %dl
movb %dl, -0x11(%rbp)
movq %rcx, -0x20(%rbp)
movq %r8, -0x28(%rbp)
movl %r9d, -0x2c(%rbp)
andb $0x1, %al
movb %al, -0x2d(%rbp)
movl -0x8(%rbp), %edi
movq -0x10(%rbp), %rsi
movq -0x20(%rbp), %rdx
leaq -0x34(%rbp), %rcx
xorl %eax, %eax
movl %eax, %r8d
movl $0x1, %r9d
callq 0xc5e0
testb $0x1, %al
jne 0xaede
jmp 0xaf01
movl -0x8(%rbp), %edi
movq -0x10(%rbp), %rsi
movq -0x28(%rbp), %rdx
leaq -0x38(%rbp), %rcx
xorl %eax, %eax
movl %eax, %r8d
movl $0x1, %r9d
callq 0xc5e0
testb $0x1, %al
jne 0xaf0d
movl $0x1, -0x4(%rbp)
jmp 0xb0ff
movl -0x34(%rbp), %eax
cmpl -0x38(%rbp), %eax
jne 0xaf43
movq 0x270cc(%rip), %rdi     # 0x31fe8
leaq 0x19985(%rip), %rsi     # 0x248a8
callq 0x53d0
movq %rax, %rdi
movq 0x27036(%rip), %rsi     # 0x31f68
callq 0x5410
movl $0x1, -0x4(%rbp)
jmp 0xb0ff
movb -0x11(%rbp), %cl
andb $0x1, %cl
movb $0xc, %al
subb %cl, %al
movb %al, -0x4d(%rbp)
leaq -0x4c(%rbp), %rdi
leaq -0x4d(%rbp), %rsi
callq 0x11b60
movb %al, -0x4b(%rbp)
movb -0x2c(%rbp), %al
movb %al, -0x4e(%rbp)
leaq -0x4b(%rbp), %rdi
leaq -0x4e(%rbp), %rsi
callq 0x11b90
movw %ax, -0x4a(%rbp)
leaq -0x4a(%rbp), %rdi
leaq -0x34(%rbp), %rsi
callq 0x11bc0
movl %eax, %ecx
movl %ecx, -0x48(%rbp)
shrq $0x20, %rax
movw %ax, -0x44(%rbp)
leaq -0x48(%rbp), %rdi
leaq -0x38(%rbp), %rsi
callq 0x132c0
movw %dx, -0x58(%rbp)
movq %rax, -0x60(%rbp)
movq -0x60(%rbp), %rax
movq %rax, -0x42(%rbp)
movw -0x58(%rbp), %ax
movw %ax, -0x3a(%rbp)
movl -0x8(%rbp), %edi
leaq -0x42(%rbp), %rsi
callq 0x13300
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 0xb039
testb $0x1, -0x11(%rbp)
je 0xb00b
movq 0x26ffa(%rip), %rdi     # 0x31fe8
leaq 0x198f6(%rip), %rsi     # 0x248eb
callq 0x53d0
movq %rax, %rdi
movq 0x26f64(%rip), %rsi     # 0x31f68
callq 0x5410
jmp 0xb02d
movq 0x26fd6(%rip), %rdi     # 0x31fe8
leaq 0x19919(%rip), %rsi     # 0x24932
callq 0x53d0
movq %rax, %rdi
movq 0x26f40(%rip), %rsi     # 0x31f68
callq 0x5410
movl $0x1, -0x4(%rbp)
jmp 0xb0ff
movq -0x10(%rbp), %rdi
xorl %esi, %esi
callq 0x113e0
movsbl %al, %eax
cmpl $0x32, %eax
je 0xb07a
movq 0x26f95(%rip), %rdi     # 0x31fe8
leaq 0x196af(%rip), %rsi     # 0x24709
callq 0x53d0
movq %rax, %rdi
movq 0x26eff(%rip), %rsi     # 0x31f68
callq 0x5410
movl $0x1, -0x4(%rbp)
jmp 0xb0ff
testb $0x1, -0x2d(%rbp)
je 0xb0f8
movq 0x26f11(%rip), %rdi     # 0x31f98
leaq 0x18fd7(%rip), %rsi     # 0x24065
callq 0x53d0
movq %rax, %rdi
movq -0x20(%rbp), %rsi
callq 0x53d0
movq %rax, %rdi
leaq 0x198b0(%rip), %rsi     # 0x24959
callq 0x53d0
movq %rax, %rdi
movq -0x28(%rbp), %rsi
callq 0x53d0
movq %rax, %rdi
leaq 0x19264(%rip), %rsi     # 0x24328
callq 0x53d0
movq %rax, %rdi
movb -0x11(%rbp), %cl
leaq 0x19899(%rip), %rsi     # 0x2496f
leaq 0x1988c(%rip), %rax     # 0x24969
testb $0x1, %cl
cmovneq %rax, %rsi
callq 0x53d0
movq %rax, %rdi
movq 0x26e75(%rip), %rsi     # 0x31f68
callq 0x5410
movl $0x0, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x60, %rsp
popq %rbp
retq
nopl (%rax,%rax)