summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinus Nielsen Feltzing <linus@haxx.se>2004-01-15 14:30:59 +0000
committerLinus Nielsen Feltzing <linus@haxx.se>2004-01-15 14:30:59 +0000
commit60b1c4bbe1099980ced1f69a9a51674f6e05dd3e (patch)
treef09a4c07a72df14c8c217c7457acd66269aa45d3
parenta73cc6afa2c6f5c244aa1ecc1acfa0f6b6fb6422 (diff)
downloadrockbox-60b1c4bbe1099980ced1f69a9a51674f6e05dd3e.tar.gz
rockbox-60b1c4bbe1099980ced1f69a9a51674f6e05dd3e.zip
Implemented the mkdir() function in the FAT32 driver
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@4238 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--firmware/common/dir.c52
-rw-r--r--firmware/drivers/fat.c88
-rw-r--r--firmware/export/fat.h5
-rw-r--r--firmware/test/fat/main.c22
-rw-r--r--firmware/test/fat/test.sh23
5 files changed, 172 insertions, 18 deletions
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)
114 114
115 return theent; 115 return theent;
116} 116}
117
118int mkdir(char *name)
119{
120 DIR *dir;
121 char namecopy[MAX_PATH];
122 char* end;
123 char *basename;
124 char *parent;
125 struct dirent *entry;
126 struct fat_dir newdir;
127 int rc;
128
129 if ( name[0] != '/' ) {
130 DEBUGF("Only absolute paths supported right now\n");
131 return -1;
132 }
133
134 strncpy(namecopy,name,sizeof(namecopy));
135 namecopy[sizeof(namecopy)-1] = 0;
136
137 /* Split the base name and the path */
138 end = strrchr(namecopy, '/');
139 *end = 0;
140 basename = end+1;
141
142 if(namecopy == end) /* Root dir? */
143 parent = "/";
144 else
145 parent = namecopy;
146
147 DEBUGF("mkdir: parent: %s, name: %s\n", parent, basename);
148
149 dir = opendir(parent);
150
151 if(!dir) {
152 DEBUGF("mkdir: can't open parent dir\n");
153 return -2;
154 }
155
156 /* Now check if the name already exists */
157 while ((entry = readdir(dir))) {
158 if ( !strcasecmp(basename, entry->d_name) ) {
159 DEBUGF("mkdir error: file exists\n");
160 errno = EEXIST;
161 return - 3;
162 }
163 }
164
165 rc = fat_create_dir(basename, &newdir, &(dir->fatdir));
166
167 return rc;
168}
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,
811 unsigned int firstentry, 811 unsigned int firstentry,
812 unsigned int numentries, 812 unsigned int numentries,
813 unsigned char* name, 813 unsigned char* name,
814 unsigned char* shortname) 814 unsigned char* shortname,
815 bool is_directory)
815{ 816{
816 unsigned char buf[SECTOR_SIZE]; 817 unsigned char buf[SECTOR_SIZE];
817 unsigned char* entry; 818 unsigned char* entry;
@@ -918,7 +919,7 @@ static int write_long_name(struct fat_file* file,
918 unsigned short date=0, time=0, tenth=0; 919 unsigned short date=0, time=0, tenth=0;
919 LDEBUGF("Shortname entry: %.13s\n", shortname); 920 LDEBUGF("Shortname entry: %.13s\n", shortname);
920 strncpy(entry + FATDIR_NAME, shortname, 11); 921 strncpy(entry + FATDIR_NAME, shortname, 11);
921 entry[FATDIR_ATTR] = 0; 922 entry[FATDIR_ATTR] = is_directory?FAT_ATTR_DIRECTORY:0;
922 entry[FATDIR_NTRES] = 0; 923 entry[FATDIR_NTRES] = 0;
923 924
924 fat_time(&date, &time, &tenth); 925 fat_time(&date, &time, &tenth);
@@ -947,7 +948,9 @@ static int write_long_name(struct fat_file* file,
947 948
948static int add_dir_entry(struct fat_dir* dir, 949static int add_dir_entry(struct fat_dir* dir,
949 struct fat_file* file, 950 struct fat_file* file,
950 char* name) 951 char* name,
952 bool is_directory,
953 bool dotdir)
951{ 954{
952 unsigned char buf[SECTOR_SIZE]; 955 unsigned char buf[SECTOR_SIZE];
953 unsigned char shortname[16]; 956 unsigned char shortname[16];
@@ -963,16 +966,26 @@ static int add_dir_entry(struct fat_dir* dir,
963 LDEBUGF( "add_dir_entry(%s,%x)\n", 966 LDEBUGF( "add_dir_entry(%s,%x)\n",
964 name, file->firstcluster); 967 name, file->firstcluster);
965 968
966 /* create dos name */ 969 /* The "." and ".." directory entries must not be long names */
967 rc = create_dos_name(name, shortname); 970 if(dotdir) {
968 if (rc < 0) 971 int i;
969 return rc * 10 - 0; 972 strncpy(shortname, name, 16);
973 for(i = strlen(shortname);i < 12;i++)
974 shortname[i] = ' ';
975
976 entries_needed = 1;
977 } else {
978 /* create dos name */
979 rc = create_dos_name(name, shortname);
980 if (rc < 0)
981 return rc * 10 - 0;
970 982
971 /* one dir entry needed for every 13 bytes of filename, 983 /* one dir entry needed for every 13 bytes of filename,
972 plus one entry for the short name */ 984 plus one entry for the short name */
973 entries_needed = namelen / NAME_BYTES_PER_ENTRY + 1; 985 entries_needed = namelen / NAME_BYTES_PER_ENTRY + 1;
974 if (namelen % NAME_BYTES_PER_ENTRY) 986 if (namelen % NAME_BYTES_PER_ENTRY)
975 entries_needed++; 987 entries_needed++;
988 }
976 989
977 restart: 990 restart:
978 firstentry = 0; 991 firstentry = 0;
@@ -1065,7 +1078,7 @@ static int add_dir_entry(struct fat_dir* dir,
1065 firstentry, sector); 1078 firstentry, sector);
1066 1079
1067 rc = write_long_name(&dir->file, firstentry, 1080 rc = write_long_name(&dir->file, firstentry,
1068 entries_needed, name, shortname); 1081 entries_needed, name, shortname, is_directory);
1069 if (rc < 0) 1082 if (rc < 0)
1070 return rc * 10 - 5; 1083 return rc * 10 - 5;
1071 1084
@@ -1304,7 +1317,7 @@ int fat_create_file(char* name,
1304 int rc; 1317 int rc;
1305 1318
1306 LDEBUGF("fat_create_file(\"%s\",%x,%x)\n",name,file,dir); 1319 LDEBUGF("fat_create_file(\"%s\",%x,%x)\n",name,file,dir);
1307 rc = add_dir_entry(dir, file, name); 1320 rc = add_dir_entry(dir, file, name, false, false);
1308 if (!rc) { 1321 if (!rc) {
1309 file->firstcluster = 0; 1322 file->firstcluster = 0;
1310 file->lastcluster = 0; 1323 file->lastcluster = 0;
@@ -1317,6 +1330,51 @@ int fat_create_file(char* name,
1317 return rc; 1330 return rc;
1318} 1331}
1319 1332
1333int fat_create_dir(char* name,
1334 struct fat_dir* newdir,
1335 struct fat_dir* dir)
1336{
1337 int rc;
1338 struct fat_file dummyfile;
1339
1340 LDEBUGF("fat_create_dir(\"%s\",%x,%x)\n",name,newdir,dir);
1341
1342 memset(newdir, sizeof(struct fat_dir), 0);
1343
1344 /* First, add the entry in the parent directory */
1345 rc = add_dir_entry(dir, &newdir->file, name, true, false);
1346 if (rc < 0)
1347 return rc * 10 - 1;
1348
1349 /* Then add the "." entry */
1350 rc = add_dir_entry(newdir, &dummyfile, ".", true, true);
1351 if (rc < 0)
1352 return rc * 10 - 2;
1353 dummyfile.firstcluster = newdir->file.firstcluster;
1354 update_short_entry(&dummyfile, 0, FAT_ATTR_DIRECTORY);
1355
1356 /* and the ".." entry */
1357 rc = add_dir_entry(newdir, &dummyfile, "..", true, true);
1358 if (rc < 0)
1359 return rc * 10 - 3;
1360
1361 /* The root cluster is cluster 0 in the ".." entry */
1362 if(dir->file.firstcluster == fat_bpb.bpb_rootclus)
1363 dummyfile.firstcluster = 0;
1364 else
1365 dummyfile.firstcluster = dir->file.firstcluster;
1366 update_short_entry(&dummyfile, 0, FAT_ATTR_DIRECTORY);
1367
1368 /* Set the firstcluster field in the direntry */
1369 update_short_entry(&newdir->file, 0, FAT_ATTR_DIRECTORY);
1370
1371 rc = flush_fat();
1372 if (rc < 0)
1373 return rc * 10 - 4;
1374
1375 return rc;
1376}
1377
1320int fat_truncate(struct fat_file *file) 1378int fat_truncate(struct fat_file *file)
1321{ 1379{
1322 /* truncate trailing clusters */ 1380 /* truncate trailing clusters */
@@ -1487,7 +1545,7 @@ int fat_rename(struct fat_file* file,
1487 return rc * 10 - 2; 1545 return rc * 10 - 2;
1488 1546
1489 /* create new name */ 1547 /* create new name */
1490 rc = add_dir_entry(&dir, &newfile, newname); 1548 rc = add_dir_entry(&dir, &newfile, newname, false, false);
1491 if (rc < 0) 1549 if (rc < 0)
1492 return rc * 10 - 3; 1550 return rc * 10 - 3;
1493 1551
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
72extern int fat_mount(int startsector); 72extern int fat_mount(int startsector);
73extern void fat_size(unsigned int* size, unsigned int* free); 73extern void fat_size(unsigned int* size, unsigned int* free);
74extern void fat_recalc_free(void); 74extern void fat_recalc_free(void);
75 75extern int fat_create_dir(char* name,
76extern int fat_create_dir(unsigned int currdir, char *name); 76 struct fat_dir* newdir,
77 struct fat_dir* dir);
77extern int fat_startsector(void); 78extern int fat_startsector(void);
78extern int fat_open(unsigned int cluster, 79extern int fat_open(unsigned int cluster,
79 struct fat_file* ent, 80 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)
486 return close(fd); 486 return close(fd);
487} 487}
488 488
489int dbg_mkdir(char* name)
490{
491 char text[BUFSIZE+1];
492 int i;
493 int fd;
494 int x=0;
495 bool stop = false;
496
497 fd = mkdir(name);
498 if (fd<0) {
499 DEBUGF("Failed creating directory\n");
500 return -1;
501 }
502}
503
489int dbg_cmd(int argc, char *argv[]) 504int dbg_cmd(int argc, char *argv[])
490{ 505{
491 char* cmd = NULL; 506 char* cmd = NULL;
@@ -577,6 +592,13 @@ int dbg_cmd(int argc, char *argv[])
577 } 592 }
578 } 593 }
579 594
595 if (!strcasecmp(cmd, "mkdir"))
596 {
597 if (arg1) {
598 return dbg_mkdir(arg1);
599 }
600 }
601
580 if (!strcasecmp(cmd, "del")) 602 if (!strcasecmp(cmd, "del"))
581 { 603 {
582 if (arg1) 604 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() {
38runtests() { 38runtests() {
39 rm $RESULT 39 rm $RESULT
40 40
41 echo ---Test: create a long name directory in the root
42 try mkdir "/very long subdir name"
43 check
44 try mkdir "/very long subdir name/apa.monkey.me.now"
45 check
46
47 echo ---Test: create a directory called "dir"
48 try mkdir "/dir"
49 check
50
41 echo ---Test: create a 10K file 51 echo ---Test: create a 10K file
42 try mkfile "/really long filenames rock" 10 52 try mkfile "/really long filenames rock" 10
43 check 53 check
54
44 try mkfile /dir/apa.monkey.me.now 10 55 try mkfile /dir/apa.monkey.me.now 10
45 check 56 check
46 try chkfile "/really long filenames rock" 10 57 try chkfile "/really long filenames rock" 10
@@ -100,24 +111,34 @@ runtests() {
100 111
101} 112}
102 113
114echo "--------------------------------------"
103echo "Building test image (4 sector/cluster)" 115echo "Building test image (4 sector/cluster)"
116echo "--------------------------------------"
104buildimage 4 117buildimage 4
105runtests 118runtests
106 119
120echo "---------------------------------------"
107echo "Building test image (32 sectors/cluster)" 121echo "Building test image (32 sectors/cluster)"
122echo "---------------------------------------"
108buildimage 32 123buildimage 32
109runtests 124runtests
110 125
126echo "--------------------------------------"
111echo "Building test image (1 sector/cluster)" 127echo "Building test image (1 sector/cluster)"
128echo "--------------------------------------"
112buildimage 1 129buildimage 1
113runtests 130runtests
114 131
132echo "--------------------------------------"
115echo "Building test image (8 sectors/cluster)" 133echo "Building test image (8 sectors/cluster)"
134echo "--------------------------------------"
116buildimage 8 135buildimage 8
117runtests 136runtests
118 137
138echo "----------------------------------------"
119echo "Building test image (128 sectors/cluster)" 139echo "Building test image (128 sectors/cluster)"
140echo "----------------------------------------"
120buildimage 128 141buildimage 128
121runtests 142runtests
122 143
123echo "== Test completed sucessfully ==" 144echo "== Test completed successfully =="