1 /* $NetBSD: fsutil.c,v 1.17 2008/02/23 21:41:47 christos 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.17 2008/02/23 21:41:47 christos Exp $");
37 #include <sys/param.h>
47 #include <sys/types.h>
51 #include "exitvalues.h"
53 static const char *dev
= NULL
;
57 #define F_ERROR 0x80000000
60 setcdevname(const char *cd
, int pr
)
83 errexit(const char *fmt
, ...)
88 (void) vfprintf(stderr
, fmt
, ap
);
90 (void)fprintf(stderr
, "\n");
91 exit(FSCK_EXIT_CHECK_FAILED
);
95 vmsg(int fatal
, const char *fmt
, va_list ap
)
97 int serr
= fatal
& F_ERROR
;
102 (void)printf("%s: ", dev
);
103 if (quiet
&& !preen
) {
104 (void)printf("** %s (vmsg)\n", dev
);
108 (void) vprintf(fmt
, ap
);
110 printf(" (%s)", strerror(serrno
));
115 if (fatal
&& preen
) {
117 "%s: UNEXPECTED INCONSISTENCY; RUN %s MANUALLY.\n",
119 exit(FSCK_EXIT_CHECK_FAILED
);
125 pfatal(const char *fmt
, ...)
136 pwarn(const char *fmt
, ...)
146 perr(const char *fmt
, ...)
151 vmsg(1 | F_ERROR
, fmt
, ap
);
156 panic(const char *fmt
, ...)
163 exit(FSCK_EXIT_CHECK_FAILED
);
167 unrawname(const char *name
)
169 static char unrawbuf
[MAXPATHLEN
];
173 if ((dp
= strrchr(name
, '/')) == 0)
175 if (stat(name
, &stb
) < 0)
177 if (!S_ISCHR(stb
.st_mode
))
181 (void)snprintf(unrawbuf
, sizeof(unrawbuf
), "%.*s/%s",
182 (int)(dp
- name
), name
, dp
+ 2);
187 rawname(const char *name
)
189 static char rawbuf
[MAXPATHLEN
];
192 if ((dp
= strrchr(name
, '/')) == 0)
194 (void)snprintf(rawbuf
, sizeof(rawbuf
), "%.*s/r%s",
195 (int)(dp
- name
), name
, dp
+ 1);
200 blockcheck(const char *origname
)
202 struct stat stslash
, stblock
, stchar
;
203 const char *newname
, *raw
;
208 if (stat("/", &stslash
) < 0) {
209 perr("Can't stat `/'");
214 if (stat(newname
, &stblock
) < 0) {
215 perr("Can't stat `%s'", newname
);
218 if (S_ISBLK(stblock
.st_mode
)) {
219 if (stslash
.st_dev
== stblock
.st_rdev
)
221 raw
= rawname(newname
);
222 if (stat(raw
, &stchar
) < 0) {
223 perr("Can't stat `%s'", raw
);
226 if (S_ISCHR(stchar
.st_mode
)) {
229 printf("%s is not a character device\n", raw
);
232 } else if (S_ISCHR(stblock
.st_mode
) && !retried
) {
233 newname
= unrawname(newname
);
236 } else if ((fsp
= getfsfile(newname
)) != 0 && !retried
) {
237 newname
= fsp
->fs_spec
;
242 * Not a block or character device, just return name and
243 * let the user decide whether to use it.