// File: /workspace/github_c_makefile_star2_O3/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
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x268, %rsp            # imm = 0x268
movq %rsi, %r14
movl %edi, %ebp
xorl %r15d, %r15d
leaq 0x4(%rsp), %r13
movl %r15d, (%r13)
leaq 0x150(%rsp), %rbx
movl $0x10e, %edx            # imm = 0x10E
movq %rbx, %rdi
xorl %esi, %esi
callq 0x21b0
leaq 0x40(%rsp), %r12
movl $0x10e, %edx            # imm = 0x10E
movq %r12, %rdi
xorl %esi, %esi
callq 0x21b0
movq %rbx, %rdi
movq %r12, %rsi
movl $0x10e, %edx            # imm = 0x10E
callq 0x2da2
movq %rbx, %rdi
callq 0x2140
movabsq $0x2e79786f7250432f, %rcx # imm = 0x2E79786F7250432F
movq %rcx, 0x150(%rsp,%rax)
movabsq $0x666e6f632e7978, %rcx # imm = 0x666E6F632E7978
movq %rcx, 0x155(%rsp,%rax)
movl $0x1, %edi
movl $0xc0, %esi
callq 0x2270
movq %rbx, %rdi
movq %rax, 0x8(%rsp)
movq %rax, %rsi
callq 0x798b
leaq 0x1634f(%rip), %rax     # 0x19664
movl %r15d, (%rax)
movaps 0x5fc1(%rip), %xmm0     # 0x92e0
leaq 0x10(%rsp), %r15
movaps %xmm0, (%r15)
movw $0x3f, 0x10(%r15)
leaq 0x5cda(%rip), %rbx      # 0x9010
movl %ebp, %edi
movq %r14, %rsi
movq %r15, %rdx
leaq 0x8f8b(%rip), %rcx      # 0xc2d0
movq %r13, %r8
callq 0x2150
leal -0x63(%rax), %ecx
cmpl $0x11, %ecx
ja 0x3564
movslq (%rbx,%rcx,4), %rax
addq %rbx, %rax
jmpq *%rax
leaq 0x1617f(%rip), %rdi     # 0x194e8
callq 0x786b
leaq 0x1617b(%rip), %rdi     # 0x194f0
callq 0x786b
leaq 0x16177(%rip), %rdi     # 0x194f8
callq 0x786b
leaq 0x16173(%rip), %rdi     # 0x19500
callq 0x786b
movq 0x8(%rsp), %r15
movq %r15, %rdi
callq 0x78ec
movl $0xc0, %edx
movq %r15, %rdi
xorl %esi, %esi
callq 0x21b0
movq 0x8c1b(%rip), %rax      # 0xbfd0
movq (%rax), %rdi
movq %r15, %rsi
leaq 0x10(%rsp), %r15
callq 0x798b
jmp 0x3336
movq 0x8bff(%rip), %rax      # 0xbfd0
movq (%rax), %rdi
callq 0x2480
leaq 0x16160(%rip), %rcx     # 0x19540
movl %eax, (%rcx)
jmp 0x3336
movq 0x8be2(%rip), %rax      # 0xbfd0
movq (%rax), %rdi
callq 0x2480
movl %eax, 0x15f80(%rip)     # 0x1937c
jmp 0x3336
movq 0x8bc8(%rip), %rax      # 0xbfd0
movq (%rax), %rdi
callq 0x2480
leaq 0x1624d(%rip), %rcx     # 0x19664
movl %eax, (%rcx)
jmp 0x3336
movq 0x8bab(%rip), %rax      # 0xbfd0
movq (%rax), %r15
movq %r15, %rdi
movl $0x3a, %esi
callq 0x2160
testq %rax, %rax
je 0x3577
movq %rax, %r13
movq %rax, %rdx
subq %r15, %rdx
leaq 0x15f82(%rip), %rdi     # 0x193d0
movq %r15, %rsi
callq 0x2060
incq %r13
movq %r13, %rdi
callq 0x2480
movl %eax, 0x16079(%rip)     # 0x194e0
jmp 0x359d
movq 0x8b5d(%rip), %rax      # 0xbfd0
movq (%rax), %r15
movq %r15, %rdi
movl $0x3a, %esi
callq 0x2160
testq %rax, %rax
je 0x3580
movq %rax, %r13
movq %rax, %rdx
subq %r15, %rdx
leaq 0x160b4(%rip), %rdi     # 0x19550
movq %r15, %rsi
callq 0x2060
incq %r13
movq %r13, %rdi
callq 0x2480
leaq 0x161aa(%rip), %rcx     # 0x19660
movl %eax, (%rcx)
jmp 0x359d
movq 0x8b0c(%rip), %rax      # 0xbfd0
movq (%rax), %r15
movq %r15, %rdi
leaq 0x5c9d(%rip), %rsi      # 0x916e
callq 0x2040
testl %eax, %eax
je 0x36fe
movq %r15, %rdi
leaq 0x5c8b(%rip), %rsi      # 0x9173
callq 0x2040
testl %eax, %eax
je 0x36fe
movq %r15, %rdi
leaq 0x5c79(%rip), %rsi      # 0x9178
callq 0x2040
testl %eax, %eax
je 0x351b
movq %r15, %rdi
leaq 0x5c6e(%rip), %rsi      # 0x9180
callq 0x2040
testl %eax, %eax
jne 0x3543
movl $0x1, %edi
movq %r12, %rsi
callq 0x2bf8
movl $0x4, %edi
movq %r12, %rsi
callq 0x2bf8
testl %eax, %eax
je 0x3528
movq 0x8a90(%rip), %rax      # 0xbfd0
movq (%rax), %r15
movq %r15, %rdi
leaq 0x5cc6(%rip), %rsi      # 0x9213
callq 0x2040
testl %eax, %eax
leaq 0x10(%rsp), %r15
jne 0x3336
jmp 0x3720
cmpl $-0x1, %eax
je 0x35ac
cmpl $0x3f, %eax
jne 0x3336
jmp 0x3714
leaq 0x15e52(%rip), %r13     # 0x193d0
jmp 0x3587
leaq 0x15fc9(%rip), %r13     # 0x19550
movq %r13, %rdi
callq 0x2140
movq %r13, %rdi
movq %r15, %rsi
movq %rax, %rdx
callq 0x2060
leaq 0x4(%rsp), %r13
leaq 0x10(%rsp), %r15
jmp 0x3336
movl $0x1, %esi
movl $0xd, %edi
callq 0x22a0
callq 0x2530
testl %eax, %eax
movq 0x8(%rsp), %r14
js 0x36db
jne 0x3736
callq 0x21f0
testl %eax, %eax
js 0x36db
movl $0x1, %esi
movl $0x1, %edi
callq 0x22a0
callq 0x2530
testl %eax, %eax
js 0x36db
jne 0x3736
movq 0x15edf(%rip), %rdi     # 0x194e8
callq 0x7837
movq %rax, 0x15ed3(%rip)     # 0x194e8
movq 0x15ed4(%rip), %rdi     # 0x194f0
callq 0x7837
movq %rax, 0x15ec8(%rip)     # 0x194f0
movq 0x15ec9(%rip), %rdi     # 0x194f8
callq 0x7837
movq %rax, 0x15ebd(%rip)     # 0x194f8
movq 0x15ebe(%rip), %rdi     # 0x19500
callq 0x7837
movq %rax, 0x15eb2(%rip)     # 0x19500
movl $0x7f8, %eax            # imm = 0x7F8
leaq 0x30(%rsp), %rsi
movq %rax, (%rsi)
movq %rax, 0x8(%rsi)
movl $0x7, %edi
callq 0x23c0
cmpl $-0x1, %eax
je 0x36ed
movq %r14, %rdi
callq 0x2f53
movl (%r14), %edi
callq 0x2520
cmpl $-0x1, %eax
je 0x3778
movl (%r14), %edi
callq 0x2560
cmpl $-0x1, %eax
je 0x3778
leaq 0x15fd9(%rip), %rbx     # 0x19678
movl 0x4(%r14), %eax
leal -0x1(%rax), %ecx
movl %ecx, 0x4(%r14)
cmpl $0x2, %eax
jl 0x36ba
callq 0x2530
movl %eax, (%rbx)
testl %eax, %eax
je 0x369f
movl $0x3fc, %edi            # imm = 0x3FC
callq 0x2490
movl %eax, 0x12cba(%rip)     # 0x16384
cmpl $-0x1, %eax
je 0x3782
movq %r14, %rdi
callq 0x316c
addq $0x268, %rsp            # imm = 0x268
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x5a93(%rip), %rdi      # 0x9187
callq 0x2460
jmp 0x366e
movq 0x8(%rsp), %rdi
callq 0x78ec
leaq 0x40(%rsp), %rsi
movl $0x1, %edi
jmp 0x372a
callq 0x2580
xorl %edi, %edi
callq 0x24b0
leaq 0x40(%rsp), %rsi
movl $0x3, %edi
callq 0x2bf8
movl %eax, %edi
callq 0x24b0
leaq 0x15dab(%rip), %rdi     # 0x194e8
callq 0x786b
leaq 0x15da7(%rip), %rdi     # 0x194f0
callq 0x786b
leaq 0x15da3(%rip), %rdi     # 0x194f8
callq 0x786b
leaq 0x15d9f(%rip), %rdi     # 0x19500
callq 0x786b
movq %r14, %rdi
callq 0x78ec
movq %r14, %rdi
callq 0x2030
jmp 0x3719
movl $0x1, %edi
callq 0x24b0
callq 0x268e