// File: akw0088[P]openssl/rsync_upload.c
// Function: rsync_file_download
int rsync_file_download(char *ip_str, unsigned short int port, char *response, int size, unsigned int *final_size, char *file_name, unsigned int block_size)
{
	struct sockaddr_in	servaddr;
	SOCKET sock;
	int ret;

	sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

	memset(&servaddr, 0, sizeof(struct sockaddr_in));
	servaddr.sin_family = AF_INET;
	servaddr.sin_addr.s_addr = inet_addr(ip_str);
	servaddr.sin_port = htons(port);

	// 3 way handshake
	printf("Attempting to connect to %s\n", ip_str);
	ret = connect(sock, (struct sockaddr *)&servaddr, sizeof(struct sockaddr_in));
	if (ret == SOCKET_ERROR)
	{
#ifdef _WIN32
		ret = WSAGetLastError();

		switch (ret)
		{
		case WSAETIMEDOUT:
			printf("Fatal Error: Connection timed out.\n");
			break;
		case WSAECONNREFUSED:
			printf("Fatal Error: Connection refused\n");
			break;
		case WSAEHOSTUNREACH:
			printf("Fatal Error: Router sent ICMP packet (destination unreachable)\n");
			break;
		default:
			printf("Fatal Error: %d\n", ret);
			break;
		}
#else
		ret = errno;

	        switch(ret)
	        {
		case ENETUNREACH:
			printf("Fatal Error: The network is unreachable from this host at this time.\n(Bad IP address)\n");
			break;
	        case ETIMEDOUT:
	                printf("Fatal Error: Connecting timed out.\n");
	                break;
	        case ECONNREFUSED:
	                printf("Fatal Error: Connection refused\n");
	                break;
	        case EHOSTUNREACH:
	                printf("Fatal Error: router sent ICMP packet (destination unreachable)\n");
	                break;
	        default:
	                printf("Fatal Error: %d\n", ret);
	                break;
	        }
#endif
		return -1;
	}
	printf("TCP handshake completed\n");

	memset(response, 0, size);

	unsigned int rnum_block = 0;
	unsigned int rfile_size = 0;
	if (Recv(sock, (char *)&rfile_size, sizeof(unsigned int), 0) == -1)
	{
		printf("recv failed\r\n");
		return -1;
	}

	if ( Recv(sock, (char *)file_name, PATH_SIZE, 0) == -1)
	{
		printf("recv failed\r\n");
		return -1;
	}

	char temp[PATH_SIZE] = {0};
	StripChars(file_name, temp, ".\\/;:*?\"<>|");
	strcpy(file_name, temp);

	unsigned char rfile_hash[MD5_SIZE + 1] = {0};
	if ( Recv(sock, (char *)rfile_hash, MD5_SIZE, 0) == -1)
	{
		printf("recv failed\r\n");
		return -1;
	}


	printf("Opening local %s file for compare\r\n", file_name);
	unsigned int file_size = 0;
	char *data = get_file(file_name, &file_size);
	if (data == NULL)
	{
		printf("Unable to open %s\r\n", file_name);
	}

	unsigned char file_hash[MD5_SIZE + 1] = {0};
	if (data != NULL)
	{
		md5sum((char *)&data[0], file_size, (char *)file_hash);
	}

	if ( Send(sock, (char *)file_hash, MD5_SIZE, 0) == -1)
	{
		printf("recv failed\r\n");
		return -1;
	}

	if (rfile_size == file_size)
	{
		printf("Our file is same size\r\n");
		if (strcmp((char *)file_hash, (char *)rfile_hash) == 0)
		{
			printf("Files have the same hash\r\n");
			*final_size = 0;
			return 0;
		}

	}
	else if (rfile_size > file_size)
	{
		printf("Our file is smaller by %d bytes\r\n", rfile_size - file_size);
	}
	else
	{
		printf("Our file is larger by %d bytes\r\n", file_size - rfile_size);
	}

	if (data == NULL)
	{
		file_size = rfile_size;
	}

	// Calculate block size first
	unsigned int num_block = file_size / block_size;
	int remainder = file_size - num_block * block_size;
	if (remainder > 0)
	{
		num_block++;
	}


	printf("File has %d blocks %d bytes remainder %d\r\n", num_block, file_size, remainder);

	char **md5_array = (char **)malloc(num_block * sizeof(char *));
	if (md5_array == NULL)
	{
		perror("malloc failed");
		return -1;
	}

	unsigned int *checksum_adler32 = (unsigned int *)malloc(num_block * sizeof(unsigned int));
	if (checksum_adler32 == NULL)
	{
		perror("malloc failed");
		return -1;
	}

	for (unsigned int i = 0; i < num_block; i++)
	{
		checksum_adler32[i] = -1;
		md5_array[i] = md5_array[i] = malloc(MD5_SIZE + 1);
		if (md5_array[i] == NULL)
		{
			perror("malloc failed");
			return -1;
		}

		memset(md5_array[i], 0, MD5_SIZE + 1);
	}

	if (data)
	{
		printf("Calculating adler32 and md5 hashes for each block\r\n");
		for (unsigned int i = 0; i < num_block; i++)
		{
			unsigned int rsize = block_size;

			if (i == num_block - 1)
			{
				rsize = file_size - block_size * i;
			}
			checksum_adler32[i] = adler32((unsigned char *)&data[block_size * i], rsize);
			md5sum((char *)&data[block_size * i], rsize, md5_array[i]);
		}
	}
	
	printf("Sending hashes to server\r\n");	
	block_t *block = (block_t *)malloc(num_block * sizeof(block_t));
	if (block == NULL)
	{
		perror("malloc failed");
		return -1;
	}

	Send(sock, (char *)&num_block, sizeof(int), 0);
	Send(sock, (char *)&block_size, sizeof(int), 0);
	Send(sock, (char *)checksum_adler32, num_block * sizeof(int), 0);
	for (unsigned int i = 0; i < num_block; i++)
	{
		Send(sock, (char *)md5_array[i], MD5_SIZE, 0);
	}

	if ( Recv(sock, (char *)&block[0], sizeof(block_t) * num_block, 0) == -1)
	{
		printf("recv failed\r\n");
		return -1;
	}

	printf("Got offsets for each block\r\n");
	for (unsigned int i = 0; i < num_block; i++)
	{
		int rsize = block_size;

		if (i == num_block - 1)
		{
			rsize = rfile_size - (num_block - 1) * block_size;
		}

		if (block[i].offset == -1)
		{
			printf("\tmissing block %d [%d bytes]\r\n", i, rsize);
		}
	}

	unsigned int diff_size = 0;
	if ( Recv(sock, (char *)&diff_size, sizeof(unsigned int), 0) == -1)
	{
		printf("recv failed\r\n");
		return -1;
	}

	printf("Delta size is %d bytes\r\n", diff_size);

	unsigned char *diff = (unsigned char *)malloc(diff_size + block_size);
	if (diff == NULL)
	{
		perror("malloc failed");
	}

	unsigned int download_size = 0;
	download_size = Recv(sock, (char *)diff, diff_size, 0);
	if (download_size == -1)
	{
		printf("recv failed\r\n");
		return -1;
	}

	printf("Downloaded delta\r\n");
	closesocket(sock);

	assemble_download(response, rfile_size, data, file_size, block, num_block, block_size, (char *)diff, diff_size);
	*final_size = rfile_size;

	// Calculate final hash to be sure it matches
	memset(file_hash, 0, MD5_SIZE + 1);
	md5sum(response, *final_size, (char *)file_hash);


	if (strcmp((char *)file_hash, (char *)rfile_hash) != 0)
	{
		printf("Rsync failed\r\n");
		printf("hashes dont match\r\n\tremote: %s\r\n\tlocal : %s\r\n", file_hash, rfile_hash);
		printf("file size\r\n\tremote: %d\r\n\tlocal : %d\r\n", *final_size, rfile_size);
		printf("First 8 bytes\r\n");
		for (int i = 0; i < 8; i++)
		{
			printf("%02X ", response[i]);
		}

		printf("\r\nLast 8 bytes\r\n");
		for (int i = 0; i < 8; i++)
		{
			printf("%02X ", response[i + *final_size - 8]);
		}
		return -1;
	}

	printf("Rsync successful\r\n");
	return 0;
}

// Assembly:
subq $0x1c8, %rsp            # imm = 0x1C8
movw %si, %ax
movl 0x1d0(%rsp), %esi
movq %rdi, 0x1b8(%rsp)
movw %ax, 0x1b6(%rsp)
movq %rdx, 0x1a8(%rsp)
movl %ecx, 0x1a4(%rsp)
movq %r8, 0x198(%rsp)
movq %r9, 0x190(%rsp)
movl $0x2, %edi
movl $0x1, %esi
movl $0x6, %edx
callq 0x1240
movl %eax, 0x17c(%rsp)
leaq 0x180(%rsp), %rdi
xorl %esi, %esi
movl $0x10, %edx
callq 0x1110
movw $0x2, 0x180(%rsp)
movq 0x1b8(%rsp), %rdi
callq 0x1130
movl %eax, 0x184(%rsp)
movzwl 0x1b6(%rsp), %edi
callq 0x10c0
movw %ax, 0x182(%rsp)
movq 0x1b8(%rsp), %rsi
leaq 0x3315(%rip), %rdi      # 0x50b6
movb $0x0, %al
callq 0x10e0
movl 0x17c(%rsp), %edi
leaq 0x180(%rsp), %rsi
movl $0x10, %edx
callq 0x1210
movl %eax, 0x178(%rsp)
cmpl $-0x1, 0x178(%rsp)
jne 0x1e74
callq 0x1050
movl (%rax), %eax
movl %eax, 0x178(%rsp)
movl 0x178(%rsp), %eax
addl $-0x65, %eax
movl %eax, %ecx
movq %rcx, 0x20(%rsp)
subl $0xc, %eax
ja 0x1e4f
movq 0x20(%rsp), %rax
leaq 0x31fe(%rip), %rcx      # 0x5004
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
leaq 0x32bd(%rip), %rdi      # 0x50d3
movb $0x0, %al
callq 0x10e0
jmp 0x1e64
leaq 0x3304(%rip), %rdi      # 0x512a
movb $0x0, %al
callq 0x10e0
jmp 0x1e64
leaq 0x3318(%rip), %rdi      # 0x514e
movb $0x0, %al
callq 0x10e0
jmp 0x1e64
leaq 0x3329(%rip), %rdi      # 0x516f
movb $0x0, %al
callq 0x10e0
jmp 0x1e64
movl 0x178(%rsp), %esi
leaq 0x3352(%rip), %rdi      # 0x51af
movb $0x0, %al
callq 0x10e0
movl $0xffffffff, 0x1c4(%rsp) # imm = 0xFFFFFFFF
jmp 0x27eb
leaq 0x3345(%rip), %rdi      # 0x51c0
movb $0x0, %al
callq 0x10e0
movq 0x1a8(%rsp), %rdi
movslq 0x1a4(%rsp), %rdx
xorl %esi, %esi
callq 0x1110
movl $0x0, 0x174(%rsp)
movl $0x0, 0x170(%rsp)
movl 0x17c(%rsp), %edi
leaq 0x170(%rsp), %rsi
movl $0x4, %edx
xorl %ecx, %ecx
callq 0x17f0
cmpl $-0x1, %eax
jne 0x1eed
leaq 0x3303(%rip), %rdi      # 0x51d9
movb $0x0, %al
callq 0x10e0
movl $0xffffffff, 0x1c4(%rsp) # imm = 0xFFFFFFFF
jmp 0x27eb
movl 0x17c(%rsp), %edi
movq 0x190(%rsp), %rsi
movl $0x80, %edx
xorl %ecx, %ecx
callq 0x17f0
cmpl $-0x1, %eax
jne 0x1f2b
leaq 0x32c5(%rip), %rdi      # 0x51d9
movb $0x0, %al
callq 0x10e0
movl $0xffffffff, 0x1c4(%rsp) # imm = 0xFFFFFFFF
jmp 0x27eb
leaq 0xf0(%rsp), %rdi
xorl %esi, %esi
movl $0x80, %edx
callq 0x1110
movq 0x190(%rsp), %rdi
leaq 0xf0(%rsp), %rsi
leaq 0x3291(%rip), %rdx      # 0x51e7
callq 0x2800
movq 0x190(%rsp), %rdi
leaq 0xf0(%rsp), %rsi
callq 0x1060
leaq 0xc0(%rsp), %rdi
xorl %esi, %esi
movl $0x21, %edx
callq 0x1110
movl 0x17c(%rsp), %edi
leaq 0xc0(%rsp), %rsi
movl $0x20, %edx
xorl %ecx, %ecx
callq 0x17f0
cmpl $-0x1, %eax
jne 0x1fc2
leaq 0x322e(%rip), %rdi      # 0x51d9
movb $0x0, %al
callq 0x10e0
movl $0xffffffff, 0x1c4(%rsp) # imm = 0xFFFFFFFF
jmp 0x27eb
movq 0x190(%rsp), %rsi
leaq 0x3222(%rip), %rdi      # 0x51f3
movb $0x0, %al
callq 0x10e0
movl $0x0, 0xbc(%rsp)
movq 0x190(%rsp), %rdi
leaq 0xbc(%rsp), %rsi
callq 0x19d0
movq %rax, 0xb0(%rsp)
cmpq $0x0, 0xb0(%rsp)
jne 0x2021
movq 0x190(%rsp), %rsi
leaq 0x31fd(%rip), %rdi      # 0x5217
movb $0x0, %al
callq 0x10e0
leaq 0x80(%rsp), %rdi
xorl %esi, %esi
movl $0x21, %edx
callq 0x1110
cmpq $0x0, 0xb0(%rsp)
je 0x205c
movq 0xb0(%rsp), %rdi
movl 0xbc(%rsp), %esi
leaq 0x80(%rsp), %rdx
callq 0x33b0
movl 0x17c(%rsp), %edi
leaq 0x80(%rsp), %rsi
movl $0x20, %edx
xorl %ecx, %ecx
callq 0x18e0
cmpl $-0x1, %eax
jne 0x209a
leaq 0x3156(%rip), %rdi      # 0x51d9
movb $0x0, %al
callq 0x10e0
movl $0xffffffff, 0x1c4(%rsp) # imm = 0xFFFFFFFF
jmp 0x27eb
movl 0x170(%rsp), %eax
cmpl 0xbc(%rsp), %eax
jne 0x2100
leaq 0x317a(%rip), %rdi      # 0x522b
movb $0x0, %al
callq 0x10e0
leaq 0x80(%rsp), %rdi
leaq 0xc0(%rsp), %rsi
callq 0x1140
cmpl $0x0, %eax
jne 0x20fe
leaq 0x316a(%rip), %rdi      # 0x5243
movb $0x0, %al
callq 0x10e0
movq 0x198(%rsp), %rax
movl $0x0, (%rax)
movl $0x0, 0x1c4(%rsp)
jmp 0x27eb
jmp 0x214c
movl 0x170(%rsp), %eax
cmpl 0xbc(%rsp), %eax
jbe 0x212e
movl 0x170(%rsp), %esi
subl 0xbc(%rsp), %esi
leaq 0x3139(%rip), %rdi      # 0x525e
movb $0x0, %al
callq 0x10e0
jmp 0x214a
movl 0xbc(%rsp), %esi
subl 0x170(%rsp), %esi
leaq 0x313d(%rip), %rdi      # 0x5280
movb $0x0, %al
callq 0x10e0
jmp 0x214c
cmpq $0x0, 0xb0(%rsp)
jne 0x2165
movl 0x170(%rsp), %eax
movl %eax, 0xbc(%rsp)
movl 0xbc(%rsp), %eax
xorl %edx, %edx
divl 0x1d0(%rsp)
movl %eax, 0x7c(%rsp)
movl 0xbc(%rsp), %eax
movl 0x7c(%rsp), %ecx
imull 0x1d0(%rsp), %ecx
subl %ecx, %eax
movl %eax, 0x78(%rsp)
cmpl $0x0, 0x78(%rsp)
jle 0x21a4
movl 0x7c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x7c(%rsp)
movl 0x7c(%rsp), %esi
movl 0xbc(%rsp), %edx
movl 0x78(%rsp), %ecx
leaq 0x30e7(%rip), %rdi      # 0x52a1
movb $0x0, %al
callq 0x10e0
movl 0x7c(%rsp), %eax
movl %eax, %edi
shlq $0x3, %rdi
callq 0x1180
movq %rax, 0x70(%rsp)
cmpq $0x0, 0x70(%rsp)
jne 0x21f9
leaq 0x30e8(%rip), %rdi      # 0x52cc
callq 0x11d0
movl $0xffffffff, 0x1c4(%rsp) # imm = 0xFFFFFFFF
jmp 0x27eb
movl 0x7c(%rsp), %eax
movl %eax, %edi
shlq $0x2, %rdi
callq 0x1180
movq %rax, 0x68(%rsp)
cmpq $0x0, 0x68(%rsp)
jne 0x2231
leaq 0x30b0(%rip), %rdi      # 0x52cc
callq 0x11d0
movl $0xffffffff, 0x1c4(%rsp) # imm = 0xFFFFFFFF
jmp 0x27eb
movl $0x0, 0x64(%rsp)
movl 0x64(%rsp), %eax
cmpl 0x7c(%rsp), %eax
jae 0x22d3
movq 0x68(%rsp), %rax
movl 0x64(%rsp), %ecx
movl $0xffffffff, (%rax,%rcx,4) # imm = 0xFFFFFFFF
movl $0x21, %edi
callq 0x1180
movq %rax, %rdx
movq 0x70(%rsp), %rax
movl 0x64(%rsp), %ecx
movq %rdx, (%rax,%rcx,8)
movq 0x70(%rsp), %rax
movl 0x64(%rsp), %ecx
movq %rdx, (%rax,%rcx,8)
movq 0x70(%rsp), %rax
movl 0x64(%rsp), %ecx
cmpq $0x0, (%rax,%rcx,8)
jne 0x22aa
leaq 0x3037(%rip), %rdi      # 0x52cc
callq 0x11d0
movl $0xffffffff, 0x1c4(%rsp) # imm = 0xFFFFFFFF
jmp 0x27eb
movq 0x70(%rsp), %rax
movl 0x64(%rsp), %ecx
movq (%rax,%rcx,8), %rdi
xorl %esi, %esi
movl $0x21, %edx
callq 0x1110
movl 0x64(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x64(%rsp)
jmp 0x2239
cmpq $0x0, 0xb0(%rsp)
je 0x23aa
leaq 0x2ff1(%rip), %rdi      # 0x52da
movb $0x0, %al
callq 0x10e0
movl $0x0, 0x60(%rsp)
movl 0x60(%rsp), %eax
cmpl 0x7c(%rsp), %eax
jae 0x23a8
movl 0x1d0(%rsp), %eax
movl %eax, 0x5c(%rsp)
movl 0x60(%rsp), %eax
movl 0x7c(%rsp), %ecx
subl $0x1, %ecx
cmpl %ecx, %eax
jne 0x2339
movl 0xbc(%rsp), %eax
movl 0x1d0(%rsp), %ecx
imull 0x60(%rsp), %ecx
subl %ecx, %eax
movl %eax, 0x5c(%rsp)
movq 0xb0(%rsp), %rdi
movl 0x1d0(%rsp), %eax
imull 0x60(%rsp), %eax
movl %eax, %eax
addq %rax, %rdi
movl 0x5c(%rsp), %esi
callq 0x1350
movl %eax, %edx
movq 0x68(%rsp), %rax
movl 0x60(%rsp), %ecx
movl %edx, (%rax,%rcx,4)
movq 0xb0(%rsp), %rdi
movl 0x1d0(%rsp), %eax
imull 0x60(%rsp), %eax
movl %eax, %eax
addq %rax, %rdi
movl 0x5c(%rsp), %esi
movq 0x70(%rsp), %rax
movl 0x60(%rsp), %ecx
movq (%rax,%rcx,8), %rdx
callq 0x33b0
movl 0x60(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x60(%rsp)
jmp 0x22f8
jmp 0x23aa
leaq 0x2f5d(%rip), %rdi      # 0x530e
movb $0x0, %al
callq 0x10e0
movl 0x7c(%rsp), %eax
movl %eax, %edi
shlq $0x3, %rdi
callq 0x1180
movq %rax, 0x50(%rsp)
cmpq $0x0, 0x50(%rsp)
jne 0x23f0
leaq 0x2ef1(%rip), %rdi      # 0x52cc
callq 0x11d0
movl $0xffffffff, 0x1c4(%rsp) # imm = 0xFFFFFFFF
jmp 0x27eb
movl 0x17c(%rsp), %edi
leaq 0x7c(%rsp), %rsi
movl $0x4, %edx
xorl %ecx, %ecx
callq 0x18e0
movl 0x17c(%rsp), %edi
leaq 0x1d0(%rsp), %rsi
movl $0x4, %edx
xorl %ecx, %ecx
callq 0x18e0
movl 0x17c(%rsp), %edi
movq 0x68(%rsp), %rsi
movl 0x7c(%rsp), %eax
shlq $0x2, %rax
movl %eax, %edx
xorl %ecx, %ecx
callq 0x18e0
movl $0x0, 0x4c(%rsp)
movl 0x4c(%rsp), %eax
cmpl 0x7c(%rsp), %eax
jae 0x247f
movl 0x17c(%rsp), %edi
movq 0x70(%rsp), %rax
movl 0x4c(%rsp), %ecx
movq (%rax,%rcx,8), %rsi
movl $0x20, %edx
xorl %ecx, %ecx
callq 0x18e0
movl 0x4c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x4c(%rsp)
jmp 0x2448
movl 0x17c(%rsp), %edi
movq 0x50(%rsp), %rsi
movl 0x7c(%rsp), %eax
shlq $0x3, %rax
movl %eax, %edx
xorl %ecx, %ecx
callq 0x17f0
cmpl $-0x1, %eax
jne 0x24bf
leaq 0x2d31(%rip), %rdi      # 0x51d9
movb $0x0, %al
callq 0x10e0
movl $0xffffffff, 0x1c4(%rsp) # imm = 0xFFFFFFFF
jmp 0x27eb
leaq 0x2e63(%rip), %rdi      # 0x5329
movb $0x0, %al
callq 0x10e0
movl $0x0, 0x48(%rsp)
movl 0x48(%rsp), %eax
cmpl 0x7c(%rsp), %eax
jae 0x2549
movl 0x1d0(%rsp), %eax
movl %eax, 0x44(%rsp)
movl 0x48(%rsp), %eax
movl 0x7c(%rsp), %ecx
subl $0x1, %ecx
cmpl %ecx, %eax
jne 0x2515
movl 0x170(%rsp), %eax
movl 0x7c(%rsp), %ecx
subl $0x1, %ecx
imull 0x1d0(%rsp), %ecx
subl %ecx, %eax
movl %eax, 0x44(%rsp)
movq 0x50(%rsp), %rax
movl 0x48(%rsp), %ecx
cmpl $-0x1, (%rax,%rcx,8)
jne 0x253a
movl 0x48(%rsp), %esi
movl 0x44(%rsp), %edx
leaq 0x2e13(%rip), %rdi      # 0x5346
movb $0x0, %al
callq 0x10e0
jmp 0x253c
movl 0x48(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x48(%rsp)
jmp 0x24d5
movl $0x0, 0x40(%rsp)
movl 0x17c(%rsp), %edi
leaq 0x40(%rsp), %rsi
movl $0x4, %edx
xorl %ecx, %ecx
callq 0x17f0
cmpl $-0x1, %eax
jne 0x258c
leaq 0x2c64(%rip), %rdi      # 0x51d9
movb $0x0, %al
callq 0x10e0
movl $0xffffffff, 0x1c4(%rsp) # imm = 0xFFFFFFFF
jmp 0x27eb
movl 0x40(%rsp), %esi
leaq 0x2dce(%rip), %rdi      # 0x5365
movb $0x0, %al
callq 0x10e0
movl 0x40(%rsp), %eax
addl 0x1d0(%rsp), %eax
movl %eax, %eax
movl %eax, %edi
callq 0x1180
movq %rax, 0x38(%rsp)
cmpq $0x0, 0x38(%rsp)
jne 0x25cb
leaq 0x2d06(%rip), %rdi      # 0x52cc
callq 0x11d0
movl $0x0, 0x34(%rsp)
movl 0x17c(%rsp), %edi
movq 0x38(%rsp), %rsi
movl 0x40(%rsp), %edx
xorl %ecx, %ecx
callq 0x17f0
movl %eax, 0x34(%rsp)
cmpl $-0x1, 0x34(%rsp)
jne 0x2613
leaq 0x2bdd(%rip), %rdi      # 0x51d9
movb $0x0, %al
callq 0x10e0
movl $0xffffffff, 0x1c4(%rsp) # imm = 0xFFFFFFFF
jmp 0x27eb
leaq 0x2d64(%rip), %rdi      # 0x537e
movb $0x0, %al
callq 0x10e0
movl 0x17c(%rsp), %edi
callq 0x1120
movq 0x1a8(%rsp), %rdi
movl 0x170(%rsp), %esi
movq 0xb0(%rsp), %rdx
movl 0xbc(%rsp), %ecx
movq 0x50(%rsp), %r8
movl 0x7c(%rsp), %r9d
movl 0x1d0(%rsp), %r11d
movq 0x38(%rsp), %r10
movl 0x40(%rsp), %eax
movl %r11d, (%rsp)
movq %r10, 0x8(%rsp)
movl %eax, 0x10(%rsp)
callq 0x1b90
movl 0x170(%rsp), %ecx
movq 0x198(%rsp), %rax
movl %ecx, (%rax)
leaq 0x80(%rsp), %rdi
xorl %esi, %esi
movl $0x21, %edx
callq 0x1110
movq 0x1a8(%rsp), %rdi
movq 0x198(%rsp), %rax
movl (%rax), %esi
leaq 0x80(%rsp), %rdx
callq 0x33b0
leaq 0x80(%rsp), %rdi
leaq 0xc0(%rsp), %rsi
callq 0x1140
cmpl $0x0, %eax
je 0x27d2
leaq 0x2cb0(%rip), %rdi      # 0x5391
movb $0x0, %al
callq 0x10e0
leaq 0x80(%rsp), %rsi
leaq 0xc0(%rsp), %rdx
leaq 0x2ca1(%rip), %rdi      # 0x53a0
movb $0x0, %al
callq 0x10e0
movq 0x198(%rsp), %rax
movl (%rax), %esi
movl 0x170(%rsp), %edx
leaq 0x2cb0(%rip), %rdi      # 0x53ce
movb $0x0, %al
callq 0x10e0
leaq 0x2cc8(%rip), %rdi      # 0x53f4
movb $0x0, %al
callq 0x10e0
movl $0x0, 0x30(%rsp)
cmpl $0x8, 0x30(%rsp)
jge 0x276e
movq 0x1a8(%rsp), %rax
movslq 0x30(%rsp), %rcx
movsbl (%rax,%rcx), %esi
leaq 0x2caa(%rip), %rdi      # 0x5404
movb $0x0, %al
callq 0x10e0
movl 0x30(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x30(%rsp)
jmp 0x273b
leaq 0x2c95(%rip), %rdi      # 0x540a
movb $0x0, %al
callq 0x10e0
movl $0x0, 0x2c(%rsp)
cmpl $0x8, 0x2c(%rsp)
jge 0x27c5
movq 0x1a8(%rsp), %rax
movl 0x2c(%rsp), %ecx
movq 0x198(%rsp), %rdx
addl (%rdx), %ecx
subl $0x8, %ecx
movl %ecx, %ecx
movsbl (%rax,%rcx), %esi
leaq 0x2c53(%rip), %rdi      # 0x5404
movb $0x0, %al
callq 0x10e0
movl 0x2c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x2c(%rsp)
jmp 0x2784
movl $0xffffffff, 0x1c4(%rsp) # imm = 0xFFFFFFFF
jmp 0x27eb
leaq 0x2c42(%rip), %rdi      # 0x541b
movb $0x0, %al
callq 0x10e0
movl $0x0, 0x1c4(%rsp)
movl 0x1c4(%rsp), %eax
addq $0x1c8, %rsp            # imm = 0x1C8
retq
nopw (%rax,%rax)