// File: lianxings[P]ftp_benchmark/ftplib.cc
// Function: ftplib::FtpOpenPort(ftphandle*, ftphandle**, ftplib::transfermode, int, char*)
int ftplib::FtpOpenPort(ftphandle *nControl, ftphandle **nData, transfermode mode, int dir, char *cmd)
{
	int sData;
	union {
	struct sockaddr sa;
	struct sockaddr_in in;
	} sin;
	struct linger lng = { 0, 0 };
	socklen_t l;
	int on=1;
	ftphandle *ctrl;
	char buf[256]; 

	if (nControl->dir != FTPLIB_CONTROL) 
        return -1;
	if ((dir != FTPLIB_READ) && (dir != FTPLIB_WRITE))	{
		sprintf(nControl->response, "Invalid direction %d\n", dir);
		return -1;
	}
	if ((mode != ftplib::ascii) && (mode != ftplib::image)) {
		sprintf(nControl->response, "Invalid mode %c\n", mode);
		return -1;
	}
	l = sizeof(sin);

	if (getsockname(nControl->handle, &sin.sa, &l) < 0) {
		perror("getsockname");
		return -1;
	}

	sData = socket(PF_INET,SOCK_STREAM,IPPROTO_TCP);
	if (sData == -1) 	{
		perror("socket");
		return -1;
	}
	if (setsockopt(sData,SOL_SOCKET,SO_REUSEADDR, SETSOCKOPT_OPTVAL_TYPE &on,sizeof(on)) == -1) 	{
		perror("setsockopt");
		net_close(sData);
		return -1;
	}
	if (setsockopt(sData,SOL_SOCKET,SO_LINGER, SETSOCKOPT_OPTVAL_TYPE &lng,sizeof(lng)) == -1) 	{
		perror("setsockopt");
		net_close(sData);
		return -1;
	}

	sin.in.sin_port = 0;
	if (bind(sData, &sin.sa, sizeof(sin)) == -1) 	{
		perror("bind");
		net_close(sData);
		return -1;
	}
	if (listen(sData, 1) < 0) 	{
		perror("listen");
		net_close(sData);
		return -1;
	}
	if (getsockname(sData, &sin.sa, &l) < 0) 
        return 0;
    
	sprintf(buf, "PORT %hhu,%hhu,%hhu,%hhu,%hhu,%hhu",
		(unsigned char) sin.sa.sa_data[2],
		(unsigned char) sin.sa.sa_data[3],
		(unsigned char) sin.sa.sa_data[4],
		(unsigned char) sin.sa.sa_data[5],
		(unsigned char) sin.sa.sa_data[0],
		(unsigned char) sin.sa.sa_data[1]);

    if (!FtpSendCmd(buf,'2',nControl)) 	{
		net_close(sData);
		return -1;
	}

	if (mp_ftphandle->offset != 0)	{
    	char buf[256];
        sprint_rest(buf, mp_ftphandle->offset);
    	if (!FtpSendCmd(buf,'3',nControl)) 	{
    		net_close(sData);
    		return 0;
    	}
	}

	ctrl = static_cast<ftphandle*>(calloc(1,sizeof(ftphandle)));
	if (ctrl == NULL) 	{
		perror("calloc");
		net_close(sData);
		return -1;
	}
	if ((mode == 'A') && ((ctrl->buf = static_cast<char*>(malloc(FTPLIB_BUFSIZ))) == NULL)) 	{
		perror("calloc");
		net_close(sData);
		free(ctrl);
		return -1;
	}

	if (!FtpSendCmd(cmd, '1', nControl)) 	{
		FtpClose(*nData);
		*nData = NULL;
		return -1;
	}

	ctrl->handle = sData;
	ctrl->dir = dir;
	ctrl->ctrl = (nControl->cmode == ftplib::pasv) ? nControl : NULL;
	ctrl->idletime = nControl->idletime;
	ctrl->cbarg = nControl->cbarg;
	ctrl->xfered = 0;
	ctrl->xfered1 = 0;
	ctrl->cbbytes = nControl->cbbytes;
	if (ctrl->idletime.tv_sec || ctrl->idletime.tv_usec) ctrl->idlecb = nControl->idlecb;
	else ctrl->idlecb = NULL;
	if (ctrl->cbbytes ) ctrl->xfercb = nControl->xfercb;
	else ctrl->xfercb = NULL;
	*nData = ctrl;

	return 1;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x280, %rsp            # imm = 0x280
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq %rdx, -0x20(%rbp)
movl %ecx, -0x24(%rbp)
movl %r8d, -0x28(%rbp)
movq %r9, -0x30(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x268(%rbp)
leaq -0x4c(%rbp), %rdi
xorl %esi, %esi
movl $0x8, %edx
callq 0x4250
movl $0x1, -0x54(%rbp)
movq -0x18(%rbp), %rax
cmpl $0x0, 0x28(%rax)
je 0x181ea
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0x18675
cmpl $0x1, -0x28(%rbp)
je 0x1821e
cmpl $0x2, -0x28(%rbp)
je 0x1821e
movq -0x18(%rbp), %rdi
addq $0x88, %rdi
movl -0x28(%rbp), %edx
leaq 0x56ef(%rip), %rsi      # 0x1d8fa
movb $0x0, %al
callq 0x40d0
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0x18675
cmpl $0x41, -0x24(%rbp)
je 0x18252
cmpl $0x49, -0x24(%rbp)
je 0x18252
movq -0x18(%rbp), %rdi
addq $0x88, %rdi
movl -0x24(%rbp), %edx
leaq 0x56d1(%rip), %rsi      # 0x1d910
movb $0x0, %al
callq 0x40d0
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0x18675
movl $0x10, -0x50(%rbp)
movq -0x18(%rbp), %rax
movl 0x10(%rax), %edi
leaq -0x44(%rbp), %rsi
leaq -0x50(%rbp), %rdx
callq 0x4420
cmpl $0x0, %eax
jge 0x1828a
leaq 0x56a8(%rip), %rdi      # 0x1d921
callq 0x43a0
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0x18675
movl $0x2, %edi
movl $0x1, %esi
movl $0x6, %edx
callq 0x40f0
movl %eax, -0x34(%rbp)
cmpl $-0x1, -0x34(%rbp)
jne 0x182bf
leaq 0x553a(%rip), %rdi      # 0x1d7e8
callq 0x43a0
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0x18675
movl -0x34(%rbp), %edi
movl $0x1, %esi
movl $0x2, %edx
leaq -0x54(%rbp), %rcx
movl $0x4, %r8d
callq 0x4840
cmpl $-0x1, %eax
jne 0x18300
leaq 0x5508(%rip), %rdi      # 0x1d7ef
callq 0x43a0
movl -0x34(%rbp), %edi
callq 0x48b0
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0x18675
movl -0x34(%rbp), %edi
movl $0x1, %esi
movl $0xd, %edx
leaq -0x4c(%rbp), %rcx
movl $0x8, %r8d
callq 0x4840
cmpl $-0x1, %eax
jne 0x18341
leaq 0x54c7(%rip), %rdi      # 0x1d7ef
callq 0x43a0
movl -0x34(%rbp), %edi
callq 0x48b0
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0x18675
movw $0x0, -0x42(%rbp)
movl -0x34(%rbp), %edi
leaq -0x44(%rbp), %rsi
movl $0x10, %edx
callq 0x40b0
cmpl $-0x1, %eax
jne 0x1837d
leaq 0x55c9(%rip), %rdi      # 0x1d92d
callq 0x43a0
movl -0x34(%rbp), %edi
callq 0x48b0
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0x18675
movl -0x34(%rbp), %edi
movl $0x1, %esi
callq 0x4550
cmpl $0x0, %eax
jge 0x183af
leaq 0x559c(%rip), %rdi      # 0x1d932
callq 0x43a0
movl -0x34(%rbp), %edi
callq 0x48b0
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0x18675
movl -0x34(%rbp), %edi
leaq -0x44(%rbp), %rsi
leaq -0x50(%rbp), %rdx
callq 0x4420
cmpl $0x0, %eax
jge 0x183d0
movl $0x0, -0x4(%rbp)
jmp 0x18675
leaq -0x160(%rbp), %rdi
movzbl -0x40(%rbp), %edx
movzbl -0x3f(%rbp), %ecx
movzbl -0x3e(%rbp), %r8d
movzbl -0x3d(%rbp), %r9d
movzbl -0x42(%rbp), %r10d
movzbl -0x41(%rbp), %eax
leaq 0x5540(%rip), %rsi      # 0x1d939
movl %r10d, (%rsp)
movl %eax, 0x8(%rsp)
movb $0x0, %al
callq 0x40d0
movq -0x268(%rbp), %rdi
leaq -0x160(%rbp), %rsi
movq -0x18(%rbp), %rcx
movl $0x32, %edx
callq 0x171c0
cmpl $0x0, %eax
jne 0x1843d
movl -0x34(%rbp), %edi
callq 0x48b0
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0x18675
movq -0x268(%rbp), %rax
movq (%rax), %rax
cmpq $0x0, 0x1b0(%rax)
je 0x184a5
movq -0x268(%rbp), %rdi
leaq -0x260(%rbp), %rsi
movq (%rdi), %rax
movq 0x1b0(%rax), %rdx
callq 0x16500
movq -0x268(%rbp), %rdi
leaq -0x260(%rbp), %rsi
movq -0x18(%rbp), %rcx
movl $0x33, %edx
callq 0x171c0
cmpl $0x0, %eax
jne 0x184a3
movl -0x34(%rbp), %edi
callq 0x48b0
movl $0x0, -0x4(%rbp)
jmp 0x18675
jmp 0x184a5
movl $0x1, %edi
movl $0x1c0, %esi            # imm = 0x1C0
callq 0x42b0
movq %rax, -0x60(%rbp)
cmpq $0x0, -0x60(%rbp)
jne 0x184df
leaq 0x5252(%rip), %rdi      # 0x1d718
callq 0x43a0
movl -0x34(%rbp), %edi
callq 0x48b0
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0x18675
cmpl $0x41, -0x24(%rbp)
jne 0x18526
movl $0x400, %edi            # imm = 0x400
callq 0x4620
movq -0x60(%rbp), %rcx
movq %rax, 0x20(%rcx)
cmpq $0x0, %rax
jne 0x18526
leaq 0x5214(%rip), %rdi      # 0x1d718
callq 0x43a0
movl -0x34(%rbp), %edi
callq 0x48b0
movq -0x60(%rbp), %rdi
callq 0x45a0
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0x18675
movq -0x268(%rbp), %rdi
movq -0x30(%rbp), %rsi
movq -0x18(%rbp), %rcx
movl $0x31, %edx
callq 0x171c0
cmpl $0x0, %eax
jne 0x1856e
movq -0x268(%rbp), %rdi
movq -0x20(%rbp), %rax
movq (%rax), %rsi
callq 0x18690
movq -0x20(%rbp), %rax
movq $0x0, (%rax)
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0x18675
movl -0x34(%rbp), %ecx
movq -0x60(%rbp), %rax
movl %ecx, 0x10(%rax)
movl -0x28(%rbp), %ecx
movq -0x60(%rbp), %rax
movl %ecx, 0x28(%rax)
movq -0x18(%rbp), %rax
cmpl $0x1, 0x38(%rax)
jne 0x18599
movq -0x18(%rbp), %rax
movq %rax, -0x270(%rbp)
jmp 0x185a4
xorl %eax, %eax
movq %rax, -0x270(%rbp)
jmp 0x185a4
movq -0x270(%rbp), %rcx
movq -0x60(%rbp), %rax
movq %rcx, 0x30(%rax)
movq -0x18(%rbp), %rcx
movq -0x60(%rbp), %rax
movq 0x40(%rcx), %rdx
movq %rdx, 0x40(%rax)
movq 0x48(%rcx), %rcx
movq %rcx, 0x48(%rax)
movq -0x18(%rbp), %rax
movq 0x68(%rax), %rcx
movq -0x60(%rbp), %rax
movq %rcx, 0x68(%rax)
movq -0x60(%rbp), %rax
movq $0x0, 0x70(%rax)
movq -0x60(%rbp), %rax
movq $0x0, 0x80(%rax)
movq -0x18(%rbp), %rax
movq 0x78(%rax), %rcx
movq -0x60(%rbp), %rax
movq %rcx, 0x78(%rax)
movq -0x60(%rbp), %rax
cmpq $0x0, 0x40(%rax)
jne 0x1861c
movq -0x60(%rbp), %rax
cmpq $0x0, 0x48(%rax)
je 0x1862e
movq -0x18(%rbp), %rax
movq 0x58(%rax), %rcx
movq -0x60(%rbp), %rax
movq %rcx, 0x58(%rax)
jmp 0x1863a
movq -0x60(%rbp), %rax
movq $0x0, 0x58(%rax)
movq -0x60(%rbp), %rax
cmpq $0x0, 0x78(%rax)
je 0x18657
movq -0x18(%rbp), %rax
movq 0x50(%rax), %rcx
movq -0x60(%rbp), %rax
movq %rcx, 0x50(%rax)
jmp 0x18663
movq -0x60(%rbp), %rax
movq $0x0, 0x50(%rax)
movq -0x60(%rbp), %rcx
movq -0x20(%rbp), %rax
movq %rcx, (%rax)
movl $0x1, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x280, %rsp            # imm = 0x280
popq %rbp
retq
nopw %cs:(%rax,%rax)