// File: /workspace/github_c_makefile_star2_O1/icebert[P]pblat/lib/https.c
// Function: netConnectHttpsThread
void *netConnectHttpsThread(void *threadParam)
/* use a thread to run socket back to user */
{
/* child */

struct netConnectHttpsParams *params = threadParam;

pthread_detach(params->thread);  // this thread will never join back with it's progenitor

int fd=0;
char *proxyUrl = getenv("https_proxy");
if (params->noProxy)
    proxyUrl = NULL;
char *connectHost;
int connectPort;

BIO *fbio=NULL;  // file descriptor bio
BIO *sbio=NULL;  // ssl bio
SSL_CTX *ctx;
SSL *ssl;

openSslInit();

ctx = SSL_CTX_new(SSLv23_client_method());

fd_set readfds;
fd_set writefds;
int err;
struct timeval tv;


/* TODO checking certificates 

char *certFile = NULL;
char *certPath = NULL;
if (certFile || certPath)
    {
    SSL_CTX_load_verify_locations(ctx,certFile,certPath);
#if (OPENSSL_VERSION_NUMBER < 0x0090600fL)
    SSL_CTX_set_verify_depth(ctx,1);
#endif
    }

// verify paths and mode.

*/



// Don't want any retries since we are non-blocking bio now
// This is available on newer versions of openssl
//SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY);

// Support for Http Proxy
struct netParsedUrl pxy;
if (proxyUrl)
    {
    netParseUrl(proxyUrl, &pxy);
    if (!sameString(pxy.protocol, "http"))
	{
	char s[256];	
	safef(s, sizeof s, "Unknown proxy protocol %s in %s. Should be http.", pxy.protocol, proxyUrl);
	xerr(s);
	goto cleanup;
	}
    connectHost = pxy.host;
    connectPort = atoi(pxy.port);
    }
else
    {
    connectHost = params->hostName;
    connectPort = params->port;
    }
fd = netConnect(connectHost,connectPort);
if (fd == -1)
    {
    xerr("netConnect() failed");
    goto cleanup;
    }

if (proxyUrl)
    {
    char *logProxy = getenv("log_proxy");
    if (sameOk(logProxy,"on"))
	verbose(1, "CONNECT %s:%d HTTP/1.0 via %s:%d\n", params->hostName, params->port, connectHost,connectPort);
    struct dyString *dy = newDyString(512);
    dyStringPrintf(dy, "CONNECT %s:%d HTTP/1.0\r\n", params->hostName, params->port);
    setAuthorization(pxy, "Proxy-Authorization", dy);
    dyStringAppend(dy, "\r\n");
    mustWriteFd(fd, dy->string, dy->stringSize);
    dyStringFree(&dy);
    // verify response
    char *newUrl = NULL;
    boolean success = netSkipHttpHeaderLinesWithRedirect(fd, proxyUrl, &newUrl);
    if (!success) 
	{
	xerr("proxy server response failed");
	goto cleanup;
	}
    if (newUrl) /* no redirects */
	{
	xerr("proxy server response should not be a redirect");
	goto cleanup;
	}
    }


fbio=BIO_new_socket(fd,BIO_NOCLOSE);  
// BIO_NOCLOSE because we handle closing fd ourselves.
if (fbio == NULL)
    {
    xerr("BIO_new_socket() failed");
    goto cleanup;
    }
sbio = BIO_new_ssl(ctx, 1);
if (sbio == NULL) 
    {
    xerr("BIO_new_ssl() failed");
    goto cleanup;
    }
sbio = BIO_push(sbio, fbio);
BIO_get_ssl(sbio, &ssl);
if(!ssl) 
    {
    xerr("Can't locate SSL pointer");
    goto cleanup;
    }


/* 
Server Name Indication (SNI)
Required to complete tls ssl negotiation for systems which house multiple domains. (SNI)
This is common when serving HTTPS requests with a wildcard certificate (*.domain.tld).
This line will allow the ssl connection to send the hostname at tls negotiation time.
It tells the remote server which hostname the client is connecting to.
The hostname must not be an IP address.
*/ 
if (!internetIsDottedQuad(params->hostName))
    SSL_set_tlsext_host_name(ssl,params->hostName);

BIO_set_nbio(sbio, 1);     /* non-blocking mode */

while (1) 
    {
    if (BIO_do_handshake(sbio) == 1) 
	{
	break;  /* Connected */
	}
    if (! BIO_should_retry(sbio)) 
	{
	xerr("BIO_do_handshake() failed");
	char s[256];	
	safef(s, sizeof s, "SSL error: %s", ERR_reason_error_string(ERR_get_error()));
	xerr(s);
	goto cleanup;
	}

    fd = BIO_get_fd(sbio, NULL);
    if (fd == -1) 
	{
	xerr("unable to get BIO descriptor");
	goto cleanup;
	}
    FD_ZERO(&readfds);
    FD_ZERO(&writefds);
    if (BIO_should_read(sbio)) 
	{
	FD_SET(fd, &readfds);
	}
    else if (BIO_should_write(sbio)) 
	{
	FD_SET(fd, &writefds);
	}
    else 
	{  /* BIO_should_io_special() */
	FD_SET(fd, &readfds);
	FD_SET(fd, &writefds);
	}
    tv.tv_sec = (long) (DEFAULTCONNECTTIMEOUTMSEC/1000);  // timeout default 10 seconds
    tv.tv_usec = (long) (((DEFAULTCONNECTTIMEOUTMSEC/1000)-tv.tv_sec)*1000000);

    err = select(fd + 1, &readfds, &writefds, NULL, &tv);
    if (err < 0) 
	{
	xerr("select() error");
	goto cleanup;
	}

    if (err == 0) 
	{
	char s[256];	
	safef(s, sizeof s, "connection timeout to %s", params->hostName);
	xerr(s);
	goto cleanup;
	}
    }


/* TODO checking certificates 

if (certFile || certPath)
    if (!check_cert(ssl, host))
	return -1;

*/

/* we need to wait on both the user's socket and the BIO SSL socket 
 * to see if we need to ferry data from one to the other */


char sbuf[32768];  // socket buffer sv[1] to user
char bbuf[32768];  // bio buffer
int srd = 0;
int swt = 0;
int brd = 0;
int bwt = 0;
while (1) 
    {

    // Do NOT move this outside the while loop. 
    /* Get underlying file descriptor, needed for select call */
    fd = BIO_get_fd(sbio, NULL);
    if (fd == -1) 
	{
	xerr("BIO doesn't seem to be initialized in https, unable to get descriptor.");
	goto cleanup;
	}


    FD_ZERO(&readfds);
    FD_ZERO(&writefds);

    if (brd == 0)
	FD_SET(fd, &readfds);
    if (swt < srd)
	FD_SET(fd, &writefds);
    if (srd == 0)
	FD_SET(params->sv[1], &readfds);

    tv.tv_sec = (long) (DEFAULTCONNECTTIMEOUTMSEC/1000);  // timeout default 10 seconds
    tv.tv_usec = (long) (((DEFAULTCONNECTTIMEOUTMSEC/1000)-tv.tv_sec)*1000000);

    err = select(max(fd,params->sv[1]) + 1, &readfds, &writefds, NULL, &tv);

    /* Evaluate select() return code */
    if (err < 0) 
	{
	xerr("error during select()");
	goto cleanup;
	}
    else if (err == 0) 
	{
	/* Timed out - just quit */
	xerr("https timeout expired");
	goto cleanup;
	}

    else 
	{
	if (FD_ISSET(params->sv[1], &readfds))
	    {
	    swt = 0;
	    srd = read(params->sv[1], sbuf, 32768);
	    if (srd == -1)
		{
		if (errno != 104) // udcCache often closes causing "Connection reset by peer"
		    xerrno("error reading user pipe for https socket");
		goto cleanup;
		}
	    if (srd == 0) 
		break;  // user closed socket, we are done
	    }

	if (FD_ISSET(fd, &writefds))
	    {
	    int swtx = BIO_write(sbio, sbuf+swt, srd-swt);
	    if (swtx <= 0)
		{
		if (!BIO_should_write(sbio))
		    {
		    ERR_print_errors_fp(stderr);
		    xerr("Error writing SSL connection");
		    goto cleanup;
		    }
		}
	    else
		{
		swt += swtx;
		if (swt >= srd)
		    {
		    swt = 0;
		    srd = 0;
		    }
		}
	    }

	if (FD_ISSET(fd, &readfds))
	    {
	    bwt = 0;
	    brd = BIO_read(sbio, bbuf, 32768);

	    if (brd <= 0)
		{
		if (BIO_should_read(sbio))
		    {
		    brd = 0;
		    continue;
		    }
		else
		    {
		    if (brd == 0) break;
		    ERR_print_errors_fp(stderr);
		    xerr("Error reading SSL connection");
		    goto cleanup;
		    }
		}
	    // write the https data received immediately back on socket to user, and it's ok if it blocks.
	    while(bwt < brd)
		{
		// NOTE: Intended as a thread-specific library-safe way not to ignore SIG_PIPE for the entire application.
		// temporarily block sigpipe on this thread
		sigset_t sigpipe_mask;
		sigemptyset(&sigpipe_mask);
		sigaddset(&sigpipe_mask, SIGPIPE);
		sigset_t saved_mask;
		if (pthread_sigmask(SIG_BLOCK, &sigpipe_mask, &saved_mask) == -1) {
		    perror("pthread_sigmask");
		    exit(1);
		}
		int bwtx = write(params->sv[1], bbuf+bwt, brd-bwt);
		int saveErrno = errno;
		if ((bwtx == -1) && (saveErrno == EPIPE))
		    { // if there was a EPIPE, accept and consume the SIGPIPE now.
		    int sigErr, sig;
		    if ((sigErr = sigwait(&sigpipe_mask, &sig)) != 0) 
			{
			errno = sigErr;
			perror("sigwait");
			exit(1);
			}
		    }
		// restore signal mask on this thread
		if (pthread_sigmask(SIG_SETMASK, &saved_mask, 0) == -1) 
		    {
		    perror("pthread_sigmask");
		    exit(1);
		    }
		errno = saveErrno;
		if (bwtx == -1)
		    {
		    if ((errno != 104)  // udcCache often closes causing "Connection reset by peer"
		     && (errno !=  32)) // udcCache often closes causing "Broken pipe"
			xerrno("error writing https data back to user pipe");
		    goto cleanup;
		    }
		bwt += bwtx;
		}
	    brd = 0;
	    bwt = 0;
	    }
	}
    }

cleanup:

BIO_free_all(sbio);  // will free entire chain of bios
close(fd);     // Needed because we use BIO_NOCLOSE above. Someday might want to re-use a connection.
close(params->sv[1]);  /* we are done with it */

return NULL;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x15328, %rsp          # imm = 0x15328
movq %rdi, %rbp
movq (%rdi), %rdi
callq 0x64a0
leaq 0x4dc0e(%rip), %rdi     # 0x97805
callq 0x68f0
xorl %r12d, %r12d
cmpl $0x0, 0x14(%rbp)
cmoveq %rax, %r12
callq 0x49b69
callq 0x6360
movq %rax, %rdi
callq 0x6a80
movq %rax, %r15
testq %r12, %r12
movq %rbp, 0x2830(%rsp)
je 0x49c68
leaq 0x2af0(%rsp), %rbx
movq %r12, %rdi
movq %rbx, %rsi
callq 0x2ea40
movl $0x70747468, %eax       # imm = 0x70747468
xorl (%rbx), %eax
movzbl 0x4(%rbx), %ecx
orl %eax, %ecx
jne 0x4a432
leaq 0x3b00(%rsp), %rbx
leaq 0x4300(%rsp), %rdi
callq 0x6bd0
movl %eax, %ebp
jmp 0x49c6f
movq 0x8(%rbp), %rbx
movl 0x10(%rbp), %ebp
movq %rbx, %rdi
movl %ebp, %esi
callq 0x2e349
cmpl $-0x1, %eax
je 0x4a3e2
movl %eax, %r14d
testq %r12, %r12
je 0x49d8a
leaq 0x48319(%rip), %rdi     # 0x91fae
callq 0x68f0
leaq 0x43aed(%rip), %rsi     # 0x8d78e
movq %rax, %rdi
callq 0x21769
testl %eax, %eax
jne 0x49cd5
movq 0x2830(%rsp), %rax
movq 0x8(%rax), %rdx
movl 0x10(%rax), %ecx
leaq 0x4db93(%rip), %rsi     # 0x97856
movl $0x1, %edi
movq %rbx, %r8
movl %ebp, %r9d
xorl %eax, %eax
callq 0x4246e
movl $0x200, %edi            # imm = 0x200
callq 0x261d0
leaq 0x2970(%rsp), %rbx
movq %rax, (%rbx)
movq 0x2830(%rsp), %rbp
movq 0x8(%rbp), %rdx
movl 0x10(%rbp), %ecx
leaq 0x4db78(%rip), %rsi     # 0x97878
movq %rax, %rdi
xorl %eax, %eax
callq 0x2656a
movq (%rbx), %rax
leaq 0x2af0(%rsp), %rsi
movl $0x506, %ecx            # imm = 0x506
movq %rsp, %rdi
rep  movsq (%rsi), %es:(%rdi)
leaq 0x482c7(%rip), %rdi     # 0x91fee
movq %rax, %rsi
callq 0x2f5b4
movq (%rbx), %rdi
leaq 0x4defa(%rip), %rsi     # 0x97c33
callq 0x26425
movq (%rbx), %rax
movq 0x8(%rax), %rsi
movslq 0x14(%rax), %rdx
movl %r14d, %edi
callq 0x231f9
movq %rbx, %rdi
callq 0x2620d
leaq 0x2870(%rsp), %rdx
movq $0x0, (%rdx)
movl %r14d, %edi
movq %r12, %rsi
callq 0x30158
testl %eax, %eax
je 0x4a4cd
cmpq $0x0, 0x2870(%rsp)
jne 0x4a4d6
movl %r14d, %edi
xorl %esi, %esi
callq 0x68b0
testq %rax, %rax
movq 0x2830(%rsp), %rbp
je 0x4a3f5
movq %rax, %rbx
movq %r15, %rdi
movl $0x1, %esi
callq 0x60b0
testq %rax, %rax
je 0x4a3ff
movq %rax, %rdi
movq %rbx, %rsi
callq 0x6740
movq %rax, %r15
leaq 0x2860(%rsp), %rbx
movq %rax, %rdi
movl $0x6e, %esi
xorl %edx, %edx
movq %rbx, %rcx
callq 0x61b0
cmpq $0x0, (%rbx)
je 0x4a409
movq 0x8(%rbp), %rdi
callq 0x4a638
testl %eax, %eax
jne 0x49e15
movq 0x2860(%rsp), %rdi
movq 0x8(%rbp), %rcx
movl $0x37, %esi
xorl %edx, %edx
callq 0x6290
movl $0x1, %edx
movq %r15, %rdi
movl $0x66, %esi
xorl %ecx, %ecx
callq 0x61b0
leaq 0x2870(%rsp), %r12
leaq 0x28f0(%rsp), %r13
leaq 0x2848(%rsp), %rbp
movq %r15, %rdi
movl $0x65, %esi
xorl %edx, %edx
xorl %ecx, %ecx
callq 0x61b0
movq %r15, %rdi
cmpq $0x1, %rax
je 0x4a00b
movl $0x8, %esi
callq 0x6ad0
testl %eax, %eax
je 0x4a464
movq %r15, %rdi
movl $0x69, %esi
xorl %edx, %edx
xorl %ecx, %ecx
callq 0x61b0
movq %rax, %r14
cmpl $-0x1, %r14d
je 0x4a4a3
xorps %xmm0, %xmm0
movaps %xmm0, 0x28e0(%rsp)
movaps %xmm0, 0x28d0(%rsp)
movaps %xmm0, 0x28c0(%rsp)
movaps %xmm0, 0x28b0(%rsp)
movaps %xmm0, 0x28a0(%rsp)
movaps %xmm0, 0x2890(%rsp)
movaps %xmm0, 0x2880(%rsp)
movaps %xmm0, 0x2870(%rsp)
movaps %xmm0, 0x28f0(%rsp)
movaps %xmm0, 0x2900(%rsp)
movaps %xmm0, 0x2910(%rsp)
movaps %xmm0, 0x2920(%rsp)
movaps %xmm0, 0x2930(%rsp)
movaps %xmm0, 0x2940(%rsp)
movaps %xmm0, 0x2950(%rsp)
movaps %xmm0, 0x2960(%rsp)
movq %r15, %rdi
movl $0x1, %esi
callq 0x6ad0
testl %eax, %eax
je 0x49f51
leal 0x3f(%r14), %eax
testl %r14d, %r14d
cmovnsl %r14d, %eax
movl %eax, %edx
andl $-0x40, %edx
movl %r14d, %ecx
subl %edx, %ecx
movl $0x1, %edx
shlq %cl, %rdx
sarl $0x6, %eax
cltq
leaq (%rsp,%rax,8), %rax
addq $0x2870, %rax           # imm = 0x2870
jmp 0x49f97
movq %r15, %rdi
movl $0x2, %esi
callq 0x6ad0
leal 0x3f(%r14), %esi
testl %r14d, %r14d
cmovnsl %r14d, %esi
movl %esi, %edx
andl $-0x40, %edx
movl %r14d, %ecx
subl %edx, %ecx
movl $0x1, %edx
shlq %cl, %rdx
sarl $0x6, %esi
movslq %esi, %rcx
testl %eax, %eax
jne 0x49f8d
orq %rdx, 0x2870(%rsp,%rcx,8)
leaq (%rsp,%rcx,8), %rax
addq $0x28f0, %rax           # imm = 0x28F0
orq %rdx, (%rax)
movq $0xa, 0x2848(%rsp)
movq $0x0, 0x2850(%rsp)
leal 0x1(%r14), %edi
movq %r12, %rsi
movq %r13, %rdx
xorl %ecx, %ecx
movq %rbp, %r8
callq 0x66b0
testl %eax, %eax
js 0x4a4b7
jne 0x49e41
movq 0x2830(%rsp), %rbp
movq 0x8(%rbp), %rcx
leaq 0x4d990(%rip), %rdx     # 0x97977
leaq 0x2970(%rsp), %rbx
movq %rbx, %rdi
movl $0x100, %esi            # imm = 0x100
xorl %eax, %eax
callq 0x23c18
movq %rbx, %rdi
callq 0x7441
jmp 0x4a4f5
movl $0x69, %esi
xorl %edx, %edx
xorl %ecx, %ecx
callq 0x61b0
movq %rax, %r14
cmpl $-0x1, %r14d
movq 0x2830(%rsp), %rbp
je 0x4a44d
xorl %esi, %esi
xorl %r12d, %r12d
xorps %xmm0, %xmm0
movaps %xmm0, 0x28e0(%rsp)
movaps %xmm0, 0x28d0(%rsp)
movaps %xmm0, 0x28c0(%rsp)
movaps %xmm0, 0x28b0(%rsp)
movaps %xmm0, 0x28a0(%rsp)
movaps %xmm0, 0x2890(%rsp)
movaps %xmm0, 0x2880(%rsp)
movaps %xmm0, 0x2870(%rsp)
movaps %xmm0, 0x28f0(%rsp)
movaps %xmm0, 0x2900(%rsp)
movaps %xmm0, 0x2910(%rsp)
movaps %xmm0, 0x2920(%rsp)
movaps %xmm0, 0x2930(%rsp)
movaps %xmm0, 0x2940(%rsp)
leal 0x3f(%r14), %eax
testl %r14d, %r14d
cmovnsl %r14d, %eax
movl %eax, %edx
andl $-0x40, %edx
movl %r14d, %ecx
subl %edx, %ecx
movl $0x1, %ebx
shlq %cl, %rbx
movaps %xmm0, 0x2950(%rsp)
movaps %xmm0, 0x2960(%rsp)
sarl $0x6, %eax
movslq %eax, %r13
orq %rbx, 0x2870(%rsp,%r13,8)
cmpl %r12d, %esi
jge 0x4a0ee
orq %rbx, 0x28f0(%rsp,%r13,8)
movl %esi, 0x283c(%rsp)
testl %r12d, %r12d
jne 0x4a121
movl 0x1c(%rbp), %ecx
leal 0x3f(%rcx), %eax
testl %ecx, %ecx
cmovnsl %ecx, %eax
movl %eax, %edx
andl $-0x40, %edx
subl %edx, %ecx
movl $0x1, %edx
shlq %cl, %rdx
sarl $0x6, %eax
cltq
orq %rdx, 0x2870(%rsp,%rax,8)
movq $0xa, 0x2848(%rsp)
movq $0x0, 0x2850(%rsp)
movl 0x1c(%rbp), %edi
cmpl %r14d, %edi
cmovlel %r14d, %edi
incl %edi
leaq 0x2870(%rsp), %rsi
leaq 0x28f0(%rsp), %rdx
xorl %ecx, %ecx
leaq 0x2848(%rsp), %r8
callq 0x66b0
testl %eax, %eax
js 0x4a546
je 0x4a552
movl 0x1c(%rbp), %edi
leal 0x3f(%rdi), %eax
testl %edi, %edi
cmovnsl %edi, %eax
sarl $0x6, %eax
cltq
movq 0x2870(%rsp,%rax,8), %rax
btq %rdi, %rax
jae 0x4a1c3
movl $0x8000, %edx           # imm = 0x8000
leaq 0xd320(%rsp), %rsi
callq 0x6aa0
movq %rax, %r12
testl %r12d, %r12d
je 0x4a4f5
movl $0x0, 0x283c(%rsp)
cmpl $-0x1, %r12d
je 0x4a413
testq %rbx, 0x28f0(%rsp,%r13,8)
je 0x4a241
movq %r13, 0x2840(%rsp)
movl 0x283c(%rsp), %r13d
movl %r13d, %eax
leaq (%rsp,%rax), %rsi
addq $0xd320, %rsi           # imm = 0xD320
movl %r12d, %edx
subl %r13d, %edx
movq %r15, %rdi
callq 0x67b0
testl %eax, %eax
jle 0x4a21a
addl %r13d, %eax
cmpl %r12d, %eax
movl $0x0, %ecx
cmovgel %ecx, %r12d
cmovgel %ecx, %eax
movb $0x1, %cl
movl %eax, 0x283c(%rsp)
jmp 0x4a231
movq %r15, %rdi
movl $0x2, %esi
callq 0x6ad0
movb $0x1, %cl
testl %eax, %eax
je 0x4a3c0
movq 0x2840(%rsp), %r13
testb %cl, %cl
je 0x4a4f5
movq %r12, 0x2858(%rsp)
testq %rbx, 0x2870(%rsp,%r13,8)
je 0x4a38e
movq %r15, %rdi
leaq 0x5320(%rsp), %rsi
movl $0x8000, %edx           # imm = 0x8000
callq 0x6840
movl %eax, 0x2840(%rsp)
testl %eax, %eax
jle 0x4a379
xorl %r12d, %r12d
movl 0x2840(%rsp), %ebx
subl %r12d, %ebx
jle 0x4a38e
leaq 0x2970(%rsp), %r13
movq %r13, %rdi
callq 0x6940
movq %r13, %rdi
movl $0xd, %esi
callq 0x6ba0
xorl %edi, %edi
movq %r13, %rsi
leaq 0x2a70(%rsp), %rdx
callq 0x61c0
cmpl $-0x1, %eax
je 0x4a563
movl 0x1c(%rbp), %edi
movslq %r12d, %rax
leaq (%rsp,%rax), %rsi
addq $0x5320, %rsi           # imm = 0x5320
movslq %ebx, %rdx
callq 0x6260
movq %rax, %r13
callq 0x6060
movq %rax, %rbp
movl (%rax), %ebx
movl %r13d, %eax
notl %eax
movl %ebx, %ecx
xorl $0x20, %ecx
orl %eax, %ecx
jne 0x4a317
leaq 0x2970(%rsp), %rdi
leaq 0x286c(%rsp), %rsi
callq 0x6210
testl %eax, %eax
jne 0x4a568
movl $0x2, %edi
leaq 0x2a70(%rsp), %rsi
xorl %edx, %edx
callq 0x61c0
cmpl $-0x1, %eax
je 0x4a55e
movl %ebx, (%rbp)
cmpl $-0x1, %r13d
je 0x4a34a
addl %r13d, %r12d
movq 0x2830(%rsp), %rbp
jmp 0x4a35c
cmpl $0x20, %ebx
movq 0x2830(%rsp), %rbp
je 0x4a35c
cmpl $0x68, %ebx
jne 0x4a36b
cmpl $-0x1, %r13d
jne 0x4a27e
jmp 0x4a4f5
leaq 0x4d70c(%rip), %rdi     # 0x97a7e
callq 0x7466
jmp 0x4a35c
movq %r15, %rdi
movl $0x1, %esi
callq 0x6ad0
testl %eax, %eax
je 0x4a521
movq %r15, %rdi
movl $0x69, %esi
xorl %edx, %edx
xorl %ecx, %ecx
callq 0x61b0
movq %rax, %r14
cmpl $-0x1, %r14d
movq 0x2858(%rsp), %r12
movl 0x283c(%rsp), %esi
jne 0x4a033
jmp 0x4a44d
movq 0x74c11(%rip), %rax     # 0xbefd8
movq (%rax), %rdi
callq 0x6390
leaq 0x4d656(%rip), %rdi     # 0x97a2c
callq 0x7441
xorl %ecx, %ecx
jmp 0x4a231
callq 0x75cd
movl $0xffffffff, %r14d      # imm = 0xFFFFFFFF
xorl %r15d, %r15d
jmp 0x4a4c3
callq 0x75a3
jmp 0x4a4f2
callq 0x7579
jmp 0x4a4f2
callq 0x754f
jmp 0x4a4f5
callq 0x6060
cmpl $0x68, (%rax)
je 0x4a4f5
leaq 0x4d5db(%rip), %rdi     # 0x97a03
callq 0x7466
jmp 0x4a4f5
leaq 0x2af0(%rsp), %rdi
movq %r12, %rsi
callq 0x74a8
xorl %r15d, %r15d
xorl %r14d, %r14d
jmp 0x4a4f5
leaq 0x4d53c(%rip), %rdi     # 0x97990
callq 0x7441
movl $0xffffffff, %r14d      # imm = 0xFFFFFFFF
jmp 0x4a4f5
leaq 0x4d4b8(%rip), %rdi     # 0x97923
callq 0x7441
callq 0x69c0
movq %rax, %rdi
callq 0x6e10
leaq 0x4d4b9(%rip), %rdx     # 0x9793d
leaq 0x2970(%rsp), %rbx
movq %rbx, %rdi
movl $0x100, %esi            # imm = 0x100
movq %rax, %rcx
xorl %eax, %eax
callq 0x23c18
movq %rbx, %rdi
jmp 0x4a4be
leaq 0x4d4a1(%rip), %rdi     # 0x9794b
callq 0x7441
movl $0xffffffff, %r14d      # imm = 0xFFFFFFFF
jmp 0x4a4c3
leaq 0x4d4aa(%rip), %rdi     # 0x97968
callq 0x7441
movq 0x2830(%rsp), %rbp
jmp 0x4a4f5
leaq 0x4d3bd(%rip), %rdi     # 0x97891
jmp 0x4a4dd
leaq 0x4d3d1(%rip), %rdi     # 0x978ae
leaq 0x2870(%rsp), %rsi
leaq 0x2970(%rsp), %rdx
callq 0x74ff
xorl %r15d, %r15d
movq %r15, %rdi
callq 0x62a0
movl %r14d, %edi
callq 0x6e80
movl 0x1c(%rbp), %edi
callq 0x6e80
xorl %eax, %eax
addq $0x15328, %rsp          # imm = 0x15328
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
cmpl $0x0, 0x2840(%rsp)
je 0x4a4f5
movq 0x74aa6(%rip), %rax     # 0xbefd8
movq (%rax), %rdi
callq 0x6390
leaq 0x4d508(%rip), %rdi     # 0x97a49
jmp 0x4a001
leaq 0x4d48a(%rip), %rdi     # 0x979d7
jmp 0x4a001
leaq 0x4d494(%rip), %rdi     # 0x979ed
jmp 0x4a001
callq 0x7525
callq 0x753a
movl %eax, (%rbp)
leaq 0x4d504(%rip), %rdi     # 0x97a76
callq 0x6590
movl $0x1, %edi
callq 0x68d0