didnt mean to commit debug enable
[oweals/busybox.git] / e2fsprogs / tune2fs.c
index b78b0139d01d012f95e8089e0c2acc8ec91f5ab8..65ff445e7fd0e2bf6b6ba1bee16aa57b27153f71 100644 (file)
  * 94/03/06    - Added the checks interval from Uwe Ohse (uwe@tirka.gun.de)
  */
 
+#include <sys/types.h>
 #include <fcntl.h>
-#include <grp.h>
-#ifdef HAVE_GETOPT_H
-#include <getopt.h>
-#else
-extern char *optarg;
-extern int optind;
-#endif
-#include <pwd.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <time.h>
 #include <unistd.h>
-#include <sys/types.h>
+#include <getopt.h>
 
 #include "e2fsbb.h"
 #include "ext2fs/ext2_fs.h"
 #include "ext2fs/ext2fs.h"
 #include "uuid/uuid.h"
 #include "e2p/e2p.h"
-#include "ext2fs/jfs_user.h"
+#include "ext2fs/kernel-jbd.h"
 #include "util.h"
 #include "blkid/blkid.h"
 
-static char * device_name;
+#include "busybox.h"
+#include "grp_.h"
+#include "pwd_.h"
+
+static char * device_name = NULL;
 static char * new_label, *new_last_mounted, *new_UUID;
 static char * io_options;
 static int c_flag, C_flag, e_flag, f_flag, g_flag, i_flag, l_flag, L_flag;
@@ -66,7 +63,7 @@ static char *features_cmd;
 static char *mntopts_cmd;
 
 static int journal_size, journal_flags;
-static char *journal_device;
+static char *journal_device = NULL;
 
 static const char *please_fsck = "Please run e2fsck on the filesystem\n";
 
@@ -166,7 +163,7 @@ no_valid_journal:
 
 /* Helper function for remove_journal_inode */
 static int release_blocks_proc(ext2_filsys fs, blk_t *blocknr,
-                              int blockcnt EXT2FS_ATTR((unused)), 
+                              int blockcnt EXT2FS_ATTR((unused)),
                               void *private EXT2FS_ATTR((unused)))
 {
        blk_t   block;
@@ -188,26 +185,36 @@ static void remove_journal_inode(ext2_filsys fs)
        struct ext2_inode       inode;
        errcode_t               retval;
        ino_t                   ino = fs->super->s_journal_inum;
-       
+       char *msg = "to read";
+       char *s = "journal inode";
+
        retval = ext2fs_read_inode(fs, ino,  &inode);
        if (retval)
-               bb_error_msg_and_die("Failed to read journal inode");
+               goto REMOVE_JOURNAL_INODE_ERROR;
        if (ino == EXT2_JOURNAL_INO) {
                retval = ext2fs_read_bitmaps(fs);
-               if (retval)
-                       bb_error_msg_and_die("Failed to read bitmaps");
+               if (retval) {
+                       msg = "to read bitmaps";
+                       s = "";
+                       goto REMOVE_JOURNAL_INODE_ERROR;
+               }
                retval = ext2fs_block_iterate(fs, ino, 0, NULL,
                                              release_blocks_proc, NULL);
-               if (retval)
-                       bb_error_msg_and_die("Failed clearing journal inode");
+               if (retval) {
+                       msg = "clearing";
+                       goto REMOVE_JOURNAL_INODE_ERROR;
+               }
                memset(&inode, 0, sizeof(inode));
                ext2fs_mark_bb_dirty(fs);
                fs->flags &= ~EXT2_FLAG_SUPER_ONLY;
        } else
                inode.i_flags &= ~EXT2_IMMUTABLE_FL;
        retval = ext2fs_write_inode(fs, ino, &inode);
-       if (retval)
-               bb_error_msg_and_die("Failed writing journal inode");
+       if (retval) {
+               msg = "writing";
+REMOVE_JOURNAL_INODE_ERROR:
+               bb_error_msg_and_die("Failed %s %s", msg, s);
+       }
        fs->super->s_journal_inum = 0;
        ext2fs_mark_super_dirty(fs);
 }
@@ -269,8 +276,8 @@ static void update_feature_set(ext2_filsys fs, char *features)
                    EXT3_FEATURE_INCOMPAT_RECOVER) {
                        bb_error_msg_and_die(
                                "The needs_recovery flag is set.  "
-                               "Please run e2fsck before clearing\n"
-                               "the has_journal flag.");
+                               "%s before clearing the has_journal flag.",
+                               please_fsck);
                }
                if (sb->s_journal_inum) {
                        remove_journal_inode(fs);
@@ -317,48 +324,14 @@ static void update_feature_set(ext2_filsys fs, char *features)
  */
 static void add_journal(ext2_filsys fs)
 {
-       unsigned long journal_blocks;
-       errcode_t       retval;
-       ext2_filsys     jfs;
-       io_manager      io_ptr;
-
        if (fs->super->s_feature_compat &
            EXT3_FEATURE_COMPAT_HAS_JOURNAL) {
-               bb_error_msg("The filesystem already has a journal");
-               goto err;
+               bb_error_msg_and_die("The filesystem already has a journal");
        }
        if (journal_device) {
-               check_plausibility(journal_device);
-               check_mount(journal_device, 0, "journal");
-               io_ptr = unix_io_manager;
-               retval = ext2fs_open(journal_device, EXT2_FLAG_RW|
-                                    EXT2_FLAG_JOURNAL_DEV_OK, 0,
-                                    fs->blocksize, io_ptr, &jfs);
-               if (retval) {
-                       bb_error_msg("Failed to open journal on %s", journal_device);
-                       goto err;
-               }
-               printf("Creating journal on device %s: ", journal_device);
-               fflush(stdout);
-
-               retval = ext2fs_add_journal_device(fs, jfs);
-               ext2fs_close(jfs);
-               if (retval) {
-                       bb_error_msg("Failed to add filesystem to journal on %s", journal_device);
-                       goto err;
-               }
-               puts("done");
+               make_journal_device(journal_device, fs, 0, 0);
        } else if (journal_size) {
-               fputs("Creating journal inode: ", stdout);
-               fflush(stdout);
-               journal_blocks = figure_journal_size(journal_size, fs);
-
-               retval = ext2fs_add_journal_inode(fs, journal_blocks,
-                                                 journal_flags);
-               if (retval)
-                       bb_error_msg_and_die("Failed to create journal file");
-               else
-                       puts("done");
+               make_journal_blocks(fs, journal_size, journal_flags, 0);
                /*
                 * If the filesystem wasn't mounted, we need to force
                 * the block group descriptors out.
@@ -368,11 +341,18 @@ static void add_journal(ext2_filsys fs)
        }
        print_check_message(fs);
        return;
+}
+
+/*
+ * Busybox stuff
+ */
+static char * x_blkid_get_devname(const char *token)
+{
+       char * dev_name;
 
-err:
-       if (journal_device)
-               free(journal_device);
-       exit(1);
+       if (!(dev_name = blkid_get_devname(NULL, token, NULL)))
+               bb_error_msg_and_die("Unable to resolve '%s'", token);
+       return dev_name;
 }
 
 #ifdef CONFIG_E2LABEL
@@ -383,16 +363,16 @@ static void parse_e2label_options(int argc, char ** argv)
        io_options = strchr(argv[1], '?');
        if (io_options)
                *io_options++ = 0;
-       device_name = blkid_get_devname(NULL, argv[1], NULL);
-       if (!device_name)
-               bb_error_msg_and_die("Unable to resolve '%s'", argv[1]);
+       device_name = x_blkid_get_devname(argv[1]);
        if (argc == 3) {
                open_flag = EXT2_FLAG_RW | EXT2_FLAG_JOURNAL_DEV_OK;
                L_flag = 1;
                new_label = argv[2];
-       } else 
+       } else
                print_label++;
 }
+#else
+#define parse_e2label_options(x,y)
 #endif
 
 static time_t parse_time(char *str)
@@ -425,17 +405,14 @@ static void parse_tune2fs_options(int argc, char **argv)
 {
        int c;
        char * tmp;
-       struct group * gr;
-       struct passwd * pw;
 
        printf("tune2fs %s (%s)\n", E2FSPROGS_VERSION, E2FSPROGS_DATE);
        while ((c = getopt(argc, argv, "c:e:fg:i:jlm:o:r:s:u:C:J:L:M:O:T:U:")) != EOF)
                switch (c)
                {
                        case 'c':
-                               max_mount_count = strtol (optarg, &tmp, 0);
-                               if (*tmp || max_mount_count > 16000) {
-                                       bb_error_msg_and_die("bad mounts count - %s", optarg);
+                               if (safe_strtoi(optarg, &max_mount_count) ||  max_mount_count > 16000) {
+                                       goto MOUNTS_COUNT_ERROR;
                                }
                                if (max_mount_count == 0)
                                        max_mount_count = -1;
@@ -443,8 +420,8 @@ static void parse_tune2fs_options(int argc, char **argv)
                                open_flag = EXT2_FLAG_RW;
                                break;
                        case 'C':
-                               mount_count = strtoul (optarg, &tmp, 0);
-                               if (*tmp || mount_count > 16000) {
+                               if (safe_strtoi(optarg, &mount_count) || mount_count > 16000) {
+MOUNTS_COUNT_ERROR:
                                        bb_error_msg_and_die("bad mounts count - %s", optarg);
                                }
                                C_flag = 1;
@@ -467,19 +444,8 @@ static void parse_tune2fs_options(int argc, char **argv)
                                f_flag = 1;
                                break;
                        case 'g':
-                               resgid = strtoul (optarg, &tmp, 0);
-                               if (*tmp) {
-                                       gr = getgrnam (optarg);
-                                       if (gr == NULL)
-                                               tmp = optarg;
-                                       else {
-                                               resgid = gr->gr_gid;
-                                               *tmp =0;
-                                       }
-                               }
-                               if (*tmp) {
-                                       bb_error_msg_and_die("bad gid/group name - %s", optarg);
-                               }
+                               if (safe_strtoul(optarg, &resgid))
+                                       resgid = bb_xgetgrnam(optarg);
                                g_flag = 1;
                                open_flag = EXT2_FLAG_RW;
                                break;
@@ -532,8 +498,7 @@ static void parse_tune2fs_options(int argc, char **argv)
                                        EXT2_FLAG_JOURNAL_DEV_OK;
                                break;
                        case 'm':
-                               reserved_ratio = strtoul (optarg, &tmp, 0);
-                               if (*tmp || reserved_ratio > 50) {
+                               if(safe_strtoul(optarg, &reserved_ratio) || reserved_ratio > 50) {
                                        bb_error_msg_and_die("bad reserved block ratio - %s", optarg);
                                }
                                m_flag = 1;
@@ -551,7 +516,7 @@ static void parse_tune2fs_options(int argc, char **argv)
                                mntopts_cmd = optarg;
                                open_flag = EXT2_FLAG_RW;
                                break;
-                               
+
                        case 'O':
                                if (features_cmd) {
                                        bb_error_msg_and_die("-O may only be specified once");
@@ -560,8 +525,7 @@ static void parse_tune2fs_options(int argc, char **argv)
                                open_flag = EXT2_FLAG_RW;
                                break;
                        case 'r':
-                               reserved_blocks = strtoul (optarg, &tmp, 0);
-                               if (*tmp) {
+                               if(safe_strtoul(optarg, &reserved_blocks)) {
                                        bb_error_msg_and_die("bad reserved blocks count - %s", optarg);
                                }
                                r_flag = 1;
@@ -577,19 +541,8 @@ static void parse_tune2fs_options(int argc, char **argv)
                                open_flag = EXT2_FLAG_RW;
                                break;
                        case 'u':
-                               resuid = strtoul (optarg, &tmp, 0);
-                               if (*tmp) {
-                                       pw = getpwnam (optarg);
-                                       if (pw == NULL)
-                                               tmp = optarg;
-                                       else {
-                                               resuid = pw->pw_uid;
-                                               *tmp = 0;
-                                       }
-                               }
-                               if (*tmp) {
-                                       bb_error_msg_and_die("bad uid/user name - %s", optarg);
-                               }
+                               if (safe_strtoul(optarg, &resuid))
+                                       resuid = bb_xgetpwnam(optarg);
                                u_flag = 1;
                                open_flag = EXT2_FLAG_RW;
                                break;
@@ -609,51 +562,48 @@ static void parse_tune2fs_options(int argc, char **argv)
        io_options = strchr(argv[optind], '?');
        if (io_options)
                *io_options++ = 0;
-       device_name = blkid_get_devname(NULL, argv[optind], NULL);
-       if (!device_name)
-               bb_error_msg_and_die("Unable to resolve '%s'", argv[optind]);
+       device_name = x_blkid_get_devname(argv[optind]);
 }
 
 #ifdef CONFIG_FINDFS
-static attribute_noreturn void do_findfs(int argc, char **argv)
+static ATTRIBUTE_NORETURN void do_findfs(int argc, char **argv)
 {
-       char *dev;
-
        if ((argc != 2) ||
            (strncmp(argv[1], "LABEL=", 6) && strncmp(argv[1], "UUID=", 5)))
                bb_show_usage();
-       dev = blkid_get_devname(NULL, argv[1], NULL);
-       if (!dev)
-               bb_error_msg_and_die("Unable to resolve '%s'", argv[1]);
-       puts(dev);
+       device_name = x_blkid_get_devname(argv[1]);
+       puts(device_name);
        exit(0);
 }
+#else
+#define do_findfs(x, y)
 #endif
 
+static void tune2fs_clean_up(void)
+{
+       if (ENABLE_FEATURE_CLEAN_UP && device_name) free(device_name);
+       if (ENABLE_FEATURE_CLEAN_UP && journal_device) free(journal_device);
+}
+
 int tune2fs_main(int argc, char **argv)
 {
        errcode_t retval;
        ext2_filsys fs;
        struct ext2_super_block *sb;
        io_manager io_ptr;
-#if defined(CONFIG_FINDFS) || defined(CONFIG_E2LABEL)
-       char *program_name = basename(argv[0]);
-#endif
 
-#ifdef CONFIG_FINDFS
-       if (strcmp(program_name, "findfs") == 0)
-               do_findfs(argc, argv);
-#endif
+       if (ENABLE_FEATURE_CLEAN_UP)
+               atexit(tune2fs_clean_up);
 
-#ifdef CONFIG_E2LABEL
-       if (strcmp(program_name, "e2label") == 0)
+       if (ENABLE_FINDFS && (bb_applet_name[0] == 'f')) /* findfs */
+               do_findfs(argc, argv);  /* no return */
+       else if (ENABLE_E2LABEL && (bb_applet_name[0] == 'e')) /* e2label */
                parse_e2label_options(argc, argv);
        else
-#endif
-               parse_tune2fs_options(argc, argv);
+               parse_tune2fs_options(argc, argv);  /* tune2fs */
 
        io_ptr = unix_io_manager;
-       retval = ext2fs_open2(device_name, io_options, open_flag, 
+       retval = ext2fs_open2(device_name, io_options, open_flag,
                              0, 0, io_ptr, &fs);
        if (retval)
                bb_error_msg_and_die("No valid superblock on %s", device_name);
@@ -662,7 +612,7 @@ int tune2fs_main(int argc, char **argv)
                /* For e2label emulation */
                printf("%.*s\n", (int) sizeof(sb->s_volume_name),
                       sb->s_volume_name);
-               exit(0);
+               return 0;
        }
        retval = ext2fs_check_if_mounted(device_name, &mount_flags);
        if (retval)