1/*-
2 * SPDX-License-Identifier: BSD-2-Clause
3 *
4 * Copyright (C) 1995 Wolfgang Solfrank
5 * Copyright (c) 1995 Martin Husemann
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 *    notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 *    notice, this list of conditions and the following disclaimer in the
14 *    documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28
29#include <sys/cdefs.h>
30#ifndef lint
31__RCSID("$NetBSD: main.c,v 1.10 1997/10/01 02:18:14 enami Exp $");
32#endif /* not lint */
33
34#include <stdlib.h>
35#include <string.h>
36#include <stdio.h>
37#include <unistd.h>
38#include <errno.h>
39#include <stdarg.h>
40
41#include "fsutil.h"
42#include "ext.h"
43
44int alwaysno;		/* assume "no" for all questions */
45int alwaysyes;		/* assume "yes" for all questions */
46int preen;		/* set when preening */
47int rdonly;		/* device is opened read only (supersedes above) */
48int skipclean;		/* skip clean file systems if preening */
49int allow_mmap;		/* Allow the use of mmap(), if possible */
50
51static void usage(void) __dead2;
52
53static void
54usage(void)
55{
56
57	fprintf(stderr, "%s\n%s\n",
58	    "usage: fsck_msdosfs -p [-f] filesystem ...",
59	    "       fsck_msdosfs [-ny] filesystem ...");
60	exit(1);
61}
62
63int
64main(int argc, char **argv)
65{
66	int ret = 0, erg;
67	int ch;
68
69	skipclean = 1;
70	allow_mmap = 1;
71	while ((ch = getopt(argc, argv, "CfFnpyM")) != -1) {
72		switch (ch) {
73		case 'C': /* for fsck_ffs compatibility */
74			break;
75		case 'f':
76			skipclean = 0;
77			break;
78		case 'F':
79			/*
80			 * We can never run in the background.  We must exit
81			 * silently with a nonzero exit code so that fsck(8)
82			 * can probe our support for -F.  The exit code
83			 * doesn't really matter, but we use an unusual one
84			 * in case someone tries -F directly.  The -F flag
85			 * is intentionally left out of the usage message.
86			 */
87			exit(5);
88		case 'n':
89			alwaysno = 1;
90			alwaysyes = 0;
91			break;
92		case 'y':
93			alwaysyes = 1;
94			alwaysno = 0;
95			break;
96
97		case 'p':
98			preen = 1;
99			break;
100
101		case 'M':
102			allow_mmap = 0;
103			break;
104
105		default:
106			usage();
107			break;
108		}
109	}
110	argc -= optind;
111	argv += optind;
112
113	if (!argc)
114		usage();
115
116	while (--argc >= 0) {
117		setcdevname(*argv, preen);
118		erg = checkfilesys(*argv++);
119		if (erg > ret)
120			ret = erg;
121	}
122
123	return ret;
124}
125
126
127/*VARARGS*/
128int
129ask(int def, const char *fmt, ...)
130{
131	va_list ap;
132
133	char prompt[256];
134	int c;
135
136	if (alwaysyes || alwaysno || rdonly)
137		def = (alwaysyes && !rdonly && !alwaysno);
138
139	if (preen) {
140		if (def)
141			printf("FIXED\n");
142		return def;
143	}
144
145	va_start(ap, fmt);
146	vsnprintf(prompt, sizeof(prompt), fmt, ap);
147	va_end(ap);
148	if (alwaysyes || alwaysno || rdonly) {
149		printf("%s? %s\n", prompt, def ? "yes" : "no");
150		return def;
151	}
152	do {
153		printf("%s? [yn] ", prompt);
154		fflush(stdout);
155		c = getchar();
156		while (c != '\n' && getchar() != '\n')
157			if (feof(stdin))
158				return 0;
159	} while (c != 'y' && c != 'Y' && c != 'n' && c != 'N');
160	return c == 'y' || c == 'Y';
161}
162