Extract usage information into a separate file.
[oweals/busybox.git] / util-linux / mkfs_minix.c
index be180a46ba850a8764512b1a8e0cd41df062b7f1..dec310d3072a419611c159fb8c08b900a1424a27 100644 (file)
@@ -57,6 +57,9 @@
  *
  * The device may be a block device or a image of one, but this isn't
  * enforced (but it's not much fun on a character device :-). 
+ *
+ * Modified for BusyBox by Erik Andersen <andersen@debian.org> --
+ *     removed getopt based parser and added a hand rolled one.
  */
 
 #include "internal.h"
 #include <termios.h>
 #include <sys/stat.h>
 #include <sys/ioctl.h>
+#include <sys/param.h>
 #include <mntent.h>
-#include <getopt.h>
 
-#include <linux/fs.h>
-#include <linux/minix_fs.h>
 
-#ifdef MINIX2_SUPER_MAGIC2
-#define HAVE_MINIX2 1
+typedef unsigned char u8;
+typedef unsigned short u16;
+typedef unsigned int u32;
+
+
+#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<<BLOCK_SIZE_BITS)
+
+#define NAME_MAX         255   /* # chars in a file name */
+
+#define MINIX_INODES_PER_BLOCK ((BLOCK_SIZE)/(sizeof (struct minix_inode)))
+
+#define MINIX_VALID_FS               0x0001          /* Clean fs. */
+#define MINIX_ERROR_FS               0x0002          /* fs has errors. */
+
+#define MINIX_SUPER_MAGIC    0x137F          /* original minix fs */
+#define MINIX_SUPER_MAGIC2   0x138F          /* minix fs, 30 char names */
+
+#ifndef BLKGETSIZE
+#define BLKGETSIZE _IO(0x12,96)    /* return device size */
 #endif
 
-#ifndef __GNUC__
-#error "needs gcc for the bitop-__asm__'s"
+
+#ifdef MINIX2_SUPER_MAGIC2
+#define HAVE_MINIX2 1
 #endif
 
 #ifndef __linux__
 
 #define BITS_PER_BLOCK (BLOCK_SIZE<<3)
 
-static char *program_name = "mkfs";
 static char *device_name = NULL;
 static int DEV = -1;
 static long BLOCKS = 0;
@@ -170,28 +263,14 @@ static unsigned long req_nr_inodes = 0;
  */
 static volatile void die(char *str)
 {
-       fprintf(stderr, "%s: %s\n", program_name, str);
+       errorMsg("%s\n", str);
        exit(8);
 }
 
+static volatile void show_usage() __attribute__ ((noreturn));
 static volatile void show_usage()
 {
-       fprintf(stderr, "BusyBox v%s (%s) multi-call binary -- GPL2\n\n",
-                       BB_VER, BB_BT);
-       fprintf(stderr,
-                       "Usage: %s [-c | -l filename] [-nXX] [-iXX] /dev/name [blocks]\n\n",
-                       program_name);
-       fprintf(stderr, "Make a MINIX filesystem.\n\n");
-       fprintf(stderr, "OPTIONS:\n");
-       fprintf(stderr, "\t-c\t\tCheck the device for bad blocks\n");
-       fprintf(stderr,
-                       "\t-n [14|30]\tSpecify the maximum length of filenames\n");
-       fprintf(stderr,
-                       "\t-i\t\tSpecify the number of inodes for the filesystem\n");
-       fprintf(stderr,
-                       "\t-l FILENAME\tRead the bad blocks list from FILENAME\n");
-       fprintf(stderr, "\t-v\t\tMake a Minix version 2 filesystem\n\n");
-       exit(16);
+       usage(mkfs_minix_usage);
 }
 
 /*
@@ -642,70 +721,105 @@ char *filename;
 
 extern int mkfs_minix_main(int argc, char **argv)
 {
-       int i;
+       int i=1;
        char *tmp;
        struct stat statbuf;
        char *listfile = NULL;
+       int stopIt=FALSE;
 
-       if (argc && *argv)
-               program_name = *argv;
        if (INODE_SIZE * MINIX_INODES_PER_BLOCK != BLOCK_SIZE)
                die("bad inode size");
 #ifdef HAVE_MINIX2
        if (INODE_SIZE2 * MINIX2_INODES_PER_BLOCK != BLOCK_SIZE)
                die("bad inode size");
 #endif
-       opterr = 0;
-       while ((i = getopt(argc, argv, "ci:l:n:v")) != EOF)
-               switch (i) {
-               case 'c':
-                       check = 1;
-                       break;
-               case 'i':
-                       req_nr_inodes = (unsigned long) atol(optarg);
-                       break;
-               case 'l':
-                       listfile = optarg;
-                       break;
-               case 'n':
-                       i = strtoul(optarg, &tmp, 0);
-                       if (*tmp)
-                               show_usage();
-                       if (i == 14)
-                               magic = MINIX_SUPER_MAGIC;
-                       else if (i == 30)
-                               magic = MINIX_SUPER_MAGIC2;
-                       else
-                               show_usage();
-                       namelen = i;
-                       dirsize = i + 2;
-                       break;
-               case 'v':
+       
+       /* Parse options */
+       argv++;
+       while (--argc >= 0 && *argv && **argv) {
+               if (**argv == '-') {
+                       stopIt=FALSE;
+                       while (i > 0 && *++(*argv) && stopIt==FALSE) {
+                               switch (**argv) {
+                                       case 'c':
+                                               check = 1;
+                                               break;
+                                       case 'i':
+                                               {
+                                                       char *cp=NULL;
+                                                       if (*(*argv+1) != 0) {
+                                                               cp = ++(*argv);
+                                                       } else {
+                                                               if (--argc == 0) {
+                                                                       goto goodbye;
+                                                               }
+                                                               cp = *(++argv);
+                                                       }
+                                                       req_nr_inodes = strtoul(cp, &tmp, 0);
+                                                       if (*tmp)
+                                                               show_usage();
+                                                       stopIt=TRUE;
+                                                       break;
+                                               }
+                                       case 'l':
+                                               if (--argc == 0) {
+                                                       goto goodbye;
+                                               }
+                                               listfile = *(++argv);
+                                               break;
+                                       case 'n':
+                                               {
+                                                       char *cp=NULL;
+
+                                                       if (*(*argv+1) != 0) {
+                                                               cp = ++(*argv);
+                                                       } else {
+                                                               if (--argc == 0) {
+                                                                       goto goodbye;
+                                                               }
+                                                               cp = *(++argv);
+                                                       }
+                                                       i = strtoul(cp, &tmp, 0);
+                                                       if (*tmp)
+                                                               show_usage();
+                                                       if (i == 14)
+                                                               magic = MINIX_SUPER_MAGIC;
+                                                       else if (i == 30)
+                                                               magic = MINIX_SUPER_MAGIC2;
+                                                       else 
+                                                               show_usage();
+                                                       namelen = i;
+                                                       dirsize = i + 2;
+                                                       stopIt=TRUE;
+                                                       break;
+                                               }
+                                       case 'v':
 #ifdef HAVE_MINIX2
-                       version2 = 1;
+                                               version2 = 1;
 #else
-                       fprintf(stderr, "%s: not compiled with minix v2 support\n",
-                                       program_name, device_name);
-                       exit(-1);
+                                               errorMsg("%s: not compiled with minix v2 support\n",
+                                                               device_name);
+                                               exit(-1);
 #endif
-                       break;
-               default:
-                       show_usage();
+                                               break;
+                                       case '-':
+                                       case 'h':
+                                       default:
+goodbye:
+                                               show_usage();
+                               }
+                       }
+               } else {
+                       if (device_name == NULL)
+                               device_name = *argv;
+                       else if (BLOCKS == 0)
+                               BLOCKS = strtol(*argv, &tmp, 0);
+                       else {
+                               goto goodbye;
+                       }
                }
-       argc -= optind;
-       argv += optind;
-       if (argc > 0 && !device_name) {
-               device_name = argv[0];
-               argc--;
                argv++;
        }
-       if (argc > 0) {
-               BLOCKS = strtol(argv[0], &tmp, 0);
-               if (*tmp) {
-                       printf("strtol error: number of blocks not specified");
-                       show_usage();
-               }
-       }
 
        if (device_name && !BLOCKS)
                BLOCKS = get_size(device_name) / 1024;
@@ -758,5 +872,6 @@ extern int mkfs_minix_main(int argc, char **argv)
        }
        mark_good_blocks();
        write_tables();
-       return 0;
+       return( 0);
+
 }