// File: /workspace/github_c_makefile_star2_O2/Carben-dev[P]ext2fs-simple-utilities/ext2_cp.c
// Function: main
int main(int argc, const char * argv[]) {
    if(argc != 4) {
        fprintf(stderr, "Usage: <image file name> <src> <dst>\n");
        exit(1);
    }
    int fd = open(argv[1], O_RDWR);
    int src_fd = open(argv[2], O_RDWR);
    
    // map disk img into memory
    disk = mmap(NULL, 128 * 1024, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
    if(disk == MAP_FAILED) {
        perror("mmap");
        exit(1);
    }
    
    // map src file into memory
    struct stat src_stat;
    if (lstat(argv[2], &src_stat) == -1) {
        return ENOENT;
    }
    int src_file_size = (int)src_stat.st_size;
    unsigned char *src_file = mmap(NULL, src_file_size, PROT_READ | PROT_WRITE, MAP_SHARED, src_fd, 0);
    if(src_file == MAP_FAILED) {
        perror("mmap");
        exit(1);
    }
    // Init utils
    ext2_utils_init();
    
    
    char dst_path[PATH_MAX];
    char dst_file_name[EXT2_NAME_LEN];
    char dst_file_parent[PATH_MAX];
    strcpy(dst_path, argv[3]);
    clear_end_slash(dst_path);
    cut_path(dst_path, dst_file_parent, dst_file_name);
    
    
    // find out dst file parent dir inode
    int dst_file_parent_inode_num = get_inode_number_by_path(dst_file_parent);
    // check if dst file parent exist
    if (dst_file_parent_inode_num < 0) {
        return ENOENT;
    }
    // check if there is a file in dst dir has same name as src file
    if (get_inode_number_by_name(dst_file_parent_inode_num, dst_file_name) > 0) {
        return EEXIST;
    }
    struct ext2_inode *dst_file_parent_inode = inode_table + (dst_file_parent_inode_num - 1);
    
    // create inode for dst_file
    int dst_file_inode_num = new_inode(EXT2_S_IFREG, src_file_size);
    struct ext2_inode *dst_file_inode = inode_table + dst_file_inode_num - 1;
    
    
    /* -- copy datablock -- */
    copy_to_inode_datablock(dst_file_inode, src_file, src_file_size);
    
    // add new file entry to dst parent dir entry
    add_to_dir_entry(dst_file_parent_inode, dst_file_inode_num, dst_file_name, EXT2_FT_REG_FILE);

    
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
subq $0x2190, %rsp           # imm = 0x2190
cmpl $0x4, %edi
jne 0x13c1
movq %rsi, %r14
movq 0x8(%rsi), %rdi
pushq $0x2
popq %rbx
movl %ebx, %esi
xorl %eax, %eax
callq 0x1100
movl %eax, %r15d
movq 0x10(%r14), %rdi
movl %ebx, %esi
xorl %eax, %eax
callq 0x1100
movl %eax, %ebp
pushq $0x3
popq %rdx
pushq $0x1
popq %rcx
movl $0x20000, %esi          # imm = 0x20000
xorl %edi, %edi
movl %r15d, %r8d
xorl %r9d, %r9d
callq 0x1080
movq %rax, 0x3e20(%rip)      # 0x50b8
cmpq $-0x1, %rax
je 0x13b3
movq 0x10(%r14), %rdi
movq %rsp, %rsi
callq 0x10c0
cmpl $-0x1, %eax
je 0x13a1
movq 0x30(%rsp), %rbx
movslq %ebx, %rsi
pushq $0x3
popq %rdx
pushq $0x1
popq %rcx
xorl %edi, %edi
movl %ebp, %r8d
xorl %r9d, %r9d
callq 0x1080
cmpq $-0x1, %rax
je 0x13b3
movq %rax, %r15
callq 0x13e8
movq 0x18(%r14), %rsi
leaq 0x1190(%rsp), %r14
movq %r14, %rdi
callq 0x1060
movq %r14, %rdi
callq 0x2023
leaq 0x190(%rsp), %r12
leaq 0x90(%rsp), %rdx
movq %r14, %rdi
movq %r12, %rsi
callq 0x203a
movq %r12, %rdi
callq 0x166f
testl %eax, %eax
js 0x1340
movl %eax, %ebp
leaq 0x90(%rsp), %rsi
movl %eax, %edi
callq 0x1457
testl %eax, %eax
jle 0x1345
pushq $0x11
jmp 0x1342
pushq $0x2
popq %rbx
jmp 0x13a1
movq 0x3d74(%rip), %rax      # 0x50c0
movl %ebp, %ecx
shlq $0x7, %rcx
leaq (%rax,%rcx), %r14
addq $-0x80, %r14
movl $0x8000, %edi           # imm = 0x8000
movl %ebx, %esi
callq 0x217e
movq 0x3d53(%rip), %rcx      # 0x50c0
movslq %eax, %r12
movq %r12, %rax
shlq $0x7, %rax
leaq (%rcx,%rax), %rdi
addq $-0x80, %rdi
movq %r15, %rsi
movl %ebx, %edx
callq 0x20ae
leaq 0x90(%rsp), %rdx
pushq $0x1
popq %rcx
movq %r14, %rdi
movl %r12d, %esi
callq 0x18b0
xorl %ebx, %ebx
movl %ebx, %eax
addq $0x2190, %rsp           # imm = 0x2190
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
retq
leaq 0x1c70(%rip), %rdi      # 0x302a
callq 0x1110
jmp 0x13dd
movq 0x3c30(%rip), %rax      # 0x4ff8
movq (%rax), %rcx
leaq 0x1c32(%rip), %rdi      # 0x3004
pushq $0x25
popq %rsi
pushq $0x1
popq %rdx
callq 0x1130
pushq $0x1
popq %rdi
callq 0x1120
nopl (%rax)