diff options
author | Jens Arnold <amiconn@rockbox.org> | 2005-02-16 20:45:56 +0000 |
---|---|---|
committer | Jens Arnold <amiconn@rockbox.org> | 2005-02-16 20:45:56 +0000 |
commit | dbf7f51cf26b75c5aa4fc7c5aa39535bfc4fec48 (patch) | |
tree | fdd7d0372b4b69f2e8097d062371a0aa835005d1 /firmware/drivers/fat.c | |
parent | 1c6b2513ea0114150447824df45e566d87fd06d9 (diff) |
Preserve the longname extension as much as possible for shortname creation. Randomise the last 4 chars of the name part instead, but only if there is a clash.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@5988 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/drivers/fat.c')
-rw-r--r-- | firmware/drivers/fat.c | 46 |
1 files changed, 37 insertions, 9 deletions
diff --git a/firmware/drivers/fat.c b/firmware/drivers/fat.c index 743e841646..b3da25cc4d 100644 --- a/firmware/drivers/fat.c +++ b/firmware/drivers/fat.c @@ -234,6 +234,7 @@ static int flush_fat(IF_MV_NONVOID(struct bpb* fat_bpb)); static int bpb_is_sane(IF_MV_NONVOID(struct bpb* fat_bpb)); static void *cache_fat_sector(IF_MV2(struct bpb* fat_bpb,) long secnum, bool dirty); static int create_dos_name(const unsigned char *name, unsigned char *newname); +static void randomize_dos_name(unsigned char *name); static unsigned long find_free_cluster(IF_MV2(struct bpb* fat_bpb,) unsigned long start); static int transfer(IF_MV2(struct bpb* fat_bpb,) unsigned long start, long count, char* buf, bool write ); @@ -1335,7 +1336,7 @@ static int add_dir_entry(struct fat_dir* dir, /* check that our intended shortname doesn't already exist */ if (!strncmp(shortname, buf + i * DIR_ENTRY_SIZE, 12)) { /* filename exists already. make a new one */ - snprintf(shortname+8, 4, "%03X", (unsigned)rand() & 0xfff); + randomize_dos_name(shortname); LDEBUGF("Duplicate shortname, changing to %s\n", shortname); @@ -1464,24 +1465,51 @@ unsigned char char2dos(unsigned char c) static int create_dos_name(const unsigned char *name, unsigned char *newname) { - int i,j; + int i; + unsigned char *ext; + + /* Find extension part */ + ext = strrchr(name, '.'); + if (ext == name) /* handle .dotnames */ + ext = NULL; /* Name part */ - for (i=0, j=0; name[i] && (j < 8); i++) + for (i = 0; *name && (!ext || name < ext) && (i < 8); name++) { - unsigned char c = char2dos(name[i]); + unsigned char c = char2dos(*name); if (c) - newname[j++] = toupper(c); + newname[i++] = toupper(c); } - while (j < 8) - newname[j++] = ' '; - /* Extension part */ - snprintf(newname+8, 4, "%03X", (unsigned)rand() & 0xfff); + /* Pad both name and extension */ + while (i < 11) + newname[i++] = ' '; + if (ext) + { /* Extension part */ + ext++; + for (i = 8; *ext && (i < 11); ext++) + { + unsigned char c = char2dos(*ext); + if (c) + newname[i++] = toupper(c); + } + } return 0; } +static void randomize_dos_name(unsigned char *name) +{ + int i; + unsigned char buf[5]; + + snprintf(buf, sizeof buf, "%04x", (unsigned)rand() & 0xffff); + + for (i = 0; (i < 4) && (name[i] != ' '); i++); + /* account for possible shortname length < 4 */ + memcpy(&name[i], buf, 4); +} + static int update_short_entry( struct fat_file* file, long size, int attr ) { unsigned char buf[SECTOR_SIZE]; |