Support bigendian
authorRobert Pengelly <robertapengelly@hotmail.com>
Sun, 31 Aug 2025 19:10:00 +0000 (20:10 +0100)
committerRobert Pengelly <robertapengelly@hotmail.com>
Sun, 31 Aug 2025 19:10:00 +0000 (20:10 +0100)
common.c
common.h
e2cp.c
e2md.c
mke2fs.c

index aff66f18059d20d8dd5bee61059cb53a485b7606..560f16e4423a82131aedb946602ca4078c522971 100644 (file)
--- a/common.c
+++ b/common.c
 #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) {
@@ -176,8 +328,12 @@ static unsigned long gd_elem_val (struct cache_link *elem) {
 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);
 
 }
@@ -208,8 +364,12 @@ static unsigned long blkmap_elem_val (struct cache_link *elem) {
 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);
 
 }
@@ -226,8 +386,12 @@ static unsigned long inode_elem_val (struct cache_link *elem) {
 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);
 
 }
@@ -262,6 +426,10 @@ struct group_descriptor *get_gd (struct filesystem *fs, unsigned long no, struct
     
     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:
     
@@ -340,6 +508,10 @@ void finish_fs (struct filesystem *fs) {
     
     }
     
+    if (fs->swapit) {
+        swap_sb (fs->sb);
+    }
+    
     if (seekto (ofp, EXT2_SUPERBLOCK_OFFSET / BLOCKSIZE)) {
     
         report_at (program_name, 0, REPORT_ERROR, "fseek");
@@ -353,6 +525,10 @@ void finish_fs (struct filesystem *fs) {
         exit (EXIT_FAILURE);
     
     }
+    
+    if (fs->swapit) {
+        swap_sb (fs->sb);
+    }
 
 }
 
@@ -421,6 +597,10 @@ struct inode *get_nod (struct filesystem *fs, unsigned long nod, struct nod_info
     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:
@@ -764,6 +944,10 @@ static unsigned int *get_blkmap (struct filesystem *fs, unsigned long blk, struc
     bmi->b = get_blk (fs, blk, &bmi->bi);
     cache_add (&fs->blkmaps, &bmi->link);
     
+    if (fs->swapit) {
+        swap_block (bmi->b);
+    }
+    
 out:
 
     *rbmi = bmi;
@@ -1291,6 +1475,10 @@ void put_dir (struct dirwalker *dw) {
     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));
     
     }
@@ -1312,6 +1500,11 @@ struct directory *get_dir (struct filesystem *fs, unsigned long nod, struct dirw
     dw->need_flush = 1;
     
     memcpy (&dw->d, dw->last_d, sizeof (struct directory));
+    
+    if (fs->swapit) {
+        swap_dir (&dw->d);
+    }
+    
     return &dw->d;
 
 }
@@ -1321,7 +1514,13 @@ struct directory *next_dir (struct dirwalker *dw) {
     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) {
@@ -1334,6 +1533,10 @@ struct directory *next_dir (struct dirwalker *dw) {
     dw->last_d = next_d;
     memcpy (&dw->d, next_d, sizeof (struct directory));
     
+    if (dw->fs->swapit) {
+        swap_dir (&dw->d);
+    }
+    
     return &dw->d;
 
 }
@@ -1394,6 +1597,10 @@ struct directory *shrink_dir (struct dirwalker *dw, unsigned long nod, const cha
     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;
index e07fbcad3ce89e4d4047a1c9f8ba163633d157fb..d39c2ff447e68b6a8fbccf47ce0a5e277fd37052 100644 (file)
--- a/common.h
+++ b/common.h
@@ -15,6 +15,7 @@ extern unsigned long offset;
 extern char *outfile;
 extern char *program_name;
 
+extern int bigendian;
 extern FILE *ofp;
 
 int seekto (FILE *fp, unsigned long sector);
diff --git a/e2cp.c b/e2cp.c
index 28caf180ebc05ac245723f4a334c5fd3bf85c950..a2abcf733ad354e314acac2d0b274a02e762e53c 100644 (file)
--- a/e2cp.c
+++ b/e2cp.c
 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 {
 
@@ -37,6 +38,7 @@ static struct option opts[] = {
 
     {   "-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      },
@@ -181,6 +183,13 @@ static void parse_args (int argc, char **argv, int optind) {
         
         switch (popt->index) {
         
+            case OPTION_BIGENDIAN: {
+            
+                bigendian = 1;
+                break;
+            
+            }
+            
             case OPTION_HELP: {
             
                 print_help ();
@@ -796,7 +805,7 @@ int main (int argc, char **argv) {
     }
     
     fs = alloc_fs ();
-    fs->swapit = 0;
+    fs->swapit = bigendian;
     
     fs->sb = &sup;
     
diff --git a/e2md.c b/e2md.c
index f24935a7bb594c095505fbd4467e55ace4697aa0..763567b71f5fdb34dc573be33d762af2ae3d9763 100644 (file)
--- a/e2md.c
+++ b/e2md.c
 
 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 {
 
@@ -35,6 +36,7 @@ static struct option opts[] = {
 
     {   "-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      },
@@ -178,6 +180,13 @@ static void parse_args (int argc, char **argv, int optind) {
         
         switch (popt->index) {
         
+            case OPTION_BIGENDIAN: {
+            
+                bigendian = 1;
+                break;
+            
+            }
+            
             case OPTION_HELP: {
             
                 print_help ();
@@ -395,7 +404,7 @@ int main (int argc, char **argv) {
     }
     
     fs = alloc_fs ();
-    fs->swapit = 0;
+    fs->swapit = bigendian;
     
     fs->sb = &sup;
     
index 435904ebbae0e254f6ae498c7d0824c03dd824b4..03772d79480c4768876ee71db1b74d477fab583e 100644 (file)
--- a/mke2fs.c
+++ b/mke2fs.c
 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 {
 
@@ -35,6 +36,7 @@ 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      },
@@ -153,6 +155,13 @@ static void parse_args (int argc, char **argv, int optind) {
         
         switch (popt->index) {
         
+            case OPTION_BIGENDIAN: {
+            
+                bigendian = 1;
+                break;
+            
+            }
+            
             case OPTION_BOOT: {
             
                 if (boot_sector) { free (boot_sector); }
@@ -383,7 +392,7 @@ static void uuid_generate (unsigned char out[16]) {
 
 }
 
-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;
@@ -449,7 +458,7 @@ static struct filesystem *init_fs (long nbblocks, long nbinodes, long nbresrvd,
     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));
     
@@ -766,7 +775,7 @@ int main (int argc, char **argv) {
     
     }
     
-    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);