// File: /workspace/github_c_makefile_star2_O0/Carben-dev[P]ext2fs-simple-utilities/ext2_utils.c
// Function: each_checker_rec
int each_checker_rec(int curr_inode_num,
                     int parent_inode_num,
                     unsigned char *ft_type_ptr) {
    struct ext2_inode *curr_inode = inode_table + curr_inode_num - 1;
    int num_fixed = 0;
    char inode_type;
    char entry_type;
    
    // check if file type in dir_entry and inode consistent
    if ((curr_inode->i_mode & EXT2_S_IFLNK) == EXT2_S_IFLNK) {
        inode_type = 's';
    } else if (curr_inode->i_mode & EXT2_S_IFREG) {
        inode_type = 'f';
    } else if (curr_inode->i_mode & EXT2_S_IFDIR) {
        inode_type = 'd';
    } else {
        exit(-1);
    }
    
    switch (*ft_type_ptr) {
        case EXT2_FT_REG_FILE:
            entry_type = 'f';
            break;
        case EXT2_FT_DIR:
            entry_type = 'd';
            break;
        case EXT2_FT_SYMLINK:
            entry_type = 's';
            break;
        default:
            exit(-1);
            break;
    }
    
    if (entry_type != inode_type) {
        if (inode_type == 'f') {
            *ft_type_ptr = EXT2_FT_REG_FILE;
        } else if (inode_type == 'd') {
            *ft_type_ptr = EXT2_FT_DIR;
        } else if (inode_type == 's') {
            *ft_type_ptr = EXT2_FT_SYMLINK;
        }
        num_fixed++;
        printf("Fixed: Entry type vs inode mismatch: inode [%d]\n", curr_inode_num);
    }
    
    // check if inode bitmap consistent
    // reuse function from restore
    if (restore_inode_bitmap(curr_inode_num) != -1) {
        num_fixed++;
        printf("Fixed: inode [%d] not marked as in-use\n", curr_inode_num);
    }
    
    // check if block bitmap consistent
    int *curr_inode_iblock_array = read_i_block_into_array(curr_inode);
    int i = 0;
    while (curr_inode_iblock_array[i] != -1) {
        if (restore_block_bitmap(curr_inode_iblock_array[i]) != -1) {
            num_fixed++;
            printf("Fixed: %d in-use data blocks not marked in data bitmap for inode: [%d]\n", curr_inode_iblock_array[i], curr_inode_num);
        }
        i++;
    }
    
    // check if dtime is 0
    if (curr_inode->i_dtime != 0) {
        curr_inode->i_dtime = 0;
        num_fixed++;
        printf("Fixed: valid inode marked for deletion: [%d]\n", curr_inode_num);
    }
    
    /*
     *  Base case curr_inode is regfile or symlinks
     */
    if (inode_type != 'd') { // not dir then is f or s
        return num_fixed;
    }
    
    /*
     *  Recursive part
     *  curr_inode is dir
     */
    i = 0;
    while (curr_inode_iblock_array[i] != -1) {
        unsigned char *curr_entry_data = disk + EXT2_BLOCK_SIZE * curr_inode_iblock_array[i];
        int curr_off = 0;
        struct ext2_dir_entry *entry;
        
        while (curr_off < EXT2_BLOCK_SIZE) {
            entry = (struct ext2_dir_entry *)(curr_entry_data + curr_off);
            if (entry->rec_len == EXT2_BLOCK_SIZE) {
                break;
            }
            if ((entry->inode != parent_inode_num) &&
                (entry->inode != curr_inode_num)) { // skip "." and ".." and "lost+found"
                num_fixed += each_checker_rec(entry->inode, curr_inode_num, &entry->file_type);
            }
            
            curr_off += entry->rec_len;
        }
        
        i++;
    }
    
    
    return num_fixed;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x60, %rsp
movl %edi, -0x8(%rbp)
movl %esi, -0xc(%rbp)
movq %rdx, -0x18(%rbp)
leaq 0x322f(%rip), %rax      # 0x60b8
movq (%rax), %rax
movslq -0x8(%rbp), %rcx
shlq $0x7, %rcx
addq %rcx, %rax
addq $-0x80, %rax
movq %rax, -0x20(%rbp)
movl $0x0, -0x24(%rbp)
movq -0x20(%rbp), %rax
movzwl (%rax), %eax
andl $0xa000, %eax           # imm = 0xA000
cmpl $0xa000, %eax           # imm = 0xA000
jne 0x2ebf
movb $0x73, -0x25(%rbp)
jmp 0x2efb
movq -0x20(%rbp), %rax
movzwl (%rax), %eax
andl $0x8000, %eax           # imm = 0x8000
cmpl $0x0, %eax
je 0x2ed6
movb $0x66, -0x25(%rbp)
jmp 0x2ef9
movq -0x20(%rbp), %rax
movzwl (%rax), %eax
andl $0x4000, %eax           # imm = 0x4000
cmpl $0x0, %eax
je 0x2eed
movb $0x64, -0x25(%rbp)
jmp 0x2ef7
movl $0xffffffff, %edi       # imm = 0xFFFFFFFF
callq 0x1120
jmp 0x2ef9
jmp 0x2efb
movq -0x18(%rbp), %rax
movzbl (%rax), %eax
movl %eax, -0x54(%rbp)
subl $0x1, %eax
je 0x2f20
jmp 0x2f0c
movl -0x54(%rbp), %eax
subl $0x2, %eax
je 0x2f26
jmp 0x2f16
movl -0x54(%rbp), %eax
subl $0x7, %eax
je 0x2f2c
jmp 0x2f32
movb $0x66, -0x26(%rbp)
jmp 0x2f3c
movb $0x64, -0x26(%rbp)
jmp 0x2f3c
movb $0x73, -0x26(%rbp)
jmp 0x2f3c
movl $0xffffffff, %edi       # imm = 0xFFFFFFFF
callq 0x1120
movsbl -0x26(%rbp), %eax
movsbl -0x25(%rbp), %ecx
cmpl %ecx, %eax
je 0x2f9a
movsbl -0x25(%rbp), %eax
cmpl $0x66, %eax
jne 0x2f5a
movq -0x18(%rbp), %rax
movb $0x1, (%rax)
jmp 0x2f80
movsbl -0x25(%rbp), %eax
cmpl $0x64, %eax
jne 0x2f6c
movq -0x18(%rbp), %rax
movb $0x2, (%rax)
jmp 0x2f7e
movsbl -0x25(%rbp), %eax
cmpl $0x73, %eax
jne 0x2f7c
movq -0x18(%rbp), %rax
movb $0x7, (%rax)
jmp 0x2f7e
jmp 0x2f80
movl -0x24(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x24(%rbp)
movl -0x8(%rbp), %esi
leaq 0x10ab(%rip), %rdi      # 0x403e
movb $0x0, %al
callq 0x10a0
movl -0x8(%rbp), %edi
callq 0x25c0
cmpl $-0x1, %eax
je 0x2fc1
movl -0x24(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x24(%rbp)
movl -0x8(%rbp), %esi
leaq 0x10b5(%rip), %rdi      # 0x406f
movb $0x0, %al
callq 0x10a0
movq -0x20(%rbp), %rdi
callq 0x15b0
movq %rax, -0x30(%rbp)
movl $0x0, -0x34(%rbp)
movq -0x30(%rbp), %rax
movslq -0x34(%rbp), %rcx
cmpl $-0x1, (%rax,%rcx,4)
je 0x3028
movq -0x30(%rbp), %rax
movslq -0x34(%rbp), %rcx
movl (%rax,%rcx,4), %edi
callq 0x26a0
cmpl $-0x1, %eax
je 0x301d
movl -0x24(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x24(%rbp)
movq -0x30(%rbp), %rax
movslq -0x34(%rbp), %rcx
movl (%rax,%rcx,4), %esi
movl -0x8(%rbp), %edx
leaq 0x1081(%rip), %rdi      # 0x4097
movb $0x0, %al
callq 0x10a0
movl -0x34(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x34(%rbp)
jmp 0x2fd5
movq -0x20(%rbp), %rax
cmpl $0x0, 0x14(%rax)
je 0x3057
movq -0x20(%rbp), %rax
movl $0x0, 0x14(%rax)
movl -0x24(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x24(%rbp)
movl -0x8(%rbp), %esi
leaq 0x108f(%rip), %rdi      # 0x40df
movb $0x0, %al
callq 0x10a0
movsbl -0x25(%rbp), %eax
cmpl $0x64, %eax
je 0x306b
movl -0x24(%rbp), %eax
movl %eax, -0x4(%rbp)
jmp 0x312c
movl $0x0, -0x34(%rbp)
movq -0x30(%rbp), %rax
movslq -0x34(%rbp), %rcx
cmpl $-0x1, (%rax,%rcx,4)
je 0x3126
leaq 0x3025(%rip), %rax      # 0x60b0
movq (%rax), %rax
movq -0x30(%rbp), %rcx
movslq -0x34(%rbp), %rdx
movl (%rcx,%rdx,4), %ecx
shll $0xa, %ecx
movslq %ecx, %rcx
addq %rcx, %rax
movq %rax, -0x40(%rbp)
movl $0x0, -0x44(%rbp)
cmpl $0x400, -0x44(%rbp)     # imm = 0x400
jge 0x3118
movq -0x40(%rbp), %rax
movslq -0x44(%rbp), %rcx
addq %rcx, %rax
movq %rax, -0x50(%rbp)
movq -0x50(%rbp), %rax
movzwl 0x4(%rax), %eax
cmpl $0x400, %eax            # imm = 0x400
jne 0x30d6
jmp 0x3118
movq -0x50(%rbp), %rax
movl (%rax), %eax
cmpl -0xc(%rbp), %eax
je 0x3108
movq -0x50(%rbp), %rax
movl (%rax), %eax
cmpl -0x8(%rbp), %eax
je 0x3108
movq -0x50(%rbp), %rax
movl (%rax), %edi
movl -0x8(%rbp), %esi
movq -0x50(%rbp), %rdx
addq $0x7, %rdx
callq 0x2e70
addl -0x24(%rbp), %eax
movl %eax, -0x24(%rbp)
movq -0x50(%rbp), %rax
movzwl 0x4(%rax), %eax
addl -0x44(%rbp), %eax
movl %eax, -0x44(%rbp)
jmp 0x30ad
movl -0x34(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x34(%rbp)
jmp 0x3072
movl -0x24(%rbp), %eax
movl %eax, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x60, %rsp
popq %rbp
retq