This patch modifies fsck.cramfs in a way that it supports images in little endian format as well as in big endian (on both kinds of machines). A second option called -b (followed by the blocksize) was added, too. It enables the user to check and extract images that were created on machines whose page size differs from the host's one. The changes were tested on the following types of machines: An i386 compatible box (little endian) UltraSparc IIi (big endian) Signed-off-by: Andi Drebes <andi@xxxxxxxxxxxxxxxxxxx> --- fsck.cramfs.c | 45 +++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 41 insertions(+), 4 deletions(-) diff --git a/disk-utils/fsck.cramfs.c b/disk-utils/fsck.cramfs.c index 2a63ac9..0672269 100644 --- a/disk-utils/fsck.cramfs.c +++ b/disk-utils/fsck.cramfs.c @@ -31,6 +31,9 @@ * 2000/07/15: Daniel Quinlan (initial support for block devices) * 2002/01/10: Daniel Quinlan (additional checks, test more return codes, * use read if mmap fails, standardize messages) + * 2007/11/22: Andi Drebes (added support for little endian images on big endian + * machines and vice versa) + * 2007/11/24: Andi Drebes (added -b option for blocksize) */ /* compile-time options */ @@ -109,15 +112,18 @@ static char *outbuffer; static size_t page_size; +static unsigned int reverse_endianness = 0; + /* Input status of 0 to print help and exit without an error. */ static void usage(int status) { FILE *stream = status ? stderr : stdout; - fprintf(stream, _("usage: %s [-hv] [-x dir] file\n" + fprintf(stream, _("usage: %s [-hv] [-x dir] [-b blksize] file\n" " -h print this help\n" " -x dir extract into dir\n" " -v be more verbose\n" + " -b blksize use this blocksize\n" " file file to test\n"), progname); exit(status); @@ -172,6 +178,12 @@ static void test_super(int *start, size_t *length) { if (read(fd, &super, sizeof(super)) != sizeof(super)) { die(FSCK_ERROR, 1, "read failed: %s", filename); } + + if (super.magic == CRAMFS_MAGIC_WEND) { + cramfsck_convert_super(&super); + reverse_endianness = 1; + } + if (super.magic == CRAMFS_MAGIC) { *start = 0; } @@ -180,6 +192,12 @@ static void test_super(int *start, size_t *length) { if (read(fd, &super, sizeof(super)) != sizeof(super)) { die(FSCK_ERROR, 1, "read failed: %s", filename); } + + if (super.magic == CRAMFS_MAGIC_WEND) { + cramfsck_convert_super(&super); + reverse_endianness = 1; + } + if (super.magic == CRAMFS_MAGIC) { *start = PAD_SIZE; } @@ -314,13 +332,19 @@ static struct cramfs_inode *cramfs_iget(struct cramfs_inode * i) if (!inode) { die(FSCK_ERROR, 1, "malloc failed"); } + *inode = *i; return inode; } static struct cramfs_inode *iget(unsigned int ino) { - return cramfs_iget(romfs_read(ino)); + struct cramfs_inode *inode = cramfs_iget(romfs_read(ino)); + + if (reverse_endianness) + cramfsck_convert_inode(inode); + + return inode; } static void iput(struct cramfs_inode *inode) @@ -343,6 +367,7 @@ static struct cramfs_inode *read_super(void) { die(FSCK_UNCORRECTED, 0, "bad root offset (%lu)", offset); } + return cramfs_iget(&super.root); } @@ -363,7 +388,7 @@ static int uncompress_block(void *src, int len) } err = inflate(&stream, Z_FINISH); if (err != Z_STREAM_END) { - die(FSCK_UNCORRECTED, 0, "decompression error %p(%d): %s", + die(FSCK_UNCORRECTED, 0, "decompression error %p(%d): %d", zError(err), src, len); } return stream.total_out; @@ -380,6 +405,9 @@ static void do_uncompress(char *path, int fd, unsigned long offset, unsigned lon unsigned long out = page_size; unsigned long next = *(u32 *) romfs_read(offset); + if (reverse_endianness) + next = cramfsck_convert_u32(next); + if (next > end_data) { end_data = next; } @@ -408,6 +436,7 @@ static void do_uncompress(char *path, int fd, unsigned long offset, unsigned lon die(FSCK_UNCORRECTED, 0, "non-size (%ld vs %ld) bytes", out, size); } } + size -= out; if (opt_extract) { if (write(fd, outbuffer, out) < 0) { @@ -542,6 +571,9 @@ static void do_symlink(char *path, struct cramfs_inode *i) unsigned long next = *(u32 *) romfs_read(offset); unsigned long size; + if (reverse_endianness) + next = cramfsck_convert_u32(next); + if (offset == 0) { die(FSCK_UNCORRECTED, 0, "symbolic link has zero offset"); } @@ -685,7 +717,7 @@ int main(int argc, char **argv) die(FSCK_ERROR, 1, "failed to allocate outbuffer"); /* command line options */ - while ((c = getopt(argc, argv, "hx:v")) != EOF) { + while ((c = getopt(argc, argv, "hx:vb:")) != EOF) { switch (c) { case 'h': usage(FSCK_OK); @@ -700,6 +732,11 @@ int main(int argc, char **argv) case 'v': opt_verbose++; break; + case 'b': + page_size = atoi(optarg); + if (page_size <= 0) + usage(1); + break; } } - To unsubscribe from this list: send the line "unsubscribe util-linux-ng" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html