* Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
* 2001, 2002, 2003, 2004, 2005 by Theodore Ts'o.
*
- * Licensed under GPLv2, see file LICENSE in this tarball for details.
+ * Licensed under GPLv2, see file LICENSE in this source tree.
*/
/* All filesystem specific hooks have been removed.
* API for fsck.something, NOT ad-hoc hacks in generic fsck. */
#define DO_PROGRESS_INDICATOR 0
+/* fsck 1.41.4 (27-Jan-2009) manpage says:
+ * 0 - No errors
+ * 1 - File system errors corrected
+ * 2 - System should be rebooted
+ * 4 - File system errors left uncorrected
+ * 8 - Operational error
+ * 16 - Usage or syntax error
+ * 32 - Fsck canceled by user request
+ * 128 - Shared library error
+ */
#define EXIT_OK 0
#define EXIT_NONDESTRUCT 1
#define EXIT_DESTRUCT 2
/*
* Internal structure for mount table entries.
*/
-
struct fs_info {
struct fs_info *next;
char *device;
const char *disk;
int len;
#endif
- cp = str = xstrdup(device);
+ str = xstrdup(device);
- /* Skip over /dev/; if it's not present, give up. */
- if (strncmp(cp, "/dev/", 5) != 0)
+ /* Skip over "/dev/"; if it's not present, give up */
+ cp = skip_dev_pfx(str);
+ if (cp == str)
goto errout;
- cp += 5;
/*
* For md devices, we treat them all as if they were all
fstab = setmntent(filename, "r");
if (!fstab) {
- bb_perror_msg("cannot read %s", filename);
+ bb_perror_msg("can't read '%s'", filename);
return;
}
static void execute(const char *type, const char *device,
const char *mntpt /*, int interactive */)
{
- char *argv[num_args + 4]; /* see count below: */
- int argc;
int i;
struct fsck_instance *inst;
pid_t pid;
- argv[0] = xasprintf("fsck.%s", type); /* 1 */
- for (i = 0; i < num_args; i++)
- argv[i+1] = args[i]; /* num_args */
- argc = num_args + 1;
+ args[0] = xasprintf("fsck.%s", type);
#if DO_PROGRESS_INDICATOR
if (progress && !progress_active()) {
if (strcmp(type, "ext2") == 0
|| strcmp(type, "ext3") == 0
) {
- argv[argc++] = xasprintf("-C%d", progress_fd); /* 1 */
+ args[XXX] = xasprintf("-C%d", progress_fd); /* 1 */
inst->flags |= FLAG_PROGRESS;
}
}
#endif
- argv[argc++] = (char*)device; /* 1 */
- argv[argc] = NULL; /* 1 */
+ args[num_args - 2] = (char*)device;
+ /* args[num_args - 1] = NULL; - already is */
if (verbose || noexecute) {
- printf("[%s (%d) -- %s]", argv[0], num_running,
+ printf("[%s (%d) -- %s]", args[0], num_running,
mntpt ? mntpt : device);
- for (i = 0; i < argc; i++)
- printf(" %s", argv[i]);
+ for (i = 0; args[i]; i++)
+ printf(" %s", args[i]);
bb_putchar('\n');
}
/* Fork and execute the correct program. */
pid = -1;
if (!noexecute) {
- pid = spawn(argv);
+ pid = spawn(args);
if (pid < 0)
- bb_simple_perror_msg(argv[0]);
+ bb_simple_perror_msg(args[0]);
}
#if DO_PROGRESS_INDICATOR
- free(argv[num_args + 1]);
+ free(args[XXX]);
#endif
/* No child, so don't record an instance */
if (pid <= 0) {
- free(argv[0]);
+ free(args[0]);
return;
}
inst = xzalloc(sizeof(*inst));
inst->pid = pid;
- inst->prog = argv[0];
+ inst->prog = args[0];
inst->device = xstrdup(device);
inst->base_device = base_device(device);
#if DO_PROGRESS_INDICATOR
}
}
+static char **new_args(void)
+{
+ args = xrealloc_vector(args, 2, num_args);
+ return &args[num_args++];
+}
+
int fsck_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
int fsck_main(int argc UNUSED_PARAM, char **argv)
{
opts_for_fsck = doall = notitle = 0;
devices = NULL;
num_devices = 0;
- /* in bss, so already zeroed
- args = NULL;
- num_args = 0;
- instance_list = NULL;
- */
+ new_args(); /* args[0] = NULL, will be replaced by fsck.<type> */
+ /* instance_list = NULL; - in bss, so already zeroed */
+
while (*++argv) {
int j;
int optpos;
}
if (arg[0] != '-' || opts_for_fsck) {
- args = xrealloc_vector(args, 2, num_args);
- args[num_args++] = arg;
+ *new_args() = arg;
continue;
}
case 'C':
progress = 1;
if (arg[++j]) { /* -Cn */
- progress_fd = xatoi_u(&arg[j]);
+ progress_fd = xatoi_positive(&arg[j]);
goto next_arg;
}
/* -C n */
if (!*++argv)
bb_show_usage();
- progress_fd = xatoi_u(*argv);
+ progress_fd = xatoi_positive(*argv);
goto next_arg;
#endif
case 'V':
if (optpos) {
options[0] = '-';
options[optpos + 1] = '\0';
- args = xrealloc_vector(args, 2, num_args);
- args[num_args++] = options;
+ *new_args() = options;
}
}
if (getenv("FSCK_FORCE_ALL_PARALLEL"))
tmp = getenv("FSCK_MAX_INST");
if (tmp)
max_running = xatoi(tmp);
+ new_args(); /* args[num_args - 2] will be replaced by <device> */
+ new_args(); /* args[num_args - 1] is the last, NULL element */
if (!notitle)
puts("fsck (busybox "BB_VER", "BB_BT")");