]> git.ipfire.org Git - thirdparty/util-linux.git/blame - historic/mkfs.c
Imported from util-linux-2.5 tarball.
[thirdparty/util-linux.git] / historic / mkfs.c
CommitLineData
726f69e2
KZ
1/*
2 * fs-util A simple generic frontend for the for the fsck and mkfs
3 * programs under Linux. See the manual pages for details.
4 *
5 * Usage: fsck [-AV] [-t fstype] [fs-options] device
6 * mkfs [-V] [-t fstype] [fs-options] device< [size]
7 *
8 * Authors: David Engel, <david@ods.com>
9 * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
10 */
11
12
13#include <sys/types.h>
14#include <sys/wait.h>
15#include <errno.h>
16#include <limits.h>
17#include <stdio.h>
18#include <stdlib.h>
19#include <string.h>
20#include <errno.h>
21#include <mntent.h>
22#include <unistd.h>
23#include <getopt.h>
24
25
26#ifndef DEFAULT_FSTYPE
27# define DEFAULT_FSTYPE "minix"
28#endif
29
30#define _PATH_PROG "%s.%s"
31#define _PROG_FSCK "fsck"
32
33#define EXIT_OK 0
34#define EXIT_NONDESTRUCT 1
35#define EXIT_DESTRUCT 2
36#define EXIT_UNCORRECTED 4
37#define EXIT_ERROR 8
38#define EXIT_USAGE 16
39#define EXIT_LIBRARY 128
40
41static char *Version = "1.8";
42static char *ignored_types[] = {
43 "ignore",
44 "iso9660",
45 "msdos",
46 "nfs",
47 "proc",
48 "sw",
49 "swap",
50 NULL
51};
52
53
54/* Execute a program. */
55int do_exec(char *prog, char **argv, int verbose)
56{
57 char *args[33];
58 register int i;
59 int pid, status;
60
61 /* Build the vector. */
62 i = 0;
63 args[i++] = prog;
64 while(*argv != NULL && i < 32)
65 args[i++] = *argv++;
66 args[i] = NULL;
67
68 if (verbose) {
69 i = 0;
70 while(args[i] != NULL) {
71 printf("%s ", args[i]);
72 i++;
73 }
74 printf("\n");
75 if (verbose > 1)
76 return EXIT_OK;
77 }
78
79 /* Fork and execute the correct program. */
80 if ((pid = fork()) < 0) {
81 perror("fork");
82 status = EXIT_ERROR;
83 } else if (pid == 0) {
84 (void) execvp(args[0], args);
85 perror(args[0]);
86 exit(EXIT_ERROR);
87 } else {
88 while(wait(&status) != pid)
89 ;
90 status = WEXITSTATUS(status);
91 }
92
93 return status;
94}
95
96
97/* Check if we have to ignore a file system type. */
98int ignore(char *type, char *opts)
99{
100 char *cp;
101 char **ip;
102
103 ip = ignored_types;
104 while (*ip != NULL) {
105 if (!strcmp(type, *ip))
106 return 1;
107 ip++;
108 }
109
110 for (cp = strtok(opts, ","); cp != NULL; cp = strtok(NULL, ",")) {
111 if (!strcmp(cp, "noauto"))
112 return 1;
113 }
114
115 return 0;
116}
117
118
119/* Check all file systems, using the /etc/fstab table. */
120int check_all(int verbose, char **argv)
121{
122 char path[PATH_MAX];
123 char *args[33];
124 FILE *mntfile;
125 struct mntent *mp;
126 register int i;
127 int status = EXIT_OK;
128
129 if (verbose)
130 printf("Checking all file systems.\n");
131
132 /* Create an array of arguments. */
133 i = 0;
134 while (*argv != NULL && i < 32)
135 args[i++] = *argv++;
136 args[i] = NULL;
137 args[i + 1] = NULL;
138
139 /* Open the mount table. */
140 if ((mntfile = setmntent(MNTTAB, "r")) == NULL) {
141 perror(MNTTAB);
142 exit(EXIT_ERROR);
143 }
144
145 /* Walk through the /etc/fstab file. */
146 while ((mp = getmntent(mntfile)) != NULL) {
147 if (verbose)
148 printf("%-7s %-15s %-15s ", mp->mnt_type,
149 mp->mnt_fsname, mp->mnt_dir);
150 if (ignore(mp->mnt_type, mp->mnt_opts)) {
151 if (verbose)
152 printf("(ignored)\n");
153 continue;
154 }
155
156 /* Build program name. */
157 sprintf(path, _PATH_PROG, _PROG_FSCK, mp->mnt_type);
158 args[i] = mp->mnt_fsname;
159 status |= do_exec(path, args, verbose);
160 }
161
162 (void) endmntent(mntfile);
163
164 return status;
165}
166
167
168/* Lookup filesys in /etc/fstab and return the corresponding entry. */
169struct mntent *lookup(char *filesys)
170{
171 FILE *mntfile;
172 struct mntent *mp;
173
174 /* No filesys name given. */
175 if (filesys == NULL)
176 return NULL;
177
178 /* Open the mount table. */
179 if ((mntfile = setmntent(MNTTAB, "r")) == NULL) {
180 perror(MNTTAB);
181 exit(EXIT_ERROR);
182 }
183
184 while ((mp = getmntent(mntfile)) != NULL) {
185 if (!strcmp(filesys, mp->mnt_fsname) ||
186 !strcmp(filesys, mp->mnt_dir))
187 break;
188 }
189
190 (void) endmntent(mntfile);
191
192 return mp;
193}
194
195
196void usage(int fsck, char *prog)
197{
198 if (fsck) {
199 fprintf(stderr, "Usage: fsck [-AV] [-t fstype] [fs-options] filesys\n");
200 } else {
201 fprintf(stderr, "Usage: mkfs [-V] [-t fstype] [fs-options] filesys [size]\n");
202 }
203
204 exit(EXIT_USAGE);
205}
206
207
208void main(int argc, char *argv[])
209{
210 char path[PATH_MAX];
211 char *oldpath, newpath[PATH_MAX];
212 register char *sp;
213 struct mntent *fsent;
214 char *fstype = NULL;
215 int verbose = 0;
216 int doall = 0;
217 int i, fsck, more;
218
219 /* Must be 1 for "fsck" and 0 for "mkfs". */
220 if ((sp = strrchr(argv[0], '/')) != NULL)
221 sp++;
222 else
223 sp = argv[0];
224 if (!strcmp(sp, _PROG_FSCK))
225 fsck = 1;
226 else
227 fsck = 0;
228
229 /* Check commandline options. */
230 opterr = 0;
231 more = 0;
232 while ((more == 0) && ((i = getopt(argc, argv, "AVt:")) != EOF))
233 switch(i) {
234 case 'A':
235 doall++;
236 break;
237 case 'V':
238 verbose++;
239 break;
240 case 't':
241 if (optarg == NULL)
242 usage(fsck, sp);
243 fstype = optarg;
244 break;
245 default:
246 more = 1;
247 break; /* start of specific arguments */
248 }
249
250 /* Did we get any specific arguments? */
251 if (more)
252 optind--;
253
254 /* Print our version number if requested. */
255 if (verbose)
256 printf("%s (fsutil) version %s (%s)\n", argv[0],
257 Version, __DATE__);
258
259 /* Update our PATH to include /etc/fs and /etc. */
260 strcpy(newpath, "PATH=/etc/fs:/etc:");
261 if ((oldpath = getenv("PATH")) != NULL)
262 strcat(newpath, oldpath);
263 putenv(newpath);
264
265 /* If -A was specified ("check all"), double-check. */
266 if (doall) {
267 if (!fsck || (fstype != NULL))
268 usage(fsck, sp);
269 exit(check_all(verbose, &argv[optind]));
270 } else {
271 /* If -t wasn't specified, we must deduce fstype. */
272 if (fstype == NULL) {
273 /* make sure that "filesys" was specified */
274 if (optind >= argc)
275 usage(fsck, sp);
276 /* then try looking for it in /etc/fstab */
277 if ((fsent = lookup(argv[argc - 1])) != NULL) {
278 argv[argc - 1] = fsent->mnt_fsname;
279 fstype = fsent->mnt_type;
280 } else {
281 if (!fsck && optind < argc-1) {
282 if ((fsent = lookup(argv[argc - 2])) != NULL) {
283 argv[argc - 2] = fsent->mnt_fsname;
284 fstype = fsent->mnt_type;
285 }
286 }
287 }
288 /* if we still don't know, use the default */
289 if (fstype == NULL) fstype = DEFAULT_FSTYPE;
290 }
291
292 /* Build program name. */
293 sprintf(path, _PATH_PROG, sp, fstype);
294 exit(do_exec(path, &argv[optind], verbose));
295 }
296 /*NOTREACHED*/
297}