static char * test_link_chain(void) { #define str1 "test" #define str2 "teest" size_t i; int res; vnode_t vnode1; vnode_t vnode2; dh_dirent_t * dea; size_t offset; ku_test_description("Test that dh_link chaining works correctly."); vnode1.vn_num = 10; vnode2.vn_num = 11; res = dh_link(&table, &vnode1, str1, sizeof(str1) - 1); ku_assert_equal("Insert succeeded.", res, 0); res = dh_link(&table, &vnode2, str2, sizeof(str2) - 1); ku_assert_equal("Insert succeeded.", res, 0); for (i = 0; i < DEHTABLE_SIZE; i++) { if ((dea = table[i]) != 0) break; } ku_assert("Created chain found.", dea != 0); ku_assert_equal("First entry has a correct vnode number.", (int)get_dirent(dea, 0)->dh_ino, (int)vnode1.vn_num); offset = get_dirent(dea, 0)->dh_size; ku_assert_equal("Second entry has a correct vnode number.", (int)get_dirent(dea, offset)->dh_ino, (int)vnode2.vn_num); #undef str1 #undef str2 return 0; }
/* * traverse root - taken from dos files. modified collectively * recursively follows directories from the root checking each file * for consistency as it goes */ void traverse_root(uint8_t *image_buf, struct bpb33* bpb) { uint16_t cluster = 0; struct direntry* dirent = (struct direntry*) cluster_to_addr(cluster, image_buf, bpb); char buffer [MAXFILENAME]; //buffer for storing file names int i; for (i = 0; i < bpb->bpbRootDirEnts; i++) { uint16_t followclust = get_dirent(dirent, buffer); // deal with normal files if (dirent->deAttributes == ATTR_NORMAL) { chkerr(dirent, buffer, image_buf, bpb); } append_clusters(followclust); // append file cluster if (is_valid_cluster(followclust, bpb)) { append_clusters(followclust); follow_dir(followclust, 1, image_buf, bpb); } dirent++; } }
/* * follow dir recursively scans through the file hierarchy * we check for consistency for every directory entry * taken from dos with some modifications. */ void follow_dir(uint16_t cluster, int indent, uint8_t *image_buf, struct bpb33* bpb) { while (is_valid_cluster(cluster, bpb)) { append_clusters(cluster); struct direntry *dirent = (struct direntry*) cluster_to_addr(cluster, image_buf, bpb); int numDirEntries = (bpb->bpbBytesPerSec * bpb->bpbSecPerClust) / sizeof(struct direntry); char buffer[MAXFILENAME]; int i = 0; for ( ; i < numDirEntries; i++) { append_clusters(cluster); uint16_t followclust = get_dirent(dirent, buffer); chkerr(dirent, buffer, image_buf, bpb); if (followclust) { follow_dir(followclust, indent+1, image_buf, bpb); } dirent++; } cluster = get_fat_entry(cluster, image_buf, bpb); } }
int fat_stat(char *filepath, struct stat *info, struct fat_part_desc *desc) { struct dirent *dir; dir = get_dirent(filepath, desc, desc->root_cluster, (desc->bootrecord.spc * desc->bootrecord.bps) / sizeof(struct dirent)); if (dir == NULL) return -1; info->size = dir->size; info->creat_time = dir->creat_time; info->creat_date = dir->creat_date; info->access_date = dir->access_date; info->mod_time = dir->mod_time; info->mod_date = dir->mod_date; kfree(dir); return 0; }
int fat_open(struct file_descriptor *fd, struct fat_part_desc *desc, char *filepath, unsigned int flags) { struct fat_fd_meta *meta; struct dirent *dir; int current_cluster = desc->root_cluster; fd->filepos = 0; fd->fs_info = kmalloc(sizeof(struct fat_fd_meta)); meta = fd->fs_info; meta->prtinfo = desc; meta->cluster = NULL; dir = get_dirent(filepath, meta->prtinfo, current_cluster, (desc->bootrecord.spc * desc->bootrecord.bps) / sizeof(struct dirent)); if (dir == NULL) { /* file does not exist */ kfree(fd->fs_info); return 0; } meta->ccluster = (dir->cluster_hi << 16) | dir->cluster_lo; meta->dir = dir; return 1; }