diff options
Diffstat (limited to 'firmware')
-rw-r--r-- | firmware/common/dir.c | 52 | ||||
-rw-r--r-- | firmware/drivers/fat.c | 88 | ||||
-rw-r--r-- | firmware/export/fat.h | 5 | ||||
-rw-r--r-- | firmware/test/fat/main.c | 22 | ||||
-rw-r--r-- | firmware/test/fat/test.sh | 23 |
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 | |||
118 | int 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 | ||
948 | static int add_dir_entry(struct fat_dir* dir, | 949 | static 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 | ||
1333 | int 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 | |||
1320 | int fat_truncate(struct fat_file *file) | 1378 | int 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 | |||
72 | extern int fat_mount(int startsector); | 72 | extern int fat_mount(int startsector); |
73 | extern void fat_size(unsigned int* size, unsigned int* free); | 73 | extern void fat_size(unsigned int* size, unsigned int* free); |
74 | extern void fat_recalc_free(void); | 74 | extern void fat_recalc_free(void); |
75 | 75 | extern int fat_create_dir(char* name, | |
76 | extern int fat_create_dir(unsigned int currdir, char *name); | 76 | struct fat_dir* newdir, |
77 | struct fat_dir* dir); | ||
77 | extern int fat_startsector(void); | 78 | extern int fat_startsector(void); |
78 | extern int fat_open(unsigned int cluster, | 79 | extern 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 | ||
489 | int 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 | |||
489 | int dbg_cmd(int argc, char *argv[]) | 504 | int 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() { | |||
38 | runtests() { | 38 | runtests() { |
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 | ||
114 | echo "--------------------------------------" | ||
103 | echo "Building test image (4 sector/cluster)" | 115 | echo "Building test image (4 sector/cluster)" |
116 | echo "--------------------------------------" | ||
104 | buildimage 4 | 117 | buildimage 4 |
105 | runtests | 118 | runtests |
106 | 119 | ||
120 | echo "---------------------------------------" | ||
107 | echo "Building test image (32 sectors/cluster)" | 121 | echo "Building test image (32 sectors/cluster)" |
122 | echo "---------------------------------------" | ||
108 | buildimage 32 | 123 | buildimage 32 |
109 | runtests | 124 | runtests |
110 | 125 | ||
126 | echo "--------------------------------------" | ||
111 | echo "Building test image (1 sector/cluster)" | 127 | echo "Building test image (1 sector/cluster)" |
128 | echo "--------------------------------------" | ||
112 | buildimage 1 | 129 | buildimage 1 |
113 | runtests | 130 | runtests |
114 | 131 | ||
132 | echo "--------------------------------------" | ||
115 | echo "Building test image (8 sectors/cluster)" | 133 | echo "Building test image (8 sectors/cluster)" |
134 | echo "--------------------------------------" | ||
116 | buildimage 8 | 135 | buildimage 8 |
117 | runtests | 136 | runtests |
118 | 137 | ||
138 | echo "----------------------------------------" | ||
119 | echo "Building test image (128 sectors/cluster)" | 139 | echo "Building test image (128 sectors/cluster)" |
140 | echo "----------------------------------------" | ||
120 | buildimage 128 | 141 | buildimage 128 |
121 | runtests | 142 | runtests |
122 | 143 | ||
123 | echo "== Test completed sucessfully ==" | 144 | echo "== Test completed successfully ==" |