// File: /workspace/github_c_makefile_star2_O3/panux[P]linit/src/linitd.c
// Function: cmd_start
void cmd_start(struct conn *c, char *args) {
    if(c->closed) {
        return;
    }
    ref(c);
    if(hasSpace(args)) {    //starting multiple - break into multiple commands
        char *arg, *a;
        arg = a = args;
        for(;;) {
            switch(*a) {
            case '\0':
                cmd_start(c, arg);
                goto end;
            case ' ':
                *a = '\0';
                cmd_start(c, arg);
                a = arg = a + 1;
                break;
            default:
                a++;
            }
        }
    } else {
        struct service *svc = findService(args);
        if(svc != NULL) {   //service already started
            if(!setNotify(svc, c)) {
                fprintf(stderr, "Failed to set conn %d to be notified about %s\n", c->fd, args);
                close_conn(c);
                goto end;
            }
            //format: "notify %s %s", args, status
            char not[] = "notify ";
            char *status = statestr(svc->state);
            char ntxt[strlen(not) + strlen(args) + strlen(status) + 2];
            char *nt = ntxt;
            strcpy(nt, not);
            nt += strlen(not);
            strcpy(nt, args);
            nt += strlen(args);
            *nt = ' ';
            nt++;
            strcpy(nt, status);
            struct buf dat = { .dat = ntxt, .len = strlen(ntxt) + 1 };
            if(notify(c, svc, dat) != notify_success) {
                fprintf(stderr, "Failed to notify conn %d about the state of %s\n", c->fd, args);
                close_conn(c);
                goto end;
            }
        } else {            //start service and mark to be notified
            struct service *ns = newService();
            if(ns == NULL) {
                fprintf(stderr, "[ERROR] Failed to start service %s: out of memory\n", args);
                close_conn(c);  //we cant notify the service because we are out of memory
                goto end;
            }
            ns->name = strdup(args);
            ns->state = service_status_starting;
            setNotify(ns, c);
            if(!runStart(args)) {
                fprintf(stderr, "[ERROR] Failed to start service %s: fork/exec error\n", args);
                ns->state = service_status_fail;
            }
            if(!notifyAll(ns)) {    //notify client of start
                fprintf(stderr, "[ERROR] Failed to send notification about %s to conn %d\n", args, c->fd);
                close_conn(c);
                goto end;
            }
            if(ns->state == service_status_fail) {  //delete the service if it failed
                rmService(ns->name);
            }
        }
    }
end:
    deref(c);
}

// Assembly:
cmpb $0x0, 0x18(%rdi)
jne 0x284c
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x18, %rsp
movq %rsi, %r14
movq %rdi, %rbx
incl 0x10(%rdi)
movq %rsi, %rax
movzbl (%rax), %ecx
testl %ecx, %ecx
je 0x26e7
cmpl $0x20, %ecx
je 0x26ab
incq %rax
jmp 0x269a
leaq 0x1(%r14), %r15
movzbl -0x1(%r15), %eax
cmpl $0x20, %eax
je 0x26c2
testl %eax, %eax
je 0x26d7
incq %r15
jmp 0x26af
movb $0x0, -0x1(%r15)
movq %rbx, %rdi
movq %r14, %rsi
callq 0x2673
movq %r15, %r14
jmp 0x26ab
movq %rbx, %rdi
movq %r14, %rsi
callq 0x2673
jmp 0x2830
movq %r14, %rdi
callq 0x1e3e
testq %rax, %rax
je 0x2728
movq %rax, %r15
movq %rax, %rdi
movq %rbx, %rsi
callq 0x1b24
testb %al, %al
je 0x284d
movl 0x8(%r15), %eax
cmpq $0x5, %rax
ja 0x27a3
leaq 0x4699(%rip), %rcx      # 0x6db8
movq (%rcx,%rax,8), %r15
jmp 0x27aa
callq 0x1e76
testq %rax, %rax
je 0x2882
movq %rax, %r15
movq %r14, %rdi
callq 0x1210
movq %rax, (%r15)
movl $0x1, 0x8(%r15)
movq %r15, %rdi
movq %rbx, %rsi
callq 0x1b24
leaq 0x1c86(%rip), %rax      # 0x43e4
leaq -0x40(%rbp), %rsi
movq %rax, (%rsi)
movq %r14, 0x8(%rsi)
movl $0x2, %edi
callq 0x258b
testb %al, %al
je 0x28a7
movq %r15, %rdi
callq 0x1cf0
testb %al, %al
je 0x28cf
cmpl $0x3, 0x8(%r15)
jne 0x2830
movq (%r15), %rdi
callq 0x1eb5
jmp 0x2830
leaq 0x187c(%rip), %r15      # 0x4026
movq %r14, %rdi
callq 0x10a0
movq %rax, %r12
movq %r15, %rdi
callq 0x10a0
movq %rsp, %r13
addq %r12, %rax
addq $0x18, %rax
andq $-0x10, %rax
movq %rsp, %rcx
movq %rcx, %r12
subq %rax, %r12
negq %rax
movq %r12, %rsp
movabsq $0x20796669746f6e, %rdx # imm = 0x20796669746F6E
movq %rdx, (%rcx,%rax)
leaq 0x7(%r12), %rdi
movq %r14, %rsi
callq 0x1060
movq %r14, %rdi
callq 0x10a0
leaq (%rax,%r12), %rdi
addq $0x8, %rdi
movb $0x20, -0x1(%rdi)
movq %r15, %rsi
callq 0x1060
movq %r12, %rdi
callq 0x10a0
leaq 0x1(%rax), %rcx
movq %rbx, %rdi
movq %r12, %rdx
callq 0x1b90
cmpl $0x1, %eax
jne 0x285a
movq %r13, %rsp
subl $0x1, 0x10(%rbx)
jae 0x283e
movq %rbx, %rdi
callq 0x1030
leaq -0x28(%rbp), %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %rbx, %rdi
movq %r14, %rsi
callq 0x16a0
jmp 0x2830
movq 0x4797(%rip), %rax      # 0x6ff8
movq (%rax), %rdi
movl 0x14(%rbx), %edx
leaq 0x1bbc(%rip), %rsi      # 0x442a
movq %r14, %rcx
xorl %eax, %eax
callq 0x1130
movq %rbx, %rdi
callq 0x1c5b
jmp 0x282d
movq 0x476f(%rip), %rax      # 0x6ff8
movq (%rax), %rdi
leaq 0x1bc7(%rip), %rsi      # 0x445a
movq %r14, %rdx
xorl %eax, %eax
callq 0x1130
movq %rbx, %rdi
callq 0x1c5b
jmp 0x2830
movq 0x474a(%rip), %rax      # 0x6ff8
movq (%rax), %rdi
leaq 0x1bd5(%rip), %rsi      # 0x448d
movq %r14, %rdx
xorl %eax, %eax
callq 0x1130
movl $0x3, 0x8(%r15)
jmp 0x277b
movq %rbx, %rdi
movq %r14, %rsi
callq 0x16cb
jmp 0x2830