summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBjörn Stenberg <bjorn@haxx.se>2002-05-07 16:01:53 +0000
committerBjörn Stenberg <bjorn@haxx.se>2002-05-07 16:01:53 +0000
commit4bd870360af595a3f90b9ccc5a09d1414fd654e9 (patch)
treefccdc0da07d36d858560129f9a3b4c66d4669943
parent44b1a21f17975c896fd41dfff2e128a81ca77fc3 (diff)
downloadrockbox-4bd870360af595a3f90b9ccc5a09d1414fd654e9.tar.gz
rockbox-4bd870360af595a3f90b9ccc5a09d1414fd654e9.zip
Added open/close/read. read() only works on whole sectors right now.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@498 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--firmware/common/dir.c1
-rw-r--r--firmware/common/dir.h1
-rw-r--r--firmware/common/file.c170
-rw-r--r--firmware/common/file.h7
-rw-r--r--firmware/test/fat/Makefile5
-rw-r--r--firmware/test/fat/main.c97
6 files changed, 230 insertions, 51 deletions
diff --git a/firmware/common/dir.c b/firmware/common/dir.c
index b0927c09c6..acc412c570 100644
--- a/firmware/common/dir.c
+++ b/firmware/common/dir.c
@@ -94,6 +94,7 @@ struct dirent* readdir(DIR* dir)
94 strncpy(theent.d_name, entry.name, sizeof( theent.d_name ) ); 94 strncpy(theent.d_name, entry.name, sizeof( theent.d_name ) );
95 theent.attribute = entry.attr; 95 theent.attribute = entry.attr;
96 theent.size = entry.filesize; 96 theent.size = entry.filesize;
97 theent.startcluster = entry.firstcluster;
97 98
98 return &theent; 99 return &theent;
99} 100}
diff --git a/firmware/common/dir.h b/firmware/common/dir.h
index e03d50901c..274c0b1ea4 100644
--- a/firmware/common/dir.h
+++ b/firmware/common/dir.h
@@ -32,6 +32,7 @@ struct dirent {
32 unsigned char d_name[256]; 32 unsigned char d_name[256];
33 int attribute; 33 int attribute;
34 int size; 34 int size;
35 int startcluster;
35}; 36};
36#endif 37#endif
37 38
diff --git a/firmware/common/file.c b/firmware/common/file.c
new file mode 100644
index 0000000000..86e1099918
--- /dev/null
+++ b/firmware/common/file.c
@@ -0,0 +1,170 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2002 by Björn Stenberg
11 *
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19#include <string.h>
20#include "file.h"
21#include "fat.h"
22#include "types.h"
23#include "dir.h"
24#include "debug.h"
25
26#define MAX_OPEN_FILES 4
27
28struct filedesc {
29 unsigned char sector[SECTOR_SIZE];
30 int offset;
31 struct fat_file fatfile;
32 bool busy;
33};
34
35static struct filedesc openfiles[MAX_OPEN_FILES];
36
37int open(char* pathname, int flags)
38{
39 DIR* dir;
40 struct dirent* entry;
41 int fd;
42 char* name;
43 int namelen;
44
45 if ( pathname[0] != '/' ) {
46 DEBUGF("'%s' is not an absolute path.\n",pathname);
47 DEBUGF("Only absolute pathnames supported at the moment\n");
48 return -1;
49 }
50
51 /* find a free file descriptor */
52 for ( fd=0; fd<MAX_OPEN_FILES; fd++ )
53 if ( !openfiles[fd].busy )
54 break;
55
56 if ( fd == MAX_OPEN_FILES ) {
57 DEBUGF("Too many files open\n");
58 return -1;
59 }
60
61 /* locate filename */
62 name=strrchr(pathname+1,'/');
63 if ( name ) {
64 *name = 0;
65 dir = opendir(pathname);
66 *name = '/';
67 name++;
68 }
69 else {
70 dir = opendir("/");
71 name = pathname+1;
72 }
73 if (!dir) {
74 DEBUGF("Failed opening dir\n");
75 return -1;
76 }
77
78 /* scan dir for name */
79 namelen = strlen(name);
80 while ((entry = readdir(dir))) {
81 if ( !strncmp(name, entry->d_name, namelen) ) {
82 fat_open(entry->startcluster, &(openfiles[fd].fatfile));
83 break;
84 }
85 else {
86 DEBUGF("entry: %s\n",entry->d_name);
87 }
88 }
89 closedir(dir);
90 if ( !entry ) {
91 DEBUGF("Couldn't find %s in %s\n",name,pathname);
92 /* fixme: we need to use proper error codes */
93 return -1;
94 }
95
96 openfiles[fd].offset = 0;
97 openfiles[fd].busy = TRUE;
98 return fd;
99}
100
101int close(int fd)
102{
103 openfiles[fd].busy = FALSE;
104 return 0;
105}
106
107int read(int fd, void* buf, int count)
108{
109 int sectors;
110 int nread=0;
111
112 /* are we in the middle of a cached sector? */
113 if ( openfiles[fd].offset ) {
114 if ( count > (SECTOR_SIZE - openfiles[fd].offset) ) {
115 memcpy( buf, openfiles[fd].sector,
116 SECTOR_SIZE - openfiles[fd].offset );
117 openfiles[fd].offset = 0;
118 nread = SECTOR_SIZE - openfiles[fd].offset;
119 count -= nread;
120 }
121 else {
122 memcpy( buf, openfiles[fd].sector, count );
123 openfiles[fd].offset += count;
124 nread = count;
125 count = 0;
126 }
127 }
128
129 /* read whole sectors right into the supplied buffer */
130 sectors = count / SECTOR_SIZE;
131 if ( sectors ) {
132 if ( fat_read(&(openfiles[fd].fatfile), sectors, buf+nread ) < 0 ) {
133 DEBUGF("Failed reading %d sectors\n",sectors);
134 return -1;
135 }
136 nread += sectors * SECTOR_SIZE;
137 count -= sectors * SECTOR_SIZE;
138 openfiles[fd].offset = 0;
139 }
140
141 /* trailing odd bytes? */
142 if ( count ) {
143 /* do we already have the sector cached? */
144 if ( count < (SECTOR_SIZE - openfiles[fd].offset) ) {
145 memcpy( buf + nread, openfiles[fd].sector, count );
146 openfiles[fd].offset += count;
147 nread += count;
148 count = 0;
149 }
150 else {
151 /* cache one sector and copy the trailing bytes */
152 if ( fat_read(&(openfiles[fd].fatfile), 1,
153 &(openfiles[fd].sector)) < 0 ) {
154 DEBUGF("Failed reading odd sector\n");
155 return -1;
156 }
157 memcpy( buf + nread, openfiles[fd].sector, count );
158 openfiles[fd].offset = nread;
159 nread += count;
160 }
161 }
162
163 return nread;
164}
165
166/*
167 * local variables:
168 * eval: (load-file "../rockbox-mode.el")
169 * end:
170 */
diff --git a/firmware/common/file.h b/firmware/common/file.h
index 58fb22d881..9d0d6f0501 100644
--- a/firmware/common/file.h
+++ b/firmware/common/file.h
@@ -33,14 +33,15 @@
33#ifndef SIMULATOR 33#ifndef SIMULATOR
34extern int open(char* pathname, int flags); 34extern int open(char* pathname, int flags);
35extern int close(int fd); 35extern int close(int fd);
36
37extern int read(int fd, void* buf, int count); 36extern int read(int fd, void* buf, int count);
38extern int write(int fd, void* buf, int count);
39
40extern int lseek(int fd, int offset, int whence); 37extern int lseek(int fd, int offset, int whence);
41 38
39#ifdef DISK_WRITE
40extern int write(int fd, void* buf, int count);
42extern int remove(char* pathname); 41extern int remove(char* pathname);
43extern int rename(char* oldname, char* newname); 42extern int rename(char* oldname, char* newname);
43#endif
44
44#else 45#else
45#ifdef WIN32 46#ifdef WIN32
46#include <io.h> 47#include <io.h>
diff --git a/firmware/test/fat/Makefile b/firmware/test/fat/Makefile
index 48bddb9630..bd6869e8e9 100644
--- a/firmware/test/fat/Makefile
+++ b/firmware/test/fat/Makefile
@@ -5,7 +5,7 @@ CFLAGS = -g -Wall -DTEST_FAT -I$(DRIVERS) -I$(FIRMWARE)/common -I$(FIRMWARE) -I.
5 5
6TARGET = fat 6TARGET = fat
7 7
8$(TARGET): fat.o ata-sim.o main.o disk.o debug.o dir.o 8$(TARGET): fat.o ata-sim.o main.o disk.o debug.o dir.o file.o
9 gcc -g -o fat $+ -lfl 9 gcc -g -o fat $+ -lfl
10 10
11fat.o: $(DRIVERS)/fat.c $(DRIVERS)/fat.h $(DRIVERS)/ata.h 11fat.o: $(DRIVERS)/fat.c $(DRIVERS)/fat.h $(DRIVERS)/ata.h
@@ -17,6 +17,9 @@ disk.o: $(FIRMWARE)/common/disk.c
17dir.o: $(FIRMWARE)/common/dir.c 17dir.o: $(FIRMWARE)/common/dir.c
18 $(CC) $(CFLAGS) -c $< -o $@ 18 $(CC) $(CFLAGS) -c $< -o $@
19 19
20file.o: $(FIRMWARE)/common/file.c
21 $(CC) $(CFLAGS) -c $< -o $@
22
20debug.o: $(FIRMWARE)/debug.c 23debug.o: $(FIRMWARE)/debug.c
21 $(CC) $(CFLAGS) -c $< -o $@ 24 $(CC) $(CFLAGS) -c $< -o $@
22 25
diff --git a/firmware/test/fat/main.c b/firmware/test/fat/main.c
index 13c30b2ed5..0cf06bdac3 100644
--- a/firmware/test/fat/main.c
+++ b/firmware/test/fat/main.c
@@ -6,6 +6,7 @@
6#include "debug.h" 6#include "debug.h"
7#include "disk.h" 7#include "disk.h"
8#include "dir.h" 8#include "dir.h"
9#include "file.h"
9 10
10void dbg_dump_sector(int sec); 11void dbg_dump_sector(int sec);
11void dbg_dump_buffer(unsigned char *buf); 12void dbg_dump_buffer(unsigned char *buf);
@@ -17,7 +18,7 @@ void dbg_dump_sector(int sec)
17 unsigned char buf[512]; 18 unsigned char buf[512];
18 19
19 ata_read_sectors(sec,1,buf); 20 ata_read_sectors(sec,1,buf);
20 printf("---< Sector %d >-----------------------------------------\n", sec); 21 DEBUGF("---< Sector %d >-----------------------------------------\n", sec);
21 dbg_dump_buffer(buf); 22 dbg_dump_buffer(buf);
22} 23}
23 24
@@ -33,7 +34,7 @@ void dbg_dump_buffer(unsigned char *buf)
33 { 34 {
34 c = buf[i*16+j]; 35 c = buf[i*16+j];
35 36
36 printf("%02x ", c); 37 DEBUGF("%02x ", c);
37 if(c < 32 || c > 127) 38 if(c < 32 || c > 127)
38 { 39 {
39 ascii[j] = '.'; 40 ascii[j] = '.';
@@ -45,39 +46,39 @@ void dbg_dump_buffer(unsigned char *buf)
45 } 46 }
46 47
47 ascii[j] = 0; 48 ascii[j] = 0;
48 printf("%s\n", ascii); 49 DEBUGF("%s\n", ascii);
49 } 50 }
50} 51}
51 52
52void dbg_print_bpb(struct bpb *bpb) 53void dbg_print_bpb(struct bpb *bpb)
53{ 54{
54 printf("bpb_oemname = \"%s\"\n", bpb->bs_oemname); 55 DEBUGF("bpb_oemname = \"%s\"\n", bpb->bs_oemname);
55 printf("bpb_bytspersec = %d\n", bpb->bpb_bytspersec); 56 DEBUGF("bpb_bytspersec = %d\n", bpb->bpb_bytspersec);
56 printf("bpb_secperclus = %d\n", bpb->bpb_secperclus); 57 DEBUGF("bpb_secperclus = %d\n", bpb->bpb_secperclus);
57 printf("bpb_rsvdseccnt = %d\n", bpb->bpb_rsvdseccnt); 58 DEBUGF("bpb_rsvdseccnt = %d\n", bpb->bpb_rsvdseccnt);
58 printf("bpb_numfats = %d\n", bpb->bpb_numfats); 59 DEBUGF("bpb_numfats = %d\n", bpb->bpb_numfats);
59 printf("bpb_rootentcnt = %d\n", bpb->bpb_rootentcnt); 60 DEBUGF("bpb_rootentcnt = %d\n", bpb->bpb_rootentcnt);
60 printf("bpb_totsec16 = %d\n", bpb->bpb_totsec16); 61 DEBUGF("bpb_totsec16 = %d\n", bpb->bpb_totsec16);
61 printf("bpb_media = %02x\n", bpb->bpb_media); 62 DEBUGF("bpb_media = %02x\n", bpb->bpb_media);
62 printf("bpb_fatsz16 = %d\n", bpb->bpb_fatsz16); 63 DEBUGF("bpb_fatsz16 = %d\n", bpb->bpb_fatsz16);
63 printf("bpb_secpertrk = %d\n", bpb->bpb_secpertrk); 64 DEBUGF("bpb_secpertrk = %d\n", bpb->bpb_secpertrk);
64 printf("bpb_numheads = %d\n", bpb->bpb_numheads); 65 DEBUGF("bpb_numheads = %d\n", bpb->bpb_numheads);
65 printf("bpb_hiddsec = %u\n", bpb->bpb_hiddsec); 66 DEBUGF("bpb_hiddsec = %u\n", bpb->bpb_hiddsec);
66 printf("bpb_totsec32 = %u\n", bpb->bpb_totsec32); 67 DEBUGF("bpb_totsec32 = %u\n", bpb->bpb_totsec32);
67 68
68 printf("bs_drvnum = %d\n", bpb->bs_drvnum); 69 DEBUGF("bs_drvnum = %d\n", bpb->bs_drvnum);
69 printf("bs_bootsig = %02x\n", bpb->bs_bootsig); 70 DEBUGF("bs_bootsig = %02x\n", bpb->bs_bootsig);
70 if(bpb->bs_bootsig == 0x29) 71 if(bpb->bs_bootsig == 0x29)
71 { 72 {
72 printf("bs_volid = %xl\n", bpb->bs_volid); 73 DEBUGF("bs_volid = %xl\n", bpb->bs_volid);
73 printf("bs_vollab = \"%s\"\n", bpb->bs_vollab); 74 DEBUGF("bs_vollab = \"%s\"\n", bpb->bs_vollab);
74 printf("bs_filsystype = \"%s\"\n", bpb->bs_filsystype); 75 DEBUGF("bs_filsystype = \"%s\"\n", bpb->bs_filsystype);
75 } 76 }
76 77
77 printf("bpb_fatsz32 = %u\n", bpb->bpb_fatsz32); 78 DEBUGF("bpb_fatsz32 = %u\n", bpb->bpb_fatsz32);
78 printf("last_word = %04x\n", bpb->last_word); 79 DEBUGF("last_word = %04x\n", bpb->last_word);
79 80
80 printf("fat_type = FAT32\n"); 81 DEBUGF("fat_type = FAT32\n");
81} 82}
82 83
83void dbg_dir(char* currdir) 84void dbg_dir(char* currdir)
@@ -88,38 +89,40 @@ void dbg_dir(char* currdir)
88 dir = opendir(currdir); 89 dir = opendir(currdir);
89 if (dir) 90 if (dir)
90 { 91 {
91 for ( entry = readdir(dir); 92 while ( (entry = readdir(dir)) ) {
92 entry; 93 DEBUGF("%15s (%d bytes)\n", entry->d_name, entry->size);
93 entry = readdir(dir) )
94 {
95 printf("%s (%08x)\n", entry->d_name, entry->size);
96 } 94 }
97 } 95 }
98 else 96 else
99 { 97 {
100 fprintf(stderr, "Could not open dir %s\n", currdir); 98 DEBUGF( "Could not open dir %s\n", currdir);
101 } 99 }
102 closedir(dir); 100 closedir(dir);
103} 101}
104 102
105void dbg_type(int cluster) 103void dbg_type(char* name)
106{ 104{
107 unsigned char buf[SECTOR_SIZE*5]; 105 unsigned char buf[SECTOR_SIZE*5];
108 struct fat_file ent; 106 int i,fd,rc;
109 int i;
110 107
111 fat_open(cluster,&ent); 108 fd = open(name,O_RDONLY);
109 if (fd<0)
110 return;
111 DEBUGF("Got file descriptor %d\n",fd);
112 112
113 for (i=0;i<5;i++) 113 for (i=0;i<5;i++) {
114 if(fat_read(&ent, 1, buf) >= 0) 114 rc = read(fd, buf, SECTOR_SIZE/3);
115 if( rc >= 0 )
115 { 116 {
116 buf[SECTOR_SIZE]=0; 117 buf[SECTOR_SIZE]=0;
117 printf("%s\n", buf); 118 DEBUGF("%d: %d\n", i, rc);
118 } 119 }
119 else 120 else
120 { 121 {
121 fprintf(stderr, "Could not read file on cluster %d\n", cluster); 122 DEBUGF("Failed reading file\n");
122 } 123 }
124 }
125 close(fd);
123} 126}
124 127
125char current_directory[256] = "\\"; 128char current_directory[256] = "\\";
@@ -127,7 +130,7 @@ int last_secnum = 0;
127 130
128void dbg_prompt(void) 131void dbg_prompt(void)
129{ 132{
130 printf("C:%s> ", current_directory); 133 DEBUGF("C:%s> ", current_directory);
131} 134}
132 135
133void dbg_console(void) 136void dbg_console(void)
@@ -173,19 +176,17 @@ void dbg_console(void)
173 { 176 {
174 last_secnum++; 177 last_secnum++;
175 } 178 }
176 printf("secnum: %d\n", last_secnum); 179 DEBUGF("secnum: %d\n", last_secnum);
177 dbg_dump_sector(last_secnum); 180 dbg_dump_sector(last_secnum);
178 continue; 181 continue;
179 } 182 }
180 183
181 if(!strcasecmp(s, "type")) 184 if(!strcasecmp(s, "type"))
182 { 185 {
183 int cluster = 0; 186 s = strtok(NULL, " \n");
184 if((s = strtok(NULL, " \n"))) 187 if (!s)
185 { 188 continue;
186 cluster = atoi(s); 189 dbg_type(s);
187 }
188 dbg_type(cluster);
189 continue; 190 continue;
190 } 191 }
191 192
@@ -196,6 +197,8 @@ void dbg_console(void)
196 } 197 }
197 } 198 }
198 } 199 }
200 else
201 quit = 1;
199 } 202 }
200} 203}
201 204