From fbaec83bc0fda4341862cc60ac9796277235e4b9 Mon Sep 17 00:00:00 2001 From: "Signed-off-by: Roy Peled" Date: Wed, 4 Feb 2009 14:56:54 +0100 Subject: [PATCH] mkfs.cramfs: add endianness support to cramfs tools cramfs is an endianness dependent file system. So far, the cramfs utilities did not support cramfs images of different endianness than the host machine. A separate utility, cramfsswap, was required in order to change the endianness of the image before and after using cramfs utilities. The extra utility introduced extra maintenance and an additional step in the process. This patch adds endianness support to mkfs.cramfs and fsck.cramfs. fsck.cramfs now automatically detects the image endianness, and can work on images of either endianness. mkfs.cramfs now accepts a new optional parameter (-N) that allows creating the cramfs image in either endianness. Signed-off-by: Roy Peled Signed-off-by: Karel Zak --- configure.ac | 1 + disk-utils/Makefile.am | 5 +- disk-utils/cramfs_common.c | 105 +++++++++++++++++++++++ disk-utils/cramfs_common.h | 37 ++++++++ disk-utils/fsck.cramfs.c | 49 ++++++++--- disk-utils/mkfs.cramfs.c | 32 ++++++- tests/Makefile.am | 2 + tests/commands.sh.in | 1 + tests/expected/ts-cramfs-endianness-fsck | 8 ++ tests/expected/ts-cramfs-endianness-mkfs | 4 + tests/input/cramfs-big.img | Bin 0 -> 4096 bytes tests/input/cramfs-little.img | Bin 0 -> 4096 bytes tests/ts-cramfs-endianness-fsck | 59 +++++++++++++ tests/ts-cramfs-endianness-mkfs | 55 ++++++++++++ 14 files changed, 340 insertions(+), 18 deletions(-) create mode 100644 disk-utils/cramfs_common.c create mode 100644 disk-utils/cramfs_common.h create mode 100644 tests/expected/ts-cramfs-endianness-fsck create mode 100644 tests/expected/ts-cramfs-endianness-mkfs create mode 100644 tests/input/cramfs-big.img create mode 100644 tests/input/cramfs-little.img create mode 100755 tests/ts-cramfs-endianness-fsck create mode 100755 tests/ts-cramfs-endianness-mkfs diff --git a/configure.ac b/configure.ac index 3bbfd5736..35d60e8b5 100644 --- a/configure.ac +++ b/configure.ac @@ -27,6 +27,7 @@ esac AC_PROG_CC_STDC AC_GNU_SOURCE AC_CANONICAL_HOST +AC_C_BIGENDIAN linux_os=no case ${host_os} in diff --git a/disk-utils/Makefile.am b/disk-utils/Makefile.am index 2304b2a09..c2cc2f9f0 100644 --- a/disk-utils/Makefile.am +++ b/disk-utils/Makefile.am @@ -38,9 +38,10 @@ endif endif if BUILD_CRAMFS +cramfs_common = $(utils_common) cramfs.h cramfs_common.c cramfs_common.h sbin_PROGRAMS += fsck.cramfs mkfs.cramfs -fsck_cramfs_SOURCES = fsck.cramfs.c cramfs.h $(utils_common) -mkfs_cramfs_SOURCES = mkfs.cramfs.c cramfs.h ../lib/md5.c $(utils_common) +fsck_cramfs_SOURCES = fsck.cramfs.c $(cramfs_common) +mkfs_cramfs_SOURCES = mkfs.cramfs.c $(cramfs_common) ../lib/md5.c fsck_cramfs_LDADD = -lz mkfs_cramfs_LDADD = -lz endif diff --git a/disk-utils/cramfs_common.c b/disk-utils/cramfs_common.c new file mode 100644 index 000000000..ffdad9b09 --- /dev/null +++ b/disk-utils/cramfs_common.c @@ -0,0 +1,105 @@ +/* + * cramfs_common - cramfs common code + * + * Copyright (c) 2008 Roy Peled, the.roy.peled -at- gmail.com + * Copyright (c) 2004-2006 by Michael Holzt, kju -at- fqdn.org + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include "cramfs_common.h" +#include "../include/bitops.h" + +u32 u32_toggle_endianness(int big_endian, u32 what) +{ + return big_endian == HOST_IS_BIG_ENDIAN ? what : swab32(what); +} + +void super_toggle_endianness(int big_endian, struct cramfs_super *super) +{ + if (big_endian != HOST_IS_BIG_ENDIAN) { + super->magic = swab32(super->magic); + super->size = swab32(super->size); + super->flags = swab32(super->flags); + super->future = swab32(super->future); + super->fsid.crc = swab32(super->fsid.crc); + super->fsid.edition = swab32(super->fsid.edition); + super->fsid.blocks = swab32(super->fsid.blocks); + super->fsid.files = swab32(super->fsid.files); + } +} + +void inode_toggle_endianness(int input_big_endian, int output_big_endian, struct cramfs_inode *inode_in, struct cramfs_inode *inode_out) +{ + if (input_big_endian == output_big_endian) { + memmove(inode_out, inode_in, sizeof(*inode_out)); + } + else { + unsigned char inode_out_buf[sizeof(*inode_in)]; + unsigned char *inode_in_buf = (unsigned char*)inode_in; + + inode_out_buf[0] = inode_in_buf[1]; /* 16 bit: mode */ + inode_out_buf[1] = inode_in_buf[0]; + + inode_out_buf[2] = inode_in_buf[3]; /* 16 bit: uid */ + inode_out_buf[3] = inode_in_buf[2]; + + inode_out_buf[4] = inode_in_buf[6]; /* 24 bit: size */ + inode_out_buf[5] = inode_in_buf[5]; + inode_out_buf[6] = inode_in_buf[4]; + + inode_out_buf[7] = inode_in_buf[7]; /* 8 bit: gid width */ + + /* Stop the madness! Outlaw C bitfields! They are unportable and nasty! + See for yourself what a mess this is: */ + + if (output_big_endian) { + inode_out_buf[ 8] = ( (inode_in_buf[ 8]&0x3F) << 2 ) | + ( (inode_in_buf[11]&0xC0) >> 6 ); + + inode_out_buf[ 9] = ( (inode_in_buf[11]&0x3F) << 2 ) | + ( (inode_in_buf[10]&0xC0) >> 6 ); + + inode_out_buf[10] = ( (inode_in_buf[10]&0x3F) << 2 ) | + ( (inode_in_buf[ 9]&0xC0) >> 6 ); + + inode_out_buf[11] = ( (inode_in_buf[ 9]&0x3F) << 2 ) | + ( (inode_in_buf[ 8]&0xC0) >> 6 ); + } + else { + inode_out_buf[ 8] = ( (inode_in_buf[ 8]&0xFD) >> 2 ) | + ( (inode_in_buf[11]&0x03) << 6 ); + + inode_out_buf[ 9] = ( (inode_in_buf[11]&0xFD) >> 2 ) | + ( (inode_in_buf[10]&0x03) << 6 ); + + inode_out_buf[10] = ( (inode_in_buf[10]&0xFD) >> 2 ) | + ( (inode_in_buf[ 9]&0x03) << 6 ); + + inode_out_buf[11] = ( (inode_in_buf[ 9]&0xFD) >> 2 ) | + ( (inode_in_buf[ 8]&0x03) << 6 ); + } + + memmove(inode_out, inode_out_buf, sizeof(*inode_out)); + } +} + +void inode_to_host(int from_big_endian, struct cramfs_inode *inode_in, struct cramfs_inode *inode_out) +{ + inode_toggle_endianness(from_big_endian, HOST_IS_BIG_ENDIAN, inode_in, inode_out); +} + +void inode_from_host(int to_big_endian, struct cramfs_inode *inode_in, struct cramfs_inode *inode_out) +{ + inode_toggle_endianness(HOST_IS_BIG_ENDIAN, to_big_endian, inode_in, inode_out); +} diff --git a/disk-utils/cramfs_common.h b/disk-utils/cramfs_common.h new file mode 100644 index 000000000..6311bce25 --- /dev/null +++ b/disk-utils/cramfs_common.h @@ -0,0 +1,37 @@ +/* + * cramfs_common - cramfs common code + * + * Copyright (c) 2008 Roy Peled, the.roy.peled -at- gmail + * Copyright (c) 2004-2006 by Michael Holzt, kju -at- fqdn.org + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef __CRAMFS_COMMON_H +#define __CRAMFS_COMMON_H + +#include "cramfs.h" + +#ifndef HOST_IS_BIG_ENDIAN +#ifdef WORDS_BIGENDIAN +#define HOST_IS_BIG_ENDIAN 1 +#else +#define HOST_IS_BIG_ENDIAN 0 +#endif +#endif + +u32 u32_toggle_endianness(int big_endian, u32 what); +void super_toggle_endianness(int from_big_endian, struct cramfs_super *super); +void inode_to_host(int from_big_endian, struct cramfs_inode *inode_in, struct cramfs_inode *inode_out); +void inode_from_host(int to_big_endian, struct cramfs_inode *inode_in, struct cramfs_inode *inode_out); + +#endif diff --git a/disk-utils/fsck.cramfs.c b/disk-utils/fsck.cramfs.c index 2d11a4071..d388e7874 100644 --- a/disk-utils/fsck.cramfs.c +++ b/disk-utils/fsck.cramfs.c @@ -55,6 +55,7 @@ #include /* for major, minor */ #include "cramfs.h" +#include "cramfs_common.h" #include "nls.h" #include "blkdev.h" @@ -63,6 +64,7 @@ static const char *progname = "cramfsck"; static int fd; /* ROM image file descriptor */ static char *filename; /* ROM image filename */ struct cramfs_super super; /* just find the cramfs superblock once */ +static int cramfs_is_big_endian = 0; /* source is big endian */ static int opt_verbose = 0; /* 1 = verbose (-v), 2+ = very verbose (-vv) */ char *extract_dir = NULL; /* extraction directory (-x) */ @@ -139,6 +141,21 @@ static void die(int status, int syserr, const char *fmt, ...) exit(status); } +int get_superblock_endianness(u32 magic) +{ + if (magic == CRAMFS_MAGIC) { + cramfs_is_big_endian = HOST_IS_BIG_ENDIAN; + return 0; + } + else if (magic == u32_toggle_endianness(!HOST_IS_BIG_ENDIAN, CRAMFS_MAGIC)) { + cramfs_is_big_endian = !HOST_IS_BIG_ENDIAN; + return 0; + } + else { + return -1; + } +} + static void test_super(int *start, size_t *length) { struct stat st; @@ -172,7 +189,7 @@ 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) { + if (get_superblock_endianness(super.magic) != -1) { *start = 0; } else if (*length >= (PAD_SIZE + sizeof(super))) { @@ -180,15 +197,22 @@ 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) { + if (get_superblock_endianness(super.magic) != -1) { *start = PAD_SIZE; } + else { + die(FSCK_UNCORRECTED, 0, "superblock magic not found"); + } } - - /* superblock tests */ - if (super.magic != CRAMFS_MAGIC) { + else { die(FSCK_UNCORRECTED, 0, _("superblock magic not found")); } + + if (opt_verbose) { + printf("cramfs endianness is %s\n", cramfs_is_big_endian ? "big" : "little"); + } + + super_toggle_endianness(cramfs_is_big_endian, &super); if (super.flags & ~CRAMFS_SUPPORTED_FLAGS) { die(FSCK_ERROR, 0, _("unsupported filesystem features")); } @@ -314,7 +338,7 @@ static struct cramfs_inode *cramfs_iget(struct cramfs_inode * i) if (!inode) { die(FSCK_ERROR, 1, _("malloc failed")); } - *inode = *i; + inode_to_host(cramfs_is_big_endian, i, inode); return inode; } @@ -333,9 +357,10 @@ static void iput(struct cramfs_inode *inode) */ static struct cramfs_inode *read_super(void) { - unsigned long offset = super.root.offset << 2; + struct cramfs_inode * root = cramfs_iget(&super.root); + unsigned long offset = root->offset << 2; - if (!S_ISDIR(super.root.mode)) + if (!S_ISDIR(root->mode)) die(FSCK_UNCORRECTED, 0, _("root inode is not directory")); if (!(super.flags & CRAMFS_FLAG_SHIFTED_ROOT_OFFSET) && ((offset != sizeof(struct cramfs_super)) && @@ -343,7 +368,7 @@ static struct cramfs_inode *read_super(void) { die(FSCK_UNCORRECTED, 0, _("bad root offset (%lu)"), offset); } - return cramfs_iget(&super.root); + return root; } static int uncompress_block(void *src, int len) @@ -378,7 +403,7 @@ static void do_uncompress(char *path, int fd, unsigned long offset, unsigned lon do { unsigned long out = page_size; - unsigned long next = *(u32 *) romfs_read(offset); + unsigned long next = u32_toggle_endianness(cramfs_is_big_endian, *(u32 *) romfs_read(offset)); if (next > end_data) { end_data = next; @@ -387,7 +412,7 @@ static void do_uncompress(char *path, int fd, unsigned long offset, unsigned lon offset += 4; if (curr == next) { if (opt_verbose > 1) { - printf(_(" hole at %ld (%d)\n"), curr, page_size); + printf(_(" hole at %ld (%zd)\n"), curr, page_size); } if (size < page_size) out = size; @@ -539,7 +564,7 @@ static void do_symlink(char *path, struct cramfs_inode *i) { unsigned long offset = i->offset << 2; unsigned long curr = offset + 4; - unsigned long next = *(u32 *) romfs_read(offset); + unsigned long next = u32_toggle_endianness(cramfs_is_big_endian, *(u32 *) romfs_read(offset)); unsigned long size; if (offset == 0) { diff --git a/disk-utils/mkfs.cramfs.c b/disk-utils/mkfs.cramfs.c index 1138bfdcc..5ac2c5b97 100644 --- a/disk-utils/mkfs.cramfs.c +++ b/disk-utils/mkfs.cramfs.c @@ -38,6 +38,7 @@ #include #include "cramfs.h" +#include "cramfs_common.h" #include "md5.h" #include "nls.h" @@ -55,6 +56,7 @@ static int verbose = 0; static unsigned int blksize; /* settable via -b option */ static long total_blocks = 0, total_nodes = 1; /* pre-count the root node */ static int image_length = 0; +static int cramfs_is_big_endian = 0; /* target is big endian */ /* * If opt_holes is set, then mkcramfs can create explicit holes in the @@ -121,7 +123,7 @@ usage(int status) { FILE *stream = status ? stderr : stdout; fprintf(stream, - _("usage: %s [-h] [-v] [-b blksize] [-e edition] [-i file] " + _("usage: %s [-h] [-v] [-b blksize] [-e edition] [-N endian] [-i file] " "[-n name] dirname outfile\n" " -h print this help\n" " -v be verbose\n" @@ -129,6 +131,7 @@ usage(int status) { "(non-zero exit status)\n" " -b blksize use this blocksize, must equal page size\n" " -e edition set edition number (part of fsid)\n" + " -N endian set cramfs endianness (big|little|host), default host\n" " -i file insert a file image into the filesystem " "(requires >= 2.4.0)\n" " -n name set name of cramfs filesystem\n" @@ -454,17 +457,22 @@ static unsigned int write_superblock(struct entry *root, char *base, int size) super->root.size = root->size; super->root.offset = offset >> 2; + super_toggle_endianness(cramfs_is_big_endian, super); + inode_from_host(cramfs_is_big_endian, &super->root, &super->root); + return offset; } static void set_data_offset(struct entry *entry, char *base, unsigned long offset) { struct cramfs_inode *inode = (struct cramfs_inode *) (base + entry->dir_offset); + inode_to_host(cramfs_is_big_endian, inode, inode); if (offset >= (1 << (2 + CRAMFS_OFFSET_WIDTH))) { fprintf(stderr, _("filesystem too big. Exiting.\n")); exit(8); } inode->offset = (offset >> 2); + inode_from_host(cramfs_is_big_endian, inode, inode); } @@ -523,6 +531,7 @@ static unsigned int write_directory_structure(struct entry *entry, char *base, u entry_stack[stack_entries] = entry; stack_entries++; } + inode_from_host(cramfs_is_big_endian, inode, inode); entry = entry->next; } @@ -630,7 +639,7 @@ do_compress(char *base, unsigned int offset, unsigned char const *name, exit(8); } - *(u32 *) (base + offset) = curr; + *(u32 *) (base + offset) = u32_toggle_endianness(cramfs_is_big_endian, curr); offset += 4; } while (size); @@ -734,6 +743,7 @@ int main(int argc, char **argv) char const *dirname, *outfile; u32 crc = crc32(0L, Z_NULL, 0); int c; + cramfs_is_big_endian = HOST_IS_BIG_ENDIAN; /* default is to use host order */ blksize = getpagesize(); total_blocks = 0; @@ -750,7 +760,7 @@ int main(int argc, char **argv) textdomain(PACKAGE); /* command line options */ - while ((c = getopt(argc, argv, "hb:Ee:i:n:psVvz")) != EOF) { + while ((c = getopt(argc, argv, "hb:Ee:i:n:N:psVvz")) != EOF) { switch (c) { case 'h': usage(0); @@ -764,6 +774,20 @@ int main(int argc, char **argv) break; case 'e': opt_edition = atoi(optarg); + break; + case 'N': + if (strcmp(optarg, "big") == 0) { + cramfs_is_big_endian = 1; + } + else if (strcmp(optarg, "little") == 0) { + cramfs_is_big_endian = 0; + } + else if (strcmp(optarg, "host") == 0); /* default */ + else { + perror("invalid endianness given. Must be 'big', 'little', or 'host'"); + exit(16); + } + break; case 'i': opt_image = optarg; @@ -891,7 +915,7 @@ int main(int argc, char **argv) /* Put the checksum in. */ crc = crc32(crc, (unsigned char *) (rom_image+opt_pad), (offset-opt_pad)); - ((struct cramfs_super *) (rom_image+opt_pad))->fsid.crc = crc; + ((struct cramfs_super *) (rom_image+opt_pad))->fsid.crc = u32_toggle_endianness(cramfs_is_big_endian, crc); if (verbose) printf(_("CRC: %x\n"), crc); diff --git a/tests/Makefile.am b/tests/Makefile.am index 1144606e2..9010e1670 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -13,6 +13,8 @@ EXTRA_DIST = expected \ ts-cal-y \ ts-col-multibyte \ ts-cramfs-mkfs \ + ts-cramfs-endianness-mkfs \ + ts-cramfs-endianness-fsck \ ts-fstab-devname \ ts-fstab-devname2label \ ts-fstab-devname2uuid \ diff --git a/tests/commands.sh.in b/tests/commands.sh.in index 25b3c3a5a..3024e9467 100644 --- a/tests/commands.sh.in +++ b/tests/commands.sh.in @@ -27,6 +27,7 @@ TS_CMD_MTABLOCK=${TS_CMD_MTABLOCK:-"$TOPDIR/mount/mtab_lock_test"} TS_CMD_MKSWAP=${TS_CMD_MKSWAP:-"$TOPDIR/disk-utils/mkswap"} TS_CMD_MKCRAMFS=${TS_CMD_MKCRAMFS:-"$TOPDIR/disk-utils/mkfs.cramfs"} +TS_CMD_FSCKCRAMFS=${TS_CMD_FSCKCRAMFS:-"$TOPDIR/disk-utils/fsck.cramfs"} TS_CMD_IPCS=${TS_CMD_IPCS:-"$TOPDIR/sys-utils/ipcs"} diff --git a/tests/expected/ts-cramfs-endianness-fsck b/tests/expected/ts-cramfs-endianness-fsck new file mode 100644 index 000000000..a7591b688 --- /dev/null +++ b/tests/expected/ts-cramfs-endianness-fsck @@ -0,0 +1,8 @@ +extract from little endian +little +create big endian +bc0b7bbef02765d32e07faa735d2e0c6 +extract from big endian +big +create little endian +4666f0d2b661f9f3962877edabadb210 diff --git a/tests/expected/ts-cramfs-endianness-mkfs b/tests/expected/ts-cramfs-endianness-mkfs new file mode 100644 index 000000000..ef935a7f3 --- /dev/null +++ b/tests/expected/ts-cramfs-endianness-mkfs @@ -0,0 +1,4 @@ +create little endian +4666f0d2b661f9f3962877edabadb210 +create big endian +bc0b7bbef02765d32e07faa735d2e0c6 diff --git a/tests/input/cramfs-big.img b/tests/input/cramfs-big.img new file mode 100644 index 0000000000000000000000000000000000000000..2ea516ed684f9b7c4348a59d524b45cf19a7aca8 GIT binary patch literal 4096 zcmdNmYwOCuAiw|w%pk%!KewPLwYWGnMIp%F*Dd&Rz!@fxI1sRcFhU+I#^CrCM1%DU z!`Lhg4B{!7MUD`@0t1jQ4dgpDE&(b9ng--6CjyyZz73dfoCGq4f#Gz;9Bxlty_09W z!#(u8&iHDF8JHNE8JZez-(V6@aMt^z&zaNSx_V(A=RADR9aBFpYLs>6f(aXg`H4l1 zK<$jiK->$&&w&5 z`&`T@V6yOMrj48Ud@JUhCN@MTMa4{-X`Xdvh2i33JyOPK44%4VhKn&Lv%s-6N{oiU jXb6mkz-S1JhQMeDjE2By2#kinXb6mkz-R~znGgT~tnA4e literal 0 HcmV?d00001 diff --git a/tests/input/cramfs-little.img b/tests/input/cramfs-little.img new file mode 100644 index 0000000000000000000000000000000000000000..a1dfab5d3a1611c5cbc9163935e81f479c1613cc GIT binary patch literal 4096 zcmZ>@J*&YWz`(%F00GYVxdlb3#l@*93PJw9Zo#uJTb=^RutG6H9-{uOBLhe~!vPis z1{nJwP;p9Tkt2w&0F*n(2If00X#{eZfP4-HhD0C}%(nsZc^DXyfc(=yTrr2+Q&;cg z8SiipJ+Cvq+F=GJMrMYl#@jcT1QeY0KIwDjw70Han8!H}-*d;*kBb^*ow;Db#$bM8 zQ6qyfBLhP(5I+ZE3!ps}bKaiW&D&tW<8W}ErVZ2o^9(r?Se4WrS_&F(#^*Tretb1q zFQvZg?V|EMX499w{gpW9+0toOgF4f0#(p_bRTn9mfeQZJ-XnjPR|9S=!$q*M2N-e= zFa;V2D8?jw6X#aQ>RSE&%OQhlMmHxdp1I5WmZ|K~HFfE?RboHJ#ID+vx!Z2f+IU_z z6!1*`40D++uN1n;KnEXSn#c(;*_5{wWO9!0L7iRQa)JIUUxA(MHS_K5F4bR?bHw)^ z-um-C7c&Z&Ec}^i<0d}eiaDo=4be$aF_UJRXPsGLxcFF)lrb8Er!JY{V$8`bU{sBQ l(GVC7fzc2c4S~@R7!85Z5Eu=C(GVC7fzc2c4S^vP0stuC%+>$^ literal 0 HcmV?d00001 diff --git a/tests/ts-cramfs-endianness-fsck b/tests/ts-cramfs-endianness-fsck new file mode 100755 index 000000000..c9d483a95 --- /dev/null +++ b/tests/ts-cramfs-endianness-fsck @@ -0,0 +1,59 @@ +#!/bin/bash + +# +# Copyright (C) 2007 Karel Zak +# +# This file is part of util-linux-ng. +# +# This file is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This file is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +. ./commands.sh +. ./functions.sh + +TS_COMPONENT="mkfs.cramfs" +TS_DESC="endianness-fsck" + +ts_init "$*" +ts_skip_nonroot + +set -o pipefail + +($TS_CMD_FSCKCRAMFS -x TEST_X_FLAG 2>&1 || true) \ + | grep -q "compiled without -x support" && ts_skip "fsck: compiled without -x support" + +IMAGE_LITTLE="$TS_INPUTDIR/cramfs-little.img" #Known good little endian image +IMAGE_BIG="$TS_INPUTDIR/cramfs-big.img" #Known good big endian image + +IMAGE_CREATED="$TS_OUTDIR/cramfs.img" #Image created during the test and compared against the known images. +IMAGE_DATA="$TS_OUTDIR/cramfs-endianness-data" + +test_image() { + local FROM_ENDIANNESS="$1"; shift + local TO_ENDIANNESS="$1"; shift + local FROM_IMAGE="$1"; shift + + rm -rf "$IMAGE_DATA" + ts_log "extract from $FROM_ENDIANNESS endian" + $TS_CMD_FSCKCRAMFS -v -x $IMAGE_DATA $FROM_IMAGE | head -n1 | cut -d" " -f4 2>&1 >> $TS_OUTPUT + + ts_log "create $TO_ENDIANNESS endian" + $TS_CMD_MKCRAMFS -N "$TO_ENDIANNESS" "$IMAGE_DATA" "$IMAGE_CREATED" 2>&1 >> $TS_OUTPUT + + md5sum $IMAGE_CREATED | cut -d" " -f1 >> $TS_OUTPUT + + rm "$IMAGE_CREATED" +} + +test_image "little" "big" "$IMAGE_LITTLE" +test_image "big" "little" "$IMAGE_BIG" + +ts_finalize + diff --git a/tests/ts-cramfs-endianness-mkfs b/tests/ts-cramfs-endianness-mkfs new file mode 100755 index 000000000..90dc93b17 --- /dev/null +++ b/tests/ts-cramfs-endianness-mkfs @@ -0,0 +1,55 @@ +#!/bin/bash + +# +# Copyright (C) 2007 Karel Zak +# +# This file is part of util-linux-ng. +# +# This file is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This file is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +. ./commands.sh +. ./functions.sh + +TS_COMPONENT="mkfs.cramfs" +TS_DESC="endianness-mkfs" + +ts_init "$*" +ts_skip_nonroot + +set -o pipefail + +IMAGE_DATA="$TS_OUTDIR/cramfs-endianness-data" +IMAGE_CREATED="$TS_OUTDIR/cramfs.img" #Image created during the test and compared against the known images. + +test_image() { + local TO_ENDIANNESS="$1"; shift + ts_log "create $TO_ENDIANNESS endian" + + $TS_CMD_MKCRAMFS -N "$TO_ENDIANNESS" "$IMAGE_DATA" "$IMAGE_CREATED" 2>&1 >> $TS_OUTPUT + + md5sum $IMAGE_CREATED | cut -d" " -f1 >> $TS_OUTPUT + + rm "$IMAGE_CREATED" +} + +#generate test data +mkdir -p $IMAGE_DATA/dirA/dirB +yes "Testing cramfs 1234567890 Endianness check 1234567890 Endianness check" \ + | dd of=$IMAGE_DATA/dirA/dirB/a bs=512 count=1 &> /dev/null +yes "Testing cramfs 1234567890 Endianness check 1234567890 Endianness check" \ + | dd of=$IMAGE_DATA/dirA/dirB/b bs=512 count=30 &> /dev/null + +#perform tests for both endians +test_image "little" +test_image "big" + +ts_finalize +