// File: lianxings[P]ftp_benchmark/ftplib.cc
// Function: ftplib::FtpXfer(char const*, char const*, ftphandle*, ftplib::accesstype, ftplib::transfermode)
int ftplib::FtpXfer(const char *localfile, const char *path, ftphandle *nControl, accesstype type, transfermode mode)
{
	int l,c;
	char *dbuf;
	FILE *local = NULL;
	ftphandle *nData;

	if (localfile != NULL)
	{
		char ac[3] = "  ";
		if ((type == ftplib::dir) || (type == ftplib::dirverbose)) { ac[0] = 'w'; ac[1] = '\0'; }
		if (type == ftplib::fileread) { ac[0] = 'w'; ac[1] = '\0'; }
		if (type == ftplib::filewriteappend) { ac[0] = 'r'; ac[1] = '\0'; }
		if (type == ftplib::filereadappend) { ac[0] = 'a'; ac[1] = '\0'; }
		if (type == ftplib::filewrite) { ac[0] = 'r'; ac[1] = '\0'; }
		if (mode == ftplib::image) ac[1] = 'b';

		local = fopen64(localfile, ac);
		if (local == NULL)
		{
			strncpy(nControl->response, strerror(errno), sizeof(nControl->response));
			return 0;
		}
		if (type == ftplib::filewriteappend) fseeko64(local,mp_ftphandle->offset,SEEK_SET);
	}
	if (local == NULL) local = ((type == ftplib::filewrite)
		|| (type == ftplib::filewriteappend)) ? stdin : stdout;
	if (!FtpAccess(path, type, mode, nControl, &nData)) {
        if (localfile != NULL) 
            fclose(local);
        return 0;
    }

	dbuf = static_cast<char*>(malloc(FTPLIB_BUFSIZ));
    long long  dataSize =0;
	if ((type == ftplib::filewrite) || (type == ftplib::filewriteappend)) {
		while ((l = fread(dbuf, 1, FTPLIB_BUFSIZ, local)) > 0) 	{
			if ((c = FtpWrite(dbuf, l, nData)) < l) {
				printf("short write: passed %d, wrote %d\n", l, c);
				break;
			}
            dataSize += l;
		}
	} else 	{
		while ((l = FtpRead(dbuf, FTPLIB_BUFSIZ, nData)) > 0) 	{
			if (fwrite(dbuf, 1, l, local) <= 0) {
				perror("localfile write");
				break;
			}
            dataSize += l;
		}
	}

    if(gFtpDebug)
        printf("Thread:%-8ld  sock:%-4d  transfer size:%lld\n", syscall(SYS_gettid), nControl->handle, dataSize);
    
	free(dbuf);
	fflush(local);
	if (localfile != NULL) 
        fclose(local);
	return FtpClose(nData);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x80, %rsp
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq %rdx, -0x20(%rbp)
movq %rcx, -0x28(%rbp)
movl %r8d, -0x2c(%rbp)
movl %r9d, -0x30(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x68(%rbp)
movq $0x0, -0x48(%rbp)
cmpq $0x0, -0x18(%rbp)
je 0x190a8
movw 0x4a2f(%rip), %ax       # 0x1da04
movw %ax, -0x53(%rbp)
movb 0x4a27(%rip), %al       # 0x1da06
movb %al, -0x51(%rbp)
cmpl $0x1, -0x2c(%rbp)
je 0x18fee
cmpl $0x2, -0x2c(%rbp)
jne 0x18ff6
movb $0x77, -0x53(%rbp)
movb $0x0, -0x52(%rbp)
cmpl $0x3, -0x2c(%rbp)
jne 0x19004
movb $0x77, -0x53(%rbp)
movb $0x0, -0x52(%rbp)
cmpl $0x6, -0x2c(%rbp)
jne 0x19012
movb $0x72, -0x53(%rbp)
movb $0x0, -0x52(%rbp)
cmpl $0x5, -0x2c(%rbp)
jne 0x19020
movb $0x61, -0x53(%rbp)
movb $0x0, -0x52(%rbp)
cmpl $0x4, -0x2c(%rbp)
jne 0x1902e
movb $0x72, -0x53(%rbp)
movb $0x0, -0x52(%rbp)
cmpl $0x49, -0x30(%rbp)
jne 0x19038
movb $0x62, -0x52(%rbp)
movq -0x18(%rbp), %rdi
leaq -0x53(%rbp), %rsi
callq 0x4540
movq %rax, -0x48(%rbp)
cmpq $0x0, -0x48(%rbp)
jne 0x19087
movq -0x28(%rbp), %rax
addq $0x88, %rax
movq %rax, -0x70(%rbp)
callq 0x4060
movl (%rax), %edi
callq 0x4150
movq -0x70(%rbp), %rdi
movq %rax, %rsi
movl $0x100, %edx            # imm = 0x100
callq 0x4230
movl $0x0, -0x4(%rbp)
jmp 0x19262
cmpl $0x6, -0x2c(%rbp)
jne 0x190a6
movq -0x68(%rbp), %rax
movq -0x48(%rbp), %rdi
movq (%rax), %rax
movq 0x1b0(%rax), %rsi
xorl %edx, %edx
callq 0x4790
jmp 0x190a8
cmpq $0x0, -0x48(%rbp)
jne 0x190e1
cmpl $0x4, -0x2c(%rbp)
je 0x190bb
cmpl $0x6, -0x2c(%rbp)
jne 0x190cb
movq 0xcef6(%rip), %rax      # 0x25fb8
movq (%rax), %rax
movq %rax, -0x78(%rbp)
jmp 0x190d9
movq 0xceb6(%rip), %rax      # 0x25f88
movq (%rax), %rax
movq %rax, -0x78(%rbp)
movq -0x78(%rbp), %rax
movq %rax, -0x48(%rbp)
movq -0x68(%rbp), %rdi
movq -0x20(%rbp), %rsi
movl -0x2c(%rbp), %edx
movl -0x30(%rbp), %ecx
movq -0x28(%rbp), %r8
leaq -0x50(%rbp), %r9
callq 0x177f0
cmpl $0x0, %eax
jne 0x1911d
cmpq $0x0, -0x18(%rbp)
je 0x19111
movq -0x48(%rbp), %rdi
callq 0x44a0
movl $0x0, -0x4(%rbp)
jmp 0x19262
movl $0x400, %edi            # imm = 0x400
callq 0x4620
movq %rax, -0x40(%rbp)
movq $0x0, -0x60(%rbp)
cmpl $0x4, -0x2c(%rbp)
je 0x1913f
cmpl $0x6, -0x2c(%rbp)
jne 0x191a2
jmp 0x19141
movq -0x40(%rbp), %rdi
movq -0x48(%rbp), %rcx
movl $0x1, %esi
movl $0x400, %edx            # imm = 0x400
callq 0x46c0
movl %eax, -0x34(%rbp)
cmpl $0x0, %eax
jle 0x191a0
movq -0x68(%rbp), %rdi
movq -0x40(%rbp), %rsi
movl -0x34(%rbp), %edx
movq -0x50(%rbp), %rcx
callq 0x18940
movl %eax, -0x38(%rbp)
cmpl -0x34(%rbp), %eax
jge 0x19192
movl -0x34(%rbp), %esi
movl -0x38(%rbp), %edx
leaq 0x487e(%rip), %rdi      # 0x1da07
movb $0x0, %al
callq 0x4070
jmp 0x191a0
movslq -0x34(%rbp), %rax
addq -0x60(%rbp), %rax
movq %rax, -0x60(%rbp)
jmp 0x19141
jmp 0x191fc
jmp 0x191a4
movq -0x68(%rbp), %rdi
movq -0x40(%rbp), %rsi
movq -0x50(%rbp), %rcx
movl $0x400, %edx            # imm = 0x400
callq 0x18800
movl %eax, -0x34(%rbp)
cmpl $0x0, %eax
jle 0x191fa
movq -0x40(%rbp), %rdi
movslq -0x34(%rbp), %rdx
movq -0x48(%rbp), %rcx
movl $0x1, %esi
callq 0x4890
cmpq $0x0, %rax
ja 0x191ec
leaq 0x4844(%rip), %rdi      # 0x1da29
callq 0x43a0
jmp 0x191fa
movslq -0x34(%rbp), %rax
addq -0x60(%rbp), %rax
movq %rax, -0x60(%rbp)
jmp 0x191a4
jmp 0x191fc
leaq 0xd3cd(%rip), %rax      # 0x265d0
testb $0x1, (%rax)
je 0x19230
movl $0xba, %edi
movb $0x0, %al
callq 0x4090
movq %rax, %rsi
movq -0x28(%rbp), %rax
movl 0x10(%rax), %edx
movq -0x60(%rbp), %rcx
leaq 0x4810(%rip), %rdi      # 0x1da39
movb $0x0, %al
callq 0x4070
movq -0x40(%rbp), %rdi
callq 0x45a0
movq -0x48(%rbp), %rdi
callq 0x4580
cmpq $0x0, -0x18(%rbp)
je 0x19252
movq -0x48(%rbp), %rdi
callq 0x44a0
movq -0x68(%rbp), %rdi
movq -0x50(%rbp), %rsi
callq 0x18690
movl %eax, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x80, %rsp
popq %rbp
retq
nop