// File: /workspace/github_c_makefile_star2_O0/Carben-dev[P]ext2fs-simple-utilities/ext2_checker.c
// Function: main
int main(int argc, const char * argv[]) {
    if(argc != 2) {
        fprintf(stderr, "Usage: <image file name>\n");
        exit(1);
    }
    int fd = open(argv[1], 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);
    }
    
    // Init utils
    ext2_utils_init();
    
    // varible
    int num_fixed = 0;
    
    // check free inode and block count in sb and gdt
    // always trust bitmap
    // output certain message
    int free_inode_count = count_inode_bitmap();
    int free_block_count = count_block_bitmap();
    
    if (sb->s_free_blocks_count != free_block_count) {
        int s_blocks_off;
        if (sb->s_free_blocks_count > free_block_count) {
            s_blocks_off = sb->s_free_blocks_count - free_block_count;
        } else {
            s_blocks_off = free_block_count - sb->s_free_blocks_count;
        }
        sb->s_free_blocks_count = free_block_count;
        num_fixed++;
        printf("Fixed: superblock's free blocks counter was off by %d compared to the bitmap\n", s_blocks_off);
    }
    
    if (sb->s_free_inodes_count != free_inode_count) {
        int s_inodes_off;
        if (sb->s_free_inodes_count > free_inode_count) {
            s_inodes_off = sb->s_free_inodes_count - free_inode_count;
        } else {
            s_inodes_off = free_inode_count - sb->s_free_inodes_count;
        }
        num_fixed++;
        sb->s_free_inodes_count = free_inode_count;
        printf("Fixed: superblock's free inodes counter was off by %d compared to the bitmap\n", s_inodes_off);
    }
    
    if (gdt->bg_free_blocks_count != free_block_count) {
        int bg_blocks_off;
        if (gdt->bg_free_blocks_count > free_block_count) {
            bg_blocks_off = gdt->bg_free_blocks_count - free_block_count;
        } else {
            bg_blocks_off = free_block_count - gdt->bg_free_blocks_count;
        }
        gdt->bg_free_blocks_count = free_block_count;
        num_fixed++;
        printf("Fixed: block group's free blocks counter was off by %d compared to the bitmap\n", bg_blocks_off);
    }
    
    if (gdt->bg_free_inodes_count != free_inode_count) {
        int bg_inodes_off;
        if (gdt->bg_free_inodes_count > free_inode_count) {
            bg_inodes_off = gdt->bg_free_inodes_count - free_inode_count;
        } else {
            bg_inodes_off = free_inode_count - gdt->bg_free_inodes_count;
        }
        gdt->bg_free_inodes_count = free_inode_count;
        num_fixed++;
        printf("Fixed: block group's free inodes counter was off by %d compared to the bitmap\n", bg_inodes_off);
    }
    
    
    // check if type in dir entry match i_mode in inode
    // trust inode
    // output certain message
    
    
    // check if each inode in bitmap mark as used
    // trust inode
    // output certain message
    
    // check if each inode dtime is 0
    // reset to 0 if not
    // output certain message
    
    // check if each inode datablock mark as used in bitmap
    // trust inode
    // output certain message
    
    unsigned char root_ft_type = EXT2_FT_DIR;
    num_fixed += each_checker_rec(2, 2, &root_ft_type);
    
    // output summary
    if (num_fixed) {
        printf("%d file system inconsistencies repaired!\n", num_fixed);
    } else {
        printf("No file system inconsistencies detected!\n");
    }
    
    
    return 0;
    
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x40, %rsp
movl $0x0, -0x4(%rbp)
movl %edi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
cmpl $0x2, -0x8(%rbp)
je 0x125e
movq 0x4db5(%rip), %rax      # 0x5ff8
movq (%rax), %rdi
leaq 0x2db7(%rip), %rsi      # 0x4004
movb $0x0, %al
callq 0x10b0
movl $0x1, %edi
callq 0x1110
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rdi
movl $0x2, %esi
movb $0x0, %al
callq 0x10f0
movl %eax, -0x14(%rbp)
movl -0x14(%rbp), %r8d
xorl %eax, %eax
movl %eax, %r9d
movl $0x20000, %esi          # imm = 0x20000
movl $0x3, %edx
movl $0x1, %ecx
movq %r9, %rdi
callq 0x1070
movq %rax, 0x4e0c(%rip)      # 0x60a8
movq $-0x1, %rax
cmpq %rax, 0x4dfe(%rip)      # 0x60a8
jne 0x12c2
leaq 0x2d6b(%rip), %rdi      # 0x401e
callq 0x1100
movl $0x1, %edi
callq 0x1110
callq 0x14e0
movl $0x0, -0x18(%rbp)
callq 0x2ad0
movl %eax, -0x1c(%rbp)
callq 0x2b60
movl %eax, -0x20(%rbp)
movq 0x4dcb(%rip), %rax      # 0x60b0
movl 0xc(%rax), %eax
cmpl -0x20(%rbp), %eax
je 0x1345
movq 0x4dbc(%rip), %rax      # 0x60b0
movl 0xc(%rax), %eax
cmpl -0x20(%rbp), %eax
jbe 0x130e
movq 0x4dad(%rip), %rax      # 0x60b0
movl 0xc(%rax), %eax
subl -0x20(%rbp), %eax
movl %eax, -0x24(%rbp)
jmp 0x131e
movl -0x20(%rbp), %eax
movq 0x4d98(%rip), %rcx      # 0x60b0
subl 0xc(%rcx), %eax
movl %eax, -0x24(%rbp)
movl -0x20(%rbp), %ecx
movq 0x4d88(%rip), %rax      # 0x60b0
movl %ecx, 0xc(%rax)
movl -0x18(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x18(%rbp)
movl -0x24(%rbp), %esi
leaq 0x2ce5(%rip), %rdi      # 0x4023
movb $0x0, %al
callq 0x1090
movq 0x4d64(%rip), %rax      # 0x60b0
movl 0x10(%rax), %eax
cmpl -0x1c(%rbp), %eax
je 0x13ac
movq 0x4d55(%rip), %rax      # 0x60b0
movl 0x10(%rax), %eax
cmpl -0x1c(%rbp), %eax
jbe 0x1375
movq 0x4d46(%rip), %rax      # 0x60b0
movl 0x10(%rax), %eax
subl -0x1c(%rbp), %eax
movl %eax, -0x28(%rbp)
jmp 0x1385
movl -0x1c(%rbp), %eax
movq 0x4d31(%rip), %rcx      # 0x60b0
subl 0x10(%rcx), %eax
movl %eax, -0x28(%rbp)
movl -0x18(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x18(%rbp)
movl -0x1c(%rbp), %ecx
movq 0x4d18(%rip), %rax      # 0x60b0
movl %ecx, 0x10(%rax)
movl -0x28(%rbp), %esi
leaq 0x2ccc(%rip), %rdi      # 0x4071
movb $0x0, %al
callq 0x1090
movq 0x4d05(%rip), %rax      # 0x60b8
movzwl 0xc(%rax), %eax
cmpl -0x20(%rbp), %eax
je 0x141d
movq 0x4cf5(%rip), %rax      # 0x60b8
movzwl 0xc(%rax), %eax
cmpl -0x20(%rbp), %eax
jle 0x13df
movq 0x4ce5(%rip), %rax      # 0x60b8
movzwl 0xc(%rax), %eax
subl -0x20(%rbp), %eax
movl %eax, -0x2c(%rbp)
jmp 0x13f2
movl -0x20(%rbp), %eax
movq 0x4ccf(%rip), %rcx      # 0x60b8
movzwl 0xc(%rcx), %ecx
subl %ecx, %eax
movl %eax, -0x2c(%rbp)
movl -0x20(%rbp), %eax
movw %ax, %cx
movq 0x4cb9(%rip), %rax      # 0x60b8
movw %cx, 0xc(%rax)
movl -0x18(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x18(%rbp)
movl -0x2c(%rbp), %esi
leaq 0x2ca9(%rip), %rdi      # 0x40bf
movb $0x0, %al
callq 0x1090
movq 0x4c94(%rip), %rax      # 0x60b8
movzwl 0xe(%rax), %eax
cmpl -0x1c(%rbp), %eax
je 0x148e
movq 0x4c84(%rip), %rax      # 0x60b8
movzwl 0xe(%rax), %eax
cmpl -0x1c(%rbp), %eax
jle 0x1450
movq 0x4c74(%rip), %rax      # 0x60b8
movzwl 0xe(%rax), %eax
subl -0x1c(%rbp), %eax
movl %eax, -0x30(%rbp)
jmp 0x1463
movl -0x1c(%rbp), %eax
movq 0x4c5e(%rip), %rcx      # 0x60b8
movzwl 0xe(%rcx), %ecx
subl %ecx, %eax
movl %eax, -0x30(%rbp)
movl -0x1c(%rbp), %eax
movw %ax, %cx
movq 0x4c48(%rip), %rax      # 0x60b8
movw %cx, 0xe(%rax)
movl -0x18(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x18(%rbp)
movl -0x30(%rbp), %esi
leaq 0x2c87(%rip), %rdi      # 0x410e
movb $0x0, %al
callq 0x1090
movb $0x2, -0x31(%rbp)
movl $0x2, %esi
leaq -0x31(%rbp), %rdx
movl %esi, %edi
callq 0x2f50
addl -0x18(%rbp), %eax
movl %eax, -0x18(%rbp)
cmpl $0x0, -0x18(%rbp)
je 0x14c1
movl -0x18(%rbp), %esi
leaq 0x2ca5(%rip), %rdi      # 0x415d
movb $0x0, %al
callq 0x1090
jmp 0x14cf
leaq 0x2cbf(%rip), %rdi      # 0x4187
movb $0x0, %al
callq 0x1090
xorl %eax, %eax
addq $0x40, %rsp
popq %rbp
retq
nopw (%rax,%rax)