Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-ports
Path: blob/main/filesystems/e2fsprogs-core/files/fsck_ext2fs.c
18160 views
1
/*
2
* fsck_ext2fs - wrapper for e2fsck on FreeBSD
3
* Copyright (C) 2004,2006 Matthias Andree <[email protected]>
4
* redistributable in accordance with the
5
* GNU General Public License v2
6
*
7
* Upstream: $Id: fsck_ext2fs.c,v 1.6 2006/07/02 11:37:49 emma Exp $
8
*
9
* format: gindent -kr
10
*/
11
12
#include <sys/types.h>
13
#include <unistd.h>
14
#include <stdlib.h>
15
#include <stdio.h>
16
#include <string.h>
17
#include <sys/wait.h>
18
#include <sys/time.h>
19
#include <sys/resource.h>
20
#include <errno.h>
21
22
__attribute__ ((noreturn))
23
static int die(const char *tag)
24
{
25
perror(tag);
26
exit(EXIT_FAILURE);
27
}
28
29
int main(int argc, char **argv)
30
{
31
int ch, i = 1, force = 0, status, verbose = 0, t;
32
long block = 0;
33
enum { normal, preen, yes, no } mode = normal;
34
char *cmd[256];
35
pid_t pid;
36
37
cmd[0] = "/sbin/e2fsck";
38
while ((ch = getopt(argc, argv, "BFpfnyb:v")) != -1) {
39
switch (ch) {
40
case 'p':
41
mode = preen;
42
break;
43
case 'f':
44
force = 1;
45
break;
46
case 'n':
47
mode = no;
48
break;
49
case 'y':
50
mode = yes;
51
break;
52
case 'b':
53
block = atol(optarg);
54
break;
55
case 'v':
56
verbose++;
57
break;
58
case 'F':
59
/* e2fsck does not support background checking,
60
* hence exit with nonzero status to force
61
* the foreground check. */
62
exit(1);
63
case 'B':
64
default:
65
fprintf(stderr, "%s: unknown option -%c\n",
66
argv[0], optopt);
67
exit(EXIT_FAILURE);
68
}
69
}
70
71
if (force)
72
cmd[i++] = "-f";
73
74
switch (mode) {
75
case normal:
76
/* FreeBSD needs -f to force a check only in context
77
* with -p -- so map normal to force to match
78
* expectations */
79
if (!force)
80
cmd[i++] = "-f";
81
break;
82
case yes:
83
cmd[i++] = "-y";
84
break;
85
case no:
86
cmd[i++] = "-n";
87
break;
88
case preen:
89
cmd[i++] = "-p";
90
break;
91
}
92
93
if (block) {
94
static char b[30];
95
96
sprintf(b, "-b %ld", block);
97
cmd[i++] = b;
98
}
99
100
/* silently limit verbose to 15 so we don't overflow the cmd array */
101
if (verbose > 15)
102
verbose = 15;
103
104
for (t = verbose; t > 1; t--)
105
cmd[i++] = "-v";
106
107
while (optind < argc) {
108
cmd[i++] = argv[optind++];
109
/* sanity check so we don't overflow the cmd buffer */
110
if (i+1 == sizeof(cmd)/sizeof(cmd[0])) {
111
errno = E2BIG;
112
die(argv[0]);
113
}
114
}
115
116
cmd[i++] = 0;
117
118
if (verbose) {
119
for (i=0; cmd[i]; i++)
120
fputs(cmd[i], stderr),
121
fputc(' ', stderr);
122
fputc('\n', stderr);
123
}
124
125
pid = fork();
126
switch (pid) {
127
case -1:
128
/* error */
129
die("fork");
130
break;
131
case 0:
132
/* child */
133
(void) execv(cmd[0], cmd);
134
perror("execve");
135
_exit(127);
136
default:
137
/* parent */
138
if (pid != waitpid(pid, &status, 0))
139
die("waitpid");
140
if (WIFSIGNALED(status)
141
|| (WIFEXITED(status) && WEXITSTATUS(status) >= 4))
142
exit(EXIT_FAILURE);
143
}
144
exit(EXIT_SUCCESS);
145
}
146
147