From 60b1c4bbe1099980ced1f69a9a51674f6e05dd3e Mon Sep 17 00:00:00 2001 From: Linus Nielsen Feltzing Date: Thu, 15 Jan 2004 14:30:59 +0000 Subject: Implemented the mkdir() function in the FAT32 driver git-svn-id: svn://svn.rockbox.org/rockbox/trunk@4238 a1c6a512-1295-4272-9138-f99709370657 --- firmware/common/dir.c | 52 ++++++++++++++++++++++++++++ firmware/drivers/fat.c | 88 +++++++++++++++++++++++++++++++++++++++-------- firmware/export/fat.h | 5 +-- firmware/test/fat/main.c | 22 ++++++++++++ firmware/test/fat/test.sh | 23 ++++++++++++- 5 files changed, 172 insertions(+), 18 deletions(-) (limited to 'firmware') diff --git a/firmware/common/dir.c b/firmware/common/dir.c index 61c3ccbf90..98adc5c730 100644 --- a/firmware/common/dir.c +++ b/firmware/common/dir.c @@ -114,3 +114,55 @@ struct dirent* readdir(DIR* dir) return theent; } + +int mkdir(char *name) +{ + DIR *dir; + char namecopy[MAX_PATH]; + char* end; + char *basename; + char *parent; + struct dirent *entry; + struct fat_dir newdir; + int rc; + + if ( name[0] != '/' ) { + DEBUGF("Only absolute paths supported right now\n"); + return -1; + } + + strncpy(namecopy,name,sizeof(namecopy)); + namecopy[sizeof(namecopy)-1] = 0; + + /* Split the base name and the path */ + end = strrchr(namecopy, '/'); + *end = 0; + basename = end+1; + + if(namecopy == end) /* Root dir? */ + parent = "/"; + else + parent = namecopy; + + DEBUGF("mkdir: parent: %s, name: %s\n", parent, basename); + + dir = opendir(parent); + + if(!dir) { + DEBUGF("mkdir: can't open parent dir\n"); + return -2; + } + + /* Now check if the name already exists */ + while ((entry = readdir(dir))) { + if ( !strcasecmp(basename, entry->d_name) ) { + DEBUGF("mkdir error: file exists\n"); + errno = EEXIST; + return - 3; + } + } + + rc = fat_create_dir(basename, &newdir, &(dir->fatdir)); + + return rc; +} diff --git a/firmware/drivers/fat.c b/firmware/drivers/fat.c index 02d472ceeb..55e6fa30cf 100644 --- a/firmware/drivers/fat.c +++ b/firmware/drivers/fat.c @@ -811,7 +811,8 @@ static int write_long_name(struct fat_file* file, unsigned int firstentry, unsigned int numentries, unsigned char* name, - unsigned char* shortname) + unsigned char* shortname, + bool is_directory) { unsigned char buf[SECTOR_SIZE]; unsigned char* entry; @@ -918,7 +919,7 @@ static int write_long_name(struct fat_file* file, unsigned short date=0, time=0, tenth=0; LDEBUGF("Shortname entry: %.13s\n", shortname); strncpy(entry + FATDIR_NAME, shortname, 11); - entry[FATDIR_ATTR] = 0; + entry[FATDIR_ATTR] = is_directory?FAT_ATTR_DIRECTORY:0; entry[FATDIR_NTRES] = 0; fat_time(&date, &time, &tenth); @@ -947,7 +948,9 @@ static int write_long_name(struct fat_file* file, static int add_dir_entry(struct fat_dir* dir, struct fat_file* file, - char* name) + char* name, + bool is_directory, + bool dotdir) { unsigned char buf[SECTOR_SIZE]; unsigned char shortname[16]; @@ -963,16 +966,26 @@ static int add_dir_entry(struct fat_dir* dir, LDEBUGF( "add_dir_entry(%s,%x)\n", name, file->firstcluster); - /* create dos name */ - rc = create_dos_name(name, shortname); - if (rc < 0) - return rc * 10 - 0; + /* The "." and ".." directory entries must not be long names */ + if(dotdir) { + int i; + strncpy(shortname, name, 16); + for(i = strlen(shortname);i < 12;i++) + shortname[i] = ' '; + + entries_needed = 1; + } else { + /* create dos name */ + rc = create_dos_name(name, shortname); + if (rc < 0) + return rc * 10 - 0; - /* one dir entry needed for every 13 bytes of filename, - plus one entry for the short name */ - entries_needed = namelen / NAME_BYTES_PER_ENTRY + 1; - if (namelen % NAME_BYTES_PER_ENTRY) - entries_needed++; + /* one dir entry needed for every 13 bytes of filename, + plus one entry for the short name */ + entries_needed = namelen / NAME_BYTES_PER_ENTRY + 1; + if (namelen % NAME_BYTES_PER_ENTRY) + entries_needed++; + } restart: firstentry = 0; @@ -1065,7 +1078,7 @@ static int add_dir_entry(struct fat_dir* dir, firstentry, sector); rc = write_long_name(&dir->file, firstentry, - entries_needed, name, shortname); + entries_needed, name, shortname, is_directory); if (rc < 0) return rc * 10 - 5; @@ -1304,7 +1317,7 @@ int fat_create_file(char* name, int rc; LDEBUGF("fat_create_file(\"%s\",%x,%x)\n",name,file,dir); - rc = add_dir_entry(dir, file, name); + rc = add_dir_entry(dir, file, name, false, false); if (!rc) { file->firstcluster = 0; file->lastcluster = 0; @@ -1317,6 +1330,51 @@ int fat_create_file(char* name, return rc; } +int fat_create_dir(char* name, + struct fat_dir* newdir, + struct fat_dir* dir) +{ + int rc; + struct fat_file dummyfile; + + LDEBUGF("fat_create_dir(\"%s\",%x,%x)\n",name,newdir,dir); + + memset(newdir, sizeof(struct fat_dir), 0); + + /* First, add the entry in the parent directory */ + rc = add_dir_entry(dir, &newdir->file, name, true, false); + if (rc < 0) + return rc * 10 - 1; + + /* Then add the "." entry */ + rc = add_dir_entry(newdir, &dummyfile, ".", true, true); + if (rc < 0) + return rc * 10 - 2; + dummyfile.firstcluster = newdir->file.firstcluster; + update_short_entry(&dummyfile, 0, FAT_ATTR_DIRECTORY); + + /* and the ".." entry */ + rc = add_dir_entry(newdir, &dummyfile, "..", true, true); + if (rc < 0) + return rc * 10 - 3; + + /* The root cluster is cluster 0 in the ".." entry */ + if(dir->file.firstcluster == fat_bpb.bpb_rootclus) + dummyfile.firstcluster = 0; + else + dummyfile.firstcluster = dir->file.firstcluster; + update_short_entry(&dummyfile, 0, FAT_ATTR_DIRECTORY); + + /* Set the firstcluster field in the direntry */ + update_short_entry(&newdir->file, 0, FAT_ATTR_DIRECTORY); + + rc = flush_fat(); + if (rc < 0) + return rc * 10 - 4; + + return rc; +} + int fat_truncate(struct fat_file *file) { /* truncate trailing clusters */ @@ -1487,7 +1545,7 @@ int fat_rename(struct fat_file* file, return rc * 10 - 2; /* create new name */ - rc = add_dir_entry(&dir, &newfile, newname); + rc = add_dir_entry(&dir, &newfile, newname, false, false); if (rc < 0) return rc * 10 - 3; diff --git a/firmware/export/fat.h b/firmware/export/fat.h index 921f04eb8d..dbc0ab20cc 100644 --- a/firmware/export/fat.h +++ b/firmware/export/fat.h @@ -72,8 +72,9 @@ struct fat_dir extern int fat_mount(int startsector); extern void fat_size(unsigned int* size, unsigned int* free); extern void fat_recalc_free(void); - -extern int fat_create_dir(unsigned int currdir, char *name); +extern int fat_create_dir(char* name, + struct fat_dir* newdir, + struct fat_dir* dir); extern int fat_startsector(void); extern int fat_open(unsigned int cluster, struct fat_file* ent, diff --git a/firmware/test/fat/main.c b/firmware/test/fat/main.c index 9c1b983925..37ea2f49be 100644 --- a/firmware/test/fat/main.c +++ b/firmware/test/fat/main.c @@ -486,6 +486,21 @@ int dbg_trunc(char* name, int size) return close(fd); } +int dbg_mkdir(char* name) +{ + char text[BUFSIZE+1]; + int i; + int fd; + int x=0; + bool stop = false; + + fd = mkdir(name); + if (fd<0) { + DEBUGF("Failed creating directory\n"); + return -1; + } +} + int dbg_cmd(int argc, char *argv[]) { char* cmd = NULL; @@ -577,6 +592,13 @@ int dbg_cmd(int argc, char *argv[]) } } + if (!strcasecmp(cmd, "mkdir")) + { + if (arg1) { + return dbg_mkdir(arg1); + } + } + if (!strcasecmp(cmd, "del")) { if (arg1) diff --git a/firmware/test/fat/test.sh b/firmware/test/fat/test.sh index 44ff6bb849..9b1036b69c 100644 --- a/firmware/test/fat/test.sh +++ b/firmware/test/fat/test.sh @@ -38,9 +38,20 @@ buildimage() { runtests() { rm $RESULT + echo ---Test: create a long name directory in the root + try mkdir "/very long subdir name" + check + try mkdir "/very long subdir name/apa.monkey.me.now" + check + + echo ---Test: create a directory called "dir" + try mkdir "/dir" + check + echo ---Test: create a 10K file try mkfile "/really long filenames rock" 10 check + try mkfile /dir/apa.monkey.me.now 10 check try chkfile "/really long filenames rock" 10 @@ -100,24 +111,34 @@ runtests() { } +echo "--------------------------------------" echo "Building test image (4 sector/cluster)" +echo "--------------------------------------" buildimage 4 runtests +echo "---------------------------------------" echo "Building test image (32 sectors/cluster)" +echo "---------------------------------------" buildimage 32 runtests +echo "--------------------------------------" echo "Building test image (1 sector/cluster)" +echo "--------------------------------------" buildimage 1 runtests +echo "--------------------------------------" echo "Building test image (8 sectors/cluster)" +echo "--------------------------------------" buildimage 8 runtests +echo "----------------------------------------" echo "Building test image (128 sectors/cluster)" +echo "----------------------------------------" buildimage 128 runtests -echo "== Test completed sucessfully ==" +echo "== Test completed successfully ==" -- cgit v1.2.3