static FRESULT follow_path ( /* FR_OK(0): successful, !=0: error code */ DIR *dj, /* Directory object to return last directory and found object */ BYTE *dir, /* 32-byte working buffer */ const char *path /* Full-path string to find a file or directory */ ) { FRESULT res; while (*path == ' ') path++; /* Strip leading spaces */ if (*path == '/') path++; /* Strip heading separator if exist */ dj->sclust = 0; /* Set start directory (always root dir) */ if ((BYTE)*path < ' ') { /* Null path means the root directory */ res = dir_rewind(dj); dir[0] = 0; } else { /* Follow path */ for (;;) { res = create_name(dj, &path); /* Get a segment */ if (res != FR_OK) break; res = dir_find(dj, dir); /* Find it */ if (res != FR_OK) break; /* Could not find the object */ if (dj->fn[11]) break; /* Last segment match. Function completed. */ if (!(dir[DIR_Attr] & AM_DIR)) { /* Cannot follow path because it is a file */ res = FR_NO_FILE; break; } dj->sclust = get_clust(dir); /* Follow next */ } } return res; }
int main(int argc, char **argv) { if(argc != 3) { fprintf(stderr, "Usage: ext2_mkdir <image file name> <path to file>\n"); exit(1); } disk_initialization(argv[1]); /* initialize disk */ /* retrieve the inode index for parent directory */ unsigned int inode_dir = inode_from_path(extract_parent_path(argv[2])); /* get filename for new directory */ char *filename = extract_filename(argv[2]); if (dir_find(inode_dir, filename)) { // Case: filename already exists fprintf(stderr, "%s: already exists\n", argv[2]); exit(EEXIST); } /* allocate inode for new directory */ unsigned int new_inode = allocate_inode(); /* initialize the new directory inode and add as entry to parent directory */ init_dir_inode(new_inode, inode_dir, filename); return 0; }
int main(int argc, char **argv) { if(argc != 3) { fprintf(stderr, "Usage: ext2_rm <image file name> <path to file>\n"); exit(1); } disk_initialization(argv[1]); /* initialize disk */ unsigned int dir_inode = inode_from_path(extract_parent_path(argv[2])); /* get inode index from path */ struct ext2_dir_entry_2 *de = dir_find(dir_inode, extract_filename(argv[2])); if (de == NULL) { fprintf(stderr, "No such file or directory\n"); exit(ENOENT); } unsigned int inode_index = de->inode; if (has_file_type(EXT2_INODE_FT_DIR, inode_index)) { fprintf(stderr, "%s: is a directory\n", argv[2]); exit(EISDIR); } else { /* remove directory entry associated with file */ delete_entry(dir_inode, extract_filename(argv[2])); } return 0; }
// Walks 'path' down the file system. // Stores the rightmost directory inode in '*dirino_store', // and a pointer to the directory entry in '*de_store'. // For instance, if path == "/a/b/c/hello", // then '*dirino_store' is the inode for "/a/b/c" // and '*de_store' points to the embedded directory entry for "hello". // If 'create != 0', the final directory entry is created if necessary. // A newly created entry will have 'de_inum == 0'. (All real entries have // 'de_inum != 0'.) // On success, '*dirino_store' is locked and must be closed with // inode_close(). // // Returns 0 on success, < 0 on error. // Error codes: See dir_find(). // static int path_walk(const char *path, struct Inode **dirino_store, struct Direntry **de_store, int create) { int r; struct Inode *ino, *next_ino; struct Direntry *de; const char *component; int component_len; *dirino_store = 0; *de_store = 0; if ((r = inode_open(1, &ino)) < 0) return r; while (1) { // Find next path component path = path_next_component(path, &component, &component_len); // Special case: root directory if (component_len == 0) { *dirino_store = ino; *de_store = &super->s_root; return 0; } // Look up directory component // (This is the last path component iff *path == 0.) if ((r = dir_find(ino, component, component_len, &de, create && *path == 0)) < 0) goto fail; // If done, return this direntry if (*path == 0) { *dirino_store = ino; *de_store = de; return 0; } // Otherwise, walk into subdirectory. // Always open the next inode before closing the current one. if ((r = inode_open(de->de_inum, &next_ino)) < 0) goto fail; inode_close(ino); ino = next_ino; } fail: inode_close(ino); return r; }
static FRESULT follow_path ( /* FR_OK(0): successful, !=0: error code */ DIR *dj, /* Directory object to return last directory and found object */ const char *path /* Full-path string to find a file or directory */ ) { FRESULT res; u8 *dir; u8 t[15]; // memcpypgm2ram(t, path, 15); while (*path == ' ') path++; /* Skip leading spaces */ if (*path == '/') path++; /* Strip heading separator */ dj->sclust = 0; /* Set start directory (always root dir) */ // memcpypgm2ram(t, path, 15); if ((u8)*path <= ' ') { /* Null path means the root directory */ res = dir_rewind(dj); FatFs->buf[0] = 0; } else { /* Follow path */ for (;;) { res = create_name(dj, &path); /* Get a segment */ if (res != FR_OK) break; res = dir_find(dj); if (res != FR_OK) { /* Could not find the object */ if (res == FR_NO_FILE && !*(dj->fn+11)) res = FR_NO_PATH; break; } if (*(dj->fn+11)) break; /* Last segment match. Function completed. */ dir = FatFs->buf; /* There is next segment. Follow the sub directory */ if (!(dir[DIR_Attr] & AM_DIR)) { /* Cannot follow because it is a file */ res = FR_NO_PATH; break; } dj->sclust = #if _FS_FAT32 ((u32)LD_WORD(dir+DIR_FstClusHI) << 16) | #endif LD_WORD(dir+DIR_FstClusLO); } } return res; }