// File: /workspace/github_c_makefile_star2_O0/niuyuling[P]CProxy/main.c
// Function: main
void _main(int argc, char *argv[])
{
    char *p = NULL;
    int longindex = 0;
    int opt;
    char path[CACHE_SIZE] = { 0 };
    char executable_filename[CACHE_SIZE] = { 0 };
    (void)get_executable_path(path, executable_filename, sizeof(path));
    char *inifile = "/CProxy.conf";
    struct rlimit rt;
    inifile = strcat(path, inifile);
    conf *configure = (struct CONF *)malloc(sizeof(struct CONF));
    memset(configure, 0, sizeof(struct CONF));
    read_conf(inifile, configure);

    sslEncodeCode = 0;          // 默认SSL不转码

    char optstring[] = ":l:f:t:p:c:e:s:h?";
    static struct option longopts[] = {
        { "local_address", required_argument, 0, 'l' },
        { "remote_address", required_argument, 0, 'f' },
        { "timeout", required_argument, 0, 't' },
        { "process", required_argument, 0, 'p' },
        { "config", required_argument, 0, 'c' },
        { "coding", required_argument, 0, 'e' },
        { "signal", required_argument, 0, 's' },
        { "help", no_argument, 0, 'h' },
        { "?", no_argument, 0, '?' },
        { 0, 0, 0, 0 }
    };
    while (-1 != (opt = getopt_long(argc, argv, optstring, longopts, &longindex))) {
        switch (opt) {
        case 'l':
            p = strchr(optarg, ':');
            if (p) {
                strncpy(local_host, optarg, p - optarg);
                local_port = atoi(p + 1);
            } else {
                strncpy(local_host, optarg, strlen(local_host));
            }
            break;
        case 'f':
            p = strchr(optarg, ':');
            if (p) {
                strncpy(remote_host, optarg, p - optarg);
                remote_port = atoi(p + 1);
            } else {
                strncpy(remote_host, optarg, strlen(remote_host));
            }
            break;
        case 't':
            timeout_minute = (time_t) atoi(optarg); // 如果指定-t,优先使用参数提供的值(输入值 > 配置文件读取的值)
            break;
        case 'p':
            process = atoi(optarg);
            break;
        case 'c':
            free_tcp(&http_head_strrep);
            free_tcp(&http_head_regrep);
            free_tcp(&https_head_strrep);
            free_tcp(&https_head_regrep);
            free_conf(configure);
            memset(configure, 0, sizeof(struct CONF));
            read_conf(optarg, configure);
            break;
        case 'e':
            sslEncodeCode = atoi(optarg);
            break;
        case 's':
            if (strcasecmp(optarg, "stop") == 0 || strcasecmp(optarg, "quit") == 0) {
                free_conf(configure);
                exit(process_signal(SERVER_TYPE_STOP, executable_filename));
            }
            if (strcasecmp(optarg, "restart") == 0 || strcasecmp(optarg, "reload") == 0) {
                process_signal(SERVER_TYPE_STOP, executable_filename);
                while (process_signal(SERVICE_TYPE_STATUS_NOT_PRINT, executable_filename) == 0) ;
            }
            if (strcasecmp(optarg, "status") == 0)
                exit(process_signal(SERVER_TYPE_STATUS, executable_filename));
            break;
        case 'h':
        case '?':
            help_information();
            exit(0);
            break;
        default:
            ;
        }
    }
    
    
    signal(SIGPIPE, SIG_IGN);
#if DAEMON
    // 守护进程
    int nochdir = 1;
    int noclose = 1;
    int pid;
    if ((pid = fork()) < 0) {
        return;
    } else if (0 != pid) {
        free_tcp(&http_head_strrep);
        free_tcp(&http_head_regrep);
        free_tcp(&https_head_strrep);
        free_tcp(&https_head_regrep);
        free_conf(configure);
        free(configure);
        exit(0);
    }

    if (setsid() < 0) {
        return;
    }

    signal(SIGHUP, SIG_IGN);
    if ((pid = fork()) < 0) {
        return;
    } else if (0 != pid) {
        free_tcp(&http_head_strrep);
        free_tcp(&http_head_regrep);
        free_tcp(&https_head_strrep);
        free_tcp(&https_head_regrep);
        free_conf(configure);
        free(configure);
        exit(0);
    }

    if (0 == nochdir) {
        chdir("/");
    }

    if (0 == noclose) {
        freopen("/dev/null", "r", stdin);
        freopen("/dev/null", "w", stdout);
        freopen("/dev/null", "w", stderr);
    }
#endif



    // 反转链表，使读取的配置正序
    http_head_strrep = local_reverse(http_head_strrep);
    http_head_regrep = local_reverse(http_head_regrep);

    https_head_strrep = local_reverse(https_head_strrep);
    https_head_regrep = local_reverse(https_head_regrep);

/*
    print_tcp(https_head_strrep);
    print_tcp(https_head_regrep);
    free_tcp(&https_head_strrep);
    free_tcp(&https_head_regrep);
    
    print_tcp(http_head_strrep);
    print_tcp(http_head_regrep);
    free_tcp(&http_head_strrep);
    free_tcp(&http_head_regrep);
    
    free_conf(configure);
    free(configure);
    exit(0);
*/

    
    rt.rlim_max = rt.rlim_cur = MAX_CONNECTION * 2; // 设置每个进程允许打开的最大文件数
    if (setrlimit(RLIMIT_NOFILE, &rt) == -1)
        perror("setrlimit");
    initialize(configure);
    
    
    if (setegid(configure->uid) == -1 || seteuid(configure->uid) == -1) // 设置uid
        exit(1);
        
    while (configure->process-- > 1 && (child_pid = fork()) == 0);
    
    epollfd = epoll_create(MAX_CONNECTION);
    if (epollfd == -1) {
        perror("epoll_create");
        exit(1);
    }

    thread_loop(configure);

    return;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x2b0, %rsp            # imm = 0x2B0
movl %edi, -0x4(%rbp)
movq %rsi, -0x10(%rbp)
movq $0x0, -0x18(%rbp)
movl $0x0, -0x1c(%rbp)
leaq -0x130(%rbp), %rdi
xorl %esi, %esi
movl $0x10e, %edx            # imm = 0x10E
callq 0x21c0
leaq -0x240(%rbp), %rdi
xorl %esi, %esi
movl $0x10e, %edx            # imm = 0x10E
callq 0x21c0
leaq -0x130(%rbp), %rdi
leaq -0x240(%rbp), %rsi
movl $0x10e, %edx            # imm = 0x10E
callq 0x2f30
leaq 0x8b85(%rip), %rax      # 0xc1ab
movq %rax, -0x248(%rbp)
leaq -0x130(%rbp), %rdi
movq -0x248(%rbp), %rsi
callq 0x24b0
movq %rax, -0x248(%rbp)
movl $0xc0, %edi
callq 0x2350
movq %rax, -0x260(%rbp)
movq -0x260(%rbp), %rdi
xorl %esi, %esi
movl $0xc0, %edx
callq 0x21c0
movq -0x248(%rbp), %rdi
movq -0x260(%rbp), %rsi
callq 0xa590
leaq 0x1902f(%rip), %rax     # 0x1c6b4
movl $0x0, (%rax)
movq 0x8cee(%rip), %rax      # 0xc380
movq %rax, -0x280(%rbp)
movq 0x8ce8(%rip), %rax      # 0xc388
movq %rax, -0x278(%rbp)
movw 0x8ce2(%rip), %ax       # 0xc390
movw %ax, -0x270(%rbp)
movl -0x4(%rbp), %edi
movq -0x10(%rbp), %rsi
leaq -0x280(%rbp), %rdx
leaq 0xbc16(%rip), %rcx      # 0xf2e0
leaq -0x1c(%rbp), %r8
callq 0x2150
movl %eax, %ecx
movl %ecx, -0x20(%rbp)
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
cmpl %ecx, %eax
je 0x3a06
movl -0x20(%rbp), %eax
addl $-0x3f, %eax
movl %eax, %ecx
movq %rcx, -0x298(%rbp)
subl $0x35, %eax
ja 0x39ff
movq -0x298(%rbp), %rax
leaq 0x8905(%rip), %rcx      # 0xc010
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq 0xb8b5(%rip), %rax      # 0xefd0
movq (%rax), %rdi
movl $0x3a, %esi
callq 0x2170
movq %rax, -0x18(%rbp)
cmpq $0x0, -0x18(%rbp)
je 0x376f
movq 0xb896(%rip), %rax      # 0xefd0
movq (%rax), %rsi
movq -0x18(%rbp), %rdx
movq 0xb888(%rip), %rax      # 0xefd0
movq (%rax), %rax
subq %rax, %rdx
leaq 0x18ccb(%rip), %rdi     # 0x1c420
callq 0x2060
movq -0x18(%rbp), %rdi
addq $0x1, %rdi
callq 0x24a0
movl %eax, 0x18dc3(%rip)     # 0x1c530
jmp 0x37a2
movq 0xb85a(%rip), %rax      # 0xefd0
movq (%rax), %rax
movq %rax, -0x2a0(%rbp)
leaq 0x18c99(%rip), %rdi     # 0x1c420
callq 0x2130
movq -0x2a0(%rbp), %rsi
movq %rax, %rdx
leaq 0x18c83(%rip), %rdi     # 0x1c420
callq 0x2060
jmp 0x3a01
movq 0xb822(%rip), %rax      # 0xefd0
movq (%rax), %rdi
movl $0x3a, %esi
callq 0x2170
movq %rax, -0x18(%rbp)
cmpq $0x0, -0x18(%rbp)
je 0x3807
movq 0xb803(%rip), %rax      # 0xefd0
movq (%rax), %rsi
movq -0x18(%rbp), %rdx
movq 0xb7f5(%rip), %rax      # 0xefd0
movq (%rax), %rax
subq %rax, %rdx
leaq 0x18db8(%rip), %rdi     # 0x1c5a0
callq 0x2060
movq -0x18(%rbp), %rdi
addq $0x1, %rdi
callq 0x24a0
movl %eax, %ecx
leaq 0x18ead(%rip), %rax     # 0x1c6b0
movl %ecx, (%rax)
jmp 0x383a
movq 0xb7c2(%rip), %rax      # 0xefd0
movq (%rax), %rax
movq %rax, -0x2a8(%rbp)
leaq 0x18d81(%rip), %rdi     # 0x1c5a0
callq 0x2130
movq -0x2a8(%rbp), %rsi
movq %rax, %rdx
leaq 0x18d6b(%rip), %rdi     # 0x1c5a0
callq 0x2060
jmp 0x3a01
movq 0xb78a(%rip), %rax      # 0xefd0
movq (%rax), %rdi
callq 0x24a0
cltq
movl %eax, %ecx
leaq 0x18d37(%rip), %rax     # 0x1c590
movl %ecx, (%rax)
jmp 0x3a01
movq 0xb769(%rip), %rax      # 0xefd0
movq (%rax), %rdi
callq 0x24a0
movl %eax, 0x18b57(%rip)     # 0x1c3cc
jmp 0x3a01
leaq 0x18cb7(%rip), %rdi     # 0x1c538
callq 0xa390
leaq 0x18cb3(%rip), %rdi     # 0x1c540
callq 0xa390
leaq 0x18caf(%rip), %rdi     # 0x1c548
callq 0xa390
leaq 0x18cab(%rip), %rdi     # 0x1c550
callq 0xa390
movq -0x260(%rbp), %rdi
callq 0xa470
movq -0x260(%rbp), %rdi
xorl %esi, %esi
movl $0xc0, %edx
callq 0x21c0
movq 0xb700(%rip), %rax      # 0xefd0
movq (%rax), %rdi
movq -0x260(%rbp), %rsi
callq 0xa590
jmp 0x3a01
movq 0xb6e5(%rip), %rax      # 0xefd0
movq (%rax), %rdi
callq 0x24a0
movl %eax, %ecx
leaq 0x18db8(%rip), %rax     # 0x1c6b4
movl %ecx, (%rax)
jmp 0x3a01
movq 0xb6c6(%rip), %rax      # 0xefd0
movq (%rax), %rdi
leaq 0x88ed(%rip), %rsi      # 0xc201
callq 0x2040
cmpl $0x0, %eax
je 0x3939
movq 0xb6ab(%rip), %rax      # 0xefd0
movq (%rax), %rdi
leaq 0x88d7(%rip), %rsi      # 0xc206
callq 0x2040
cmpl $0x0, %eax
jne 0x395d
movq -0x260(%rbp), %rdi
callq 0xa470
leaq -0x240(%rbp), %rsi
movl $0x1, %edi
callq 0x2ce0
movl %eax, %edi
callq 0x24e0
movq 0xb66c(%rip), %rax      # 0xefd0
movq (%rax), %rdi
leaq 0x889d(%rip), %rsi      # 0xc20b
callq 0x2040
cmpl $0x0, %eax
je 0x3993
movq 0xb651(%rip), %rax      # 0xefd0
movq (%rax), %rdi
leaq 0x888a(%rip), %rsi      # 0xc213
callq 0x2040
cmpl $0x0, %eax
jne 0x39be
leaq -0x240(%rbp), %rsi
movl $0x1, %edi
callq 0x2ce0
leaq -0x240(%rbp), %rsi
movl $0x4, %edi
callq 0x2ce0
cmpl $0x0, %eax
jne 0x39bc
jmp 0x39a4
jmp 0x39be
movq 0xb60b(%rip), %rax      # 0xefd0
movq (%rax), %rdi
leaq 0x88e3(%rip), %rsi      # 0xc2b2
callq 0x2040
cmpl $0x0, %eax
jne 0x39f1
leaq -0x240(%rbp), %rsi
movl $0x3, %edi
callq 0x2ce0
movl %eax, %edi
callq 0x24e0
jmp 0x3a01
callq 0x3cf0
xorl %edi, %edi
callq 0x24e0
jmp 0x3a01
jmp 0x36b5
movl $0xd, %edi
movl $0x1, %esi
callq 0x22c0
movl $0x1, -0x284(%rbp)
movl $0x1, -0x288(%rbp)
callq 0x2560
movl %eax, -0x28c(%rbp)
cmpl $0x0, %eax
jge 0x3a3e
jmp 0x3ce2
xorl %eax, %eax
cmpl -0x28c(%rbp), %eax
je 0x3a97
leaq 0x18ae9(%rip), %rdi     # 0x1c538
callq 0xa390
leaq 0x18ae5(%rip), %rdi     # 0x1c540
callq 0xa390
leaq 0x18ae1(%rip), %rdi     # 0x1c548
callq 0xa390
leaq 0x18add(%rip), %rdi     # 0x1c550
callq 0xa390
movq -0x260(%rbp), %rdi
callq 0xa470
movq -0x260(%rbp), %rdi
callq 0x2030
xorl %edi, %edi
callq 0x24e0
jmp 0x3a99
callq 0x2210
cmpl $0x0, %eax
jge 0x3aa8
jmp 0x3ce2
movl $0x1, %edi
movl $0x1, %esi
callq 0x22c0
callq 0x2560
movl %eax, -0x28c(%rbp)
cmpl $0x0, %eax
jge 0x3acc
jmp 0x3ce2
xorl %eax, %eax
cmpl -0x28c(%rbp), %eax
je 0x3b25
leaq 0x18a5b(%rip), %rdi     # 0x1c538
callq 0xa390
leaq 0x18a57(%rip), %rdi     # 0x1c540
callq 0xa390
leaq 0x18a53(%rip), %rdi     # 0x1c548
callq 0xa390
leaq 0x18a4f(%rip), %rdi     # 0x1c550
callq 0xa390
movq -0x260(%rbp), %rdi
callq 0xa470
movq -0x260(%rbp), %rdi
callq 0x2030
xorl %edi, %edi
callq 0x24e0
jmp 0x3b27
xorl %eax, %eax
cmpl -0x284(%rbp), %eax
jne 0x3b3d
leaq 0x890a(%rip), %rdi      # 0xc442
callq 0x2140
xorl %eax, %eax
cmpl -0x288(%rbp), %eax
jne 0x3b9e
movq 0xb47a(%rip), %rax      # 0xefc8
movq (%rax), %rdx
leaq 0x86c2(%rip), %rdi      # 0xc21a
leaq 0x8a92(%rip), %rsi      # 0xc5f1
callq 0x21d0
movq 0xb44d(%rip), %rax      # 0xefb8
movq (%rax), %rdx
leaq 0x86a5(%rip), %rdi      # 0xc21a
leaq 0x86a8(%rip), %rsi      # 0xc224
callq 0x21d0
movq 0xb468(%rip), %rax      # 0xeff0
movq (%rax), %rdx
leaq 0x8688(%rip), %rdi      # 0xc21a
leaq 0x868b(%rip), %rsi      # 0xc224
callq 0x21d0
movq 0x18993(%rip), %rdi     # 0x1c538
callq 0xa300
movq %rax, 0x18987(%rip)     # 0x1c538
movq 0x18988(%rip), %rdi     # 0x1c540
callq 0xa300
movq %rax, 0x1897c(%rip)     # 0x1c540
movq 0x1897d(%rip), %rdi     # 0x1c548
callq 0xa300
movq %rax, 0x18971(%rip)     # 0x1c548
movq 0x18972(%rip), %rdi     # 0x1c550
callq 0xa300
movq %rax, 0x18966(%rip)     # 0x1c550
movq $0x7f8, -0x258(%rbp) # imm = 0x7F8
movq $0x7f8, -0x250(%rbp) # imm = 0x7F8
movl $0x7, %edi
leaq -0x258(%rbp), %rsi
callq 0x23d0
cmpl $-0x1, %eax
jne 0x3c22
leaq 0x8609(%rip), %rdi      # 0xc226
callq 0x2480
movq -0x260(%rbp), %rdi
callq 0x3180
movq -0x260(%rbp), %rax
movl (%rax), %edi
callq 0x2550
cmpl $-0x1, %eax
je 0x3c54
movq -0x260(%rbp), %rax
movl (%rax), %edi
callq 0x2590
cmpl $-0x1, %eax
jne 0x3c5e
movl $0x1, %edi
callq 0x24e0
jmp 0x3c60
movq -0x260(%rbp), %rax
movl 0x4(%rax), %ecx
movl %ecx, %edx
addl $-0x1, %edx
movl %edx, 0x4(%rax)
xorl %eax, %eax
cmpl $0x1, %ecx
movb %al, -0x2a9(%rbp)
jle 0x3c99
callq 0x2560
leaq 0x18a3d(%rip), %rcx     # 0x1c6c8
movl %eax, (%rcx)
cmpl $0x0, %eax
sete %al
movb %al, -0x2a9(%rbp)
movb -0x2a9(%rbp), %al
testb $0x1, %al
jne 0x3ca5
jmp 0x3ca7
jmp 0x3c60
movl $0x3fc, %edi            # imm = 0x3FC
callq 0x24c0
movl %eax, 0x1571d(%rip)     # 0x193d4
cmpl $-0x1, 0x15716(%rip)    # 0x193d4
jne 0x3cd6
leaq 0x8569(%rip), %rdi      # 0xc230
callq 0x2480
movl $0x1, %edi
callq 0x24e0
movq -0x260(%rbp), %rdi
callq 0x34b0
addq $0x2b0, %rsp            # imm = 0x2B0
popq %rbp
retq
nopl (%rax,%rax)