1/*
2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23/*
24 * Copyright (C) 1995 Wolfgang Solfrank
25 * Copyright (c) 1995 Martin Husemann
26 *
27 * Redistribution and use in source and binary forms, with or without
28 * modification, are permitted provided that the following conditions
29 * are met:
30 * 1. Redistributions of source code must retain the above copyright
31 *    notice, this list of conditions and the following disclaimer.
32 * 2. Redistributions in binary form must reproduce the above copyright
33 *    notice, this list of conditions and the following disclaimer in the
34 *    documentation and/or other materials provided with the distribution.
35 * 3. All advertising materials mentioning features or use of this software
36 *    must display the following acknowledgement:
37 *	This product includes software developed by Martin Husemann
38 *	and Wolfgang Solfrank.
39 * 4. Neither the name of the University nor the names of its contributors
40 *    may be used to endorse or promote products derived from this software
41 *    without specific prior written permission.
42 *
43 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
44 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
45 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
46 * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
47 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
48 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
49 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
50 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
51 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
52 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
53 */
54
55
56#include <sys/cdefs.h>
57
58#include <stdlib.h>
59#include <string.h>
60#include <ctype.h>
61#include <stdio.h>
62#include <unistd.h>
63#include <errno.h>
64#if __STDC__
65#include <stdarg.h>
66#else
67#include <varargs.h>
68#endif
69
70#include "fsutil.h"
71#include "ext.h"
72
73int alwaysno;		/* assume "no" for all questions */
74int alwaysyes;		/* assume "yes" for all questions */
75int preen;		/* set when preening */
76int quick;		/* set to quickly check if volume is dirty */
77int quiet;		/* set to supress most messages */
78int rdonly;		/* device is opened read only (supersedes above) */
79size_t maxmem;	/* If non-zero, limit major allocations to this many bytes */
80
81static void usage __P((void));
82int main __P((int, char **));
83
84static void
85usage()
86{
87	errexit("Usage: fsck_msdos [-fnpqy] [-M <integer>[k|K|m|M]] filesystem ... \n");
88}
89
90int
91main(argc, argv)
92	int argc;
93	char **argv;
94{
95	int ret = 0, erg;
96	int ch;
97	int offset;
98
99	/*
100	 * Allow default maximum memory to be specified at compile time.
101	 */
102	#ifdef FSCK_MAX_MEM
103	maxmem = FSCK_MAX_MEM;
104	#endif
105
106	while ((ch = getopt(argc, argv, "pynfqM:")) != -1) {
107		switch (ch) {
108		case 'f':
109			/*
110			 * We are always forced, since we don't
111			 * have a clean flag
112			 */
113			break;
114		case 'n':
115			alwaysno = 1;
116			alwaysyes = preen = 0;
117			break;
118		case 'y':
119			alwaysyes = 1;
120			alwaysno = preen = 0;
121			break;
122
123		case 'p':
124			preen = 1;
125			alwaysyes = alwaysno = 0;
126			break;
127
128		case 'q':
129			quick = 1;
130			break;
131		case 'M':
132			if (sscanf(optarg, "%zi%n", &maxmem, &offset) == 0)
133			{
134				pfatal("Size argument '%s' not recognized\n", optarg);
135				usage();
136			}
137			switch (optarg[offset])
138			{
139				case 'M':
140				case 'm':
141					maxmem *= 1024;
142					/* Fall through */
143				case 'K':
144				case 'k':
145					maxmem *= 1024;
146					if (optarg[offset+1])
147						goto bad_multiplier;
148					break;
149				case '\0':
150					break;
151				default:
152bad_multiplier:
153					pfatal("Size multiplier '%s' not recognized\n", optarg+offset);
154					usage();
155			}
156			break;
157		default:
158			pfatal("Option '%c' not recognized\n", optopt);
159			usage();
160			break;
161		}
162	}
163	argc -= optind;
164	argv += optind;
165
166	if (!argc)
167		usage();
168
169	while (--argc >= 0) {
170		setcdevname(*argv);
171		erg = checkfilesys(*argv++);
172		if (erg > ret)
173			ret = erg;
174	}
175
176	return ret;
177}
178
179
180/*VARARGS*/
181int
182#if __STDC__
183ask(int def, const char *fmt, ...)
184#else
185ask(def, fmt, va_alist)
186	int def;
187	char *fmt;
188	va_dcl
189#endif
190{
191	va_list ap;
192
193	char prompt[256];
194	int c;
195
196	if (preen) {
197		if (rdonly)
198			def = 0;
199		if (def)
200			printf("FIXED\n");
201		return def;
202	}
203
204#if __STDC__
205	va_start(ap, fmt);
206#else
207	va_start(ap);
208#endif
209	vsnprintf(prompt, sizeof(prompt), fmt, ap);
210
211	if (alwaysyes || rdonly) {
212		if (!quiet)
213			printf("%s? %s\n", prompt, rdonly ? "no" : "yes");
214		return !rdonly;
215	}
216	do {
217		printf("%s? [yn] ", prompt);
218		fflush(stdout);
219		c = getchar();
220		while (c != '\n' && getchar() != '\n')
221			if (feof(stdin))
222				return 0;
223	} while (c != 'y' && c != 'Y' && c != 'n' && c != 'N');
224	return c == 'y' || c == 'Y';
225}
226