mirror of
https://git.freebsd.org/ports.git
synced 2025-05-14 08:11:50 -04:00
* fsck_ext2fs.8 (1.3): Reformat long lines. * fsck_ext2fs.8 (1.2): Add copyright notice and license. Change - to \- where appropriate. Add Id and FreeBSD keywords for ident. * fsck_ext2fs.c (1.6): Update license. * fsck_ext2fs.8 (1.1): Add a manual page. * fsck_ext2fs.c (1.5): When run with -F, do not report 'unknown option'. PR: 99712 Submitted by: Matthias Andree <matthias.andree at gmx.de>
147 lines
2.6 KiB
C
147 lines
2.6 KiB
C
/*
|
|
* fsck_ext2fs - wrapper for e2fsck on FreeBSD
|
|
* Copyright (C) 2004,2006 Matthias Andree <matthias.andree@gmx.de>
|
|
* redistributable in accordance with the
|
|
* GNU General Public License v2
|
|
*
|
|
* $FreeBSD$
|
|
*
|
|
* Upstream: $Id: fsck_ext2fs.c,v 1.6 2006/07/02 11:37:49 emma Exp $
|
|
*
|
|
* format: gindent -kr
|
|
*/
|
|
|
|
#include <sys/types.h>
|
|
#include <unistd.h>
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <sys/wait.h>
|
|
#include <sys/time.h>
|
|
#include <sys/resource.h>
|
|
#include <errno.h>
|
|
|
|
__attribute__ ((noreturn))
|
|
static int die(const char *tag)
|
|
{
|
|
perror(tag);
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
int main(int argc, char **argv)
|
|
{
|
|
int ch, i = 1, force = 0, status, verbose = 0, t;
|
|
long block = 0;
|
|
enum { normal, preen, yes, no } mode = normal;
|
|
char *cmd[256];
|
|
pid_t pid;
|
|
|
|
cmd[0] = "/sbin/e2fsck";
|
|
while ((ch = getopt(argc, argv, "BFpfnyb:v")) != -1) {
|
|
switch (ch) {
|
|
case 'p':
|
|
mode = preen;
|
|
break;
|
|
case 'f':
|
|
force = 1;
|
|
break;
|
|
case 'n':
|
|
mode = no;
|
|
break;
|
|
case 'y':
|
|
mode = yes;
|
|
break;
|
|
case 'b':
|
|
block = atol(optarg);
|
|
break;
|
|
case 'v':
|
|
verbose++;
|
|
break;
|
|
case 'F':
|
|
/* e2fsck does not support background checking,
|
|
* hence exit with nonzero status to force
|
|
* the foreground check. */
|
|
exit(1);
|
|
case 'B':
|
|
default:
|
|
fprintf(stderr, "%s: unknown option -%c\n",
|
|
argv[0], optopt);
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
}
|
|
|
|
if (force)
|
|
cmd[i++] = "-f";
|
|
|
|
switch (mode) {
|
|
case normal:
|
|
/* FreeBSD needs -f to force a check only in context
|
|
* with -p -- so map normal to force to match
|
|
* expectations */
|
|
if (!force)
|
|
cmd[i++] = "-f";
|
|
break;
|
|
case yes:
|
|
cmd[i++] = "-y";
|
|
break;
|
|
case no:
|
|
cmd[i++] = "-n";
|
|
break;
|
|
case preen:
|
|
cmd[i++] = "-p";
|
|
break;
|
|
}
|
|
|
|
if (block) {
|
|
static char b[30];
|
|
|
|
sprintf(b, "-b %ld", block);
|
|
cmd[i++] = b;
|
|
}
|
|
|
|
/* silently limit verbose to 15 so we don't overflow the cmd array */
|
|
if (verbose > 15)
|
|
verbose = 15;
|
|
|
|
for (t = verbose; t > 1; t--)
|
|
cmd[i++] = "-v";
|
|
|
|
while (optind < argc) {
|
|
cmd[i++] = argv[optind++];
|
|
/* sanity check so we don't overflow the cmd buffer */
|
|
if (i+1 == sizeof(cmd)/sizeof(cmd[0])) {
|
|
errno = E2BIG;
|
|
die(argv[0]);
|
|
}
|
|
}
|
|
|
|
cmd[i++] = 0;
|
|
|
|
if (verbose) {
|
|
for (i=0; cmd[i]; i++)
|
|
fputs(cmd[i], stderr),
|
|
fputc(' ', stderr);
|
|
fputc('\n', stderr);
|
|
}
|
|
|
|
pid = fork();
|
|
switch (pid) {
|
|
case -1:
|
|
/* error */
|
|
die("fork");
|
|
break;
|
|
case 0:
|
|
/* child */
|
|
(void) execv(cmd[0], cmd);
|
|
perror("execve");
|
|
_exit(127);
|
|
default:
|
|
/* parent */
|
|
if (pid != waitpid(pid, &status, 0))
|
|
die("waitpid");
|
|
if (WIFSIGNALED(status)
|
|
|| (WIFEXITED(status) && WEXITSTATUS(status) >= 4))
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
exit(EXIT_SUCCESS);
|
|
}
|