// File: qian-jiahong[P]uvncrep017-ws/repeater.cpp
// Function: main
int main(int argc, char **argv)
{
    //Viewer port listener variable
    listenPortInfo viewerListener = {-1, -1};

    //Server port listener variable
    listenPortInfo serverListener = {-1, -1};

    //ctrl+c signal handler
    struct sigaction saInt;

    //ini file default
    char defaultIniFilePathAndName[] = "/etc/uvnc/uvncrepeater.ini";
    char tmpBuf[MAX_PATH];
    bool memoryOk;

    //Startup event
    startEndEvent seEv;
    
    stopped = false;
    mode1ConnCode = 0;
    
    fprintf(stderr, "UltraVnc Linux Repeater version %s\n", REPEATER_VERSION);
    
    //Read parameters from ini file
    // strlcpy(tmpBuf, (argc >= 2) ? argv[1] : defaultIniFilePathAndName, MAX_PATH);
    strlcpy(tmpBuf, (argc >= 2) ? argv[1] : DEFAULT_INI_FILE_PATH_AND_NAME, MAX_PATH);
    if (false == readIniFile(tmpBuf)) {
        debug(LEVEL_1, "main(): ini file (%s) read error, using defaults\n", tmpBuf);
    }
    listInitializationValues();

    //Send startup event to event interface 
    initRepeaterEventInterface();
    if (useEventInterface) {
        event.eventNum = REPEATER_STARTUP;
        event.timeStamp = time(NULL);
        event.repeaterProcessId = getpid();
        
        seEv.maxSessions = maxSessions;
        memcpy(event.extraInfo, &seEv, sizeof(startEndEvent));
        
        //Event fifo can not be full here ;-)
        sendRepeaterEvent(event);
    }

    //Allocate and clean various repeater lists
    if (false == allocateMemoryForRepeaterLists(maxSessions)) {
        debug(LEVEL_0, "main(): memory allocation for repeater lists failed, exiting program\n");
        memoryOk = false;
    }
    else {
        memoryOk = true;
        cleanLists();
    }

    //If we got lists allocated, we can run
    if (memoryOk) {
        //Initialize ctrl+c signal handler
        memset(&saInt, 0, sizeof(saInt));
    
        //Restart interrupted system calls after handler returns    
        saInt.sa_flags = SA_RESTART;    
        saInt.sa_handler = &handleSigInt;
        sigaction(SIGINT, &saInt, NULL);

        //Initialize and start listening on viewer port
        if (((allowedModes & CONN_MODE1) > 0) || ((allowedModes & CONN_MODE2) > 0)) {
            viewerListener.port = viewerPort;
            startListeningOnPort(&viewerListener);
        }

        //Initialize and start listening on server port
        if ((allowedModes & CONN_MODE2) > 0) {
            serverListener.port = serverPort;
            startListeningOnPort(&serverListener);
        }

        //Drop root privileges (if we are running as root) after all listen ports have been bound
        if (geteuid() == 0) {
            dropRootPrivileges(); 
        }

        //Accept & Route new connections
        if (stopped == false) {
            routeConnections(viewerListener.socket, serverListener.socket);
        }

        close(viewerListener.socket);
        close(serverListener.socket);
    }

    //Free allocated memory of repeater lists
    freeMemoryOfRepeaterLists();

    //Send shutdown event to event interface
    if (useEventInterface) {
        event.eventNum = REPEATER_SHUTDOWN;
        event.timeStamp = time(NULL);
        event.repeaterProcessId = getpid();
        
        seEv.maxSessions = maxSessions;
        memcpy(event.extraInfo, &seEv, sizeof(startEndEvent));
        if (false == sendRepeaterEvent(event)) {
            debug(LEVEL_1, "main(): Warning, event fifo is full\n");
        }
        handleRepeaterEvents();
    }

    debug(LEVEL_0, "main(): relaying done.\n");

    return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x370, %rsp            # imm = 0x370
movl $0x0, -0x4(%rbp)
movl %edi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq 0x8e3c(%rip), %rax      # 0xc0fc
movq %rax, -0x18(%rbp)
movq 0x8e31(%rip), %rax      # 0xc0fc
movq %rax, -0x20(%rbp)
movq 0x8e3a(%rip), %rax      # 0xc110
movq %rax, -0xe0(%rbp)
movq 0x8e34(%rip), %rax      # 0xc118
movq %rax, -0xd8(%rbp)
movq 0x8e2e(%rip), %rax      # 0xc120
movq %rax, -0xd0(%rbp)
movw 0x8e28(%rip), %ax       # 0xc128
movw %ax, -0xc8(%rbp)
movb 0x8e1d(%rip), %al       # 0xc12a
movb %al, -0xc6(%rbp)
movb $0x0, 0xc886(%rip)      # 0xfba0
movq $0x0, 0xe7cb(%rip) # 0x11af0
movq 0xbcb4(%rip), %rax      # 0xefe0
movq (%rax), %rdi
leaq 0x7005(%rip), %rsi      # 0xa33b
leaq 0x7022(%rip), %rdx      # 0xa35f
movb $0x0, %al
callq 0x22d0
leaq -0x1e0(%rbp), %rax
movq %rax, -0x2e0(%rbp)
cmpl $0x2, -0x8(%rbp)
jl 0x3369
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x2e8(%rbp)
jmp 0x3379
leaq 0xbe60(%rip), %rax      # 0xf1d0
movq %rax, -0x2e8(%rbp)
jmp 0x3379
movq -0x2e0(%rbp), %rdi
movq -0x2e8(%rbp), %rsi
movl $0xfa, %edx
callq 0x76d0
leaq -0x1e0(%rbp), %rdi
callq 0x8b00
andb $0x1, %al
movzbl %al, %ecx
xorl %eax, %eax
cmpl %ecx, %eax
jne 0x33c2
leaq -0x1e0(%rbp), %rdx
movl $0x1, %edi
leaq 0x6fa9(%rip), %rsi      # 0xa364
movb $0x0, %al
callq 0x2480
callq 0x36d0
callq 0x9100
leaq 0x14f21(%rip), %rax     # 0x182f4
testb $0x1, (%rax)
je 0x349a
movl $0x6, 0xe712(%rip)      # 0x11af8
xorl %eax, %eax
movl %eax, %edi
callq 0x21e0
movq %rax, 0xe70a(%rip)      # 0x11b00
callq 0x22f0
movl %eax, 0xe707(%rip)      # 0x11b08
leaq 0xc638(%rip), %rax      # 0xfa40
movl (%rax), %eax
movl %eax, -0x1e8(%rbp)
movl -0x1e8(%rbp), %eax
movl %eax, 0xe6f0(%rip)      # 0x11b0c
leaq -0x260(%rbp), %rdi
leaq 0xe6ce(%rip), %rsi      # 0x11af8
movl $0x78, %edx
callq 0x21b0
movq -0x1f0(%rbp), %rcx
movq %rsp, %rax
movq %rax, -0x2f0(%rbp)
movq %rcx, 0x70(%rax)
movups -0x200(%rbp), %xmm0
movups %xmm0, 0x60(%rax)
movups -0x210(%rbp), %xmm0
movups %xmm0, 0x50(%rax)
movups -0x220(%rbp), %xmm0
movups %xmm0, 0x40(%rax)
movups -0x260(%rbp), %xmm0
movups -0x250(%rbp), %xmm1
movups -0x240(%rbp), %xmm2
movups -0x230(%rbp), %xmm3
movups %xmm3, 0x30(%rax)
movups %xmm2, 0x20(%rax)
movups %xmm1, 0x10(%rax)
movups %xmm0, (%rax)
callq 0x9130
leaq 0xc59f(%rip), %rax      # 0xfa40
movl (%rax), %edi
callq 0x3b30
andb $0x1, %al
movzbl %al, %ecx
xorl %eax, %eax
cmpl %ecx, %eax
jne 0x34cc
xorl %edi, %edi
leaq 0x6eda(%rip), %rsi      # 0xa396
movb $0x0, %al
callq 0x2480
movb $0x0, -0x1e1(%rbp)
jmp 0x34d8
movb $0x1, -0x1e1(%rbp)
callq 0x3cc0
testb $0x1, -0x1e1(%rbp)
je 0x35b9
leaq -0xb8(%rbp), %rdi
xorl %esi, %esi
movl $0x98, %edx
callq 0x2120
movl $0x10000000, -0x30(%rbp) # imm = 0x10000000
leaq 0x85a(%rip), %rax       # 0x3d60
movq %rax, -0xb8(%rbp)
movl $0x2, %edi
leaq -0xb8(%rbp), %rsi
xorl %eax, %eax
movl %eax, %edx
callq 0x2290
leaq 0xbccf(%rip), %rax      # 0xf1f8
movl (%rax), %eax
andl $0x1, %eax
cmpl $0x0, %eax
jg 0x3544
leaq 0xbcbe(%rip), %rax      # 0xf1f8
movl (%rax), %eax
andl $0x2, %eax
cmpl $0x0, %eax
jle 0x3559
leaq 0xbca5(%rip), %rax      # 0xf1f0
movl (%rax), %eax
movl %eax, -0x14(%rbp)
leaq -0x18(%rbp), %rdi
callq 0x3d70
leaq 0xbc98(%rip), %rax      # 0xf1f8
movl (%rax), %eax
andl $0x2, %eax
cmpl $0x0, %eax
jle 0x357f
leaq 0xbc83(%rip), %rax      # 0xf1f4
movl (%rax), %eax
movl %eax, -0x1c(%rbp)
leaq -0x20(%rbp), %rdi
callq 0x3d70
callq 0x2140
cmpl $0x0, %eax
jne 0x358e
callq 0x3f50
movb 0xc60c(%rip), %al       # 0xfba0
andb $0x1, %al
movzbl %al, %eax
cmpl $0x0, %eax
jne 0x35a9
movl -0x18(%rbp), %edi
movl -0x20(%rbp), %esi
callq 0x4050
movl -0x18(%rbp), %edi
callq 0x2370
movl -0x20(%rbp), %edi
callq 0x2370
callq 0x4460
leaq 0x14d2f(%rip), %rax     # 0x182f4
testb $0x1, (%rax)
je 0x36af
movl $0x7, 0xe520(%rip)      # 0x11af8
xorl %eax, %eax
movl %eax, %edi
callq 0x21e0
movq %rax, 0xe518(%rip)      # 0x11b00
callq 0x22f0
movl %eax, 0xe515(%rip)      # 0x11b08
leaq 0xc446(%rip), %rax      # 0xfa40
movl (%rax), %eax
movl %eax, -0x1e8(%rbp)
movl -0x1e8(%rbp), %eax
movl %eax, 0xe4fe(%rip)      # 0x11b0c
leaq -0x2d8(%rbp), %rdi
leaq 0xe4dc(%rip), %rsi      # 0x11af8
movl $0x78, %edx
callq 0x21b0
movq -0x268(%rbp), %rcx
movq %rsp, %rax
movq %rax, -0x2f8(%rbp)
movq %rcx, 0x70(%rax)
movups -0x278(%rbp), %xmm0
movups %xmm0, 0x60(%rax)
movups -0x288(%rbp), %xmm0
movups %xmm0, 0x50(%rax)
movups -0x298(%rbp), %xmm0
movups %xmm0, 0x40(%rax)
movups -0x2d8(%rbp), %xmm0
movups -0x2c8(%rbp), %xmm1
movups -0x2b8(%rbp), %xmm2
movups -0x2a8(%rbp), %xmm3
movups %xmm3, 0x30(%rax)
movups %xmm2, 0x20(%rax)
movups %xmm1, 0x10(%rax)
movups %xmm0, (%rax)
callq 0x9130
andb $0x1, %al
movzbl %al, %ecx
xorl %eax, %eax
cmpl %ecx, %eax
jne 0x36aa
movl $0x1, %edi
leaq 0x6d39(%rip), %rsi      # 0xa3dc
movb $0x0, %al
callq 0x2480
callq 0x9200
xorl %edi, %edi
leaq 0x6d49(%rip), %rsi      # 0xa401
movb $0x0, %al
callq 0x2480
xorl %eax, %eax
addq $0x370, %rsp            # imm = 0x370
popq %rbp
retq
nopw (%rax,%rax)