diff options
-rw-r--r-- | ChangeLog | 5 | ||||
-rw-r--r-- | TODO | 5 | ||||
-rw-r--r-- | libmpio/defs.h | 34 | ||||
-rw-r--r-- | libmpio/directory.c | 379 | ||||
-rw-r--r-- | libmpio/directory.h | 13 | ||||
-rw-r--r-- | libmpio/fat.c | 53 | ||||
-rw-r--r-- | libmpio/mpio.c | 38 | ||||
-rw-r--r-- | libmpio/mpio.h | 12 | ||||
-rw-r--r-- | mpiosh/callback.c | 63 | ||||
-rw-r--r-- | mpiosh/callback.h | 5 | ||||
-rw-r--r-- | mpiosh/global.c | 11 | ||||
-rw-r--r-- | mpiosh/readline.c | 6 |
12 files changed, 529 insertions, 95 deletions
@@ -1,3 +1,8 @@ +2003-04-07 Markus Germeier <mager@tzi.de> + * Mega-Update all over the place + initial support for directories + [BEWARE: this might have broken some things!!!] + 2003-04-06 Markus Germeier <mager@tzi.de> * libmpio/directory.c (mpio_dentry_put): Another 8.3 filename fix @@ -1,4 +1,4 @@ -$Id: TODO,v 1.18 2002/11/04 16:25:17 crunchy Exp $ +$Id: TODO,v 1.19 2003/04/06 23:09:19 germeier Exp $ * Kernel Module - the MPIO can no multitasking, so: @@ -24,6 +24,9 @@ $Id: TODO,v 1.18 2002/11/04 16:25:17 crunchy Exp $ * write code to fix defective CIS (??), MBR, PBR [DONE] - implement formating of internal memory (BEWARE !!!!) [DONE: BEWARE no config files are written!!!!] + - written config files file setting/permissions seem not + to be right for the newer players (CONFIG.DAT appears as + a playable track) * mpio_tool [is deprecated, use mpiosh] diff --git a/libmpio/defs.h b/libmpio/defs.h index 2e3d02d..0018591 100644 --- a/libmpio/defs.h +++ b/libmpio/defs.h @@ -1,7 +1,7 @@ /* -*- linux-c -*- */ /* - * $Id: defs.h,v 1.17 2003/04/04 09:25:38 germeier Exp $ + * $Id: defs.h,v 1.18 2003/04/06 23:09:20 germeier Exp $ * * Library for USB MPIO-* * @@ -73,7 +73,9 @@ typedef enum { FTYPE_CHAN = 0x00, FTYPE_OTHER = 'H', FTYPE_MEMO = 'M', FTYPE_WAV = 'V', - FTYPE_ENTRY = 'R' } mpio_filetype_t; + FTYPE_ENTRY = 'R', + FTYPE_DIR = 'D', + FTYPE_PLAIN = '-'} mpio_filetype_t; /* fixed filenames */ #define MPIO_CONFIG_FILE "CONFIG.DAT" @@ -129,6 +131,7 @@ typedef struct { char *msg; } mpio_error_t; +#define MPIO_OK 0 #define MPIO_ERR_FILE_NOT_FOUND -1 #define MPIO_ERR_NOT_ENOUGH_SPACE -2 #define MPIO_ERR_FILE_EXISTS -3 @@ -136,6 +139,10 @@ typedef struct { #define MPIO_ERR_READING_FILE -5 #define MPIO_ERR_PERMISSION_DENIED -6 #define MPIO_ERR_WRITING_FILE -7 +#define MPIO_ERR_DIR_TOO_LONG -8 +#define MPIO_ERR_DIR_NOT_FOUND -9 +#define MPIO_ERR_DIR_NOT_A_DIR -10 +#define MPIO_ERR_DIR_NAME_ERROR -11 /* internal errors, occur when UI has errors! */ #define MPIO_ERR_INT_STRING_INVALID -101 @@ -172,6 +179,22 @@ typedef struct { DWORD SumSector; } mpio_disk_phy_t; +/* */ + +struct mpio_directory_tx { + BYTE name[INFO_LINE]; + BYTE dir[BLOCK_SIZE]; + + BYTE *dentry; + + struct mpio_directory_tx *prev; + struct mpio_directory_tx *next; + +}; + +typedef struct mpio_directory_tx mpio_directory_t; + + /* view of a SmartMedia(tm) card */ typedef struct { BYTE id; @@ -198,6 +221,10 @@ typedef struct { int fat_nums; /* # of FATs */ BYTE * fat; /* *real FAT (like in block allocation :-) */ + /* needed for directory support */ + mpio_directory_t *root; /* root directory */ + mpio_directory_t *cdir; /* current directory */ + /* how many physical blocks are available * for internal memory is this value equal to max_cluster */ @@ -207,9 +234,6 @@ typedef struct { /* lookup table for phys.<->log. block mapping */ mpio_zonetable_t zonetable; - /* seems to be a fixed size according to the - Samsung documentation */ - BYTE dir[DIR_SIZE]; /* file index */ } mpio_smartmedia_t; diff --git a/libmpio/directory.c b/libmpio/directory.c index be1f00d..0dd8abd 100644 --- a/libmpio/directory.c +++ b/libmpio/directory.c @@ -1,6 +1,6 @@ /* * - * $Id: directory.c,v 1.15 2003/04/06 12:54:27 germeier Exp $ + * $Id: directory.c,v 1.16 2003/04/06 23:09:20 germeier Exp $ * * Library for USB MPIO-* * @@ -104,7 +104,90 @@ mpio_charset_set(mpio_t *m, BYTE *charset) return r; } +int +mpio_directory_init(mpio_t *m, mpio_mem_t mem, mpio_directory_t *dir, + WORD self, WORD parent) +{ + mpio_dir_entry_t *dentry; + + memset(dir->dir, 0, BLOCK_SIZE); + memset(dir->dir, 0x20, 11); + memset(dir->dir+0x20, 0x20, 11); + + dentry = (mpio_dir_entry_t *)dir->dir; + + strncpy(dentry->name, ". ", 8); + strncpy(dentry->ext, " ", 3); + dentry->start[0] = self & 0xff; + dentry->start[1] = self / 0x100; + dentry->attr = 0x10; + + dentry++; + strncpy(dentry->name, ".. ", 8); + strncpy(dentry->ext, " ", 3); + dentry->start[0] = parent & 0xff; + dentry->start[1] = parent / 0x100; + dentry->attr = 0x10; + + hexdumpn(2, dir->dir, 64); + + return 0; +} + + +int +mpio_directory_read(mpio_t *m, mpio_mem_t mem, mpio_directory_t *dir) +{ + mpio_fatentry_t *f = 0; + + f = mpio_dentry_get_startcluster(m, mem, dir->dentry); + + if (!f) + { + debug("something bad has happened here!"); + exit (-1); + } + + mpio_io_block_read(m, mem, f, dir->dir); + + hexdumpn(5, dir->dir, DIR_SIZE); + + return 0; +} + +int +mpio_directory_write(mpio_t *m, mpio_mem_t mem, mpio_directory_t *dir) +{ + mpio_fatentry_t *f = 0; + + f = mpio_dentry_get_startcluster(m, mem, dir->dentry); + if (!f) + { + debug("something bad has happened here!"); + exit (-1); + } + + if (mem==MPIO_INTERNAL_MEM) + { + f->i_fat[0x01]= f->i_index; + if (m->model >= MPIO_MODEL_FD100) + f->i_fat[0x0e] = f->i_index; + + /* only one block needed for directory */ + f->i_fat[0x02]=0; + f->i_fat[0x03]=1; + + /* set type to directory */ + f->i_fat[0x06] = FTYPE_ENTRY; + hexdumpn(0, f->i_fat, 16); + } + + mpio_io_block_delete(m, mem, f); + mpio_io_block_write(m, mem, f, dir->dir); + + return 0; +} /* directory operations */ BYTE * @@ -113,12 +196,12 @@ mpio_directory_open(mpio_t *m, mpio_mem_t mem) BYTE *out; if (mem == MPIO_EXTERNAL_MEM) { if (m->external.id) { - out = m->external.dir; + out = m->external.cdir->dir; } else { return NULL; } } else { - out = m->internal.dir; + out = m->internal.cdir->dir; } if (out[0] == 0x00) @@ -132,6 +215,192 @@ mpio_directory_open(mpio_t *m, mpio_mem_t mem) return out; } +int +mpio_directory_make(mpio_t *m, mpio_mem_t mem, BYTE *dir) +{ + mpio_smartmedia_t *sm; + mpio_directory_t *new; + mpio_fatentry_t *f, *current; + WORD self, parent; + struct tm tt; + + if (mem == MPIO_INTERNAL_MEM) sm = &m->internal; + if (mem == MPIO_EXTERNAL_MEM) sm = &m->external; + + if ((strcmp(dir, "..") == 0) || + (strcmp(dir, ".") == 0)) + { + debugn(2, "directory name not allowed: %s\n", dir); + return MPIO_ERR_DIR_NAME_ERROR; + } + + /* find free sector */ + f = mpio_fatentry_find_free(m, mem, FTYPE_ENTRY); + if (!f) + { + debug("could not free cluster for file!\n"); + return (MPIO_ERR_FAT_ERROR); + } else { + self=f->entry; + } + + /* find file-id for internal memory */ + if (mem==MPIO_INTERNAL_MEM) + { + f->i_index=mpio_fat_internal_find_fileindex(m); + debugn(2, "fileindex: %02x\n", f->i_index); + f->i_fat[0x01]= f->i_index; + if (m->model >= MPIO_MODEL_FD100) + f->i_fat[0x0e] = f->i_index; + self = f->i_index; + + /* only one block needed for directory */ + f->i_fat[0x02]=0; + f->i_fat[0x03]=1; + hexdumpn(0, f->i_fat, 16); + } + + if (sm->cdir == sm->root) + { + parent=0; + } else { + current = mpio_dentry_get_startcluster(m, mem, sm->cdir->dentry); + if (mem==MPIO_INTERNAL_MEM) + { + parent = current->i_index; + } else { + parent = current->entry; + } + } + + + new = malloc(sizeof(mpio_directory_t)); + mpio_directory_init(m, mem, new, self, parent); + + mpio_fatentry_set_eof(m ,mem, f); + mpio_io_block_write(m, mem, f, new->dir); + mpio_dentry_put(m, mem, + dir, strlen(dir), + mktime(&tt), + 0, self, 0x10); + + free(new); + + return MPIO_OK; +} + +int +mpio_directory_cd(mpio_t *m, mpio_mem_t mem, BYTE *dir) +{ + mpio_smartmedia_t *sm; + BYTE *p; + BYTE month, day, hour, minute, type; + BYTE fname[100]; + WORD year; + DWORD fsize; + int i, size; + BYTE pwd[INFO_LINE]; + mpio_directory_t *old, *new; + + if (strcmp(dir, ".")==0) + return MPIO_OK; + + if (mem == MPIO_INTERNAL_MEM) sm = &m->internal; + if (mem == MPIO_EXTERNAL_MEM) sm = &m->external; + + if (strcmp(dir, "..") == 0) + { + if (sm->cdir->prev) + { + old = sm->cdir; + sm->cdir = sm->cdir->prev; + sm->cdir->next = NULL; + free(old); + } + + return MPIO_OK; + } + + mpio_directory_pwd(m, mem, pwd); + + if ((strlen(pwd) + strlen(dir) + 2) > INFO_LINE) + { + debugn(2, "directory name gets to long!\n"); + return MPIO_ERR_DIR_TOO_LONG; + } + + + p = mpio_dentry_find_name(m, mem, dir); + + /* second try */ + if (!p) + p = mpio_dentry_find_name_8_3(m, mem, dir); + + if (!p) + { + debugn(2, "could not find directory: %s\n", dir); + return MPIO_ERR_DIR_NOT_FOUND; + } + + mpio_dentry_get(m, mem, p, + fname, 100, + &year, &month, &day, + &hour, &minute, &fsize, + &type); + + if (type != FTYPE_DIR) + { + debugn(2, "this is not a directory: %s\n", dir); + return MPIO_ERR_DIR_NOT_A_DIR; + } + + new = malloc(sizeof(mpio_directory_t)); + strcpy(new->name, dir); + new->next = NULL; + new->prev = sm->cdir; + new->dentry = p; + sm->cdir->next = new; + sm->cdir = new; + + mpio_directory_pwd(m, mem, pwd); + + if (strcmp(dir, "/") != 0) + { + /* read new directory */ + size=mpio_directory_read(m, mem, sm->cdir); + } + + return MPIO_OK; + +} + + +void +mpio_directory_pwd(mpio_t *m, mpio_mem_t mem, BYTE pwd[INFO_LINE]) +{ + mpio_smartmedia_t *sm; + mpio_directory_t *d; + + if (mem == MPIO_INTERNAL_MEM) sm = &m->internal; + if (mem == MPIO_EXTERNAL_MEM) sm = &m->external; + + d = sm->root->next; + pwd[0] = 0; + + if (!d) + strcat(pwd, "/"); + + while (d) + { + strcat(pwd, "/"); + debugn(2, "name: %s\n", d->name); + strcat(pwd, d->name); + d = d->next; + } + + return; +} + int mpio_dentry_get_size(mpio_t *m, mpio_mem_t mem, BYTE *buffer) { @@ -225,13 +494,13 @@ int mpio_dentry_get(mpio_t *m, mpio_mem_t mem, BYTE *buffer, BYTE *filename, int filename_size, WORD *year, BYTE *month, BYTE *day, - BYTE *hour, BYTE *minute, DWORD *fsize) + BYTE *hour, BYTE *minute, DWORD *fsize, BYTE *type) { BYTE filename_8_3[13]; return mpio_dentry_get_real(m, mem, buffer, filename, filename_size, filename_8_3, - year, month, day, hour, minute, fsize); + year, month, day, hour, minute, fsize, type); } /* TODO: please clean me up !!! */ @@ -240,7 +509,8 @@ mpio_dentry_get_real(mpio_t *m, mpio_mem_t mem, BYTE *buffer, BYTE *filename, int filename_size, BYTE *filename_8_3, WORD *year, BYTE *month, BYTE *day, - BYTE *hour, BYTE *minute, DWORD *fsize) + BYTE *hour, BYTE *minute, DWORD *fsize, + BYTE *type) { int date, time; int vfat = 0; @@ -319,12 +589,19 @@ mpio_dentry_get_real(mpio_t *m, mpio_mem_t mem, BYTE *buffer, i--; filename_8_3[i] = 0; hexdumpn(4, filename_8_3, 13); - + if (!vfat) { if (filename_size >= 12) { snprintf(filename, 13, "%s", filename_8_3); + /* UGLY !! */ + if (((strncmp(dentry->name, ". ", 8)==0) && + (strncmp(dentry->ext, " ", 3) == 0))) + filename[1]=0; + if (((strncmp(dentry->name, ".. ", 8)==0) && + (strncmp(dentry->ext, " ", 3) == 0))) + filename[2]=0; } else { snprintf(filename, filename_size, "%s", "ERROR"); } @@ -347,6 +624,13 @@ mpio_dentry_get_real(mpio_t *m, mpio_mem_t mem, BYTE *buffer, *fsize *= 0x100; *fsize += dentry->size[0]; + if (dentry->attr & 0x10) { + /* is this a directory? */ + *type = FTYPE_DIR; + } else { + *type = FTYPE_PLAIN; + } + return(((BYTE *)dentry) - buffer); } @@ -365,7 +649,7 @@ mpio_rootdir_read (mpio_t *m, mpio_mem_t mem) if (mpio_io_sector_read(m, mem, (sm->dir_offset + i), recvbuff)) return 1; - memcpy(sm->dir + (i * SECTOR_SIZE), recvbuff, SECTOR_SIZE); + memcpy(sm->root->dir + (i * SECTOR_SIZE), recvbuff, SECTOR_SIZE); } return (0); @@ -379,7 +663,7 @@ mpio_rootdir_clear (mpio_t *m, mpio_mem_t mem) if (mem == MPIO_INTERNAL_MEM) sm=&m->internal; if (mem == MPIO_EXTERNAL_MEM) sm=&m->external; - memset(sm->dir, 0x00, DIR_SIZE); + memset(sm->root->dir, 0x00, DIR_SIZE); return 0; } @@ -401,14 +685,18 @@ mpio_dentry_get_filesize(mpio_t *m, mpio_mem_t mem, BYTE *p) s -= DIR_ENTRY_SIZE ; } - fsize = dentry->size[3]; - fsize *= 0x100; - fsize += dentry->size[2]; - fsize *= 0x100; - fsize += dentry->size[1]; - fsize *= 0x100; - fsize += dentry->size[0]; - + if (dentry->attr & 0x10) { + fsize = BLOCK_SIZE; + } else { + fsize = dentry->size[3]; + fsize *= 0x100; + fsize += dentry->size[2]; + fsize *= 0x100; + fsize += dentry->size[1]; + fsize *= 0x100; + fsize += dentry->size[0]; + } + return fsize; } @@ -440,6 +728,7 @@ mpio_dentry_get_startcluster(mpio_t *m, mpio_mem_t mem, BYTE *p) { int s; DWORD cluster; + BYTE i_index; mpio_dir_slot_t *dentry; mpio_fatentry_t *new; @@ -456,7 +745,10 @@ mpio_dentry_get_startcluster(mpio_t *m, mpio_mem_t mem, BYTE *p) cluster = dentry->start[1] * 0x100 + dentry->start[0]; if (mem == MPIO_INTERNAL_MEM) - cluster = mpio_fat_internal_find_startsector(m, cluster); + { + i_index=dentry->start[0]; + cluster = mpio_fat_internal_find_startsector(m, cluster); + } if (cluster < 0) return NULL; @@ -465,8 +757,11 @@ mpio_dentry_get_startcluster(mpio_t *m, mpio_mem_t mem, BYTE *p) if (mem == MPIO_INTERNAL_MEM) { new->entry=cluster; + new->i_index=i_index; mpio_fatentry_entry2hw(m, new); } + + debugn(2,"i_index=0x%02x\n", new->i_index); return new; } @@ -474,7 +769,7 @@ mpio_dentry_get_startcluster(mpio_t *m, mpio_mem_t mem, BYTE *p) int mpio_dentry_put(mpio_t *m, mpio_mem_t mem, BYTE *filename, int filename_size, - time_t date, DWORD fsize, WORD ssector) + time_t date, DWORD fsize, WORD ssector, BYTE attr) { BYTE *unicode = 0; BYTE *back, *fback; @@ -505,9 +800,9 @@ mpio_dentry_put(mpio_t *m, mpio_mem_t mem, p += 0x20; } else { if (mem == MPIO_EXTERNAL_MEM) - p = m->external.dir; + p = m->external.cdir->dir; if (mem == MPIO_INTERNAL_MEM) - p = m->internal.dir; + p = m->internal.cdir->dir; } /* generate vfat filename in UNICODE */ @@ -621,7 +916,7 @@ mpio_dentry_put(mpio_t *m, mpio_mem_t mem, memcpy(dentry->name, f_8_3, 8); memcpy(dentry->ext, f_8_3+9, 3); - dentry->attr = 0x20; + dentry->attr = attr; dentry->lcase = 0x00; @@ -676,7 +971,7 @@ mpio_dentry_find_name_8_3(mpio_t *m, BYTE mem, BYTE *filename) fname, 128, fname_8_3, &wdummy, &bdummy, &bdummy, - &bdummy, &bdummy, &ddummy); + &bdummy, &bdummy, &ddummy, &bdummy); if ((strcmp(fname_8_3, filename) == 0) && (strcmp(filename,fname_8_3) == 0)) { found = p; @@ -704,7 +999,7 @@ mpio_dentry_find_name(mpio_t *m, BYTE mem, BYTE *filename) mpio_dentry_get (m, mem, p, fname, 128, &wdummy, &bdummy, &bdummy, - &bdummy, &bdummy, &ddummy); + &bdummy, &bdummy, &ddummy, &bdummy); if ((strcmp(fname,filename) == 0) && (strcmp(filename,fname) == 0)) { found = p; p = NULL; @@ -751,13 +1046,13 @@ mpio_dentry_delete(mpio_t *m, BYTE mem, BYTE *filename) /* clear new buffer */ memset(tmp, 0, DIR_SIZE); /* copy before delete */ - if (start != sm->dir) - memcpy(tmp, sm->dir, (start - (sm->dir))); + if (start != sm->cdir->dir) + memcpy(tmp, sm->cdir->dir, (start - (sm->cdir->dir))); /* copy after delete */ - memcpy(tmp + (start - (sm->dir)), (start + size), - (sm->dir + DIR_SIZE - (start + size))); + memcpy(tmp + (start - (sm->cdir->dir)), (start + size), + (sm->cdir->dir + DIR_SIZE - (start + size))); - memcpy(sm->dir, tmp, DIR_SIZE); + memcpy(sm->cdir->dir, tmp, DIR_SIZE); return 0; } @@ -789,7 +1084,7 @@ mpio_dentry_move(mpio_t *m,mpio_mem_t mem,BYTE *m_file,BYTE *a_file) { // -- if a_file == NULL this is the start of the directory. if(a_file==NULL) { - b_file = sm->dir; + b_file = sm->cdir->dir; } else { b_file = a_file + a_file_s; } @@ -805,8 +1100,8 @@ mpio_dentry_move(mpio_t *m,mpio_mem_t mem,BYTE *m_file,BYTE *a_file) { if(m_file > b_file) { fprintf(stderr,"U "); - t0 = sm->dir; - s0 = b_file - sm->dir; + t0 = sm->cdir->dir; + s0 = b_file - sm->cdir->dir; t1 = m_file; s1 = m_file_s; @@ -815,11 +1110,11 @@ mpio_dentry_move(mpio_t *m,mpio_mem_t mem,BYTE *m_file,BYTE *a_file) { s2 = m_file - b_file; t3 = m_file + m_file_s; - s3 = DIR_SIZE - (m_file-sm->dir) - m_file_s; + s3 = DIR_SIZE - (m_file-sm->cdir->dir) - m_file_s; } else { fprintf(stderr,"D "); - t0 = sm->dir; - s0 = m_file - sm->dir; + t0 = sm->cdir->dir; + s0 = m_file - sm->cdir->dir; t1 = m_file + m_file_s; s1 = a_file + a_file_s - (m_file + m_file_s); @@ -828,7 +1123,7 @@ mpio_dentry_move(mpio_t *m,mpio_mem_t mem,BYTE *m_file,BYTE *a_file) { s2 = m_file_s; t3 = b_file; - s3 = DIR_SIZE - (b_file - sm->dir); + s3 = DIR_SIZE - (b_file - sm->cdir->dir); } if(s0) { @@ -850,7 +1145,7 @@ mpio_dentry_move(mpio_t *m,mpio_mem_t mem,BYTE *m_file,BYTE *a_file) { fprintf(stderr," -- t0=%ld, s0=%d, t1=%ld, s1=%d, t2=%ld, s2=%d, t3=%ld, s3=%d; sum=%d, DIRSIZE=%d\n", (long)t0,s0,(long)t1,s1,(long)t2,s2,(long)t3,s3,s0+s1+s2+s3,DIR_SIZE); - memcpy(sm->dir, tmp, DIR_SIZE); + memcpy(sm->cdir->dir, tmp, DIR_SIZE); } void @@ -882,10 +1177,10 @@ mpio_dentry_switch(mpio_t *m, mpio_mem_t mem, BYTE *file1, BYTE *file2) current = tmp; memset(tmp, 0xff, DIR_SIZE); /* before the first file */ - if (p1 != sm->dir) + if (p1 != sm->cdir->dir) { - memcpy(current, sm->dir, p1 - sm->dir); - current += (p1 - sm->dir); + memcpy(current, sm->cdir->dir, p1 - sm->cdir->dir); + current += (p1 - sm->cdir->dir); } /* the second file*/ memcpy(current, p2, size2); @@ -897,10 +1192,10 @@ mpio_dentry_switch(mpio_t *m, mpio_mem_t mem, BYTE *file1, BYTE *file2) memcpy(current, p1, size1); current += size1; /* and the rest */ - memcpy(current, p2+size2, (sm->dir+DIR_SIZE-p2-size2)); + memcpy(current, p2+size2, (sm->cdir->dir+DIR_SIZE-p2-size2)); /* really update the directory */ - memcpy(sm->dir, tmp, DIR_SIZE); + memcpy(sm->cdir->dir, tmp, DIR_SIZE); return; } diff --git a/libmpio/directory.h b/libmpio/directory.h index 6e54a04..8281bfa 100644 --- a/libmpio/directory.h +++ b/libmpio/directory.h @@ -1,6 +1,6 @@ /* * - * $Id: directory.h,v 1.7 2003/02/21 18:28:55 crunchy Exp $ + * $Id: directory.h,v 1.8 2003/04/06 23:09:20 germeier Exp $ * * Library for USB MPIO-* * @@ -38,11 +38,17 @@ int mpio_rootdir_read (mpio_t *, mpio_mem_t); int mpio_rootdir_clear (mpio_t *, mpio_mem_t); int mpio_rootdir_format(mpio_t *, mpio_mem_t); +/* directory opertations */ +int mpio_directory_init(mpio_t *, mpio_mem_t, mpio_directory_t *, + WORD, WORD); +int mpio_directory_read(mpio_t *, mpio_mem_t, mpio_directory_t *); +int mpio_directory_write(mpio_t *, mpio_mem_t, mpio_directory_t *); + /* operations on a single directory entry */ int mpio_dentry_get_size(mpio_t *, mpio_mem_t, BYTE *); int mpio_dentry_get_raw(mpio_t *, mpio_mem_t, BYTE *, BYTE *, int); int mpio_dentry_put(mpio_t *, mpio_mem_t, BYTE *, int, - time_t, DWORD, WORD); + time_t, DWORD, WORD, BYTE); BYTE * mpio_dentry_find_name_8_3(mpio_t *, BYTE, BYTE *); BYTE * mpio_dentry_find_name(mpio_t *, BYTE, BYTE *); int mpio_dentry_delete(mpio_t *, BYTE, BYTE *); @@ -63,7 +69,8 @@ void mpio_dentry_copy_from_slot(BYTE *, mpio_dir_slot_t *); void mpio_dentry_copy_to_slot(BYTE *, mpio_dir_slot_t *); int mpio_dentry_get_real(mpio_t *, mpio_mem_t, BYTE *, BYTE *, int, BYTE[12], - WORD *, BYTE *, BYTE *, BYTE *, BYTE *, DWORD *); + WORD *, BYTE *, BYTE *, BYTE *, BYTE *, DWORD *, + BYTE *); #ifdef __cplusplus } diff --git a/libmpio/fat.c b/libmpio/fat.c index f26f009..c24f56e 100644 --- a/libmpio/fat.c +++ b/libmpio/fat.c @@ -1,6 +1,6 @@ /* * - * $Id: fat.c,v 1.25 2003/04/04 22:08:53 germeier Exp $ + * $Id: fat.c,v 1.26 2003/04/06 23:09:20 germeier Exp $ * * Library for USB MPIO-* * @@ -837,24 +837,31 @@ mpio_fat_write(mpio_t *m, mpio_mem_t mem) if (mem == MPIO_INTERNAL_MEM) { sm = &m->internal; - f=mpio_fatentry_new(m, mem, 0, FTYPE_MUSIC); - mpio_io_block_delete(m, mem, f); - free(f); - - memset(dummy, 0x00, BLOCK_SIZE); - - /* only write the FAT */ - for (i= 0; i< 0x20; i++) - { - - if (i<DIR_NUM) + if (sm->cdir == sm->root) + { + f=mpio_fatentry_new(m, mem, 0, FTYPE_MUSIC); + mpio_io_block_delete(m, mem, f); + free(f); + + memset(dummy, 0x00, BLOCK_SIZE); + + /* only write the root dir */ + for (i= 0; i< 0x20; i++) { - mpio_io_sector_write(m, mem, i, (sm->dir + SECTOR_SIZE * i)); - } else { - /* fill the rest of the block with zeros */ - mpio_io_sector_write(m, mem, i, dummy); - } - } + + if (i<DIR_NUM) + { + mpio_io_sector_write(m, mem, i, + (sm->root->dir + SECTOR_SIZE * i)); + } else { + /* fill the rest of the block with zeros */ + mpio_io_sector_write(m, mem, i, dummy); + } + } + } else { + mpio_directory_write(m, mem, sm->cdir); + } + } if (mem == MPIO_EXTERNAL_MEM) @@ -896,9 +903,15 @@ mpio_fat_write(mpio_t *m, mpio_mem_t mem) if (i>=sm->dir_offset) mpio_io_sector_write(m, mem, i, - (sm->dir + (i - sm->dir_offset) * SECTOR_SIZE)); + (sm->root->dir + + (i - sm->dir_offset) * SECTOR_SIZE)); } - } + + if (sm->cdir != sm->root) + mpio_directory_write(m, mem, sm->cdir); + + } + return 0; } diff --git a/libmpio/mpio.c b/libmpio/mpio.c index ea91ce2..0c6a7e8 100644 --- a/libmpio/mpio.c +++ b/libmpio/mpio.c @@ -1,6 +1,6 @@ /* * - * $Id: mpio.c,v 1.47 2003/04/05 12:19:49 germeier Exp $ + * $Id: mpio.c,v 1.48 2003/04/06 23:09:20 germeier Exp $ * * Library for USB MPIO-* * @@ -81,6 +81,14 @@ static mpio_error_t mpio_errors[] = { "There are not enough rights to access the file/directory." }, { MPIO_ERR_WRITING_FILE, "There are no permisson to write to the selected file." }, + { MPIO_ERR_DIR_TOO_LONG, + "The selected directory name is to long." }, + { MPIO_ERR_DIR_NOT_FOUND, + "The selected directory can not be found." }, + { MPIO_ERR_DIR_NOT_A_DIR, + "The selected directory is not a directory." }, + { MPIO_ERR_DIR_NAME_ERROR, + "The selected directory name is not allowed." }, { MPIO_ERR_INT_STRING_INVALID, "Internal Error: Supported is invalid!" } }; @@ -121,7 +129,7 @@ mpio_check_filename(mpio_filename_t filename) void mpio_init_internal(mpio_t *m) { - mpio_smartmedia_t *sm = &(m->internal); + mpio_smartmedia_t *sm = &m->internal; BYTE i_offset = 0x18; /* init main memory parameters */ @@ -187,7 +195,12 @@ mpio_init_internal(mpio_t *m) /* Read directory from internal memory */ sm->dir_offset=0; + sm->root = malloc (sizeof(mpio_directory_t)); + sm->root->name[0] = 0; + sm->root->next = NULL; + sm->root->prev = NULL; mpio_rootdir_read(m, MPIO_INTERNAL_MEM); + sm->cdir = sm->root; } void @@ -234,6 +247,14 @@ mpio_init_external(mpio_t *m) sm->max_blocks = sm->size / 16 * 1024; /* 1 cluster == 16 KB */ sm->spare = malloc(sm->max_blocks * 0x10); } + + /* setup directory support */ + sm->dir_offset=0; + sm->root = malloc (sizeof(mpio_directory_t)); + sm->root->name[0] = 0; + sm->root->next = NULL; + sm->root->prev = NULL; + sm->cdir = sm->root; } mpio_t * @@ -822,7 +843,7 @@ mpio_file_put_real(mpio_t *m, mpio_mem_t mem, mpio_filename_t i_filename, mpio_dentry_put(m, mem, o_filename, strlen(o_filename), ((memory)?mktime(&tt):file_stat.st_ctime), - fsize, start); + fsize, start, 0x20); } return fsize-filesize; @@ -1021,6 +1042,13 @@ mpio_file_del(mpio_t *m, mpio_mem_t mem, mpio_filename_t filename, if (mem == MPIO_INTERNAL_MEM) sm = &m->internal; if (mem == MPIO_EXTERNAL_MEM) sm = &m->external; + if ((strcmp(filename, "..") == 0) || + (strcmp(filename, ".") == 0)) + { + debugn(2, "directory name not allowed: %s\n", filename); + return MPIO_ERR_DIR_NAME_ERROR; + } + /* find file */ p = mpio_dentry_find_name(m, mem, filename); if (!p) @@ -1099,14 +1127,14 @@ mpio_memory_dump(mpio_t *m, mpio_mem_t mem) if (mem == MPIO_INTERNAL_MEM) { hexdump(m->internal.fat, m->internal.max_blocks*0x10); - hexdump(m->internal.dir, DIR_SIZE); + hexdump(m->internal.root->dir, DIR_SIZE); } if (mem == MPIO_EXTERNAL_MEM) { hexdump(m->external.spare, m->external.max_blocks*0x10); hexdump(m->external.fat, m->external.fat_size*SECTOR_SIZE); - hexdump(m->external.dir, DIR_SIZE); + hexdump(m->external.root->dir, DIR_SIZE); } for (i = 0 ; i<=0x100 ; i++) diff --git a/libmpio/mpio.h b/libmpio/mpio.h index 152c27a..94db5af 100644 --- a/libmpio/mpio.h +++ b/libmpio/mpio.h @@ -1,7 +1,7 @@ #/* -*- linux-c -*- */ /* - * $Id: mpio.h,v 1.14 2003/02/21 18:28:56 crunchy Exp $ + * $Id: mpio.h,v 1.15 2003/04/06 23:09:20 germeier Exp $ * * Library for USB MPIO-* * @@ -75,11 +75,17 @@ BYTE mpio_charset_set(mpio_t *, BYTE *); /* context, memory bank */ BYTE* mpio_directory_open(mpio_t *, mpio_mem_t); +/* context, memory bank, directory name */ +int mpio_directory_make(mpio_t *, mpio_mem_t, BYTE *); +/* context, memory bank, directory name */ +int mpio_directory_cd(mpio_t *, mpio_mem_t, BYTE *); +/* context, memory bank, directory name buffer space */ +void mpio_directory_pwd(mpio_t *, mpio_mem_t, BYTE pwd[INFO_LINE]); /* context, dir context */ BYTE* mpio_dentry_next(mpio_t *, mpio_mem_t, BYTE *); /* context, dir context */ int mpio_dentry_get(mpio_t *, mpio_mem_t, BYTE *, BYTE *, int,WORD *, - BYTE *, BYTE *, BYTE *, BYTE *, DWORD *); + BYTE *, BYTE *, BYTE *, BYTE *, DWORD *, BYTE *); /* * reading/writing/deleting of files @@ -143,7 +149,7 @@ int mpio_file_move(mpio_t *,mpio_mem_t m,mpio_filename_t,mpio_filename_t); int mpio_memory_format(mpio_t *, mpio_mem_t, mpio_callback_t); /* mpio_sync has to be called after every set of mpio_file_{del,put} - * operations to write the current state of FAT and root directory. + * operations to write the current state of FAT and (root) directory. * This is done explicitly to avoid writing these informations to often * and thereby exhausting the SmartMedia chips */ diff --git a/mpiosh/callback.c b/mpiosh/callback.c index fd86825..c3e82d4 100644 --- a/mpiosh/callback.c +++ b/mpiosh/callback.c @@ -2,7 +2,7 @@ * * Author: Andreas Büsching <crunchy@tzi.de> * - * $Id: callback.c,v 1.34 2003/03/08 17:28:20 germeier Exp $ + * $Id: callback.c,v 1.35 2003/04/06 23:09:20 germeier Exp $ * * Copyright (C) 2001 Andreas Büsching <crunchy@tzi.de> * @@ -120,7 +120,7 @@ void mpiosh_cmd_dir(char *args[]) { BYTE *p; - BYTE month, day, hour, minute; + BYTE month, day, hour, minute, type; BYTE fname[100]; WORD year; DWORD fsize; @@ -136,16 +136,57 @@ mpiosh_cmd_dir(char *args[]) mpio_dentry_get(mpiosh.dev, mpiosh.card, p, fname, 100, &year, &month, &day, - &hour, &minute, &fsize); + &hour, &minute, &fsize, + &type); - printf ("%02d.%02d.%04d %02d:%02d %9d - %s\n", - day, month, year, hour, minute, fsize, fname); + printf ("%02d.%02d.%04d %02d:%02d %9d %c %s\n", + day, month, year, hour, minute, fsize, type, fname); p = mpio_dentry_next(mpiosh.dev, mpiosh.card, p); } } void +mpiosh_cmd_pwd(char *args[]) +{ + BYTE pwd[INFO_LINE]; + + UNUSED(args); + + MPIOSH_CHECK_CONNECTION_CLOSED; + + mpio_directory_pwd(mpiosh.dev, mpiosh.card, pwd); + printf ("%s\n", pwd); + +} + +void +mpiosh_cmd_mkdir(char *args[]) +{ + BYTE pwd[INFO_LINE]; + + MPIOSH_CHECK_CONNECTION_CLOSED; + + mpio_directory_make(mpiosh.dev, mpiosh.card, args[0]); + mpio_sync(mpiosh.dev, mpiosh.card); + +} + +void +mpiosh_cmd_cd(char *args[]) +{ + BYTE pwd[INFO_LINE]; + + MPIOSH_CHECK_CONNECTION_CLOSED; + + mpio_directory_cd(mpiosh.dev, mpiosh.card, args[0]); + + mpio_directory_pwd(mpiosh.dev, mpiosh.card, pwd); + printf ("directory is now: %s\n", pwd); + +} + +void mpiosh_cmd_info(char *args[]) { mpio_info_t info; @@ -296,7 +337,7 @@ mpiosh_cmd_mget(char *args[]) regex_t regex; BYTE fname[100]; BYTE errortext[100]; - BYTE month, day, hour, minute; + BYTE month, day, hour, minute, type; WORD year; DWORD fsize; int found; @@ -316,7 +357,7 @@ mpiosh_cmd_mget(char *args[]) while (p != NULL) { memset(fname, '\0', 100); mpio_dentry_get(mpiosh.dev, mpiosh.card, p, fname, 100, - &year, &month, &day, &hour, &minute, &fsize); + &year, &month, &day, &hour, &minute, &fsize, &type); if (!(error = regexec(®ex, fname, 0, NULL, 0))) { found = 1; @@ -482,7 +523,7 @@ mpiosh_cmd_mdel(char *args[]) regex_t regex; BYTE fname[100]; BYTE errortext[100]; - BYTE month, day, hour, minute; + BYTE month, day, hour, minute, type; WORD year; DWORD fsize; int deleted = 0; @@ -500,7 +541,7 @@ mpiosh_cmd_mdel(char *args[]) while ((p != NULL) && (!mpiosh_cancel)) { memset(fname, '\0', 100); mpio_dentry_get(mpiosh.dev, mpiosh.card, p, fname, 100, - &year, &month, &day, &hour, &minute, &fsize); + &year, &month, &day, &hour, &minute, &fsize, &type); if (!(error = regexec(®ex, fname, 0, NULL, 0))) { /* this line has to be above the del, or we won't write @@ -535,7 +576,7 @@ void mpiosh_cmd_dump(char *args[]) { BYTE *p; - BYTE month, day, hour, minute; + BYTE month, day, hour, minute, type; BYTE fname[256]; char *arg[2]; WORD year; @@ -555,7 +596,7 @@ mpiosh_cmd_dump(char *args[]) mpio_dentry_get(mpiosh.dev, mpiosh.card, p, fname, 256, &year, &month, &day, - &hour, &minute, &fsize); + &hour, &minute, &fsize, &type); mpiosh_cmd_mget(arg); diff --git a/mpiosh/callback.h b/mpiosh/callback.h index eefbd31..ac9862c 100644 --- a/mpiosh/callback.h +++ b/mpiosh/callback.h @@ -2,7 +2,7 @@ * * Author: Andreas Büsching <crunchy@tzi.de> * - * $Id: callback.h,v 1.7 2002/10/27 02:45:28 germeier Exp $ + * $Id: callback.h,v 1.8 2003/04/06 23:09:20 germeier Exp $ * * Copyright (C) 2001 Andreas Büsching <crunchy@tzi.de> * @@ -31,6 +31,9 @@ void mpiosh_cmd_debug(char *args[]); void mpiosh_cmd_version(char *args[]); void mpiosh_cmd_help(char *args[]); void mpiosh_cmd_dir(char *args[]); +void mpiosh_cmd_pwd(char *args[]); +void mpiosh_cmd_mkdir(char *args[]); +void mpiosh_cmd_cd(char *args[]); void mpiosh_cmd_info(char *args[]); void mpiosh_cmd_mem(char *args[]); void mpiosh_cmd_open(char *args[]); diff --git a/mpiosh/global.c b/mpiosh/global.c index 0d8e374..4bfe7b5 100644 --- a/mpiosh/global.c +++ b/mpiosh/global.c @@ -2,7 +2,7 @@ * * Author: Andreas Buesching <crunchy@tzi.de> * - * $Id: global.c,v 1.7 2003/03/06 23:41:30 germeier Exp $ + * $Id: global.c,v 1.8 2003/04/06 23:09:20 germeier Exp $ * * Copyright (C) 2001 Andreas Büsching <crunchy@tzi.de> * @@ -56,6 +56,15 @@ struct mpiosh_cmd_t commands[] = { { "dir", (char *[]){ "ls", "ll", NULL }, NULL, " list content of current memory card", mpiosh_cmd_dir, NULL }, + { "pwd", NULL, NULL, + " print the current working directory", + mpiosh_cmd_pwd, NULL }, + { "mkdir", (char *[]){ "md", NULL }, "<directory>", + " make a new directory", + mpiosh_cmd_mkdir, mpiosh_readline_comp_mpio_file }, + { "cd", NULL, "<directory>", + " change the current working directory", + mpiosh_cmd_cd, mpiosh_readline_comp_mpio_file }, { "info", NULL, NULL, " show information about MPIO player", mpiosh_cmd_info, NULL }, diff --git a/mpiosh/readline.c b/mpiosh/readline.c index 8b97219..d10209b 100644 --- a/mpiosh/readline.c +++ b/mpiosh/readline.c @@ -2,7 +2,7 @@ * * Author: Andreas Büsching <crunchy@tzi.de> * - * $Id: readline.c,v 1.5 2002/10/29 20:03:35 crunchy Exp $ + * $Id: readline.c,v 1.6 2003/04/06 23:09:20 germeier Exp $ * * Copyright (C) 2001 Andreas Büsching <crunchy@tzi.de> * @@ -84,7 +84,7 @@ mpiosh_readline_comp_mpio_file(const char *text, int state) { static BYTE *p; char *arg = NULL; - BYTE month, day, hour, minute; + BYTE month, day, hour, minute, type; char fname[100]; WORD year; DWORD fsize; @@ -102,7 +102,7 @@ mpiosh_readline_comp_mpio_file(const char *text, int state) mpio_dentry_get(mpiosh.dev, mpiosh.card, p, fname, 100, &year, &month, &day, - &hour, &minute, &fsize); + &hour, &minute, &fsize, &type); if (strstr(fname, text) == fname) { arg = strdup(fname); |