Prepare new maemo release
[maemo-rb.git] / firmware / test / fat / main.c
blob756f326bb350a58e06975aae6b935d75ba702cb6
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <stdarg.h>
5 #include <time.h>
6 #include "fat.h"
7 #include "debug.h"
8 #include "disk.h"
9 #include "dir.h"
10 #include "file.h"
11 #include "ata.h"
12 #include "storage.h"
14 void dbg_dump_sector(int sec);
15 void dbg_dump_buffer(unsigned char *buf, int len, int offset);
16 void dbg_console(void);
18 void mutex_init(struct mutex* l) {}
19 void mutex_lock(struct mutex* l) {}
20 void mutex_unlock(struct mutex* l) {}
22 void panicf( char *fmt, ...)
24 va_list ap;
25 va_start( ap, fmt );
26 fprintf(stderr,"***PANIC*** ");
27 vfprintf(stderr, fmt, ap );
28 va_end( ap );
29 exit(1);
32 void debugf(const char *fmt, ...)
34 va_list ap;
35 va_start( ap, fmt );
36 fprintf(stderr,"DEBUGF: ");
37 vfprintf( stderr, fmt, ap );
38 va_end( ap );
41 void ldebugf(const char* file, int line, const char *fmt, ...)
43 va_list ap;
44 va_start( ap, fmt );
45 fprintf( stderr, "%s:%d ", file, line );
46 vfprintf( stderr, fmt, ap );
47 va_end( ap );
50 void dbg_dump_sector(int sec)
52 unsigned char buf[512];
54 storage_read_sectors(sec,1,buf);
55 DEBUGF("---< Sector %d >-----------------------------------------\n", sec);
56 dbg_dump_buffer(buf, 512, 0);
59 void dbg_dump_buffer(unsigned char *buf, int len, int offset)
61 int i, j;
62 unsigned char c;
63 unsigned char ascii[33];
65 for(i = 0;i < len/16;i++)
67 DEBUGF("%03x: ", i*16 + offset);
68 for(j = 0;j < 16;j++)
70 c = buf[i*16+j];
72 DEBUGF("%02x ", c);
73 if(c < 32 || c > 127)
75 ascii[j] = '.';
77 else
79 ascii[j] = c;
83 ascii[j] = 0;
84 DEBUGF("%s\n", ascii);
88 void dbg_dir(char* currdir)
90 DIR* dir;
91 struct dirent* entry;
93 dir = opendir(currdir);
94 if (dir)
96 while ( (entry = readdir(dir)) ) {
97 DEBUGF("%15s %lx\n", entry->d_name, entry->startcluster);
99 closedir(dir);
101 else
103 DEBUGF( "Could not open dir %s\n", currdir);
107 #define CHUNKSIZE 8
108 #define BUFSIZE 8192
110 int dbg_mkfile(char* name, int num)
112 char text[BUFSIZE+1];
113 int i;
114 int fd;
115 int x=0;
116 bool stop = false;
118 fd = creat(name,O_WRONLY);
119 if (fd<0) {
120 DEBUGF("Failed creating file\n");
121 return -1;
123 num *= 1024;
124 while ( num ) {
125 int rc;
126 int len = num > BUFSIZE ? BUFSIZE : num;
128 for (i=0; i<len/CHUNKSIZE; i++ )
129 sprintf(text+i*CHUNKSIZE,"%c%06x,",name[1],x++);
131 rc = write(fd, text, len);
132 if ( rc < 0 ) {
133 DEBUGF("Failed writing data\n");
134 return -1;
136 else
137 if ( rc == 0 ) {
138 DEBUGF("No space left\n");
139 return -2;
141 else
142 DEBUGF("wrote %d bytes\n",rc);
144 num -= len;
146 if ( !num ) {
147 if ( stop )
148 break;
150 /* add a random number of chunks to test byte-copy code */
151 num = ((int) rand() % SECTOR_SIZE) & ~7;
152 LDEBUGF("Adding random size %d\n",num);
153 stop = true;
157 return close(fd);
161 int dbg_chkfile(char* name, int size)
163 char text[81920];
164 int i;
165 int x=0;
166 int pos = 0;
167 int block=0;
168 int fd = open(name,O_RDONLY);
169 if (fd<0) {
170 DEBUGF("Failed opening file\n");
171 return -1;
174 size = lseek(fd, 0, SEEK_END);
175 DEBUGF("File is %d bytes\n", size);
176 /* random start position */
177 if ( size )
178 pos = ((int)rand() % size) & ~7;
179 lseek(fd, pos, SEEK_SET);
180 x = pos / CHUNKSIZE;
182 LDEBUGF("Check base is %x (%d)\n",x,pos);
184 while (1) {
185 int rc = read(fd, text, sizeof text);
186 DEBUGF("read %d bytes\n",rc);
187 if (rc < 0) {
188 panicf("Failed reading data\n");
190 else {
191 char tmp[CHUNKSIZE+1];
192 if (!rc)
193 break;
194 for (i=0; i<rc/CHUNKSIZE; i++ ) {
195 sprintf(tmp,"%c%06x,",name[1],x++);
196 if (strncmp(text+i*CHUNKSIZE,tmp,CHUNKSIZE)) {
197 int idx = pos + block*sizeof(text) + i*CHUNKSIZE;
198 DEBUGF("Mismatch in byte 0x%x (byte 0x%x of sector 0x%x)."
199 "\nExpected %.8s found %.8s\n",
200 idx, idx % SECTOR_SIZE, idx / SECTOR_SIZE,
201 tmp,
202 text+i*CHUNKSIZE);
203 DEBUGF("i=%x, idx=%x\n",i,idx);
204 dbg_dump_buffer(text+i*CHUNKSIZE - 0x20, 0x40, idx - 0x20);
205 return -1;
209 block++;
212 return close(fd);
215 int dbg_wrtest(char* name)
217 char text[81920];
218 int i;
219 int x=0;
220 int pos = 0;
221 int block=0;
222 int size, fd, rc;
223 char tmp[CHUNKSIZE+1];
225 fd = open(name,O_RDWR);
226 if (fd<0) {
227 DEBUGF("Failed opening file\n");
228 return -1;
231 size = lseek(fd, 0, SEEK_END);
232 DEBUGF("File is %d bytes\n", size);
233 /* random start position */
234 if ( size )
235 pos = ((int)rand() % size) & ~7;
236 rc = lseek(fd, pos, SEEK_SET);
237 if ( rc < 0 )
238 panicf("Failed seeking\n");
239 x = pos / CHUNKSIZE;
240 LDEBUGF("Check base is %x (%d)\n",x,pos);
242 sprintf(tmp,"%c%06x,",name[1],x++);
243 rc = write(fd, tmp, 8);
244 if ( rc < 0 )
245 panicf("Failed writing data\n");
247 if ( size )
248 pos = ((int)rand() % size) & ~7;
249 rc = lseek(fd, pos, SEEK_SET);
250 if ( rc < 0 )
251 panicf("Failed seeking\n");
252 x = pos / CHUNKSIZE;
253 LDEBUGF("Check base 2 is %x (%d)\n",x,pos);
255 while (1) {
256 rc = read(fd, text, sizeof text);
257 DEBUGF("read %d bytes\n",rc);
258 if (rc < 0) {
259 panicf("Failed reading data\n");
261 else {
262 if (!rc)
263 break;
264 for (i=0; i<rc/CHUNKSIZE; i++ ) {
265 sprintf(tmp,"%c%06x,",name[1],x++);
266 if (strncmp(text+i*CHUNKSIZE,tmp,CHUNKSIZE)) {
267 int idx = pos + block*sizeof(text) + i*CHUNKSIZE;
268 DEBUGF("Mismatch in byte 0x%x (byte 0x%x of sector 0x%x)."
269 "\nExpected %.8s found %.8s\n",
270 idx, idx % SECTOR_SIZE, idx / SECTOR_SIZE,
271 tmp,
272 text+i*CHUNKSIZE);
273 DEBUGF("i=%x, idx=%x\n",i,idx);
274 dbg_dump_buffer(text+i*CHUNKSIZE - 0x20, 0x40, idx - 0x20);
275 return -1;
279 block++;
282 return close(fd);
285 void dbg_type(char* name)
287 const int size = SECTOR_SIZE*5;
288 unsigned char buf[SECTOR_SIZE*5+1];
289 int fd,rc;
291 fd = open(name,O_RDONLY);
292 if (fd<0)
293 return;
294 DEBUGF("Got file descriptor %d\n",fd);
296 while ( 1 ) {
297 rc = read(fd, buf, size);
298 if( rc > 0 )
300 buf[size] = 0;
301 printf("%d: %.*s\n", rc, rc, buf);
303 else if ( rc == 0 ) {
304 DEBUGF("EOF\n");
305 break;
307 else
309 DEBUGF("Failed reading file: %d\n",rc);
310 break;
313 close(fd);
316 int dbg_append(char* name)
318 int x=0;
319 int size, fd, rc;
320 char tmp[CHUNKSIZE+1];
322 fd = open(name,O_RDONLY);
323 if (fd<0) {
324 DEBUGF("Failed opening file\n");
325 return -1;
328 size = lseek(fd, 0, SEEK_END);
329 DEBUGF("File is %d bytes\n", size);
330 x = size / CHUNKSIZE;
331 LDEBUGF("Check base is %x (%d)\n",x,size);
333 if (close(fd) < 0)
334 return -1;
336 fd = open(name,O_RDWR|O_APPEND);
337 if (fd<0) {
338 DEBUGF("Failed opening file\n");
339 return -1;
342 sprintf(tmp,"%c%06x,",name[1],x++);
343 rc = write(fd, tmp, 8);
344 if ( rc < 0 )
345 panicf("Failed writing data\n");
347 return close(fd);
350 int dbg_test(char* name)
352 int x=0;
353 int j;
354 int fd;
355 char text[BUFSIZE+1];
357 for (j=0; j<5; j++) {
358 int num = 40960;
360 fd = open(name,O_WRONLY|O_CREAT|O_APPEND, 0666);
361 if (fd<0) {
362 DEBUGF("Failed opening file\n");
363 return -1;
366 while ( num ) {
367 int rc, i;
368 int len = num > BUFSIZE ? BUFSIZE : num;
370 for (i=0; i<len/CHUNKSIZE; i++ )
371 sprintf(text+i*CHUNKSIZE,"%c%06x,",name[1],x++);
373 rc = write(fd, text, len);
374 if ( rc < 0 ) {
375 DEBUGF("Failed writing data\n");
376 return -1;
378 else
379 if ( rc == 0 ) {
380 DEBUGF("No space left\n");
381 return -2;
383 else
384 DEBUGF("wrote %d bytes\n",rc);
386 num -= len;
389 if (close(fd) < 0)
390 return -1;
393 return 0;
396 int dbg_dump(char* name, int offset)
398 char buf[SECTOR_SIZE];
400 int rc;
401 int fd = open(name,O_RDONLY);
402 if (fd<0) {
403 DEBUGF("Failed opening file\n");
404 return -1;
406 lseek(fd, offset, SEEK_SET);
407 rc = read(fd, buf, sizeof buf);
409 if ( rc < 0 )
410 panicf("Error reading data\n");
412 if (close(fd) < 0)
413 return -1;
415 dbg_dump_buffer(buf, rc, offset);
417 return 0;
420 void dbg_tail(char* name)
422 unsigned char buf[SECTOR_SIZE*5];
423 int fd,rc;
425 fd = open(name,O_RDONLY);
426 if (fd<0)
427 return;
428 DEBUGF("Got file descriptor %d\n",fd);
430 rc = lseek(fd,-512,SEEK_END);
431 if ( rc >= 0 ) {
432 rc = read(fd, buf, SECTOR_SIZE);
433 if( rc > 0 )
435 buf[rc]=0;
436 printf("%d:\n%s\n", (int)strlen(buf), buf);
438 else if ( rc == 0 ) {
439 DEBUGF("EOF\n");
441 else
443 DEBUGF("Failed reading file: %d\n",rc);
446 else {
447 perror("lseek");
450 close(fd);
453 int dbg_head(char* name)
455 unsigned char buf[SECTOR_SIZE*5];
456 int fd,rc;
458 fd = open(name,O_RDONLY);
459 if (fd<0)
460 return -1;
461 DEBUGF("Got file descriptor %d\n",fd);
463 rc = read(fd, buf, SECTOR_SIZE*3);
464 if( rc > 0 )
466 buf[rc]=0;
467 printf("%d:\n%s\n", (int)strlen(buf), buf);
469 else if ( rc == 0 ) {
470 DEBUGF("EOF\n");
472 else
474 DEBUGF("Failed reading file: %d\n",rc);
477 return close(fd);
480 int dbg_trunc(char* name, int size)
482 int fd,rc;
484 #if 1
485 fd = open(name,O_RDWR);
486 if (fd<0)
487 return -1;
489 rc = ftruncate(fd, size);
490 if (rc<0) {
491 DEBUGF("ftruncate(%d) failed\n", size);
492 return -2;
495 #else
496 fd = open(name,O_RDWR|O_TRUNC);
497 if (fd<0)
498 return -1;
500 rc = lseek(fd, size, SEEK_SET);
501 if (fd<0)
502 return -2;
503 #endif
505 return close(fd);
508 int dbg_mkdir(char* name)
510 int fd;
512 fd = mkdir(name);
513 if (fd<0) {
514 DEBUGF("Failed creating directory\n");
515 return -1;
517 return 0;
520 int dbg_cmd(int argc, char *argv[])
522 char* cmd = NULL;
523 char* arg1 = NULL;
524 char* arg2 = NULL;
526 if (argc > 1) {
527 cmd = argv[1];
528 if ( argc > 2 ) {
529 arg1 = argv[2];
530 if ( argc > 3 ) {
531 arg2 = argv[3];
535 else {
536 DEBUGF("usage: fat command [options]\n"
537 "commands:\n"
538 " dir <dir>\n"
539 " ds <sector> - display sector\n"
540 " type <file>\n"
541 " head <file>\n"
542 " tail <file>\n"
543 " mkfile <file> <size (KB)>\n"
544 " chkfile <file>\n"
545 " del <file>\n"
546 " rmdir <dir>\n"
547 " dump <file> <offset>\n"
548 " mkdir <dir>\n"
549 " trunc <file> <size>\n"
550 " wrtest <file>\n"
551 " append <file>\n"
552 " test <file>\n"
553 " ren <file> <newname>\n"
555 return -1;
558 if (!strcasecmp(cmd, "dir"))
560 if ( arg1 )
561 dbg_dir(arg1);
562 else
563 dbg_dir("/");
566 if (!strcasecmp(cmd, "ds"))
568 if ( arg1 ) {
569 DEBUGF("secnum: %ld\n", strtol(arg1, NULL, 0));
570 dbg_dump_sector(strtol(arg1, NULL, 0));
574 if (!strcasecmp(cmd, "type"))
576 if (arg1)
577 dbg_type(arg1);
580 if (!strcasecmp(cmd, "head"))
582 if (arg1)
583 return dbg_head(arg1);
586 if (!strcasecmp(cmd, "tail"))
588 if (arg1)
589 dbg_tail(arg1);
592 if (!strcasecmp(cmd, "mkfile"))
594 if (arg1) {
595 if (arg2)
596 return dbg_mkfile(arg1,strtol(arg2, NULL, 0));
597 else
598 return dbg_mkfile(arg1,1);
602 if (!strcasecmp(cmd, "chkfile"))
604 if (arg1) {
605 if (arg2)
606 return dbg_chkfile(arg1, strtol(arg2, NULL, 0));
607 else
608 return dbg_chkfile(arg1, 0);
612 if (!strcasecmp(cmd, "mkdir"))
614 if (arg1) {
615 return dbg_mkdir(arg1);
619 if (!strcasecmp(cmd, "del"))
621 if (arg1)
622 return remove(arg1);
625 if (!strcasecmp(cmd, "rmdir"))
627 if (arg1)
628 return rmdir(arg1);
631 if (!strcasecmp(cmd, "dump"))
633 if (arg1) {
634 if (arg2)
635 return dbg_dump(arg1, strtol(arg2, NULL, 0));
636 else
637 return dbg_dump(arg1, 0);
641 if (!strcasecmp(cmd, "wrtest"))
643 if (arg1)
644 return dbg_wrtest(arg1);
647 if (!strcasecmp(cmd, "append"))
649 if (arg1)
650 return dbg_append(arg1);
653 if (!strcasecmp(cmd, "test"))
655 if (arg1)
656 return dbg_test(arg1);
659 if (!strcasecmp(cmd, "trunc"))
661 if (arg1 && arg2)
662 return dbg_trunc(arg1, strtol(arg2, NULL, 0));
665 if (!strcasecmp(cmd, "ren"))
667 if (arg1 && arg2)
668 return rename(arg1, arg2);
671 return 0;
674 extern void ata_exit(void);
676 int main(int argc, char *argv[])
678 int rc,i;
679 struct partinfo* pinfo;
681 srand(clock());
683 if(ata_init()) {
684 DEBUGF("*** Warning! The disk is uninitialized\n");
685 return -1;
687 pinfo = disk_init();
688 if (!pinfo) {
689 DEBUGF("*** Failed reading partitions\n");
690 return -1;
693 for ( i=0; i<4; i++ ) {
694 if ( pinfo[i].type == PARTITION_TYPE_FAT32
695 #ifdef HAVE_FAT16SUPPORT
696 || pinfo[i].type == PARTITION_TYPE_FAT16
697 #endif
699 DEBUGF("*** Mounting at block %ld\n",pinfo[i].start);
700 rc = fat_mount(IF_MV2(0,) IF_MD2(0,) pinfo[i].start);
701 if(rc) {
702 DEBUGF("mount: %d",rc);
703 return -1;
705 break;
708 if ( i==4 ) {
709 if(fat_mount(IF_MV2(0,) IF_MD2(0,) 0)) {
710 DEBUGF("No FAT32 partition!");
711 return -1;
715 rc = dbg_cmd(argc, argv);
717 ata_exit();
719 if (rc)
720 DEBUGF("Return code: %d\n", rc);
722 return rc;