// File: lianxings[P]ftp_benchmark/ftp_benchmark.cc
// Function: local2ftp_dispatcher_core(ftplib*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>)
static void local2ftp_dispatcher_core (ftplib * ftpClient, string localPath, string ftpPath) 
{
    // judge the local path is directory
    if (!is_dir(localPath)) {
        fprintf(stderr, "local path '%s' is not directory.\n", localPath.c_str());
        return;
    }

    // normalize directory path format
    normalize_dir_format(localPath, ftpPath);

    // check if destination dir path exists
    if (!ftpClient->Chdir(ftpPath.c_str())) {
        fprintf(stderr, "change to directory %s failed.\n", ftpPath.c_str());
        return;
    }

    std::queue<task<string> > dirQue;
    task<string> taskTmp;
    taskTmp.src = localPath;
    taskTmp.dst = ftpPath;
    dirQue.push(taskTmp);
    while (!dirQue.empty()) {
        int queSize = dirQue.size();
        for (int i = 0; i < queSize; i++) {
            taskTmp = dirQue.front();
            dirQue.pop();
            string srcPath = taskTmp.src;
            string dstPath = taskTmp.dst;

            // concat and create dst path in ftp
            string baseName = resolve_base_name(srcPath);
            dstPath += baseName;
            if (dstPath.at(dstPath.size() - 1) != '/') {
                dstPath.push_back('/');
            }
            if (!ftpClient->Chdir(dstPath.c_str())) {
                if (!ftpClient->Mkdir(dstPath.c_str())) {
                    fprintf(stderr, "make directory %s failed.\n", dstPath.c_str());
                    return;
                }
            }

            // get files name under the src path
            DIR *dir;
            struct dirent *pDirEnt;
            if ((dir = opendir(srcPath.c_str())) == NULL) {
                fprintf(stderr, "open directory '%s' failed.\n", srcPath.c_str());
                return;
            }

            while ((pDirEnt = readdir(dir)) != NULL) {
                if ((strcmp(pDirEnt->d_name, ".") == 0) || (strcmp(pDirEnt->d_name, "..") == 0))
                    continue;
                else if (pDirEnt->d_type == 4) { // dir
                    string nowSrcPath = srcPath + pDirEnt->d_name + "/";
                    string nowDstPath = dstPath;
                    taskTmp.src = nowSrcPath;
                    taskTmp.dst = nowDstPath;
                    dirQue.push(taskTmp);
                } else if ((pDirEnt->d_type == 8) || (pDirEnt->d_type == 10) ) { 
                    // file or link file , lock and add task
                    fileInfo srcInfo, dstInfo;
                    task<fileInfo> curTask;
                    srcInfo.name = srcPath + pDirEnt->d_name;
                    dstInfo.name = dstPath + pDirEnt->d_name;
                    // statistic the source file information
                    int fdTmp = open(srcInfo.name.c_str(), O_RDONLY);
                    if (fdTmp < 0) {
                        fprintf(stderr, "open file %s failed: %s\n", srcInfo.name.c_str(), strerror(-fdTmp));
                        continue;
                    }
                    struct stat mstat;
                    fstat(fdTmp, &mstat);
                    close(fdTmp);
                    srcInfo.size = dstInfo.size = mstat.st_size;
                    curTask.src = srcInfo;
                    curTask.dst = dstInfo;
                    if (put_task_to_queue(curTask) < 0)
                        break;
                    fileNum++;
                    totalFileSize += mstat.st_size;
                }
            }
            closedir(dir);
        }
    }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x410, %rsp            # imm = 0x410
movq %rsi, -0x350(%rbp)
movq %rdx, -0x348(%rbp)
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
leaq -0x38(%rbp), %rdi
movq %rdi, -0x340(%rbp)
callq 0x41c0
movq -0x340(%rbp), %rdi
callq 0x15a30
movl %eax, -0x334(%rbp)
jmp 0x6299
movl -0x334(%rbp), %eax
cmpl $0x0, %eax
setne %al
xorb $-0x1, %al
movb %al, -0x351(%rbp)
leaq -0x38(%rbp), %rdi
callq 0x4280
movb -0x351(%rbp), %al
testb $0x1, %al
jne 0x62c2
jmp 0x6316
movq -0x350(%rbp), %rdi
movq 0x1fcf8(%rip), %rax     # 0x25fc8
movq (%rax), %rax
movq %rax, -0x360(%rbp)
callq 0x41b0
movq -0x360(%rbp), %rdi
movq %rax, %rdx
leaq 0x16ab2(%rip), %rsi     # 0x1cda2
movb $0x0, %al
callq 0x4680
jmp 0x6bb7
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
leaq -0x38(%rbp), %rdi
callq 0x4280
jmp 0x6bd8
movq -0x348(%rbp), %rsi
movq -0x350(%rbp), %rdi
callq 0x15d20
movq -0x348(%rbp), %rdi
movq -0x8(%rbp), %rax
movq %rax, -0x368(%rbp)
callq 0x41b0
movq -0x368(%rbp), %rdi
movq %rax, %rsi
callq 0x18d00
cmpl $0x0, %eax
jne 0x638e
movq -0x348(%rbp), %rdi
movq 0x1fc66(%rip), %rax     # 0x25fc8
movq (%rax), %rax
movq %rax, -0x370(%rbp)
callq 0x41b0
movq -0x370(%rbp), %rdi
movq %rax, %rdx
leaq 0x1697b(%rip), %rsi     # 0x1ccfd
movb $0x0, %al
callq 0x4680
jmp 0x6bb7
leaq -0x98(%rbp), %rdi
callq 0xecd0
leaq -0xd8(%rbp), %rdi
callq 0xed00
jmp 0x63a8
movq -0x350(%rbp), %rsi
leaq -0xd8(%rbp), %rdi
callq 0x4050
jmp 0x63bd
movq -0x348(%rbp), %rsi
leaq -0xb8(%rbp), %rdi
callq 0x4050
jmp 0x63d2
leaq -0x98(%rbp), %rdi
leaq -0xd8(%rbp), %rsi
callq 0xed30
jmp 0x63e7
jmp 0x63e9
leaq -0x98(%rbp), %rdi
callq 0xed60
movb %al, -0x371(%rbp)
jmp 0x63fd
movb -0x371(%rbp), %al
xorb $-0x1, %al
testb $0x1, %al
jne 0x640e
jmp 0x6b95
leaq -0x98(%rbp), %rdi
callq 0xed80
movq %rax, -0x380(%rbp)
jmp 0x6423
movq -0x380(%rbp), %rax
movl %eax, -0xdc(%rbp)
movl $0x0, -0xe0(%rbp)
movl -0xe0(%rbp), %eax
cmpl -0xdc(%rbp), %eax
jge 0x6b90
leaq -0x98(%rbp), %rdi
callq 0xeda0
movq %rax, -0x388(%rbp)
jmp 0x6461
movq -0x388(%rbp), %rsi
leaq -0xd8(%rbp), %rdi
callq 0xedc0
jmp 0x6476
leaq -0x98(%rbp), %rdi
callq 0xee00
jmp 0x6484
leaq -0x100(%rbp), %rdi
leaq -0xd8(%rbp), %rsi
callq 0x41c0
jmp 0x6499
leaq -0xb8(%rbp), %rsi
leaq -0x120(%rbp), %rdi
callq 0x41c0
jmp 0x64ae
leaq -0x140(%rbp), %rdi
leaq -0x100(%rbp), %rsi
callq 0x15f20
jmp 0x64c3
leaq -0x120(%rbp), %rdi
leaq -0x140(%rbp), %rsi
callq 0x45f0
jmp 0x64d8
leaq -0x120(%rbp), %rdi
movq %rdi, -0x398(%rbp)
callq 0x42e0
movq -0x398(%rbp), %rdi
movq %rax, %rsi
decq %rsi
callq 0x4880
movq %rax, -0x390(%rbp)
jmp 0x6506
movq -0x390(%rbp), %rax
movsbl (%rax), %eax
cmpl $0x2f, %eax
je 0x657f
leaq -0x120(%rbp), %rdi
movl $0x2f, %esi
callq 0x43c0
jmp 0x6528
jmp 0x657f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
jmp 0x6bcc
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
jmp 0x6bc0
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
jmp 0x6b82
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
jmp 0x6b76
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
jmp 0x6b6a
movq -0x8(%rbp), %rax
movq %rax, -0x3a8(%rbp)
leaq -0x120(%rbp), %rdi
callq 0x41b0
movq -0x3a8(%rbp), %rdi
movq %rax, %rsi
callq 0x18d00
movl %eax, -0x39c(%rbp)
jmp 0x65ad
movl -0x39c(%rbp), %eax
cmpl $0x0, %eax
jne 0x6637
movq -0x8(%rbp), %rax
movq %rax, -0x3b8(%rbp)
leaq -0x120(%rbp), %rdi
callq 0x41b0
movq -0x3b8(%rbp), %rdi
movq %rax, %rsi
callq 0x18c60
movl %eax, -0x3ac(%rbp)
jmp 0x65e6
movl -0x3ac(%rbp), %eax
cmpl $0x0, %eax
jne 0x6635
movq 0x1f9d0(%rip), %rax     # 0x25fc8
movq (%rax), %rax
movq %rax, -0x3c0(%rbp)
leaq -0x120(%rbp), %rdi
callq 0x41b0
movq -0x3c0(%rbp), %rdi
movq %rax, %rdx
leaq 0x166fe(%rip), %rsi     # 0x1cd1d
movb $0x0, %al
callq 0x4680
movl $0x1, -0x144(%rbp)
jmp 0x6b24
jmp 0x6637
leaq -0x100(%rbp), %rdi
callq 0x41b0
movq %rax, %rdi
callq 0x46e0
movq %rax, -0x3c8(%rbp)
jmp 0x6654
movq -0x3c8(%rbp), %rax
movq %rax, -0x150(%rbp)
cmpq $0x0, %rax
jne 0x66ac
movq 0x1f959(%rip), %rax     # 0x25fc8
movq (%rax), %rax
movq %rax, -0x3d0(%rbp)
leaq -0x100(%rbp), %rdi
callq 0x41b0
movq -0x3d0(%rbp), %rdi
movq %rax, %rdx
leaq 0x166a2(%rip), %rsi     # 0x1cd38
movb $0x0, %al
callq 0x4680
movl $0x1, -0x144(%rbp)
jmp 0x6b24
jmp 0x66ae
movq -0x150(%rbp), %rdi
callq 0x46f0
movq %rax, -0x3d8(%rbp)
jmp 0x66c3
movq -0x3d8(%rbp), %rax
movq %rax, -0x158(%rbp)
cmpq $0x0, %rax
je 0x6b0c
movq -0x158(%rbp), %rdi
addq $0x13, %rdi
leaq 0x16669(%rip), %rsi     # 0x1cd56
callq 0x4660
cmpl $0x0, %eax
je 0x6713
movq -0x158(%rbp), %rdi
addq $0x13, %rdi
leaq 0x1664c(%rip), %rsi     # 0x1cd55
callq 0x4660
cmpl $0x0, %eax
jne 0x6715
jmp 0x66ae
movq -0x158(%rbp), %rax
movzbl 0x12(%rax), %eax
cmpl $0x4, %eax
jne 0x6836
movq -0x158(%rbp), %rdx
addq $0x13, %rdx
leaq -0x198(%rbp), %rdi
leaq -0x100(%rbp), %rsi
callq 0xd5c0
jmp 0x6749
leaq 0x1672d(%rip), %rdx     # 0x1ce7d
leaq -0x178(%rbp), %rdi
leaq -0x198(%rbp), %rsi
callq 0xd8a0
jmp 0x6765
leaq -0x198(%rbp), %rdi
callq 0x4280
leaq -0x1b8(%rbp), %rdi
leaq -0x120(%rbp), %rsi
callq 0x41c0
jmp 0x6786
leaq -0xd8(%rbp), %rdi
leaq -0x178(%rbp), %rsi
callq 0x4050
jmp 0x679b
leaq -0xb8(%rbp), %rdi
leaq -0x1b8(%rbp), %rsi
callq 0x4050
jmp 0x67b0
leaq -0x98(%rbp), %rdi
leaq -0xd8(%rbp), %rsi
callq 0xed30
jmp 0x67c5
leaq -0x1b8(%rbp), %rdi
callq 0x4280
leaq -0x178(%rbp), %rdi
callq 0x4280
jmp 0x6b05
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
leaq -0x198(%rbp), %rdi
callq 0x4280
jmp 0x6b6a
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
jmp 0x6825
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
leaq -0x1b8(%rbp), %rdi
callq 0x4280
leaq -0x178(%rbp), %rdi
callq 0x4280
jmp 0x6b6a
movq -0x158(%rbp), %rax
movzbl 0x12(%rax), %eax
cmpl $0x8, %eax
je 0x685a
movq -0x158(%rbp), %rax
movzbl 0x12(%rax), %eax
cmpl $0xa, %eax
jne 0x6b03
leaq -0x1e0(%rbp), %rdi
callq 0xd460
jmp 0x6868
leaq -0x208(%rbp), %rdi
callq 0xd460
jmp 0x6876
leaq -0x258(%rbp), %rdi
callq 0xd410
jmp 0x6884
movq -0x158(%rbp), %rdx
addq $0x13, %rdx
leaq -0x278(%rbp), %rdi
leaq -0x100(%rbp), %rsi
callq 0xd5c0
jmp 0x68a4
leaq -0x1e0(%rbp), %rdi
leaq -0x278(%rbp), %rsi
movq %rsi, -0x3e0(%rbp)
callq 0x45c0
movq -0x3e0(%rbp), %rdi
callq 0x4280
movq -0x158(%rbp), %rdx
addq $0x13, %rdx
leaq -0x298(%rbp), %rdi
leaq -0x120(%rbp), %rsi
callq 0xd5c0
jmp 0x68ea
leaq -0x208(%rbp), %rdi
leaq -0x298(%rbp), %rsi
movq %rsi, -0x3f0(%rbp)
callq 0x45c0
movq -0x3f0(%rbp), %rdi
callq 0x4280
leaq -0x1e0(%rbp), %rdi
callq 0x41b0
movq %rax, %rdi
xorl %esi, %esi
movb %sil, %al
callq 0x4310
movl %eax, -0x3e4(%rbp)
jmp 0x6931
movl -0x3e4(%rbp), %eax
movl %eax, -0x29c(%rbp)
cmpl $0x0, -0x29c(%rbp)
jge 0x69e8
movq 0x1f677(%rip), %rax     # 0x25fc8
movq (%rax), %rax
movq %rax, -0x400(%rbp)
leaq -0x1e0(%rbp), %rdi
callq 0x41b0
movq %rax, -0x3f8(%rbp)
xorl %edi, %edi
subl -0x29c(%rbp), %edi
callq 0x4150
movq -0x400(%rbp), %rdi
movq -0x3f8(%rbp), %rdx
movq %rax, %rcx
leaq 0x163c5(%rip), %rsi     # 0x1cd58
movb $0x0, %al
callq 0x4680
movl $0x7, -0x144(%rbp)
jmp 0x6a9e
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
jmp 0x6af5
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
jmp 0x6ae9
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
leaq -0x258(%rbp), %rdi
callq 0xd660
jmp 0x6ae9
movl -0x29c(%rbp), %edi
leaq -0x330(%rbp), %rsi
callq 0x47b0
movl -0x29c(%rbp), %edi
callq 0x48b0
jmp 0x6a07
movq -0x300(%rbp), %rax
movq %rax, -0x1e8(%rbp)
movq %rax, -0x1c0(%rbp)
leaq -0x258(%rbp), %rdi
leaq -0x1e0(%rbp), %rsi
callq 0xd4d0
jmp 0x6a31
leaq -0x230(%rbp), %rdi
leaq -0x208(%rbp), %rsi
callq 0xd4d0
jmp 0x6a46
leaq -0x258(%rbp), %rdi
callq 0xd0e0
movl %eax, -0x404(%rbp)
jmp 0x6a5a
movl -0x404(%rbp), %eax
cmpl $0x0, %eax
jge 0x6a71
movl $0x8, -0x144(%rbp)
jmp 0x6a9e
leaq 0x1fb80(%rip), %rdi     # 0x265f8
xorl %esi, %esi
callq 0xee20
movq -0x300(%rbp), %rax
addq 0x1fba3(%rip), %rax     # 0x26630
movq %rax, 0x1fb9c(%rip)     # 0x26630
movl $0x0, -0x144(%rbp)
leaq -0x258(%rbp), %rdi
callq 0xd660
leaq -0x208(%rbp), %rdi
callq 0xd640
leaq -0x1e0(%rbp), %rdi
callq 0xd640
movl -0x144(%rbp), %eax
movl %eax, -0x408(%rbp)
testl %eax, %eax
je 0x6ae7
jmp 0x6ad4
movl -0x408(%rbp), %eax
subl $0x7, %eax
je 0x66ae
jmp 0x6ae5
jmp 0x6b0c
jmp 0x6b03
leaq -0x208(%rbp), %rdi
callq 0xd640
leaq -0x1e0(%rbp), %rdi
callq 0xd640
jmp 0x6b6a
jmp 0x6b05
jmp 0x6b07
jmp 0x66ae
movq -0x150(%rbp), %rdi
callq 0x4750
jmp 0x6b1a
movl $0x0, -0x144(%rbp)
leaq -0x140(%rbp), %rdi
callq 0x4280
leaq -0x120(%rbp), %rdi
callq 0x4280
leaq -0x100(%rbp), %rdi
callq 0x4280
movl -0x144(%rbp), %eax
testl %eax, %eax
jne 0x6b9f
jmp 0x6b54
jmp 0x6b56
movl -0xe0(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xe0(%rbp)
jmp 0x643a
leaq -0x140(%rbp), %rdi
callq 0x4280
leaq -0x120(%rbp), %rdi
callq 0x4280
leaq -0x100(%rbp), %rdi
callq 0x4280
jmp 0x6bc0
jmp 0x63e9
movl $0x0, -0x144(%rbp)
leaq -0xd8(%rbp), %rdi
callq 0xeee0
leaq -0x98(%rbp), %rdi
callq 0xef10
addq $0x410, %rsp            # imm = 0x410
popq %rbp
retq
leaq -0xd8(%rbp), %rdi
callq 0xeee0
leaq -0x98(%rbp), %rdi
callq 0xef10
movq -0x40(%rbp), %rdi
callq 0x4810
nopw %cs:(%rax,%rax)