// File: /workspace/github_c_makefile_star2_O0/sheheryarbutt[P]Ext2-File-System/ext2_mkdir.c
// Function: main
int main(int argc, char **argv) {

    if(argc != 3) {
        fprintf(stderr, "Usage: ext2_mkdir <image file name> <dest path>\n");
        exit(1);
    }
    int fd = open(argv[1], O_RDWR);

    disk = mmap(NULL, 128 * 1024, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
    if(disk == MAP_FAILED) {
	perror("mmap");
	exit(1);
    }

    // setting global vars
    sb = (struct ext2_super_block *)(disk + EXT2_BLOCK_SIZE);
    gd = (struct ext2_group_desc *)(disk + (2*EXT2_BLOCK_SIZE)); 
	inode_table = (struct ext2_inode *)(disk + (5*EXT2_BLOCK_SIZE));

	char * path = argv[2];
	remove_trailing_slash(path);
	// need for pathTraversal function
	unsigned int * parent_block= malloc(sizeof(unsigned int *));
	int cur_inode=pathTraversal(path,disk,parent_block);
	
	if (cur_inode!=0){
		// file/directory already exists at path
		free(parent_block);
		fprintf(stderr, "ERROR: %s\n", strerror(EEXIST));     
		exit(EEXIST);
	}

	free(parent_block);
	char *cpyPath=malloc((unsigned int)strlen(path) + 1);
	strcpy(cpyPath,path);
	parent_block= malloc(sizeof(unsigned int *));
	// name of dir we want to create
	char *name;
	name=basename(cpyPath);

	if (strlen(name)>EXT2_NAME_LEN){
		fprintf(stderr, "ERROR: %s\n", strerror(ENAMETOOLONG));     
		exit(ENAMETOOLONG);
	}
	path[strlen(path)-(strlen(name))]='\0';
	cur_inode=pathTraversal(path,disk,parent_block);

	if (cur_inode==0){
		// path to directory we want to create new dir in, doesnt exist
		fprintf(stderr, "ERROR: %s\n", strerror(ENOENT));     
		exit(ENOENT);
	}
	if ((gd->bg_free_blocks_count<2) || (gd->bg_free_inodes_count<1) ){
		// no space left to create new dir
		fprintf(stderr, "ERROR: %s\n", strerror(ENOSPC));     
		exit(ENOSPC);
	}

	//var for available datablocks and inodes
	int avail_db,avail_db2;
	int avail_ib;

	//cannot create directory in reserved inodes, except root
	if(cur_inode==EXT2_ROOT_INO || cur_inode > EXT2_GOOD_OLD_FIRST_INO){

		struct ext2_inode inode = inode_table[cur_inode-1];

		if(!((inode.i_mode & EXT2_S_IFDIR) == EXT2_S_IFDIR)){
			// path to create directory in is not to a directory
			fprintf(stderr, "ERROR: %s\n", strerror(ENOTDIR));     
			exit(ENOTDIR);
		}
		else { 
			int block_pointer=0; 
			//find next block pointer to use for new dir entry
			while(inode_table[cur_inode-1].i_block[block_pointer]!=0){
				block_pointer++;
			}
			//datablock to store new dir entry
			avail_db= set_avail_db();
			//update dir info 
			inode_table[cur_inode-1].i_block[block_pointer]=avail_db;
			inode_table[cur_inode-1].i_blocks+=2;
			inode_table[cur_inode-1].i_size+=EXT2_BLOCK_SIZE;
			inode_table[cur_inode-1].i_links_count+=1;

			//datablock and inode for new dir
			avail_ib= set_avail_ib();
			avail_db2= set_avail_db();

			unsigned int * blocks=malloc(sizeof(unsigned int)*15);

			blocks[0]=avail_db2;
			// create inode for new dir
			create_inode(avail_ib,EXT2_S_IFDIR,EXT2_BLOCK_SIZE,2,2,blocks);
			// create dir entry for new dir
			create_entry((EXT2_BLOCK_SIZE*avail_db),(unsigned int)avail_ib,(unsigned short)EXT2_BLOCK_SIZE,(unsigned char)strlen(name),(unsigned char)EXT2_FT_DIR,name);
			// create dir entries for . and ..
			create_entry((EXT2_BLOCK_SIZE*avail_db2),(unsigned int)avail_ib,(unsigned short)12,(unsigned char)1,(unsigned char)EXT2_FT_DIR,".");
			create_entry((EXT2_BLOCK_SIZE*avail_db2)+12,(unsigned int)cur_inode,(unsigned short)1012,(unsigned char)2,(unsigned char)EXT2_FT_DIR,"..");

		}

	}else{
		fprintf(stderr, "ERROR: %s\n", strerror(EPERM));     
		exit(EPERM);
		
	}
					   	   
    return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x120, %rsp            # imm = 0x120
movl $0x0, -0x4(%rbp)
movl %edi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
cmpl $0x3, -0x8(%rbp)
je 0x1261
movq 0x3db2(%rip), %rax      # 0x4ff8
movq (%rax), %rdi
leaq 0x1db4(%rip), %rsi      # 0x3004
movb $0x0, %al
callq 0x1090
movl $0x1, %edi
callq 0x1100
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rdi
movl $0x2, %esi
movb $0x0, %al
callq 0x10e0
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, 0x3e09(%rip)      # 0x50a8
movq $-0x1, %rax
cmpq %rax, 0x3dfb(%rip)      # 0x50a8
jne 0x12c5
leaq 0x1d7f(%rip), %rdi      # 0x3035
callq 0x10f0
movl $0x1, %edi
callq 0x1100
movq 0x3ddc(%rip), %rax      # 0x50a8
addq $0x400, %rax            # imm = 0x400
movq %rax, 0x3dd7(%rip)      # 0x50b0
movq 0x3dc8(%rip), %rax      # 0x50a8
addq $0x800, %rax            # imm = 0x800
movq %rax, 0x3dcb(%rip)      # 0x50b8
movq 0x3db4(%rip), %rax      # 0x50a8
addq $0x1400, %rax           # imm = 0x1400
movq %rax, 0x3dbf(%rip)      # 0x50c0
movq -0x10(%rbp), %rax
movq 0x10(%rax), %rax
movq %rax, -0x20(%rbp)
movq -0x20(%rbp), %rdi
callq 0x17a0
movl $0x8, %edi
callq 0x10d0
movq %rax, -0x28(%rbp)
movq -0x20(%rbp), %rdi
movq 0x3d79(%rip), %rsi      # 0x50a8
movq -0x28(%rbp), %rdx
callq 0x1970
movl %eax, -0x2c(%rbp)
cmpl $0x0, -0x2c(%rbp)
je 0x1387
movq -0x28(%rbp), %rdi
callq 0x1030
movq 0x3ca7(%rip), %rax      # 0x4ff8
movq (%rax), %rax
movq %rax, -0xe0(%rbp)
movl $0x11, %edi
callq 0x1110
movq -0xe0(%rbp), %rdi
movq %rax, %rdx
leaq 0x1cc4(%rip), %rsi      # 0x303a
movb $0x0, %al
callq 0x1090
movl $0x11, %edi
callq 0x1100
movq -0x28(%rbp), %rdi
callq 0x1030
movq -0x20(%rbp), %rdi
callq 0x1060
addl $0x1, %eax
movl %eax, %eax
movl %eax, %edi
callq 0x10d0
movq %rax, -0x38(%rbp)
movq -0x38(%rbp), %rdi
movq -0x20(%rbp), %rsi
callq 0x1050
movl $0x8, %edi
callq 0x10d0
movq %rax, -0x28(%rbp)
movq -0x38(%rbp), %rdi
callq 0x10b0
movq %rax, -0x40(%rbp)
movq -0x40(%rbp), %rdi
callq 0x1060
cmpq $0xff, %rax
jbe 0x141f
movq 0x3c0f(%rip), %rax      # 0x4ff8
movq (%rax), %rax
movq %rax, -0xe8(%rbp)
movl $0x24, %edi
callq 0x1110
movq -0xe8(%rbp), %rdi
movq %rax, %rdx
leaq 0x1c2c(%rip), %rsi      # 0x303a
movb $0x0, %al
callq 0x1090
movl $0x24, %edi
callq 0x1100
movq -0x20(%rbp), %rax
movq %rax, -0xf0(%rbp)
movq -0x20(%rbp), %rdi
callq 0x1060
movq %rax, -0xf8(%rbp)
movq -0x40(%rbp), %rdi
callq 0x1060
movq -0xf8(%rbp), %rcx
movq %rax, %rdx
movq -0xf0(%rbp), %rax
subq %rdx, %rcx
movb $0x0, (%rax,%rcx)
movq -0x20(%rbp), %rdi
movq 0x3c42(%rip), %rsi      # 0x50a8
movq -0x28(%rbp), %rdx
callq 0x1970
movl %eax, -0x2c(%rbp)
cmpl $0x0, -0x2c(%rbp)
jne 0x14b5
movq 0x3b79(%rip), %rax      # 0x4ff8
movq (%rax), %rax
movq %rax, -0x100(%rbp)
movl $0x2, %edi
callq 0x1110
movq -0x100(%rbp), %rdi
movq %rax, %rdx
leaq 0x1b96(%rip), %rsi      # 0x303a
movb $0x0, %al
callq 0x1090
movl $0x2, %edi
callq 0x1100
movq 0x3bfc(%rip), %rax      # 0x50b8
movzwl 0xc(%rax), %eax
cmpl $0x2, %eax
jl 0x14d5
movq 0x3bec(%rip), %rax      # 0x50b8
movzwl 0xe(%rax), %eax
cmpl $0x1, %eax
jge 0x1512
movq 0x3b1c(%rip), %rax      # 0x4ff8
movq (%rax), %rax
movq %rax, -0x108(%rbp)
movl $0x1c, %edi
callq 0x1110
movq -0x108(%rbp), %rdi
movq %rax, %rdx
leaq 0x1b39(%rip), %rsi      # 0x303a
movb $0x0, %al
callq 0x1090
movl $0x1c, %edi
callq 0x1100
cmpl $0x2, -0x2c(%rbp)
je 0x1522
cmpl $0xb, -0x2c(%rbp)
jle 0x174e
movq 0x3b97(%rip), %rsi      # 0x50c0
movl -0x2c(%rbp), %eax
subl $0x1, %eax
cltq
shlq $0x7, %rax
addq %rax, %rsi
leaq -0xcc(%rbp), %rdi
movl $0x80, %edx
callq 0x10a0
movzwl -0xcc(%rbp), %eax
andl $0x4000, %eax           # imm = 0x4000
cmpl $0x4000, %eax           # imm = 0x4000
je 0x1599
movq 0x3a95(%rip), %rax      # 0x4ff8
movq (%rax), %rax
movq %rax, -0x110(%rbp)
movl $0x14, %edi
callq 0x1110
movq -0x110(%rbp), %rdi
movq %rax, %rdx
leaq 0x1ab2(%rip), %rsi      # 0x303a
movb $0x0, %al
callq 0x1090
movl $0x14, %edi
callq 0x1100
movl $0x0, -0xd0(%rbp)
movq 0x3b16(%rip), %rax      # 0x50c0
movl -0x2c(%rbp), %ecx
subl $0x1, %ecx
movslq %ecx, %rcx
shlq $0x7, %rcx
addq %rcx, %rax
movslq -0xd0(%rbp), %rcx
cmpl $0x0, 0x28(%rax,%rcx,4)
je 0x15d9
movl -0xd0(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xd0(%rbp)
jmp 0x15a3
movb $0x0, %al
callq 0x1d20
movl %eax, -0x44(%rbp)
movl -0x44(%rbp), %edx
movq 0x3ad3(%rip), %rax      # 0x50c0
movl -0x2c(%rbp), %ecx
subl $0x1, %ecx
movslq %ecx, %rcx
shlq $0x7, %rcx
addq %rcx, %rax
movslq -0xd0(%rbp), %rcx
movl %edx, 0x28(%rax,%rcx,4)
movq 0x3ab1(%rip), %rax      # 0x50c0
movl -0x2c(%rbp), %ecx
subl $0x1, %ecx
movslq %ecx, %rcx
shlq $0x7, %rcx
addq %rcx, %rax
movl 0x1c(%rax), %ecx
addl $0x2, %ecx
movl %ecx, 0x1c(%rax)
movq 0x3a91(%rip), %rax      # 0x50c0
movl -0x2c(%rbp), %ecx
subl $0x1, %ecx
movslq %ecx, %rcx
shlq $0x7, %rcx
addq %rcx, %rax
movl 0x4(%rax), %ecx
addl $0x400, %ecx            # imm = 0x400
movl %ecx, 0x4(%rax)
movq 0x3a6e(%rip), %rax      # 0x50c0
movl -0x2c(%rbp), %ecx
subl $0x1, %ecx
movslq %ecx, %rcx
shlq $0x7, %rcx
addq %rcx, %rax
movzwl 0x1a(%rax), %ecx
addl $0x1, %ecx
movw %cx, 0x1a(%rax)
movb $0x0, %al
callq 0x1e00
movl %eax, -0x4c(%rbp)
movb $0x0, %al
callq 0x1d20
movl %eax, -0x48(%rbp)
movl $0x3c, %edi
callq 0x10d0
movq %rax, -0xd8(%rbp)
movl -0x48(%rbp), %ecx
movq -0xd8(%rbp), %rax
movl %ecx, (%rax)
movl -0x4c(%rbp), %edi
movq -0xd8(%rbp), %r9
movl $0x4000, %esi           # imm = 0x4000
movl $0x400, %edx            # imm = 0x400
movl $0x2, %r8d
movl %r8d, %ecx
callq 0x1ea0
movl -0x44(%rbp), %eax
shll $0xa, %eax
movl %eax, -0x118(%rbp)
movl -0x4c(%rbp), %eax
movl %eax, -0x114(%rbp)
movq -0x40(%rbp), %rdi
callq 0x1060
movl -0x118(%rbp), %edi
movl -0x114(%rbp), %esi
movq -0x40(%rbp), %r9
movl $0x400, %edx            # imm = 0x400
movl $0x2, %r8d
movzbl %al, %ecx
callq 0x1fe0
movl -0x48(%rbp), %edi
shll $0xa, %edi
movl -0x4c(%rbp), %esi
movl $0xc, %edx
movl $0x1, %ecx
movl $0x2, %r8d
leaq 0x1925(%rip), %r9       # 0x3046
callq 0x1fe0
movl -0x48(%rbp), %edi
shll $0xa, %edi
addl $0xc, %edi
movl -0x2c(%rbp), %esi
movl $0x3f4, %edx            # imm = 0x3F4
movl $0x2, %r8d
leaq 0x1901(%rip), %r9       # 0x3045
movl %r8d, %ecx
callq 0x1fe0
jmp 0x178b
movq 0x38a3(%rip), %rax      # 0x4ff8
movq (%rax), %rax
movq %rax, -0x120(%rbp)
movl $0x1, %edi
callq 0x1110
movq -0x120(%rbp), %rdi
movq %rax, %rdx
leaq 0x18c0(%rip), %rsi      # 0x303a
movb $0x0, %al
callq 0x1090
movl $0x1, %edi
callq 0x1100
xorl %eax, %eax
addq $0x120, %rsp            # imm = 0x120
popq %rbp
retq
nopw %cs:(%rax,%rax)