summaryrefslogtreecommitdiff
path: root/firmware/drivers
diff options
context:
space:
mode:
authorBjörn Stenberg <bjorn@haxx.se>2002-11-19 12:48:50 +0000
committerBjörn Stenberg <bjorn@haxx.se>2002-11-19 12:48:50 +0000
commitc5f5be565ea5488b3c6ba18b4af7696ef0cd92b8 (patch)
tree4bb0853b28ed368f04472372331b2bce7df5418d /firmware/drivers
parentfde9b57f7010369800d56b6b2eb98e6593236e13 (diff)
downloadrockbox-c5f5be565ea5488b3c6ba18b4af7696ef0cd92b8.zip
rockbox-c5f5be565ea5488b3c6ba18b4af7696ef0cd92b8.tar.gz
rockbox-c5f5be565ea5488b3c6ba18b4af7696ef0cd92b8.tar.bz2
rockbox-c5f5be565ea5488b3c6ba18b4af7696ef0cd92b8.tar.xz
Added rename()
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@2857 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/drivers')
-rw-r--r--firmware/drivers/fat.c159
-rw-r--r--firmware/drivers/fat.h3
2 files changed, 109 insertions, 53 deletions
diff --git a/firmware/drivers/fat.c b/firmware/drivers/fat.c
index 2ff36e2..b6bedc1 100644
--- a/firmware/drivers/fat.c
+++ b/firmware/drivers/fat.c
@@ -1175,6 +1175,68 @@ int fat_closewrite(struct fat_file *file, int size)
return 0;
}
+static int free_direntries(int dircluster, int startentry, int numentries)
+{
+ unsigned char buf[SECTOR_SIZE];
+ struct fat_file dir;
+ unsigned int entry = startentry - numentries + 1;
+ unsigned int sector = entry / DIR_ENTRIES_PER_SECTOR;
+ int i;
+ int err;
+
+ /* create a temporary file handle for the dir holding this file */
+ err = fat_open(dircluster, &dir, NULL);
+ if (err<0)
+ return -1;
+
+ err = fat_seek( &dir, sector );
+ if (err<0)
+ return -2;
+
+ err = fat_readwrite(&dir, 1, buf, false);
+ if (err<1)
+ return -3;
+
+ for (i=0; i < numentries; i++) {
+ LDEBUGF("Clearing dir entry %d (%d/%d)\n",
+ entry, i+1, numentries);
+ buf[(entry % DIR_ENTRIES_PER_SECTOR) * DIR_ENTRY_SIZE] = 0xe5;
+ entry++;
+
+ if ( (entry % DIR_ENTRIES_PER_SECTOR) == 0 ) {
+ /* flush this sector */
+ err = fat_seek(&dir, sector);
+ if (err<0)
+ return -4;
+
+ err = fat_readwrite(&dir, 1, buf, true);
+ if (err<1)
+ return -5;
+
+ if ( i+1 < numentries ) {
+ /* read next sector */
+ err = fat_readwrite(&dir, 1, buf, false);
+ if (err<1)
+ return -6;
+ }
+ sector++;
+ }
+ }
+
+ if ( entry % DIR_ENTRIES_PER_SECTOR ) {
+ /* flush this sector */
+ err = fat_seek(&dir, sector);
+ if (err<0)
+ return -7;
+
+ err = fat_readwrite(&dir, 1, buf, true);
+ if (err<1)
+ return -8;
+ }
+
+ return 0;
+}
+
int fat_remove(struct fat_file* file)
{
int next, last = file->firstcluster;
@@ -1187,68 +1249,59 @@ int fat_remove(struct fat_file* file)
last = next;
}
- /* free all dir entries */
- if ( file->dircluster ) {
- unsigned char buf[SECTOR_SIZE];
- struct fat_file dir;
- unsigned int entry = file->direntry - file->direntries + 1;
- unsigned int sector = entry / DIR_ENTRIES_PER_SECTOR;
- unsigned int i;
- int err;
-
- /* create a temporary file handle for the dir holding this file */
- err = fat_open(file->dircluster, &dir, NULL);
- if (err<0)
+ if ( file->dircluster )
+ if ( free_direntries(file->dircluster,
+ file->direntry,
+ file->direntries) < 0 )
return -1;
- err = fat_seek( &dir, sector );
- if (err<0)
- return -2;
+ file->firstcluster = 0;
+ file->dircluster = 0;
- err = fat_readwrite(&dir, 1, buf, false);
- if (err<1)
- return -3;
+ return 0;
+}
- for (i=0; i < file->direntries; i++) {
- LDEBUGF("Clearing dir entry %d (%d/%d)\n",
- entry, i+1, file->direntries);
- buf[(entry % DIR_ENTRIES_PER_SECTOR) * DIR_ENTRY_SIZE] = 0xe5;
- entry++;
+int fat_rename(struct fat_file* file,
+ unsigned char* newname,
+ int size)
+{
+ int err;
+ struct fat_dir dir;
+ struct fat_file newfile = *file;
- if ( (entry % DIR_ENTRIES_PER_SECTOR) == 0 ) {
- /* flush this sector */
- err = fat_seek(&dir, sector);
- if (err<0)
- return -4;
+ if ( !file->dircluster ) {
+ LDEBUGF("File has no dir cluster!\n");
+ return -1;
+ }
- err = fat_readwrite(&dir, 1, buf, true);
- if (err<1)
- return -5;
+ /* create a temporary file handle */
+ LDEBUGF("create a temporary file handle: fat_opendir(%x,%x)\n",
+ &dir, file->dircluster);
+ err = fat_opendir(&dir, file->dircluster);
+ if (err<0)
+ return -2;
- if ( i+1 < file->direntries ) {
- /* read next sector */
- err = fat_readwrite(&dir, 1, buf, false);
- if (err<1)
- return -6;
- }
- sector++;
- }
- }
+ /* create new name */
+ LDEBUGF("create new name\n");
+ err = add_dir_entry(&dir, &newfile, newname);
+ if (err<0)
+ return -3;
- if ( entry % DIR_ENTRIES_PER_SECTOR ) {
- /* flush this sector */
- err = fat_seek(&dir, sector);
- if (err<0)
- return -7;
-
- err = fat_readwrite(&dir, 1, buf, true);
- if (err<1)
- return -8;
- }
- }
+ /* write size and cluster link */
+ LDEBUGF("write size and cluster link\n");
+ err = update_file_size(&newfile, size);
+ if (err<0)
+ return -4;
- file->firstcluster = 0;
- file->dircluster = 0;
+ /* remove old name */
+ LDEBUGF("remove old name\n");
+ err = free_direntries(file->dircluster, file->direntry, file->direntries);
+ if (err<0)
+ return -5;
+
+ err = flush_fat();
+ if (err<0)
+ return -6;
return 0;
}
diff --git a/firmware/drivers/fat.h b/firmware/drivers/fat.h
index a5abfd5..d81ec65 100644
--- a/firmware/drivers/fat.h
+++ b/firmware/drivers/fat.h
@@ -84,6 +84,9 @@ extern int fat_closewrite(struct fat_file *ent, int size);
extern int fat_seek(struct fat_file *ent, unsigned int sector );
extern int fat_remove(struct fat_file *ent);
extern int fat_truncate(struct fat_file *ent);
+extern int fat_rename(struct fat_file* file,
+ unsigned char* newname,
+ int size);
extern int fat_opendir(struct fat_dir *ent, unsigned int currdir);
extern int fat_getnext(struct fat_dir *ent, struct fat_direntry *entry);