1 /* $NetBSD: fsutil.c,v 1.24 2013/01/13 19:53:16 mlelstv Exp $ */
4 * Copyright (c) 1990, 1993
5 * The Regents of the University of California. All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
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 * 3. Neither the name of the University nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 #include <sys/cdefs.h>
34 __RCSID("$NetBSD: fsutil.c,v 1.24 2013/01/13 19:53:16 mlelstv Exp $");
37 #include <sys/param.h>
50 #include <sys/types.h>
54 #include "exitvalues.h"
56 static const char *dev
= NULL
;
60 #define F_ERROR 0x80000000
63 setcdevname(const char *cd
, int pr
)
86 errexit(const char *fmt
, ...)
91 (void) vfprintf(stderr
, fmt
, ap
);
93 (void)fprintf(stderr
, "\n");
94 exit(FSCK_EXIT_CHECK_FAILED
);
98 vmsg(int fatal
, const char *fmt
, va_list ap
)
100 int serr
= fatal
& F_ERROR
;
105 (void)printf("%s: ", dev
);
106 if (quiet
&& !preen
) {
107 (void)printf("** %s (vmsg)\n", dev
);
111 (void) vprintf(fmt
, ap
);
113 printf(" (%s)", strerror(serrno
));
118 if (fatal
&& preen
) {
120 "%s: UNEXPECTED INCONSISTENCY; RUN %s MANUALLY.\n",
122 exit(FSCK_EXIT_CHECK_FAILED
);
128 pfatal(const char *fmt
, ...)
139 pwarn(const char *fmt
, ...)
149 perr(const char *fmt
, ...)
154 vmsg(1 | F_ERROR
, fmt
, ap
);
159 panic(const char *fmt
, ...)
166 exit(FSCK_EXIT_CHECK_FAILED
);
170 blockcheck(const char *origname
)
175 struct stat stslash
, stblock
, stchar
;
176 const char *newname
, *raw
, *cooked
;
180 char cbuf
[MAXPATHLEN
];
181 static char buf
[MAXPATHLEN
];
184 if (stat("/", &stslash
) < 0) {
185 perr("Can't stat `/'");
188 len
= readlink(origname
, cbuf
, sizeof(cbuf
)-1);
196 if (stat(newname
, &stblock
) < 0) {
197 perr("Can't stat `%s'", newname
);
200 if (S_ISBLK(stblock
.st_mode
)) {
201 if (stslash
.st_dev
== stblock
.st_rdev
)
203 raw
= getdiskrawname(buf
, sizeof(buf
), newname
);
205 perr("Can't convert to raw `%s'", newname
);
208 if (stat(raw
, &stchar
) < 0) {
209 perr("Can't stat `%s'", raw
);
212 if (S_ISCHR(stchar
.st_mode
)) {
215 perr("%s is not a character device\n", raw
);
218 } else if (S_ISCHR(stblock
.st_mode
) && !retried
) {
219 cooked
= getdiskcookedname(cbuf
, sizeof(cbuf
), newname
);
220 if (cooked
== NULL
) {
221 perr("Can't convert to cooked `%s'", newname
);
227 } else if ((fsp
= getfsfile(newname
)) != 0 && !retried
) {
228 newname
= getfsspecname(cbuf
, sizeof(cbuf
), fsp
->fs_spec
);
235 * Not a block or character device, just return name and
236 * let the user decide whether to use it.
239 #endif /* defined(__minix) */
243 print_mtime(time_t t
)
248 (void)snprintf(b
, sizeof(b
), "%12.12s %4.4s ", &p
[4], &p
[20]);
250 (void)snprintf(b
, sizeof(b
), "%lld ", (long long)t
);
258 if (ckfinish
) (*ckfinish
)(0);
259 _exit(FSCK_EXIT_SIGNALLED
);
263 * When preening, allow a single quit to signal
264 * a special exit after filesystem checks complete
265 * so that reboot sequence may be interrupted.
270 static const char msg
[] =
271 "returning to single-user after filesystem check\n";
274 (void)write(STDOUT_FILENO
, msg
, sizeof(msg
) - 1);
276 (void)signal(SIGQUIT
, SIG_DFL
);
281 * Ignore a single quit signal; wait and flush just in case.
282 * Used by child processes in preen.
290 (void)signal(SIGQUIT
, SIG_IGN
);
291 (void)signal(SIGQUIT
, SIG_DFL
);