// File: qian-jiahong[P]uvncrep017-ws/repeater.cpp
// Function: connectWithTimeout(int, sockaddr const*, unsigned int, int)
static int connectWithTimeout(int socket, const struct sockaddr *addr, socklen_t addrlen, int timeOutSecs)
{
    int res;
    long arg; 
    fd_set myset; 
    struct timeval tv; 
    int valopt;     
    socklen_t lon;
    
    //First, set socket non-blocking 
    arg = fcntl(socket, F_GETFL, NULL);
    if (arg < 0) { 
        debug(LEVEL_2, "connectWithTimeout(): error in fcntl(..., F_GETFL) (%s)\n", strerror(errno)); 
        return -1; 
    } 
    arg |= O_NONBLOCK; 
    if (fcntl(socket, F_SETFL, arg) < 0) { 
        debug(LEVEL_2, "connectWithTimeout(): error in fcntl(..., F_SETFL) (%s)\n", strerror(errno)); 
        return -1; 
    }     

    //Try to connect with timeout 
    res = connect(socket, addr, addrlen); 
    if (res < 0) { 
        if (errno == EINPROGRESS) { 
            debug(LEVEL_3, "connectWithTimeout(): EINPROGRESS in connect() - selecting\n"); 
        
            do { 
                tv.tv_sec = timeOutSecs; 
                tv.tv_usec = 0; 
                
                FD_ZERO(&myset); 
                FD_SET(socket, &myset); 
                
                res = select(socket + 1, NULL, &myset, NULL, &tv); 
           
                if ((res < 0) && (errno != EINTR)) { 
                    debug(LEVEL_3, "connectWithTimeout(): Error connecting %d (%s)\n", errno, strerror(errno)); 
                    return -1; 
                } 
                else if (res > 0) { 
                    // Socket selected for write, check if connection was succesful 
                    lon = sizeof(int); 
                    
                    if (getsockopt(socket, SOL_SOCKET, SO_ERROR, (void*)(&valopt), &lon) < 0) { 
                        debug(LEVEL_2, "connectWithTimeout(): Error in getsockopt() %d (%s)\n", errno, strerror(errno)); 
                        return -1; 
                    } 
              
                    // Check the value returned... 
                    if (valopt) { 
                        debug(LEVEL_2, "connectWithTimeout(): Error in delayed connection() %d (%s)\n", 
                            valopt, strerror(valopt)); 
                        return -1; 
                    } 
                    else {
                        debug(LEVEL_3, "connectWithTimeout(): connected OK\n"); 
                        break;
                    } 
                } 
                else { 
                    debug(LEVEL_3, "connectWithTimeout(): Timeout in select() - Cancelling!\n"); 
                    return -1; 
                } 
            } while (1); 
        } 
        else { 
            debug(LEVEL_3, "connectWithTimeout(): Error connecting %d (%s)\n", errno, strerror(errno)); 
            return -1; 
        } 
    } 
  
    //Set to blocking mode again... 
    if ((arg = fcntl(socket, F_GETFL, NULL)) < 0) { 
        debug(LEVEL_2, "connectWithTimeout(): Error fcntl(..., F_GETFL) (%s)\n", strerror(errno)); 
        return -1; 
    } 
    arg &= (~O_NONBLOCK); 
    if (fcntl(socket, F_SETFL, arg) < 0) { 
        debug(LEVEL_2, "connectWithTimeout(): Error fcntl(..., F_SETFL) (%s)\n", strerror(errno)); 
        return -1; 
    } 
    
    return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xe0, %rsp
movl %edi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movl %edx, -0x14(%rbp)
movl %ecx, -0x18(%rbp)
movl -0x8(%rbp), %edi
movl $0x3, %esi
xorl %eax, %eax
movl %eax, %edx
movb $0x0, %al
callq 0x2130
cltq
movq %rax, -0x28(%rbp)
cmpq $0x0, -0x28(%rbp)
jge 0x2866
callq 0x2030
movl (%rax), %edi
callq 0x20b0
movq %rax, %rdx
movl $0x2, %edi
leaq 0x7bce(%rip), %rsi      # 0xa421
movb $0x0, %al
callq 0x2480
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0x2be1
movq -0x28(%rbp), %rax
orq $0x800, %rax            # imm = 0x800
movq %rax, -0x28(%rbp)
movl -0x8(%rbp), %edi
movq -0x28(%rbp), %rdx
movl $0x4, %esi
movb $0x0, %al
callq 0x2130
cmpl $0x0, %eax
jge 0x28ba
callq 0x2030
movl (%rax), %edi
callq 0x20b0
movq %rax, %rdx
movl $0x2, %edi
leaq 0x7bb3(%rip), %rsi      # 0xa45a
movb $0x0, %al
callq 0x2480
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0x2be1
movl -0x8(%rbp), %edi
movq -0x10(%rbp), %rsi
movl -0x14(%rbp), %edx
callq 0x21c0
movl %eax, -0x1c(%rbp)
cmpl $0x0, -0x1c(%rbp)
jge 0x2b3f
callq 0x2030
cmpl $0x73, (%rax)
jne 0x2afc
movl $0x3, %edi
leaq 0x7ba3(%rip), %rsi      # 0xa493
movb $0x0, %al
callq 0x2480
movslq -0x18(%rbp), %rax
movq %rax, -0xb8(%rbp)
movq $0x0, -0xb0(%rbp)
leaq -0xa8(%rbp), %rax
movq %rax, -0xd0(%rbp)
movl $0x0, -0xc4(%rbp)
movl -0xc4(%rbp), %eax
cmpq $0x10, %rax
jae 0x2957
movq -0xd0(%rbp), %rax
movl -0xc4(%rbp), %ecx
movq $0x0, (%rax,%rcx,8)
movl -0xc4(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xc4(%rbp)
jmp 0x2925
jmp 0x2959
movl -0x8(%rbp), %eax
movl $0x40, %ecx
cltd
idivl %ecx
movl %edx, %eax
movl %eax, %ecx
movl $0x1, %eax
shlq %cl, %rax
movq %rax, %rcx
movl -0x8(%rbp), %eax
movl $0x40, %esi
cltd
idivl %esi
cltq
orq -0xa8(%rbp,%rax,8), %rcx
movq %rcx, -0xa8(%rbp,%rax,8)
movl -0x8(%rbp), %edi
addl $0x1, %edi
xorl %eax, %eax
movl %eax, %ecx
leaq -0xa8(%rbp), %rdx
leaq -0xb8(%rbp), %r8
movq %rcx, %rsi
callq 0x21f0
movl %eax, -0x1c(%rbp)
cmpl $0x0, -0x1c(%rbp)
jge 0x2a04
callq 0x2030
cmpl $0x4, (%rax)
je 0x2a04
callq 0x2030
movl (%rax), %eax
movl %eax, -0xd4(%rbp)
callq 0x2030
movl (%rax), %edi
callq 0x20b0
movl -0xd4(%rbp), %edx
movq %rax, %rcx
movl $0x3, %edi
leaq 0x7ade(%rip), %rsi      # 0xa4cf
movb $0x0, %al
callq 0x2480
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0x2be1
cmpl $0x0, -0x1c(%rbp)
jle 0x2adb
movl $0x4, -0xc0(%rbp)
movl -0x8(%rbp), %edi
movl $0x1, %esi
movl $0x4, %edx
leaq -0xbc(%rbp), %rcx
leaq -0xc0(%rbp), %r8
callq 0x2180
cmpl $0x0, %eax
jge 0x2a7e
callq 0x2030
movl (%rax), %eax
movl %eax, -0xd8(%rbp)
callq 0x2030
movl (%rax), %edi
callq 0x20b0
movl -0xd8(%rbp), %edx
movq %rax, %rcx
movl $0x2, %edi
leaq 0x7a94(%rip), %rsi      # 0xa4ff
movb $0x0, %al
callq 0x2480
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0x2be1
cmpl $0x0, -0xbc(%rbp)
je 0x2ac6
movl -0xbc(%rbp), %eax
movl %eax, -0xdc(%rbp)
movl -0xbc(%rbp), %edi
callq 0x20b0
movl -0xdc(%rbp), %edx
movq %rax, %rcx
movl $0x2, %edi
leaq 0x7a81(%rip), %rsi      # 0xa534
movb $0x0, %al
callq 0x2480
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0x2be1
movl $0x3, %edi
leaq 0x7a9f(%rip), %rsi      # 0xa571
movb $0x0, %al
callq 0x2480
jmp 0x2afa
movl $0x3, %edi
leaq 0x7aae(%rip), %rsi      # 0xa595
movb $0x0, %al
callq 0x2480
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0x2be1
jmp 0x2b3d
callq 0x2030
movl (%rax), %eax
movl %eax, -0xe0(%rbp)
callq 0x2030
movl (%rax), %edi
callq 0x20b0
movl -0xe0(%rbp), %edx
movq %rax, %rcx
movl $0x3, %edi
leaq 0x79a5(%rip), %rsi      # 0xa4cf
movb $0x0, %al
callq 0x2480
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0x2be1
jmp 0x2b3f
movl -0x8(%rbp), %edi
movl $0x3, %esi
xorl %eax, %eax
movl %eax, %edx
movb $0x0, %al
callq 0x2130
cltq
movq %rax, -0x28(%rbp)
cmpq $0x0, %rax
jge 0x2b89
callq 0x2030
movl (%rax), %edi
callq 0x20b0
movq %rax, %rdx
movl $0x2, %edi
leaq 0x7a55(%rip), %rsi      # 0xa5ce
movb $0x0, %al
callq 0x2480
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0x2be1
movq -0x28(%rbp), %rax
andq $-0x801, %rax           # imm = 0xF7FF
movq %rax, -0x28(%rbp)
movl -0x8(%rbp), %edi
movq -0x28(%rbp), %rdx
movl $0x4, %esi
movb $0x0, %al
callq 0x2130
cmpl $0x0, %eax
jge 0x2bda
callq 0x2030
movl (%rax), %edi
callq 0x20b0
movq %rax, %rdx
movl $0x2, %edi
leaq 0x7a3a(%rip), %rsi      # 0xa604
movb $0x0, %al
callq 0x2480
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0x2be1
movl $0x0, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0xe0, %rsp
popq %rbp
retq
nopl (%rax)