1/*	$NetBSD: main.c,v 1.22 2010/04/11 08:23:52 hannken Exp $	*/
2
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.22 2010/04/11 08:23:52 hannken Exp $");
32#endif /* not lint */
33
34#include <stdlib.h>
35#include <string.h>
36#include <stdio.h>
37#include <unistd.h>
38#include <err.h>
39#include <errno.h>
40#include <stdarg.h>
41#include <signal.h>
42
43#include "fsutil.h"
44#include "snapshot.h"
45#include "ext.h"
46#include "exitvalues.h"
47
48int alwaysno;		/* assume "no" for all questions */
49int alwaysyes;		/* assume "yes" for all questions */
50int preen;		/* set when preening */
51int rdonly;		/* device is opened read only (supersedes above) */
52
53static void usage(void) __dead;
54
55static void
56usage(void)
57{
58    	(void)fprintf(stderr,
59	    "Usage: %s [-fnpy] [-x snap_backup] filesystem ... \n",
60	    getprogname());
61	exit(FSCK_EXIT_USAGE);
62}
63
64int
65main(int argc, char **argv)
66{
67	int ret = FSCK_EXIT_OK, erg;
68	int ch, snapfd;
69	char *snap_backup = NULL, *snap_dev;
70
71	while ((ch = getopt(argc, argv, "pPqynfx:")) != -1) {
72		switch (ch) {
73		case 'f':
74			/*
75			 * We are always forced, since we don't
76			 * have a clean flag
77			 */
78			break;
79		case 'n':
80			alwaysno = 1;
81			alwaysyes = preen = 0;
82			break;
83		case 'y':
84			alwaysyes = 1;
85			alwaysno = preen = 0;
86			break;
87
88		case 'p':
89			preen = 1;
90			alwaysyes = alwaysno = 0;
91			break;
92
93		case 'P':		/* Progress meter not implemented. */
94			break;
95
96		case 'q':		/* Quiet not implemented. */
97			break;
98
99		case 'x':
100			snap_backup = optarg;
101			break;
102
103		default:
104			usage();
105			break;
106		}
107	}
108	if (snap_backup != NULL && (!alwaysno || alwaysyes)) {
109		warnx("Cannot use -x without -n\n");
110		snap_backup = NULL;
111	}
112	argc -= optind;
113	argv += optind;
114
115	if (!argc)
116		usage();
117
118	if (signal(SIGINT, SIG_IGN) != SIG_IGN)
119		(void) signal(SIGINT, catch);
120	if (preen)
121		(void) signal(SIGQUIT, catch);
122
123	while (--argc >= 0) {
124		setcdevname(*argv, preen);
125		if (snap_backup != NULL) {
126			snapfd = snap_open(*argv, snap_backup, NULL, &snap_dev);
127			if (snapfd < 0) {
128				warn("can't take snapshot of %s", *argv);
129				erg = checkfilesys(*argv);
130			} else {
131				erg = checkfilesys(snap_dev);
132				close(snapfd);
133			}
134			argv++;
135		} else
136			erg = checkfilesys(*argv++);
137		if (erg > ret)
138			ret = erg;
139	}
140
141	return ret;
142}
143
144
145/*VARARGS*/
146int
147ask(int def, const char *fmt, ...)
148{
149	va_list ap;
150
151	char prompt[256];
152	int c;
153
154	if (preen) {
155		if (rdonly)
156			def = 0;
157		if (def)
158			printf("FIXED\n");
159		return def;
160	}
161
162	va_start(ap, fmt);
163	vsnprintf(prompt, sizeof(prompt), fmt, ap);
164	va_end(ap);
165	if (alwaysyes || rdonly) {
166		printf("%s? %s\n", prompt, rdonly ? "no" : "yes");
167		return !rdonly;
168	}
169	do {
170		printf("%s? [yn] ", prompt);
171		fflush(stdout);
172		c = getchar();
173		while (c != '\n' && getchar() != '\n')
174			if (feof(stdin))
175				return 0;
176	} while (c != 'y' && c != 'Y' && c != 'n' && c != 'N');
177	return c == 'y' || c == 'Y';
178}
179