X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=fsck_minix.c;h=9ebabe9e5801a2c9b7523076b7128b73e95eb3e0;hb=f3b2b52b589bccae28b1740c155733028f2b8fd5;hp=084c76d36cd5ee31c612e75b2fb9ac344d110023;hpb=e49d5ecbbe51718fa925b6890a735e5937cc2aa2;p=oweals%2Fbusybox.git diff --git a/fsck_minix.c b/fsck_minix.c index 084c76d36..9ebabe9e5 100644 --- a/fsck_minix.c +++ b/fsck_minix.c @@ -86,7 +86,7 @@ * enforced (but it's not much fun on a character device :-). */ -#include "internal.h" +#include "busybox.h" #include #include #include @@ -96,14 +96,103 @@ #include #include #include -#include -#include /* for PATH_MAX */ +#include -#include -#include + + typedef unsigned char u8; +typedef unsigned short u16; +typedef unsigned int u32; -#ifdef MINIX2_SUPER_MAGIC2 -#define HAVE_MINIX2 1 + +#define MINIX_ROOT_INO 1 +#define MINIX_LINK_MAX 250 +#define MINIX2_LINK_MAX 65530 + +#define MINIX_I_MAP_SLOTS 8 +#define MINIX_Z_MAP_SLOTS 64 +#define MINIX_SUPER_MAGIC 0x137F /* original minix fs */ +#define MINIX_SUPER_MAGIC2 0x138F /* minix fs, 30 char names */ +#define MINIX2_SUPER_MAGIC 0x2468 /* minix V2 fs */ +#define MINIX2_SUPER_MAGIC2 0x2478 /* minix V2 fs, 30 char names */ +#define MINIX_VALID_FS 0x0001 /* Clean fs. */ +#define MINIX_ERROR_FS 0x0002 /* fs has errors. */ + +#define MINIX_INODES_PER_BLOCK ((BLOCK_SIZE)/(sizeof (struct minix_inode))) +#define MINIX2_INODES_PER_BLOCK ((BLOCK_SIZE)/(sizeof (struct minix2_inode))) + +#define MINIX_V1 0x0001 /* original minix fs */ +#define MINIX_V2 0x0002 /* minix V2 fs */ + +#define INODE_VERSION(inode) inode->i_sb->u.minix_sb.s_version + +/* + * This is the original minix inode layout on disk. + * Note the 8-bit gid and atime and ctime. + */ +struct minix_inode { + u16 i_mode; + u16 i_uid; + u32 i_size; + u32 i_time; + u8 i_gid; + u8 i_nlinks; + u16 i_zone[9]; +}; + +/* + * The new minix inode has all the time entries, as well as + * long block numbers and a third indirect block (7+1+1+1 + * instead of 7+1+1). Also, some previously 8-bit values are + * now 16-bit. The inode is now 64 bytes instead of 32. + */ +struct minix2_inode { + u16 i_mode; + u16 i_nlinks; + u16 i_uid; + u16 i_gid; + u32 i_size; + u32 i_atime; + u32 i_mtime; + u32 i_ctime; + u32 i_zone[10]; +}; + +/* + * minix super-block data on disk + */ +struct minix_super_block { + u16 s_ninodes; + u16 s_nzones; + u16 s_imap_blocks; + u16 s_zmap_blocks; + u16 s_firstdatazone; + u16 s_log_zone_size; + u32 s_max_size; + u16 s_magic; + u16 s_state; + u32 s_zones; +}; + +struct minix_dir_entry { + u16 inode; + char name[0]; +}; + +#define BLOCK_SIZE_BITS 10 +#define BLOCK_SIZE (1<> 3] & (1<<(i & 7))) != 0; +} #define inode_in_use(x) (bit(inode_map,(x))) #define zone_in_use(x) (bit(zone_map,(x)-FIRSTZONE+1)) @@ -196,26 +291,12 @@ static void leave(int status) static void show_usage(void) { - fprintf(stderr, "BusyBox v%s (%s) multi-call binary -- GPL2\n\n", - BB_VER, BB_BT); - fprintf(stderr, "Usage: %s [-larvsmf] /dev/name\n\n", program_name); - fprintf(stderr, - "Performs a consistency check for MINIX filesystems.\n\n"); - fprintf(stderr, "OPTIONS:\n"); - fprintf(stderr, "\t-l\tLists all filenames\n"); - fprintf(stderr, "\t-r\tPerform interactive repairs\n"); - fprintf(stderr, "\t-a\tPerform automatic repairs\n"); - fprintf(stderr, "\t-v\tverbose\n"); - fprintf(stderr, "\t-s\tOutputs super-block information\n"); - fprintf(stderr, - "\t-m\tActivates MINIX-like \"mode not cleared\" warnings\n"); - fprintf(stderr, "\t-f\tForce file system check.\n\n"); - leave(16); + usage(fsck_minix_usage); } static void die(const char *str) { - fprintf(stderr, "%s: %s\n", program_name, str); + error_msg("%s\n", str); leave(8); } @@ -344,7 +425,7 @@ static int check_zone_nr(unsigned short *nr, int *corrected) return 0; } -#ifdef HAVE_MINIX2 +#ifdef BB_FEATURE_MINIX2 static int check_zone_nr2(unsigned int *nr, int *corrected) { if (!*nr) @@ -451,7 +532,7 @@ static int map_block(struct minix_inode *inode, unsigned int blknr) return result; } -#ifdef HAVE_MINIX2 +#ifdef BB_FEATURE_MINIX2 static int map_block2(struct minix2_inode *inode, unsigned int blknr) { unsigned int ind[BLOCK_SIZE >> 2]; @@ -549,7 +630,7 @@ static void get_dirsize(void) char blk[BLOCK_SIZE]; int size; -#if HAVE_MINIX2 +#ifdef BB_FEATURE_MINIX2 if (version2) block = Inode2[ROOT_INO].i_zone[0]; else @@ -580,7 +661,7 @@ static void read_superblock(void) namelen = 30; dirsize = 32; version2 = 0; -#ifdef HAVE_MINIX2 +#ifdef BB_FEATURE_MINIX2 } else if (MAGIC == MINIX2_SUPER_MAGIC) { namelen = 14; dirsize = 16; @@ -602,23 +683,13 @@ static void read_superblock(void) static void read_tables(void) { - inode_map = malloc(IMAPS * BLOCK_SIZE); - if (!inode_map) - die("Unable to allocate buffer for inode map"); - zone_map = malloc(ZMAPS * BLOCK_SIZE); - if (!inode_map) - die("Unable to allocate buffer for zone map"); + inode_map = xmalloc(IMAPS * BLOCK_SIZE); + zone_map = xmalloc(ZMAPS * BLOCK_SIZE); memset(inode_map, 0, sizeof(inode_map)); memset(zone_map, 0, sizeof(zone_map)); - inode_buffer = malloc(INODE_BUFFER_SIZE); - if (!inode_buffer) - die("Unable to allocate buffer for inodes"); - inode_count = malloc(INODES + 1); - if (!inode_count) - die("Unable to allocate buffer for inode count"); - zone_count = malloc(ZONES); - if (!zone_count) - die("Unable to allocate buffer for zone count"); + inode_buffer = xmalloc(INODE_BUFFER_SIZE); + inode_count = xmalloc(INODES + 1); + zone_count = xmalloc(ZONES); if (IMAPS * BLOCK_SIZE != read(IN, inode_map, IMAPS * BLOCK_SIZE)) die("Unable to read inode map"); if (ZMAPS * BLOCK_SIZE != read(IN, zone_map, ZMAPS * BLOCK_SIZE)) @@ -688,7 +759,7 @@ struct minix_inode *get_inode(unsigned int nr) return inode; } -#ifdef HAVE_MINIX2 +#ifdef BB_FEATURE_MINIX2 struct minix2_inode *get_inode2(unsigned int nr) { struct minix2_inode *inode; @@ -744,7 +815,7 @@ static void check_root(void) die("root inode isn't a directory"); } -#ifdef HAVE_MINIX2 +#ifdef BB_FEATURE_MINIX2 static void check_root2(void) { struct minix2_inode *inode = Inode2 + ROOT_INO; @@ -787,7 +858,7 @@ static int add_zone(unsigned short *znr, int *corrected) return block; } -#ifdef HAVE_MINIX2 +#ifdef BB_FEATURE_MINIX2 static int add_zone2(unsigned int *znr, int *corrected) { int result; @@ -838,7 +909,7 @@ static void add_zone_ind(unsigned short *znr, int *corrected) write_block(block, blk); } -#ifdef HAVE_MINIX2 +#ifdef BB_FEATURE_MINIX2 static void add_zone_ind2(unsigned int *znr, int *corrected) { static char blk[BLOCK_SIZE]; @@ -872,7 +943,7 @@ static void add_zone_dind(unsigned short *znr, int *corrected) write_block(block, blk); } -#ifdef HAVE_MINIX2 +#ifdef BB_FEATURE_MINIX2 static void add_zone_dind2(unsigned int *znr, int *corrected) { static char blk[BLOCK_SIZE]; @@ -923,7 +994,7 @@ static void check_zones(unsigned int i) add_zone_dind(8 + inode->i_zone, &changed); } -#ifdef HAVE_MINIX2 +#ifdef BB_FEATURE_MINIX2 static void check_zones2(unsigned int i) { struct minix2_inode *inode; @@ -1008,7 +1079,7 @@ static void check_file(struct minix_inode *dir, unsigned int offset) return; } -#ifdef HAVE_MINIX2 +#ifdef BB_FEATURE_MINIX2 static void check_file2(struct minix2_inode *dir, unsigned int offset) { static char blk[BLOCK_SIZE]; @@ -1089,7 +1160,7 @@ static void recursive_check(unsigned int ino) check_file(dir, offset); } -#ifdef HAVE_MINIX2 +#ifdef BB_FEATURE_MINIX2 static void recursive_check2(unsigned int ino) { struct minix2_inode *dir; @@ -1167,7 +1238,7 @@ static void check_counts(void) } } -#ifdef HAVE_MINIX2 +#ifdef BB_FEATURE_MINIX2 static void check_counts2(void) { int i; @@ -1229,7 +1300,7 @@ static void check(void) check_counts(); } -#ifdef HAVE_MINIX2 +#ifdef BB_FEATURE_MINIX2 static void check2(void) { memset(inode_count, 0, (INODES + 1) * sizeof(*inode_count)); @@ -1240,17 +1311,51 @@ static void check2(void) } #endif +/* Wed Feb 9 15:17:06 MST 2000 */ +/* dynamically allocate name_list (instead of making it static) */ +static void alloc_name_list(void) +{ + int i; + + name_list = xmalloc(sizeof(char *) * MAX_DEPTH); + for (i = 0; i < MAX_DEPTH; i++) + name_list[i] = xmalloc(sizeof(char) * BUFSIZ + 1); +} + +#ifdef BB_FEATURE_CLEAN_UP +/* execute this atexit() to deallocate name_list[] */ +/* piptigger was here */ +static void free_name_list(void) +{ + int i; + + if (name_list) { + for (i = 0; i < MAX_DEPTH; i++) { + if (name_list[i]) { + free(name_list[i]); + } + } + free(name_list); + } +} +#endif + extern int fsck_minix_main(int argc, char **argv) { struct termios tmp; int count; int retcode = 0; - if (argc && *argv) - program_name = *argv; + alloc_name_list(); +#ifdef BB_FEATURE_CLEAN_UP + /* Don't bother to free memory. Exit does + * that automagically, so we can save a few bytes */ + atexit(free_name_list); +#endif + if (INODE_SIZE * MINIX_INODES_PER_BLOCK != BLOCK_SIZE) die("bad inode size"); -#ifdef HAVE_MINIX2 +#ifdef BB_FEATURE_MINIX2 if (INODE_SIZE2 * MINIX2_INODES_PER_BLOCK != BLOCK_SIZE) die("bad v2 inode size"); #endif @@ -1311,7 +1416,7 @@ extern int fsck_minix_main(int argc, char **argv) * flags and whether or not the -f switch was specified on the * command line. */ - printf("%s, %s\n", program_name, program_version); + printf("%s, %s\n", applet_name, program_version); if (!(Super.s_state & MINIX_ERROR_FS) && (Super.s_state & MINIX_VALID_FS) && !force) { if (repair) @@ -1332,7 +1437,7 @@ extern int fsck_minix_main(int argc, char **argv) tcsetattr(0, TCSANOW, &tmp); termios_set = 1; } -#if HAVE_MINIX2 +#ifdef BB_FEATURE_MINIX2 if (version2) { check_root2(); check2();