// File: /workspace/github_c_makefile_star2_O2/icysunlight[P]miniftpd/main.c
// Function: main
int main()
{
    if ( 0 != getuid() )
    {
        fprintf(stderr,"miniftpd should start from root.\n");
        exit(EXIT_FAILURE);
    }

    if ( tunable_listen_address == NULL) 
    {
        //绑定到eth0对应的ip
        listenip = (char*)malloc(sizeof(char) * 128);
        getlocalip(listenip);
    }
    else
        strcpy(listenip,tunable_listen_address);

    parseconf_load_file(CONFFILE);
    printconf();
    hash_test();

    umask(tunable_local_umask);

    signal(SIGCHLD,handle_sigchld);
    int listenfd = tcp_srv(listenip,5188);
    
    pid_t pid;
    int conn;
    

    clntlmt_init();

    //daemon(0,0);

    while (1)
    {
        struct sockaddr_in addr;
        conn = accept_timeout(listenfd,&addr,tunable_connect_timeout);
        if ( -1 == conn )
            ERR_EXIT("connect error");

        
        session_t sessioninf;
        init_session(&sessioninf,conn);

        int lmt_fd[2];
        if ( -1 == socketpair(AF_UNIX,SOCK_STREAM,0,lmt_fd) )
            ERR_EXIT("socketpair");

        pid = fork();
        if (-1 == pid)
            ERR_EXIT("fork");


        if (0 == pid)
        {
            signal(SIGCHLD,SIG_IGN);
            close(listenfd);
            close(lmt_fd[0]);
            char cmd = '\0';
            readn(lmt_fd[1],&cmd,1);
            if ( cmd == 'r' )
            {
                close(lmt_fd[1]);
            }
            else if ( cmd == 'i' )
            {
                close(lmt_fd[1]);
                ftp_reply(&sessioninf,FTP_TOO_MANY_USERS,"There are too many connections from your internet address");
                exit(EXIT_FAILURE);    
            }
            else 
            {
                close(lmt_fd[1]);
                ftp_reply(&sessioninf,FTP_TOO_MANY_USERS,"There are too many connected users, please try later");
                exit(EXIT_FAILURE);    
            }
            begin_session(&sessioninf);
            break;
        }
        if (pid > 0)
        {
            close(lmt_fd[1]);
            //检查是否满足limit限制
            clntlmt_add(pid,addr.sin_addr.s_addr);
            int ret = clntlmt_check(addr.sin_addr.s_addr);
            if ( 0 == ret )
            {
                writen(lmt_fd[0],"r",1);
            }
            if ( -1 == ret )
            {
            }
            else if ( -2 == ret )
                printf("max clients total.\n");    
            close(conn);
            close(lmt_fd[0]);
        }
    }
        

    free(listenip);

    return 0;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xc68, %rsp            # imm = 0xC68
callq 0x31a0
testl %eax, %eax
jne 0x387f
leaq 0x7c87(%rip), %rax      # 0xb318
movq (%rax), %rsi
testq %rsi, %rsi
je 0x36a7
movq 0x7c68(%rip), %rdi      # 0xb308
callq 0x3090
jmp 0x36c0
movl $0x80, %edi
callq 0x33a0
movq %rax, 0x7c50(%rip)      # 0xb308
movq %rax, %rdi
callq 0x3b5e
leaq 0x395f(%rip), %rdi      # 0x7026
callq 0x4610
xorl %eax, %eax
callq 0x6a14
xorl %eax, %eax
callq 0x666c
leaq 0x7c07(%rip), %rax      # 0xb2e8
movl (%rax), %edi
callq 0x3330
leaq 0x1c6(%rip), %rsi       # 0x38b5
pushq $0x11
popq %rdi
callq 0x32f0
movq 0x7c0a(%rip), %rdi      # 0xb308
movl $0x1444, %esi           # imm = 0x1444
callq 0x39c5
movl %eax, %ebx
xorl %eax, %eax
callq 0x6b48
leaq 0x20(%rsp), %r15
pushq $0x1
popq %rbp
leaq 0x8(%rsp), %r12
leaq 0x7beb(%rip), %rax      # 0xb310
movl (%rax), %edx
movl %ebx, %edi
leaq 0x10(%rsp), %rsi
callq 0x3dba
cmpl $-0x1, %eax
je 0x384b
movl %eax, %r13d
movq %r15, %rdi
movl %eax, %esi
callq 0x427c
movl %ebp, %edi
movl %ebp, %esi
xorl %edx, %edx
movq %r12, %rcx
callq 0x3360
cmpl $-0x1, %eax
je 0x3854
callq 0x3540
testl %eax, %eax
je 0x37da
movl %eax, %r14d
cmpl $-0x1, %eax
je 0x385d
testl %r14d, %r14d
jle 0x371e
movl 0xc(%rsp), %edi
callq 0x3260
movl 0x14(%rsp), %esi
movl %r14d, %edi
callq 0x6bc0
movl 0x14(%rsp), %edi
xorl %eax, %eax
callq 0x6cad
cmpl $-0x2, %eax
je 0x37b8
testl %eax, %eax
jne 0x37c4
movl 0x8(%rsp), %edi
leaq 0x3913(%rip), %rsi      # 0x70c1
pushq $0x1
popq %rdx
callq 0x401f
jmp 0x37c4
leaq 0x3904(%rip), %rdi      # 0x70c3
callq 0x30c0
movl %r13d, %edi
callq 0x3260
movl 0x8(%rsp), %edi
callq 0x3260
jmp 0x371e
pushq $0x11
popq %rdi
pushq $0x1
popq %r14
movq %r14, %rsi
callq 0x32f0
movl %ebx, %edi
callq 0x3260
movl 0x8(%rsp), %edi
callq 0x3260
leaq 0x7(%rsp), %rbx
movb $0x0, (%rbx)
movl 0xc(%rsp), %edi
movq %rbx, %rsi
movq %r14, %rdx
callq 0x3fc7
movzbl (%rbx), %ebx
movl 0xc(%rsp), %edi
callq 0x3260
cmpl $0x72, %ebx
jne 0x3871
leaq 0x20(%rsp), %rdi
callq 0x42bd
movq 0x7ad6(%rip), %rdi      # 0xb308
callq 0x3040
xorl %eax, %eax
addq $0xc68, %rsp            # imm = 0xC68
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x37e4(%rip), %rdi      # 0x7036
jmp 0x3864
leaq 0x37e9(%rip), %rdi      # 0x7044
jmp 0x3864
leaq 0x37eb(%rip), %rdi      # 0x704f
callq 0x3470
pushq $0x1
popq %rdi
callq 0x34e0
cmpl $0x69, %ebx
jne 0x389d
leaq 0x37d7(%rip), %rdx      # 0x7054
jmp 0x38a4
movq 0x7772(%rip), %rax      # 0xaff8
movq (%rax), %rcx
leaq 0x3774(%rip), %rdi      # 0x7004
pushq $0x21
popq %rsi
pushq $0x1
popq %rdx
callq 0x3500
jmp 0x3869
leaq 0x37ea(%rip), %rdx      # 0x708e
leaq 0x20(%rsp), %rdi
movl $0x1a5, %esi            # imm = 0x1A5
callq 0x489c
jmp 0x3869