#include "pathnames.h"
#include "exitcodes.h"
#include "c.h"
-#include "closestream.h"
#include "fileutils.h"
#include "monotonic.h"
-
-#define STRTOXX_EXIT_CODE FSCK_EX_ERROR
#include "strutils.h"
#define XALLOC_EXIT_CODE FSCK_EX_ERROR
#include "xalloc.h"
+#define CLOSE_EXIT_CODE FSCK_EX_ERROR
+#include "closestream.h"
+
#ifndef DEFAULT_FSTYPE
# define DEFAULT_FSTYPE "ext2"
#endif
};
/*
- * Internal structure for mount tabel entries.
+ * Internal structure for mount table entries.
*/
struct fsck_fs_data
{
l = strtol(s, &p, 0);
if (*p || l == LONG_MIN || l == LONG_MAX || l < 0 || l > INT_MAX)
return -1;
- else
- return (int) l;
+
+ return (int) l;
}
/* Do we really really want to check this fs? */
"/sys/dev/block/%d:%d/queue/rotational",
major(disk), minor(disk));
- if (rc < 0 || (unsigned int) (rc + 1) > sizeof(path))
+ if (rc < 0 || (unsigned int) rc >= sizeof(path))
return 0;
f = fopen(path, "r");
inst->lockpath = NULL;
}
free(diskpath);
- return;
}
static void unlock_disk(struct fsck_instance *inst)
printf(_("Unlocking %s.\n"), inst->lockpath);
close(inst->lock); /* unlock */
- unlink(inst->lockpath);
free(inst->lockpath);
free(i->lockpath);
mnt_unref_fs(i->fs);
free(i);
- return;
}
static struct libmnt_fs *add_dummy_fs(const char *device)
static int parser_errcb(struct libmnt_table *tb __attribute__ ((__unused__)),
const char *filename, int line)
{
- warnx(_("%s: parse error at line %d -- ignore"), filename, line);
+ warnx(_("%s: parse error at line %d -- ignored"), filename, line);
return 1;
}
errno = 0;
/*
- * Let's follow libmount defauls if $FSTAB_FILE is not specified
+ * Let's follow libmount defaults if $FSTAB_FILE is not specified
*/
path = getenv("FSTAB_FILE");
}
/* Find fsck program for a given fs type. */
-static char *find_fsck(const char *type)
+static int find_fsck(const char *type, char **progpath)
{
char *s;
const char *tpl;
- static char prog[256];
+ char *prog = NULL;
char *p = xstrdup(fsck_path);
- struct stat st;
+ int rc;
/* Are we looking for a program or just a type? */
tpl = (strncmp(type, "fsck.", 5) ? "%s/fsck.%s" : "%s/%s");
for(s = strtok(p, ":"); s; s = strtok(NULL, ":")) {
- sprintf(prog, tpl, s, type);
- if (stat(prog, &st) == 0)
+ xasprintf(&prog, tpl, s, type);
+ if (access(prog, X_OK) == 0)
break;
+ free(prog);
+ prog = NULL;
}
+
free(p);
+ rc = prog ? 1 : 0;
- return(s ? prog : NULL);
+ if (progpath)
+ *progpath = prog;
+ else
+ free(prog);
+
+ return rc;
}
static int progress_active(void)
if (report_stats_file)
fprintf(report_stats_file, "%s %d %ld "
- "%ld.%06ld %d.%06d %d.%06d\n",
+ "%ld.%06ld %ld.%06ld %ld.%06ld\n",
fs_get_device(inst->fs),
inst->exit_status,
inst->rusage.ru_maxrss,
- delta.tv_sec, delta.tv_usec,
- (int)inst->rusage.ru_utime.tv_sec,
- (int)inst->rusage.ru_utime.tv_usec,
- (int)inst->rusage.ru_stime.tv_sec,
- (int)inst->rusage.ru_stime.tv_usec);
+ (long)delta.tv_sec, (long)delta.tv_usec,
+ (long)inst->rusage.ru_utime.tv_sec,
+ (long)inst->rusage.ru_utime.tv_usec,
+ (long)inst->rusage.ru_stime.tv_sec,
+ (long)inst->rusage.ru_stime.tv_usec);
else
fprintf(stdout, "%s: status %d, rss %ld, "
- "real %ld.%06ld, user %d.%06d, sys %d.%06d\n",
+ "real %ld.%06ld, user %ld.%06ld, sys %ld.%06ld\n",
fs_get_device(inst->fs),
inst->exit_status,
inst->rusage.ru_maxrss,
- delta.tv_sec, delta.tv_usec,
- (int)inst->rusage.ru_utime.tv_sec,
- (int)inst->rusage.ru_utime.tv_usec,
- (int)inst->rusage.ru_stime.tv_sec,
- (int)inst->rusage.ru_stime.tv_usec);
+ (long)delta.tv_sec, (long)delta.tv_usec,
+ (long)inst->rusage.ru_utime.tv_sec,
+ (long)inst->rusage.ru_utime.tv_usec,
+ (long)inst->rusage.ru_stime.tv_sec,
+ (long)inst->rusage.ru_stime.tv_usec);
}
/*
for (i=0; i <num_args; i++)
argv[argc++] = xstrdup(args[i]);
- if (progress) {
- if ((strcmp(type, "ext2") == 0) ||
- (strcmp(type, "ext3") == 0) ||
- (strcmp(type, "ext4") == 0) ||
- (strcmp(type, "ext4dev") == 0)) {
- char tmp[80];
-
- tmp[0] = 0;
- if (!progress_active()) {
- snprintf(tmp, 80, "-C%d", progress_fd);
- inst->flags |= FLAG_PROGRESS;
- } else if (progress_fd)
- snprintf(tmp, 80, "-C%d", progress_fd * -1);
- if (tmp[0])
- argv[argc++] = xstrdup(tmp);
- }
+ if (progress &&
+ ((strcmp(type, "ext2") == 0) ||
+ (strcmp(type, "ext3") == 0) ||
+ (strcmp(type, "ext4") == 0) ||
+ (strcmp(type, "ext4dev") == 0))) {
+
+ char tmp[80];
+ tmp[0] = 0;
+ if (!progress_active()) {
+ snprintf(tmp, 80, "-C%d", progress_fd);
+ inst->flags |= FLAG_PROGRESS;
+ } else if (progress_fd)
+ snprintf(tmp, 80, "-C%d", progress_fd * -1);
+ if (tmp[0])
+ argv[argc++] = xstrdup(tmp);
}
argv[argc++] = xstrdup(fs_get_device(fs));
- argv[argc] = 0;
+ argv[argc] = NULL;
if (verbose || noexecute) {
const char *tgt = mnt_fs_get_target(fs);
if (noexecute) {
inst = instance_list;
- prev = 0;
+ prev = NULL;
#ifdef RANDOM_DEBUG
while (inst->next && (random() & 1)) {
prev = inst;
warn(_("waitpid failed"));
continue;
}
- for (prev = 0, inst = instance_list;
+ for (prev = NULL, inst = instance_list;
inst;
prev = inst, inst = inst->next) {
if (inst->pid == pid)
for (inst2 = instance_list; inst2; inst2 = inst2->next) {
if (inst2->flags & FLAG_DONE)
continue;
- if (strcmp(inst2->type, "ext2") &&
+ if (strcmp(inst2->type, "ext2") != 0 &&
strcmp(inst2->type, "ext3") &&
- strcmp(inst2->type, "ext4") &&
- strcmp(inst2->type, "ext4dev"))
+ strcmp(inst2->type, "ext4") != 0 &&
+ strcmp(inst2->type, "ext4dev") != 0)
continue;
/*
* If we've just started the fsck, wait a tiny
* bit before sending the kill, to give it
* time to set up the signal handler
*/
- if (inst2->start_time.tv_sec < time(0) + 2) {
+ if (inst2->start_time.tv_sec < time(NULL) + 2) {
if (fork() == 0) {
sleep(1);
kill(inst2->pid, SIGUSR1);
*/
static int fsck_device(struct libmnt_fs *fs, int interactive)
{
- char progname[80], *progpath;
+ char *progname, *progpath;
const char *type;
int retval;
if (type && strcmp(type, "auto") != 0)
;
- else if (fstype && strncmp(fstype, "no", 2) &&
- strncmp(fstype, "opts=", 5) && strncmp(fstype, "loop", 4) &&
+ else if (fstype && strncmp(fstype, "no", 2) != 0 &&
+ strncmp(fstype, "opts=", 5) != 0 && strncmp(fstype, "loop", 4) != 0 &&
!strchr(fstype, ','))
type = fstype;
else
type = DEFAULT_FSTYPE;
- sprintf(progname, "fsck.%s", type);
- progpath = find_fsck(progname);
- if (progpath == NULL) {
+ xasprintf(&progname, "fsck.%s", type);
+
+ if (!find_fsck(progname, &progpath)) {
+ free(progname);
if (fs_check_required(type)) {
retval = ENOENT;
goto err;
num_running++;
retval = execute(progname, progpath, type, fs, interactive);
+ free(progname);
+ free(progpath);
if (retval) {
num_running--;
goto err;
/*
* Deal with the fsck -t argument.
*/
-struct fs_type_compile {
+static struct fs_type_compile {
char **list;
int *type;
int negate;
int n, ret = 0, checked_type = 0;
char *cp;
- if (cmp->list == 0 || cmp->list[0] == 0)
+ if (cmp->list == NULL || cmp->list[0] == NULL)
return 1;
for (n=0; (cp = cmp->list[n]); n++) {
/* See if the <fsck.fs> program is available. */
- if (find_fsck(type) == NULL) {
+ if (!find_fsck(type, NULL)) {
if (fs_check_required(type))
warnx(_("cannot check %s: fsck.%s not found"),
fs_get_device(fs), type);
if (!(dir = opendir(dirname)))
return -1;
- while ((dp = readdir(dir)) != 0) {
+ while ((dp = readdir(dir)) != NULL) {
#ifdef _DIRENT_HAVE_D_TYPE
if (dp->d_type != DT_UNKNOWN && dp->d_type != DT_LNK)
continue;
* Don't check a stacked device with any other disk too.
*/
if (!disk || fs_is_stacked(fs))
- return (instance_list != 0);
+ return (instance_list != NULL);
for (inst = instance_list; inst; inst = inst->next) {
dev_t idisk = fs_get_disk(inst->fs, 0);
/*
* This is for the bone-headed user who enters the root
- * filesystem twice. Skip root will skep all root entries.
+ * filesystem twice. Skip root will skip all root entries.
*/
if (skip_root) {
mnt_reset_iter(itr, MNT_ITER_FORWARD);
return status;
}
-static void __attribute__((__noreturn__)) usage(FILE *out)
+static void __attribute__((__noreturn__)) usage(void)
{
+ FILE *out = stdout;
fputs(USAGE_HEADER, out);
fprintf(out, _(" %s [options] -- [fs-options] [<filesystem> ...]\n"),
program_invocation_short_name);
fputs(_(" -t <type> specify filesystem types to be checked;\n"
" <type> is allowed to be a comma-separated list\n"), out);
fputs(_(" -V explain what is being done\n"), out);
- fputs(_(" -? display this help and exit\n"), out);
+ fputs(USAGE_SEPARATOR, out);
+ printf( " -?, --help %s\n", USAGE_OPTSTR_HELP);
+ printf( " --version %s\n", USAGE_OPTSTR_VERSION);
fputs(USAGE_SEPARATOR, out);
fputs(_("See the specific fsck.* commands for available fs-options."), out);
- fprintf(out, USAGE_MAN_TAIL("fsck(8)"));
-
- exit(out == stderr ? FSCK_EX_USAGE : FSCK_EX_OK);
+ printf(USAGE_MAN_TAIL("fsck(8)"));
+ exit(FSCK_EX_OK);
}
static void signal_cancel(int sig __attribute__((__unused__)))
static void parse_argv(int argc, char *argv[])
{
int i, j;
- char *arg, *dev, *tmp = 0;
+ char *arg, *dev, *tmp = NULL;
char options[128];
int opt = 0;
int opts_for_fsck = 0;
*/
memset(&sa, 0, sizeof(struct sigaction));
sa.sa_handler = signal_cancel;
- sigaction(SIGINT, &sa, 0);
- sigaction(SIGTERM, &sa, 0);
+ sigaction(SIGINT, &sa, NULL);
+ sigaction(SIGTERM, &sa, NULL);
num_devices = 0;
num_args = 0;
- instance_list = 0;
+ instance_list = NULL;
for (i=1; i < argc; i++) {
arg = argv[i];
if (!arg)
continue;
+
+ /* the only two longopts to satisfy UL standards */
+ if (!opts_for_fsck && !strcmp(arg, "--help"))
+ usage();
+ if (!opts_for_fsck && !strcmp(arg, "--version"))
+ print_version(FSCK_EX_OK);
+
if ((arg[0] == '/' && !opts_for_fsck) || strchr(arg, '=')) {
if (num_devices >= MAX_DEVICES)
errx(FSCK_EX_ERROR, _("too many devices"));
serialize = 1;
break;
case 't':
- tmp = 0;
+ tmp = NULL;
if (fstype)
- usage(stderr);
+ errx(FSCK_EX_USAGE,
+ _("option '%s' may be specified only once"), "-t");
if (arg[j+1])
tmp = arg+j+1;
else if ((i+1) < argc)
tmp = argv[++i];
else
- usage(stderr);
+ errx(FSCK_EX_USAGE,
+ _("option '%s' requires an argument"), "-t");
fstype = xstrdup(tmp);
compile_fs_type(fstype, &fs_type_compiled);
goto next_arg;
opts_for_fsck++;
break;
case '?':
- usage(stdout);
+ usage();
break;
default:
options[++opt] = arg[j];
setlocale(LC_CTYPE, "");
bindtextdomain(PACKAGE, LOCALEDIR);
textdomain(PACKAGE);
- atexit(close_stdout);
+ close_stdout_atexit();
+ strutils_set_exitcode(FSCK_EX_USAGE);
mnt_init_debug(0); /* init libmount debug mask */
mntcache = mnt_new_cache(); /* no fatal error if failed */