#include "inode.h"
#include "report.h"
+static void swap16 (unsigned char *arr) {
+
+ unsigned char temp[2];
+ memcpy (temp, arr, 2);
+
+ arr[0] = temp[1];
+ arr[1] = temp[0];
+
+}
+
+static void swap32 (unsigned char *arr) {
+
+ unsigned char temp[4];
+ memcpy (temp, arr, 4);
+
+ arr[0] = temp[3];
+ arr[1] = temp[2];
+ arr[2] = temp[1];
+ arr[3] = temp[0];
+
+}
+
+static void swap32_byte_array (unsigned char *arr, unsigned long n) {
+
+ unsigned char *temp = xmalloc (n * 4);
+ unsigned long i;
+
+ memcpy (temp, arr, n * 4);
+
+ for (i = 0; i < n; i++) {
+
+ arr[(i * 4) + 0] = temp[(i * 4) + 3];
+ arr[(i * 4) + 1] = temp[(i * 4) + 2];
+ arr[(i * 4) + 2] = temp[(i * 4) + 1];
+ arr[(i * 4) + 3] = temp[(i * 4) + 0];
+
+ }
+
+ free (temp);
+
+}
+
+static void swap_sb (struct superblock *sb) {
+
+ swap32 (sb->s_inodes_count);
+ swap32 (sb->s_blocks_count);
+
+ swap32 (sb->s_r_blocks_count);
+
+ swap32 (sb->s_free_blocks_count);
+ swap32 (sb->s_free_inodes_count);
+
+ swap32 (sb->s_first_data_block);
+
+ swap32 (sb->s_log_block_size);
+ swap32 (sb->s_log_frag_size);
+
+ swap32 (sb->s_blocks_per_group);
+ swap32 (sb->s_frags_per_group);
+ swap32 (sb->s_inodes_per_group);
+
+ swap32 (sb->s_mtime);
+ swap32 (sb->s_wtime);
+
+ swap16 (sb->s_mount_count);
+ swap16 (sb->s_max_mount_count);
+
+ swap16 (sb->s_magic);
+ swap16 (sb->s_state);
+ swap16 (sb->s_errors);
+
+ swap16 (sb->s_minor_rev_level);
+
+ swap32 (sb->s_lastcheck);
+ swap32 (sb->s_checkinterval);
+ swap32 (sb->s_creator_os);
+ swap32 (sb->s_rev_level);
+
+ swap16 (sb->s_def_resuid);
+ swap16 (sb->s_def_resgid);
+
+ swap32 (sb->s_first_ino);
+ swap16 (sb->s_inode_size);
+ swap16 (sb->s_block_group_nr);
+
+ swap32 (sb->s_feature_compat);
+ swap32 (sb->s_feature_incompat);
+ swap32 (sb->s_feature_ro_compat);
+
+ swap32 (sb->s_algorithm_usage_bitmap);
+
+}
+
+static void swap_gd (struct group_descriptor *gd) {
+
+ swap32 (gd->bg_block_bitmap);
+ swap32 (gd->bg_inode_bitmap);
+ swap32 (gd->bg_inode_table);
+
+ swap16 (gd->bg_free_blocks_count);
+ swap16 (gd->bg_free_inodes_count);
+ swap16 (gd->bg_used_dirs_count);
+
+}
+
+static void swap_nod (struct inode *nod) {
+
+ swap16 (nod->i_mode);
+ swap16 (nod->i_uid);
+ swap32 (nod->i_size);
+
+ swap32 (nod->i_atime);
+ swap32 (nod->i_ctime);
+ swap32 (nod->i_mtime);
+ swap32 (nod->i_dtime);
+
+ swap16 (nod->i_gid);
+ swap16 (nod->i_nlinks);
+
+ swap32 (nod->i_blocks);
+ swap32 (nod->i_flags);
+
+ swap32_byte_array (nod->i_block, EXT2_NBLOCKS);
+ swap32 (nod->i_version);
+
+ swap32 (nod->i_file_acl);
+ swap32 (nod->i_dir_acl);
+
+ swap32 (nod->i_faddr);
+
+}
+
+static void swap_dir (struct directory *dir) {
+
+ swap32 (dir->d_inode);
+
+ swap16 (dir->d_rec_len);
+ swap16 (dir->d_name_len);
+
+}
+
+static void swap_block (unsigned char *block) {
+
+ unsigned long i;
+
+ for (i = 0; i < BLOCKSIZE; i += 4) {
+ swap32 (block + i);
+ }
+
+}
+
unsigned long offset = 0;
char *program_name = 0;
char *outfile = 0;
+int bigendian = 0;
FILE *ofp = 0;
int seekto (FILE *fp, unsigned long sector) {
static void gd_freed (struct cache_link *elem) {
struct gd_info *gi = container_of (elem, struct gd_info, link);
- put_blk (gi->bi);
+ if (gi->fs->swapit) {
+ swap_gd (gi->gd);
+ }
+
+ put_blk (gi->bi);
free (gi);
}
static void blkmap_freed (struct cache_link *elem) {
struct blkmap_info *bmi = container_of (elem, struct blkmap_info, link);
- put_blk (bmi->bi);
+ if (bmi->fs->swapit) {
+ swap_block (bmi->b);
+ }
+
+ put_blk (bmi->bi);
free (bmi);
}
static void inode_freed (struct cache_link *elem) {
struct nod_info *ni = container_of (elem, struct nod_info, link);
- put_blk (ni->bi);
+ if (ni->fs->swapit) {
+ swap_nod (ni->itab);
+ }
+
+ put_blk (ni->bi);
free (ni);
}
gi->gd = ((struct group_descriptor *) get_blk (fs, gdblk, &gi->bi)) + offset;
cache_add (&fs->gds, &gi->link);
+
+ if (fs->swapit) {
+ swap_gd (gi->gd);
+ }
out:
}
+ if (fs->swapit) {
+ swap_sb (fs->sb);
+ }
+
if (seekto (ofp, EXT2_SUPERBLOCK_OFFSET / BLOCKSIZE)) {
report_at (program_name, 0, REPORT_ERROR, "fseek");
exit (EXIT_FAILURE);
}
+
+ if (fs->swapit) {
+ swap_sb (fs->sb);
+ }
}
ni->b = get_blk (fs, byte_array_to_integer (gd->bg_inode_table, 4) + boffset, &ni->bi);
ni->itab = ((struct inode *) ni->b) + offset;
+ if (fs->swapit) {
+ swap_nod (ni->itab);
+ }
+
put_gd (gi);
out:
bmi->b = get_blk (fs, blk, &bmi->bi);
cache_add (&fs->blkmaps, &bmi->link);
+ if (fs->swapit) {
+ swap_block (bmi->b);
+ }
+
out:
*rbmi = bmi;
if (dw->need_flush) {
/* Walk ended before reaching the end of block b. */
+ if (dw->fs->swapit) {
+ swap_dir (&dw->d);
+ }
+
memcpy (dw->last_d, &dw->d, sizeof (dw->d));
}
dw->need_flush = 1;
memcpy (&dw->d, dw->last_d, sizeof (struct directory));
+
+ if (fs->swapit) {
+ swap_dir (&dw->d);
+ }
+
return &dw->d;
}
unsigned char *next_d = dw->last_d + byte_array_to_integer (dw->d.d_rec_len, 2);
if (dw->need_flush) {
+
+ if (dw->fs->swapit) {
+ swap_dir (&dw->d);
+ }
+
memcpy (dw->last_d, &dw->d, sizeof (struct directory));
+
}
if (next_d - dw->b >= BLOCKSIZE) {
dw->last_d = next_d;
memcpy (&dw->d, next_d, sizeof (struct directory));
+ if (dw->fs->swapit) {
+ swap_dir (&dw->d);
+ }
+
return &dw->d;
}
preclen = byte_array_to_integer (d->d_rec_len, 2);
reclen -= preclen;
+ if (dw->fs->swapit) {
+ swap_dir (&dw->d);
+ }
+
memcpy (dw->last_d, &dw->d, sizeof (dw->d));
dw->last_d = dw->last_d + preclen;
static char *mode = 0;
static char *root = 0;
-#define OPTION_INPUT 0x0001
-#define OPTION_HELP 0x0002
-#define OPTION_MODE 0x0003
-#define OPTION_OFFSET 0x0004
-#define OPTION_ROOT 0x0005
+#define OPTION_BIGENDIAN 0x0001
+#define OPTION_INPUT 0x0002
+#define OPTION_HELP 0x0003
+#define OPTION_MODE 0x0004
+#define OPTION_OFFSET 0x0005
+#define OPTION_ROOT 0x0006
struct option {
{ "-i", OPTION_INPUT, OPTION_HAS_ARG },
+ { "--bigendian", OPTION_BIGENDIAN, OPTION_NO_ARG },
{ "--help", OPTION_HELP, OPTION_NO_ARG },
{ "--mode", OPTION_MODE, OPTION_HAS_ARG },
{ "--offset", OPTION_OFFSET, OPTION_HAS_ARG },
switch (popt->index) {
+ case OPTION_BIGENDIAN: {
+
+ bigendian = 1;
+ break;
+
+ }
+
case OPTION_HELP: {
print_help ();
}
fs = alloc_fs ();
- fs->swapit = 0;
+ fs->swapit = bigendian;
fs->sb = ⊃
static char *mode = 0;
-#define OPTION_INPUT 0x0001
-#define OPTION_HELP 0x0002
-#define OPTION_MODE 0x0003
-#define OPTION_OFFSET 0x0004
+#define OPTION_BIGENDIAN 0x0001
+#define OPTION_INPUT 0x0002
+#define OPTION_HELP 0x0003
+#define OPTION_MODE 0x0004
+#define OPTION_OFFSET 0x0005
struct option {
{ "-i", OPTION_INPUT, OPTION_HAS_ARG },
+ { "--bigendian", OPTION_BIGENDIAN, OPTION_NO_ARG },
{ "--help", OPTION_HELP, OPTION_NO_ARG },
{ "--mode", OPTION_MODE, OPTION_HAS_ARG },
{ "--offset", OPTION_OFFSET, OPTION_HAS_ARG },
switch (popt->index) {
+ case OPTION_BIGENDIAN: {
+
+ bigendian = 1;
+ break;
+
+ }
+
case OPTION_HELP: {
print_help ();
}
fs = alloc_fs ();
- fs->swapit = 0;
+ fs->swapit = bigendian;
fs->sb = ⊃
static unsigned long sectors = 0;
static char *boot_sector = 0;
-#define OPTION_BOOT 0x0001
-#define OPTION_HELP 0x0002
-#define OPTION_OFFSET 0x0003
-#define OPTION_SECTORS 0x0004
-#define OPTION_VERBOSE 0x0005
+#define OPTION_BIGENDIAN 0x0001
+#define OPTION_BOOT 0x0002
+#define OPTION_HELP 0x0003
+#define OPTION_OFFSET 0x0004
+#define OPTION_SECTORS 0x0005
+#define OPTION_VERBOSE 0x0006
struct option {
static struct option opts[] = {
+ { "--bigendian", OPTION_BIGENDIAN, OPTION_NO_ARG },
{ "--boot", OPTION_BOOT, OPTION_HAS_ARG },
{ "--help", OPTION_HELP, OPTION_NO_ARG },
{ "--offset", OPTION_OFFSET, OPTION_HAS_ARG },
switch (popt->index) {
+ case OPTION_BIGENDIAN: {
+
+ bigendian = 1;
+ break;
+
+ }
+
case OPTION_BOOT: {
if (boot_sector) { free (boot_sector); }
}
-static struct filesystem *init_fs (long nbblocks, long nbinodes, long nbresrvd, int holes, unsigned long fs_timestamp, unsigned long creator_os, int swapit) {
+static struct filesystem *init_fs (long nbblocks, long nbinodes, long nbresrvd, int holes, unsigned long fs_timestamp, unsigned long creator_os) {
struct group_descriptor *gd;
struct gd_info *gi;
free_blocks_per_group = nbblocks_per_group - overhead_per_group;
fs = alloc_fs ();
- fs->swapit = swapit;
+ fs->swapit = bigendian;
fs->sb = xmalloc (sizeof (*fs->sb));
}
- fs = init_fs (nbblocks, nbinodes, nbresrvd, holes, time (0), 0, 0);
+ fs = init_fs (nbblocks, nbinodes, nbresrvd, holes, time (0), 0);
fs_upgrade_rev1_largefile (fs);
finish_fs (fs);