diff options
author | bencollins <tailor@grayson> | 2001-06-08 14:12:12 -0400 |
---|---|---|
committer | Ben Collins <bcollins@ubuntu.com> | 2006-06-01 13:17:56 -0400 |
commit | e8197a2e074ce9b78b27af565c27b3f3126bc2f7 (patch) | |
tree | 685e049d3ff28dafc7ddf020605504a5d1450134 | |
parent | 346430d57e474b2571ff9c300cf20a138037bd3d (diff) | |
download | silo-e8197a2e074ce9b78b27af565c27b3f3126bc2f7.tar.gz |
[silo @ 31]
* second/file.c (dump_block): Kill common args.
* second/file.h: Update decleration of dump_block.
* second/fs/ext2.c: Update dump_block Interface.
* second/fs/isofs.c: Likewise.
* second/fs/ufs.c: Likewise.
* second/fs/romfs.c: Likewise. Also fix cut and paste error.
* second/fs/romfs.c: Add ls support.#
-rw-r--r-- | ChangeLog | 11 | ||||
-rw-r--r-- | common/printf.c | 2 | ||||
-rw-r--r-- | second/disk.c | 3 | ||||
-rw-r--r-- | second/file.c | 23 | ||||
-rw-r--r-- | second/file.h | 4 | ||||
-rw-r--r-- | second/fs/ext2.c | 15 | ||||
-rw-r--r-- | second/fs/iom.c | 7 | ||||
-rw-r--r-- | second/fs/isofs.c | 21 | ||||
-rw-r--r-- | second/fs/romfs.c | 226 | ||||
-rw-r--r-- | second/fs/ufs.c | 25 |
10 files changed, 180 insertions, 157 deletions
@@ -1,3 +1,14 @@ +Fri Jun 8 10:10:47 EDT 2001 Ben Collins <bcollins@debian.org> + + * second/file.c (dump_block): Kill common args. + * second/file.h: Update decleration of dump_block. + * second/fs/ext2.c: Update dump_block Interface. + * second/fs/isofs.c: Likewise. + * second/fs/ufs.c: Likewise. + * second/fs/romfs.c: Likewise. Also fix cut and paste error. + + * second/fs/romfs.c: Add ls support. + Wed Jun 6 14:48:30 EDT 2001 Ben Collins <bcollins@debian.org> * second/Makefile: Add fs/ufs.o and fs/romfs.o to libfs.a. diff --git a/common/printf.c b/common/printf.c index 584d609..c10d2c7 100644 --- a/common/printf.c +++ b/common/printf.c @@ -103,7 +103,7 @@ void vprintf (char *fmt, va_list adx) /* * Scaled down version of C Library printf. - * Only %c %s %u %d (==%u) %o %x %D %O are recognized. + * Only %c %s %u %d (==%u) %o %x %l %O are recognized. */ void prom_printf (char *fmt,...) diff --git a/second/disk.c b/second/disk.c index 3fdee54..b736d6b 100644 --- a/second/disk.c +++ b/second/disk.c @@ -320,7 +320,8 @@ int read (char *buff, int size, unsigned long long offset) reopen(); while (size) { if (size < 32768) j = size; else j = 32768; - if (read (buff, j, offset) != j) return -1; + if (read (buff, j, offset) != j) + return -1; size -= j; offset += j; buff += j; diff --git a/second/file.c b/second/file.c index 0b65c5c..c9cc479 100644 --- a/second/file.c +++ b/second/file.c @@ -1,4 +1,4 @@ -/* File related stuff +/* Filesystem interface abstraction. Copyright (C) 1996 Maurizio Plaza 1996,1997,1999 Jakub Jelinek @@ -45,7 +45,7 @@ static char *gunzip_inp; static char *gunzip_endbuf; static char *match; -/* Externally provided filesystem operations */ +/* Externally provided filesystem interfaces */ extern struct fs_ops ext2_fs_ops; extern struct fs_ops iso_fs_ops; extern struct fs_ops rom_fs_ops; @@ -362,7 +362,7 @@ int load_file (char *device, int partno, char *filename, char *buffer, if (cmd & LOADFILE_LS && cur_ops->ls == NULL) { if (!(cmd & LOADFILE_MATCH)) - printf("\nls is not supported for `%s' filesystems\n", cur_ops->name); + printf("\nls is not supported for the `%s' filesystems\n", cur_ops->name); goto done_1; } @@ -394,8 +394,6 @@ int load_file (char *device, int partno, char *filename, char *buffer, goto done_1; } - printf("\nImage found, getting ready to load (%s)\n", filename); - if (lenfunc) { do_gunzip = 0; size = cur_ops->ino_size(); @@ -403,8 +401,6 @@ int load_file (char *device, int partno, char *filename, char *buffer, do_gunzip = cmd & LOADFILE_GZIP; } - printf("Image is being loaded via %s\n", do_gunzip ? "gunzip" : "disk"); - first_block = do_gunzip; last_blockcnt = 0; block_no = 0; @@ -412,9 +408,7 @@ int load_file (char *device, int partno, char *filename, char *buffer, retval = 0; if (cur_ops->have_inode) { - printf("Have an inode, caling "); if (cmd & LOADFILE_LS) { - printf("ls.\n"); if ((retval = cur_ops->ls())) { if (!(cmd & LOADFILE_MATCH)) { printf("\nError: could not list ("); @@ -428,13 +422,12 @@ int load_file (char *device, int partno, char *filename, char *buffer, retval = 1; } } else { - printf("dump.\n"); - retval = cur_ops->dump(filename); + retval = cur_ops->dump(); + if (!retval && !(cmd & LOADFILE_MATCH)) + printf("\nError loading %s\n", filename); } } - printf("Dump run (%d)\n", retval); - if (retval && len) { if (size != -1) *len = size; @@ -442,13 +435,11 @@ int load_file (char *device, int partno, char *filename, char *buffer, *len = gunzipped_len; else *len = cur_ops->ino_size(); - - printf("Length = %d\n", *len); } done_1: if (dir) free(dir); - cur_ops->close (fs); + cur_ops->close(); done_2: release (mmark); diff --git a/second/file.h b/second/file.h index 20f47e5..b009c12 100644 --- a/second/file.h +++ b/second/file.h @@ -40,10 +40,10 @@ struct fs_ops { char *name; int (*open) (char *); int (*ls) (void); - int (*dump) (char *); + int (*dump) (void); int (*ino_size) (void); int (*namei_follow) (const char *); void (*print_error) (int); - void (*close) (ext2_filsys); + void (*close) (void); int have_inode; }; diff --git a/second/fs/ext2.c b/second/fs/ext2.c index 318ad36..e5c33f5 100644 --- a/second/fs/ext2.c +++ b/second/fs/ext2.c @@ -78,18 +78,11 @@ static int dump_block_ext2 (ext2_filsys fs, blk_t *blocknr, return dump_block(blocknr, blockcnt); } -static int dump_ext2 (char *filename) +static int dump_ext2 (void) { - errcode_t retval; - - retval = ext2fs_block_iterate (fs, inode, 0, 0, - dump_block_ext2, 0); - if (retval) { - printf ("\n"); - ext2fs_error (retval); - printf ("\n"); + if (ext2fs_block_iterate (fs, inode, 0, 0, dump_block_ext2, 0)) return 0; - } + return dump_finish (); } @@ -154,7 +147,7 @@ static void print_error_ext2 (int error_val) { ext2fs_error (error_val); } -void close_ext2 (ext2_filsys fs) { +void close_ext2 (void) { ext2fs_close(fs); } diff --git a/second/fs/iom.c b/second/fs/iom.c index 255e6c6..def8874 100644 --- a/second/fs/iom.c +++ b/second/fs/iom.c @@ -88,11 +88,12 @@ static errcode_t silo_set_blksize (io_channel channel, int blksize) static errcode_t silo_read_blk (io_channel channel, unsigned long block, int count, void *data) { - int size; + int size, got; size = (count < 0) ? -count : count * bs; - if (read (data, size, ((unsigned long long)block) * bs + doff) != size) { - printf ("\nRead error on block %d\n", block); + got = read (data, size, ((unsigned long long)block) * bs + doff); + if (got != size) { + printf ("\nRead error on block %d (tried %d, got %d)\n", block, size, got); return EXT2_ET_SHORT_READ; } return 0; diff --git a/second/fs/isofs.c b/second/fs/isofs.c index 8cf3f4f..ce7fa4d 100644 --- a/second/fs/isofs.c +++ b/second/fs/isofs.c @@ -414,13 +414,13 @@ static int isofs_namei (const char *filename) return ret; } -static void isofs_close(isofs_filsys fs) +static void isofs_close(void) { free (fs->io); free (fs); } -static int isofs_block_iterate(int (*func)(blk_t *, int)) +static int isofs_block_iterate(void) { int i; blk_t nr; @@ -429,22 +429,13 @@ static int isofs_block_iterate(int (*func)(blk_t *, int)) nr = inode.extent; size = (inode.size + 2047) / 2048; for (i = 0; i < size; i++, nr++) { - switch ((*func) (&nr, i)) { + switch (dump_block (&nr, i)) { case BLOCK_ABORT: case BLOCK_ERROR: - return -1; + return 0; } } - return 0; -} - -static int dump_isofs (char *filename) -{ - if (isofs_block_iterate (dump_block)) { - printf ("Error while loading of %s", filename); - return 0; - } - return dump_finish (); + return dump_finish(); } static void print_error_isofs (int error_val) { @@ -455,7 +446,7 @@ struct fs_ops iso_fs_ops = { name: "ISO-9660 CDROM", open: open_isofs, ls: ls_isofs, - dump: dump_isofs, + dump: isofs_block_iterate, close: isofs_close, ino_size: ino_size_isofs, print_error: print_error_isofs, diff --git a/second/fs/romfs.c b/second/fs/romfs.c index 964c884..871f71e 100644 --- a/second/fs/romfs.c +++ b/second/fs/romfs.c @@ -31,18 +31,27 @@ typedef ext2_filsys romfs_filsys; static ino_t inode = 0; +static int link_count = 0; #define SUPROMFS (struct romfs_super_block *)(fs->io->private_data) +#define BLOCK_SIZE_BITS 9 /* 512 */ +#define BLOCK_SIZE (1<<BLOCK_SIZE_BITS) + +static int inline min(int a, int b) +{ + return a<b ? a : b; +} static __s32 romfs_checksum(void *data, int size) { __s32 sum, *ptr; + sum = 0; ptr = data; size>>=2; while (size>0) { sum += *ptr++; - size--; + size--; } return sum; } @@ -51,16 +60,23 @@ static struct romfs_super_block *romfs_read_super(romfs_filsys fs) { struct romfs_super_block *rsb; - rsb = (struct romfs_super_block *) malloc (2048+512); - if (!rsb) return 0; + /* The 2048 comes from the space needed to make room for the first + * stage loader. The image has to be created with "-A 2048,/.." + */ + rsb = (struct romfs_super_block *) malloc (2048+ROMBSIZE); + if (!rsb) return NULL; + if (io_channel_read_blk (fs->io, 0, 1, (char *)rsb)) - return 0; + return NULL; + if (strncmp((char *)rsb, "-rom1fs-", 8) || rsb->size < ROMFH_SIZE) - return 0; - if (romfs_checksum(rsb, 512)) { - printf("Bad ROMFS initial checksum\n"); - return 0; + return NULL; + + if (romfs_checksum(rsb, min(rsb->size,512))) { + printf("ROMFS: Bad initial checksum.\n"); + return NULL; } + rsb->checksum = strlen(rsb->name); if (rsb->checksum > ROMFS_MAXFN) rsb->checksum = ROMFS_MAXFN; rsb->checksum += (ROMFH_SIZE + 1 + ROMFH_PAD); @@ -73,43 +89,37 @@ static struct romfs_super_block *romfs_read_super(romfs_filsys fs) static int romfs_copyfrom(romfs_filsys fs, void *dest, unsigned long offset, unsigned long count) { - int off; struct romfs_super_block *rsb = SUPROMFS; + unsigned long res; + char buffer[ROMBSIZE]; + int maxsize; + + if ((offset>>ROMBSBITS)<<ROMBSBITS >= rsb->size+ROMBSIZE || count > rsb->size || + offset+count>rsb->size+ROMBSIZE) + return -1; + + maxsize = min(count, (ROMBSIZE - (offset & ROMBMASK))); + res = maxsize; + + if (io_channel_read_blk (fs->io, offset>>ROMBSBITS, 1, buffer)) + return -1; + + memcpy(dest, buffer + (offset & ROMBMASK), maxsize); - for (;;) { - if (rsb->word0 != (__u32)-1 && offset >= rsb->word0 && offset < rsb->word0 + 1024) { - int cnt = 1024 - (offset & 1023); - if (count < cnt) - cnt = count; - memcpy(dest, (char *)rsb + 512 + (offset & 1023), cnt); - if (count == cnt) return 0; - dest = (char *)dest + cnt; - offset += cnt; - count -= cnt; - } - if (rsb->word1 != (__u32)-1 && offset >= rsb->word1 && offset < rsb->word1 + 1024) { - int cnt = 1024 - (offset & 1023); - if (count < cnt) - cnt = count; - memcpy(dest, (char *)rsb + 1536 + (offset & 1023), cnt); - if (count == cnt) return 0; - dest = (char *)dest + cnt; - count -= cnt; - } - off = offset & ~1023; - if (io_channel_read_blk (fs->io, off / 512, 2, (char *)rsb + (rsb->name[0] ? 1536 : 512))) { - if (rsb->name[0]) - rsb->word1 = -1; - else - rsb->word0 = -1; + while (res < count) { + offset += maxsize; + + if (io_channel_read_blk (fs->io, offset>>ROMBSBITS, 1, buffer)) return -1; - } - if (rsb->name[0]) - rsb->word1 = off; - else - rsb->word0 = off; - rsb->name[0] ^= 1; + + dest += maxsize; + maxsize = min(count-res, ROMBSIZE); + + memcpy(dest, buffer, maxsize); + + res += maxsize; } + return 0; } static int romfs_read_inode (romfs_filsys fs, ino_t inode, struct romfs_inode *ui) @@ -120,38 +130,68 @@ static int romfs_read_inode (romfs_filsys fs, ino_t inode, struct romfs_inode *u if (inode < rsb->checksum || inode >= rsb->size) return -1; - if (romfs_copyfrom (fs, &romfsip, inode, 16)) + if (romfs_copyfrom (fs, &romfsip, inode, ROMFH_SIZE)) return -1; + *ui = romfsip; return 0; } -static int romfs_lookup (romfs_filsys fs, ino_t dir, struct romfs_inode *dirui, +static mode_t romfs_modemap[] = +{ + 0, LINUX_S_IFDIR+0555, LINUX_S_IFREG+0444, LINUX_S_IFLNK+0777, + LINUX_S_IFBLK+0600, LINUX_S_IFCHR+0600, LINUX_S_IFSOCK+0644, + LINUX_S_IFIFO+0644 +}; + +static int romfs_lookup (romfs_filsys fs, struct romfs_inode *dirui, const char *name, int len, ino_t *result) { char buffer [8192]; struct romfs_inode ui; + ino_t dir = dirui->spec & ROMFH_MASK; + struct romfs_super_block *rsb = SUPROMFS; - dir = dirui->spec & ROMFH_MASK; - while (dir) { + while (dir && dir < rsb->size) { if (romfs_read_inode (fs, dir, &ui)) return -1; - if (romfs_copyfrom (fs, buffer, dir + 16, ROMFS_MAXFN)) + + if (romfs_copyfrom (fs, buffer, dir + ROMFH_SIZE, ROMFS_MAXFN)) return -1; - if ((!len && buffer[0] == '.' && !buffer[1]) || + + if (result == NULL) { + /* We aren't returning an inode, so we must be iterating */ + char symlink[1024] = {0}; + unsigned int mode = romfs_modemap[ui.next & ROMFH_TYPE]; + + /* Check for symlinks */ + if ((ui.next & ROMFH_TYPE) == ROMFH_SYM) { + int offset = dir + ROMFH_SIZE + ((strlen(buffer) + ROMFH_SIZE) & ROMFH_MASK); + if (romfs_copyfrom (fs, symlink, offset, ROMFS_MAXFN)) + return -1; + } + + if (buffer[0] == '.' && (!buffer[1] || (buffer[1] == '.' && !buffer[2]))) + mode = LINUX_S_IFDIR+0555; + + register_silo_inode(0, ui.size, mode, + 0, 0, buffer, symlink[0] ? symlink : NULL); + + } else if ((!len && buffer[0] == '.' && !buffer[1]) || (strlen(buffer) == len && !memcmp(buffer, name, len))) { - if ((ui.next & ROMFH_TYPE) == ROMFH_HRD) - dir = ui.spec; - *result = dir; - return 0; - } + if ((ui.next & ROMFH_TYPE) == ROMFH_HRD) + dir = ui.spec; + *result = dir; + return 0; + } dir = ui.next & ROMFH_MASK; } + if (result == NULL) + return 0; + return -1; } -static int link_count = 0; - static int open_namei(romfs_filsys, const char *, ino_t *, ino_t); static int romfs_follow_link(romfs_filsys fs, ino_t dir, ino_t inode, @@ -165,12 +205,12 @@ static int romfs_follow_link(romfs_filsys fs, ino_t dir, ino_t inode, return 0; } if (link_count > 5) { - printf ("Symlink loop\n"); + printf ("ROMFS: Symlink loop.\n"); return -1; /* Loop */ } - if (romfs_copyfrom (fs, buffer, inode + 16, ROMFS_MAXFN)) + if (romfs_copyfrom (fs, buffer, inode + ROMFH_SIZE, ROMFS_MAXFN)) return -1; - error = inode + 16 + ((strlen(buffer) + 16) & ~15); + error = inode + ROMFH_SIZE + ((strlen(buffer) + ROMFH_SIZE) & ROMFH_MASK); if (romfs_copyfrom (fs, buffer, error, ROMFS_MAXFN)) return -1; link_count++; @@ -192,12 +232,13 @@ static int dir_namei(romfs_filsys fs, const char *pathname, int *namelen, base = (ino_t)fs->private; pathname++; } + if (romfs_read_inode (fs, base, &ub)) return -1; while (1) { thisname = pathname; for(len=0;(c = *(pathname++))&&(c != '/');len++); if (!c) break; - if (romfs_lookup (fs, base, &ub, thisname, len, &inode)) return -1; + if (romfs_lookup (fs, &ub, thisname, len, &inode)) return -1; if (romfs_read_inode (fs, inode, &ub)) return -1; if (romfs_follow_link (fs, base, inode, &ub, &base)) return -1; if (base != inode && romfs_read_inode (fs, base, &ub)) return -1; @@ -222,7 +263,7 @@ static int open_namei(romfs_filsys fs, const char *pathname, return 0; } if (romfs_read_inode (fs, dir, &ub)) return -1; - if (romfs_lookup (fs, dir, &ub, basename, namelen, &inode)) return -1; + if (romfs_lookup (fs, &ub, basename, namelen, &inode)) return -1; if (romfs_read_inode (fs, inode, &ub)) return -1; if (romfs_follow_link (fs, dir, inode, &ub, &inode)) return -1; *res_inode = inode; @@ -244,37 +285,37 @@ static int namei_follow_romfs (const char *filename) return ret; } -static void romfs_close(romfs_filsys fs) +static void romfs_close(void) { free (fs->io); free (fs); } -static int romfs_block_iterate(int (*func)(blk_t *, int)) +static int romfs_block_iterate(void) { struct romfs_inode ub; int i; blk_t nr; int size; char buffer[ROMFS_MAXFN]; - - if (romfs_read_inode (fs, inode, &ub)) return -1; - if (romfs_copyfrom (fs, buffer, inode + 16, ROMFS_MAXFN)) return -1; - nr = inode + 16 + ((strlen(buffer) + 16) & ~15); - if (nr & 511) { - printf("romfs: File not aligned on a 512B boundary\n"); - return -1; + + if (romfs_read_inode (fs, inode, &ub)) return 0; + if (romfs_copyfrom (fs, buffer, inode + ROMFH_SIZE, ROMFS_MAXFN)) return 0; + nr = inode + ROMFH_SIZE + ((strlen(buffer) + ROMFH_SIZE) & ROMFH_MASK); + if (nr & ROMBMASK) { + printf("ROMFS: File not aligned on a %dB boundary.\n", ROMBSIZE); + return 0; } - size = (ub.size + 511) / 512; - nr /= 512; + size = (ub.size + ROMBMASK) / ROMBSIZE; + nr /= ROMBSIZE; for (i = 0; i < size; i++, nr++) { - switch ((*func) (&nr, i)) { + switch (dump_block (&nr, i)) { case BLOCK_ABORT: case BLOCK_ERROR: - return -1; + return 0; } } - return 0; + return dump_finish(); } static int open_romfs (char *device) @@ -286,50 +327,53 @@ static int open_romfs (char *device) if (((struct struct_io_manager *)(silo_io_manager))->open (device, 0, &fs->io)) return 0; - io_channel_set_blksize (fs->io, 512); + io_channel_set_blksize (fs->io, ROMBSIZE); fs->io->private_data = romfs_read_super(fs); if (!fs->io->private_data) return 0; root = ((struct romfs_super_block *)(fs->io->private_data))->checksum; + inode = 1; return 1; } -static int dump_romfs (char *filename) -{ - printf(__FUNCTION__": called\n"); - if (romfs_block_iterate (dump_block)) { - printf ("Error while loading of %s", filename); - return 0; - } - printf(__FUNCTION__": romfs_block_iterate done, calling dump_finish\n"); - return dump_finish (); -} - static int ino_size_romfs (void) { struct romfs_inode ri; if (romfs_read_inode (fs, inode, &ri)) return 0; - if ((ri.next & ROMFH_TYPE) != ROMFH_REG) { - printf("romfs: get length on non-reg file?\n"); + + if ((ri.next & ROMFH_TYPE) != ROMFH_REG) return 0; - } + return ri.size; } +static int ls_romfs (void) +{ + struct romfs_inode ub; + link_count = 0; + + if (romfs_read_inode (fs, inode, &ub)) return -1; + + if (romfs_lookup (fs, &ub, NULL, 0, NULL)) + return -1; + + return 0; +} + static void print_error_romfs (int error_val) { - printf("Unknown romfs error"); + printf("Unknown ROMFS error"); } struct fs_ops rom_fs_ops = { name: "Linux ROMFS", open: open_romfs, - ls: NULL/*ls_romfs*/, - dump: dump_romfs, + ls: ls_romfs, + dump: romfs_block_iterate, close: romfs_close, ino_size: ino_size_romfs, print_error: print_error_romfs, diff --git a/second/fs/ufs.c b/second/fs/ufs.c index eb75502..f826979 100644 --- a/second/fs/ufs.c +++ b/second/fs/ufs.c @@ -325,13 +325,13 @@ static int ufs_namei (ufs_filsys fs, ino_t root, ino_t cwd, const char *filename return open_namei (fs, filename, inode, cwd); } -static void ufs_close(ufs_filsys fs) +static void ufs_close(void) { free (fs->io); free (fs); } -static int ufs_block_iterate(int (*func)(blk_t *, int)) +static int ufs_block_iterate(void) { struct ufs_inode ub; int i; @@ -339,18 +339,18 @@ static int ufs_block_iterate(int (*func)(blk_t *, int)) int frags; struct ufs_superblock *sb = SUPUFS; - if (ufs_read_inode (fs, inode, &ub)) return -1; + if (ufs_read_inode (fs, inode, &ub)) return 0; frags = (ufsi_size(&ub) + sb->fs_fsize - 1) / sb->fs_fsize; for (i = 0; i < frags; i++) { nr = ufs_bmap (fs, inode, &ub, i); - if (!nr) return -1; - switch ((*func) (&nr, i)) { + if (!nr) return 0; + switch (dump_block(&nr, i)) { case BLOCK_ABORT: case BLOCK_ERROR: - return -1; + return 0; } } - return 0; + return dump_finish(); } struct fs_ops ufs_fs_ops; @@ -419,15 +419,6 @@ static int open_ufs (char *device) return 1; } -static int dump_ufs (char *filename) -{ - if (ufs_block_iterate (dump_block)) { - printf ("Error while loading of %s", filename); - return 0; - } - return dump_finish (); -} - static int ino_size_ufs (void) { struct ufs_inode ui; @@ -448,7 +439,7 @@ struct fs_ops ufs_fs_ops = { name: "SunOS UFS", open: open_ufs, ls: NULL/*ls_ufs*/, - dump: dump_ufs, + dump: ufs_block_iterate, close: ufs_close, ino_size: ino_size_ufs, print_error: print_error_ufs, |