1 1.24 christos /* $NetBSD: main.c,v 1.24 2015/06/16 23:18:55 christos Exp $ */ 2 1.1 ws 3 1.1 ws /* 4 1.1 ws * Copyright (C) 1995 Wolfgang Solfrank 5 1.1 ws * Copyright (c) 1995 Martin Husemann 6 1.1 ws * 7 1.1 ws * Redistribution and use in source and binary forms, with or without 8 1.1 ws * modification, are permitted provided that the following conditions 9 1.1 ws * are met: 10 1.1 ws * 1. Redistributions of source code must retain the above copyright 11 1.1 ws * notice, this list of conditions and the following disclaimer. 12 1.1 ws * 2. Redistributions in binary form must reproduce the above copyright 13 1.1 ws * notice, this list of conditions and the following disclaimer in the 14 1.1 ws * documentation and/or other materials provided with the distribution. 15 1.1 ws * 16 1.1 ws * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR 17 1.1 ws * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 1.1 ws * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 1.1 ws * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, 20 1.1 ws * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21 1.1 ws * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 1.1 ws * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 1.1 ws * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 1.1 ws * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 1.1 ws * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 1.1 ws */ 27 1.1 ws 28 1.1 ws 29 1.9 lukem #include <sys/cdefs.h> 30 1.1 ws #ifndef lint 31 1.24 christos __RCSID("$NetBSD: main.c,v 1.24 2015/06/16 23:18:55 christos Exp $"); 32 1.1 ws #endif /* not lint */ 33 1.1 ws 34 1.1 ws #include <stdlib.h> 35 1.1 ws #include <string.h> 36 1.1 ws #include <stdio.h> 37 1.1 ws #include <unistd.h> 38 1.22 hannken #include <err.h> 39 1.1 ws #include <errno.h> 40 1.1 ws #include <stdarg.h> 41 1.20 christos #include <signal.h> 42 1.1 ws 43 1.6 christos #include "fsutil.h" 44 1.22 hannken #include "snapshot.h" 45 1.1 ws #include "ext.h" 46 1.19 christos #include "exitvalues.h" 47 1.1 ws 48 1.1 ws int alwaysno; /* assume "no" for all questions */ 49 1.1 ws int alwaysyes; /* assume "yes" for all questions */ 50 1.1 ws int preen; /* set when preening */ 51 1.1 ws int rdonly; /* device is opened read only (supersedes above) */ 52 1.1 ws 53 1.19 christos static void usage(void) __dead; 54 1.3 christos 55 1.1 ws static void 56 1.17 xtraeme usage(void) 57 1.1 ws { 58 1.22 hannken (void)fprintf(stderr, 59 1.22 hannken "Usage: %s [-fnpy] [-x snap_backup] filesystem ... \n", 60 1.19 christos getprogname()); 61 1.19 christos exit(FSCK_EXIT_USAGE); 62 1.1 ws } 63 1.1 ws 64 1.1 ws int 65 1.17 xtraeme main(int argc, char **argv) 66 1.1 ws { 67 1.19 christos int ret = FSCK_EXIT_OK, erg; 68 1.22 hannken int ch, snapfd; 69 1.22 hannken char *snap_backup = NULL, *snap_dev; 70 1.1 ws 71 1.22 hannken while ((ch = getopt(argc, argv, "pPqynfx:")) != -1) { 72 1.1 ws switch (ch) { 73 1.7 christos case 'f': 74 1.7 christos /* 75 1.7 christos * We are always forced, since we don't 76 1.7 christos * have a clean flag 77 1.7 christos */ 78 1.7 christos break; 79 1.1 ws case 'n': 80 1.1 ws alwaysno = 1; 81 1.1 ws alwaysyes = preen = 0; 82 1.1 ws break; 83 1.1 ws case 'y': 84 1.1 ws alwaysyes = 1; 85 1.1 ws alwaysno = preen = 0; 86 1.1 ws break; 87 1.1 ws 88 1.1 ws case 'p': 89 1.1 ws preen = 1; 90 1.1 ws alwaysyes = alwaysno = 0; 91 1.14 dsl break; 92 1.14 dsl 93 1.16 christos case 'P': /* Progress meter not implemented. */ 94 1.16 christos break; 95 1.16 christos 96 1.16 christos case 'q': /* Quiet not implemented. */ 97 1.1 ws break; 98 1.11 ws 99 1.22 hannken case 'x': 100 1.22 hannken snap_backup = optarg; 101 1.22 hannken break; 102 1.22 hannken 103 1.1 ws default: 104 1.1 ws usage(); 105 1.1 ws break; 106 1.1 ws } 107 1.1 ws } 108 1.22 hannken if (snap_backup != NULL && (!alwaysno || alwaysyes)) { 109 1.24 christos warnx("Cannot use -x without -n"); 110 1.22 hannken snap_backup = NULL; 111 1.22 hannken } 112 1.1 ws argc -= optind; 113 1.1 ws argv += optind; 114 1.1 ws 115 1.5 ws if (!argc) 116 1.5 ws usage(); 117 1.5 ws 118 1.20 christos if (signal(SIGINT, SIG_IGN) != SIG_IGN) 119 1.20 christos (void) signal(SIGINT, catch); 120 1.20 christos if (preen) 121 1.20 christos (void) signal(SIGQUIT, catch); 122 1.20 christos 123 1.5 ws while (--argc >= 0) { 124 1.4 christos setcdevname(*argv, preen); 125 1.22 hannken if (snap_backup != NULL) { 126 1.22 hannken snapfd = snap_open(*argv, snap_backup, NULL, &snap_dev); 127 1.22 hannken if (snapfd < 0) { 128 1.22 hannken warn("can't take snapshot of %s", *argv); 129 1.22 hannken erg = checkfilesys(*argv); 130 1.22 hannken } else { 131 1.22 hannken erg = checkfilesys(snap_dev); 132 1.22 hannken close(snapfd); 133 1.22 hannken } 134 1.22 hannken argv++; 135 1.22 hannken } else 136 1.22 hannken erg = checkfilesys(*argv++); 137 1.4 christos if (erg > ret) 138 1.4 christos ret = erg; 139 1.1 ws } 140 1.3 christos 141 1.3 christos return ret; 142 1.1 ws } 143 1.1 ws 144 1.1 ws 145 1.1 ws /*VARARGS*/ 146 1.1 ws int 147 1.1 ws ask(int def, const char *fmt, ...) 148 1.1 ws { 149 1.1 ws va_list ap; 150 1.11 ws 151 1.1 ws char prompt[256]; 152 1.1 ws int c; 153 1.1 ws 154 1.1 ws if (preen) { 155 1.1 ws if (rdonly) 156 1.1 ws def = 0; 157 1.1 ws if (def) 158 1.1 ws printf("FIXED\n"); 159 1.1 ws return def; 160 1.1 ws } 161 1.1 ws 162 1.1 ws va_start(ap, fmt); 163 1.1 ws vsnprintf(prompt, sizeof(prompt), fmt, ap); 164 1.12 wiz va_end(ap); 165 1.1 ws if (alwaysyes || rdonly) { 166 1.1 ws printf("%s? %s\n", prompt, rdonly ? "no" : "yes"); 167 1.1 ws return !rdonly; 168 1.1 ws } 169 1.1 ws do { 170 1.1 ws printf("%s? [yn] ", prompt); 171 1.1 ws fflush(stdout); 172 1.1 ws c = getchar(); 173 1.1 ws while (c != '\n' && getchar() != '\n') 174 1.1 ws if (feof(stdin)) 175 1.1 ws return 0; 176 1.1 ws } while (c != 'y' && c != 'Y' && c != 'n' && c != 'N'); 177 1.1 ws return c == 'y' || c == 'Y'; 178 1.1 ws } 179