1 /* $NetBSD: fsutil.c,v 1.26 2015/06/21 04:01:40 dholland 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.26 2015/06/21 04:01:40 dholland Exp $");
39 * used by sbin/fsck_ext2fs
40 * used by sbin/fsck_ffs
41 * used by sbin/fsck_lfs
42 * used by sbin/fsck_msdos
43 * used by sbin/fsck_v7fs
45 * used by usr.sbin/quotacheck
48 #include <sys/param.h>
61 #include <sys/types.h>
65 #include "exitvalues.h"
67 volatile sig_atomic_t returntosingle
;
69 static const char *dev
= NULL
;
73 #define F_ERROR 0x80000000
76 setcdevname(const char *cd
, int pr
)
99 errexit(const char *fmt
, ...)
104 (void) vfprintf(stderr
, fmt
, ap
);
106 (void)fprintf(stderr
, "\n");
107 exit(FSCK_EXIT_CHECK_FAILED
);
111 vmsg(int fatal
, const char *fmt
, va_list ap
)
113 int serr
= fatal
& F_ERROR
;
118 (void)printf("%s: ", dev
);
119 if (quiet
&& !preen
) {
120 (void)printf("** %s (vmsg)\n", dev
);
124 (void) vprintf(fmt
, ap
);
126 printf(" (%s)", strerror(serrno
));
131 if (fatal
&& preen
) {
133 "%s: UNEXPECTED INCONSISTENCY; RUN %s MANUALLY.\n",
135 exit(FSCK_EXIT_CHECK_FAILED
);
141 pfatal(const char *fmt
, ...)
152 pwarn(const char *fmt
, ...)
162 perr(const char *fmt
, ...)
167 vmsg(1 | F_ERROR
, fmt
, ap
);
172 panic(const char *fmt
, ...)
179 exit(FSCK_EXIT_CHECK_FAILED
);
183 blockcheck(const char *origname
)
188 struct stat stslash
, stblock
, stchar
;
189 const char *newname
, *raw
, *cooked
;
193 char cbuf
[MAXPATHLEN
];
194 static char buf
[MAXPATHLEN
];
197 if (stat("/", &stslash
) < 0) {
198 perr("Can't stat `/'");
201 len
= readlink(origname
, cbuf
, sizeof(cbuf
)-1);
209 if (stat(newname
, &stblock
) < 0) {
210 perr("Can't stat `%s'", newname
);
213 if (S_ISBLK(stblock
.st_mode
)) {
214 if (stslash
.st_dev
== stblock
.st_rdev
)
216 raw
= getdiskrawname(buf
, sizeof(buf
), newname
);
218 perr("Can't convert to raw `%s'", newname
);
221 if (stat(raw
, &stchar
) < 0) {
222 perr("Can't stat `%s'", raw
);
225 if (S_ISCHR(stchar
.st_mode
)) {
228 perr("%s is not a character device\n", raw
);
231 } else if (S_ISCHR(stblock
.st_mode
) && !retried
) {
232 cooked
= getdiskcookedname(cbuf
, sizeof(cbuf
), newname
);
233 if (cooked
== NULL
) {
234 perr("Can't convert to cooked `%s'", newname
);
240 } else if ((fsp
= getfsfile(newname
)) != 0 && !retried
) {
241 newname
= getfsspecname(cbuf
, sizeof(cbuf
), fsp
->fs_spec
);
248 * Not a block or character device, just return name and
249 * let the user decide whether to use it.
252 #endif /* defined(__minix) */
256 print_mtime(time_t t
)
261 (void)snprintf(b
, sizeof(b
), "%12.12s %4.4s ", &p
[4], &p
[20]);
263 (void)snprintf(b
, sizeof(b
), "%lld ", (long long)t
);
271 if (ckfinish
) (*ckfinish
)(0);
272 _exit(FSCK_EXIT_SIGNALLED
);
276 * When preening, allow a single quit to signal
277 * a special exit after filesystem checks complete
278 * so that reboot sequence may be interrupted.
283 static const char msg
[] =
284 "returning to single-user after filesystem check\n";
287 (void)write(STDOUT_FILENO
, msg
, sizeof(msg
) - 1);
289 (void)signal(SIGQUIT
, SIG_DFL
);
294 * Ignore a single quit signal; wait and flush just in case.
295 * Used by child processes in preen.
303 (void)signal(SIGQUIT
, SIG_IGN
);
304 (void)signal(SIGQUIT
, SIG_DFL
);