Path: blob/main/filesystems/e2fsprogs-core/files/fsck_ext2fs.c
18160 views
/*1* fsck_ext2fs - wrapper for e2fsck on FreeBSD2* Copyright (C) 2004,2006 Matthias Andree <[email protected]>3* redistributable in accordance with the4* GNU General Public License v25*6* Upstream: $Id: fsck_ext2fs.c,v 1.6 2006/07/02 11:37:49 emma Exp $7*8* format: gindent -kr9*/1011#include <sys/types.h>12#include <unistd.h>13#include <stdlib.h>14#include <stdio.h>15#include <string.h>16#include <sys/wait.h>17#include <sys/time.h>18#include <sys/resource.h>19#include <errno.h>2021__attribute__ ((noreturn))22static int die(const char *tag)23{24perror(tag);25exit(EXIT_FAILURE);26}2728int main(int argc, char **argv)29{30int ch, i = 1, force = 0, status, verbose = 0, t;31long block = 0;32enum { normal, preen, yes, no } mode = normal;33char *cmd[256];34pid_t pid;3536cmd[0] = "/sbin/e2fsck";37while ((ch = getopt(argc, argv, "BFpfnyb:v")) != -1) {38switch (ch) {39case 'p':40mode = preen;41break;42case 'f':43force = 1;44break;45case 'n':46mode = no;47break;48case 'y':49mode = yes;50break;51case 'b':52block = atol(optarg);53break;54case 'v':55verbose++;56break;57case 'F':58/* e2fsck does not support background checking,59* hence exit with nonzero status to force60* the foreground check. */61exit(1);62case 'B':63default:64fprintf(stderr, "%s: unknown option -%c\n",65argv[0], optopt);66exit(EXIT_FAILURE);67}68}6970if (force)71cmd[i++] = "-f";7273switch (mode) {74case normal:75/* FreeBSD needs -f to force a check only in context76* with -p -- so map normal to force to match77* expectations */78if (!force)79cmd[i++] = "-f";80break;81case yes:82cmd[i++] = "-y";83break;84case no:85cmd[i++] = "-n";86break;87case preen:88cmd[i++] = "-p";89break;90}9192if (block) {93static char b[30];9495sprintf(b, "-b %ld", block);96cmd[i++] = b;97}9899/* silently limit verbose to 15 so we don't overflow the cmd array */100if (verbose > 15)101verbose = 15;102103for (t = verbose; t > 1; t--)104cmd[i++] = "-v";105106while (optind < argc) {107cmd[i++] = argv[optind++];108/* sanity check so we don't overflow the cmd buffer */109if (i+1 == sizeof(cmd)/sizeof(cmd[0])) {110errno = E2BIG;111die(argv[0]);112}113}114115cmd[i++] = 0;116117if (verbose) {118for (i=0; cmd[i]; i++)119fputs(cmd[i], stderr),120fputc(' ', stderr);121fputc('\n', stderr);122}123124pid = fork();125switch (pid) {126case -1:127/* error */128die("fork");129break;130case 0:131/* child */132(void) execv(cmd[0], cmd);133perror("execve");134_exit(127);135default:136/* parent */137if (pid != waitpid(pid, &status, 0))138die("waitpid");139if (WIFSIGNALED(status)140|| (WIFEXITED(status) && WEXITSTATUS(status) >= 4))141exit(EXIT_FAILURE);142}143exit(EXIT_SUCCESS);144}145146147