static char *find_external(char *const name, t_bsh *const bsh) { char *external; external = get_path_table(&bsh->hashtable, name); if (external != NULL) { if ((external = ft_strdup(external)) == NULL) ft_putstr_fd("42sh: allocation error\n", 2); } else external = sh_path_search(&bsh->env, name); if (external && bsh && add_hash_table(&bsh->hashtable, name, external)) ft_dprintf(STDERR_FILENO, "42sh: failed to add %s to hashtable\n", external); return (external); }
int main(int argc, char **argv) { if (argc != 4) { fprintf(stderr, "Usage: readimg <image file name> filepath \n"); exit(1); } // open source file int fd_src = open(argv[2], O_RDONLY); if (fd_src < 0){ fprintf(stderr, "No such file exists in the native file system \n"); exit(ENOENT); } int filesize_src = lseek(fd_src, 0, SEEK_END); // mmap cannot map size 0 file. if (filesize_src <= 0){ fprintf(stderr, "The source file is empty \n"); exit(ENOENT); } int req_block_num = (filesize_src - 1) / EXT2_BLOCK_SIZE + 1; // open the image int fd = open(argv[1], O_RDWR); if (fd < 0){ fprintf(stderr, "No such virtual disk exists \n"); exit(ENOENT); } // map the virtual disk and source file on memory ptr_disk = mmap(NULL, BLOCK_NUM * BLOCK_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); unsigned char* ptr_disk_src = mmap(NULL, filesize_src, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd_src, 0); if (ptr_disk == MAP_FAILED || ptr_disk_src == MAP_FAILED) { perror("mmap"); exit(1); } struct ext2_group_desc *ptr_group_desc = (struct ext2_group_desc *)(ptr_disk + EXT2_SB_OFFSET + EXT2_BLOCK_SIZE); // get the inode table struct ext2_inode *ptr_inode = (struct ext2_inode *)(ptr_disk + EXT2_BLOCK_SIZE * ptr_group_desc->bg_inode_table); unsigned char *bm_inode = (ptr_disk + (ptr_group_desc -> bg_inode_bitmap) * BLOCK_SIZE); unsigned char *bm_block = (ptr_disk + (ptr_group_desc -> bg_block_bitmap) * BLOCK_SIZE); struct ext2_super_block *ptr_super_block = (struct ext2_super_block *)(ptr_disk + EXT2_SB_OFFSET); char *ptr_path_src = strdup(argv[2]); char *ptr_path_dest = strdup(argv[3]); char *table_path_src[10]; char *table_path_dest[10]; int count_path_src = get_path_table(table_path_src, ptr_path_src); int count_path_dest = get_path_table(table_path_dest, ptr_path_dest); // Find the destination directory in the virtual disk struct ext2_dir_entry_2 *ptr_dir_dest = recurse_inode(ptr_inode + 1, table_path_dest, count_path_dest, 0, ptr_group_desc->bg_inode_table); if(ptr_dir_dest == 0) { printf("No such directory exists on virtual disk\n"); return -1; } int table_new_block[req_block_num]; int copy_flag = 0; int i = 0; while(i < req_block_num) { int free_block = get_free_block(bm_block, ptr_super_block); SETBIT(bm_block, free_block); table_new_block[i] = free_block; if(filesize_src - copy_flag <= BLOCK_SIZE) { memcpy(ptr_disk + EXT2_BLOCK_SIZE * (free_block + 1), ptr_disk_src + BLOCK_SIZE * i, filesize_src - copy_flag - 1); } else { memcpy(ptr_disk + EXT2_BLOCK_SIZE * (free_block + 1), ptr_disk_src + BLOCK_SIZE * i, EXT2_BLOCK_SIZE); copy_flag += BLOCK_SIZE; } i++; } int block_id_inderect; if(req_block_num > 11) { block_id_inderect = get_free_block(bm_block, ptr_super_block); int *indirect_block = (int *)(ptr_disk + EXT2_BLOCK_SIZE * (block_id_inderect + 1)); SETBIT(bm_block, block_id_inderect); for(i = 12; i < req_block_num; i++) { *indirect_block = table_new_block[i]; indirect_block++; } } int fr_inode = get_free_inode(bm_inode, ptr_super_block); struct ext2_inode *node_new = ptr_inode + (fr_inode); SETBIT(bm_inode, fr_inode); node_new->i_links_count = 1; node_new->i_mode = EXT2_S_IFREG; node_new->i_size = filesize_src; node_new->i_blocks = req_block_num * 2; i = 0; while (i < 11 && req_block_num != i) { node_new->i_block[i] = table_new_block[i]; i++; } if(req_block_num > 11) { node_new -> i_block[12] = block_id_inderect; } struct ext2_inode *in_src = (struct ext2_inode *)(ptr_disk + EXT2_BLOCK_SIZE * ptr_group_desc->bg_inode_table); struct ext2_inode *in_cur = (struct ext2_inode *)(ptr_disk + EXT2_BLOCK_SIZE * ptr_group_desc->bg_inode_table); in_src = in_src + ptr_dir_dest -> inode - 1; in_cur = in_cur + ptr_dir_dest -> inode - 1; in_cur->i_links_count++; int len_req = strlen(table_path_src[count_path_src - 1]) + 8; struct ext2_dir_entry_2 *ptr_dir = get_free_space(in_cur, len_req); if(ptr_dir == 0) { int free_block_new = get_free_block(bm_block, ptr_super_block); ptr_dir = (void*)ptr_disk + EXT2_BLOCK_SIZE * (free_block_new + 1); ptr_dir -> inode = fr_inode + 1; ptr_dir -> name_len = strlen(table_path_dest[count_path_dest - 1]); ptr_dir -> file_type = EXT2_FT_DIR; strcpy(ptr_dir -> name, table_path_dest[count_path_dest - 1]); ptr_dir -> rec_len = BLOCK_SIZE; in_src -> i_blocks += 2; in_src ->i_block[in_src -> i_size / BLOCK_SIZE] = free_block_new + 1; in_src -> i_size += BLOCK_SIZE; } else { int new_rec_len = ptr_dir -> rec_len - (4 * (ptr_dir -> name_len) + 8); ptr_dir -> rec_len = 4 * (ptr_dir -> name_len) + 8; ptr_dir = (void*)ptr_dir + ptr_dir -> rec_len; ptr_dir -> rec_len = new_rec_len; ptr_dir -> inode = fr_inode + 1; ptr_dir -> name_len = strlen(table_path_dest[count_path_dest - 1]); ptr_dir -> file_type = EXT2_FT_REG_FILE; strcpy(ptr_dir -> name, table_path_dest[count_path_dest - 1]); } ptr_group_desc->bg_used_dirs_count++; return 0; }