]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sbin/fsck/fsutil.c
This commit was generated by cvs2svn to compensate for changes in r98524,
[FreeBSD/FreeBSD.git] / sbin / fsck / fsutil.c
1 /*      $NetBSD: fsutil.c,v 1.7 1998/07/30 17:41:03 thorpej Exp $       */
2
3 /*
4  * Copyright (c) 1990, 1993
5  *      The Regents of the University of California.  All rights reserved.
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  * 3. All advertising materials mentioning features or use of this software
16  *    must display the following acknowledgement:
17  *      This product includes software developed by the University of
18  *      California, Berkeley and its contributors.
19  * 4. Neither the name of the University nor the names of its contributors
20  *    may be used to endorse or promote products derived from this software
21  *    without specific prior written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33  * SUCH DAMAGE.
34  */
35
36 #include <sys/cdefs.h>
37 #ifndef lint
38 __RCSID("$NetBSD: fsutil.c,v 1.7 1998/07/30 17:41:03 thorpej Exp $");
39 #endif /* not lint */
40 __FBSDID("$FreeBSD$");
41
42 #include <sys/param.h>
43 #include <sys/stat.h>
44 #include <sys/mount.h>
45
46 #include <err.h>
47 #include <errno.h>
48 #include <fstab.h>
49 #include <paths.h>
50 #include <stdarg.h>
51 #include <stdio.h>
52 #include <stdlib.h>
53 #include <string.h>
54
55 #include "fsutil.h"
56
57 static const char *dev = NULL;
58 static int hot = 0;
59 static int preen = 0;
60
61 static void vmsg(int, const char *, va_list) __printflike(2, 0);
62
63 void
64 setcdevname(const char *cd, int pr)
65 {
66         dev = cd;
67         preen = pr;
68 }
69
70 const char *
71 cdevname(void)
72 {
73         return dev;
74 }
75
76 int
77 hotroot(void)
78 {
79         return hot;
80 }
81
82 /*VARARGS*/
83 void
84 errexit(const char *fmt, ...)
85 {
86         va_list ap;
87
88         va_start(ap, fmt);
89         (void) vfprintf(stderr, fmt, ap);
90         va_end(ap);
91         exit(8);
92 }
93
94 static void
95 vmsg(int fatal, const char *fmt, va_list ap)
96 {
97         if (!fatal && preen)
98                 (void) printf("%s: ", dev);
99
100         (void) vprintf(fmt, ap);
101
102         if (fatal && preen)
103                 (void) printf("\n");
104
105         if (fatal && preen) {
106                 (void) printf(
107                     "%s: UNEXPECTED INCONSISTENCY; RUN %s MANUALLY.\n",
108                     dev, getprogname());
109                 exit(8);
110         }
111 }
112
113 /*VARARGS*/
114 void
115 pfatal(const char *fmt, ...)
116 {
117         va_list ap;
118
119         va_start(ap, fmt);
120         vmsg(1, fmt, ap);
121         va_end(ap);
122 }
123
124 /*VARARGS*/
125 void
126 pwarn(const char *fmt, ...)
127 {
128         va_list ap;
129
130         va_start(ap, fmt);
131         vmsg(0, fmt, ap);
132         va_end(ap);
133 }
134
135 void
136 perror(const char *s)
137 {
138         pfatal("%s (%s)", s, strerror(errno));
139 }
140
141 void
142 panic(const char *fmt, ...)
143 {
144         va_list ap;
145
146         va_start(ap, fmt);
147         vmsg(1, fmt, ap);
148         va_end(ap);
149         exit(8);
150 }
151
152 const char *
153 unrawname(const char *name)
154 {
155         static char unrawbuf[32];
156         const char *dp;
157         struct stat stb;
158
159         if ((dp = strrchr(name, '/')) == 0)
160                 return (name);
161         if (stat(name, &stb) < 0)
162                 return (name);
163         if (!S_ISCHR(stb.st_mode))
164                 return (name);
165         if (dp[1] != 'r')
166                 return (name);
167         (void)snprintf(unrawbuf, 32, "%.*s/%s", (int)(dp - name), name, dp + 2);
168         return (unrawbuf);
169 }
170
171 const char *
172 rawname(const char *name)
173 {
174         static char rawbuf[32];
175         const char *dp;
176
177         if ((dp = strrchr(name, '/')) == 0)
178                 return (0);
179         (void)snprintf(rawbuf, 32, "%.*s/r%s", (int)(dp - name), name, dp + 1);
180         return (rawbuf);
181 }
182
183 const char *
184 devcheck(const char *origname)
185 {
186         struct stat stslash, stchar;
187
188         if (stat("/", &stslash) < 0) {
189                 perror("/");
190                 printf("Can't stat root\n");
191                 return (origname);
192         }
193         if (stat(origname, &stchar) < 0) {
194                 perror(origname);
195                 printf("Can't stat %s\n", origname);
196                 return (origname);
197         }
198         if (!S_ISCHR(stchar.st_mode)) {
199                 perror(origname);
200                 printf("%s is not a char device\n", origname);
201         }
202         return (origname);
203 }
204
205 /*
206  * Get the mount point information for name.
207  */
208 struct statfs *
209 getmntpt(const char *name)
210 {
211         struct stat devstat, mntdevstat;
212         char device[sizeof(_PATH_DEV) - 1 + MNAMELEN];
213         char *devname;
214         struct statfs *mntbuf, *statfsp;
215         int i, mntsize, isdev;
216
217         if (stat(name, &devstat) != 0)
218                 return (NULL);
219         if (S_ISCHR(devstat.st_mode) || S_ISBLK(devstat.st_mode))
220                 isdev = 1;
221         else
222                 isdev = 0;
223         mntsize = getmntinfo(&mntbuf, MNT_NOWAIT);
224         for (i = 0; i < mntsize; i++) {
225                 statfsp = &mntbuf[i];
226                 devname = statfsp->f_mntfromname;
227                 if (*devname != '/') {
228                         strcpy(device, _PATH_DEV);
229                         strcat(device, devname);
230                         strcpy(statfsp->f_mntfromname, device);
231                 }
232                 if (isdev == 0) {
233                         if (strcmp(name, statfsp->f_mntonname))
234                                 continue;
235                         return (statfsp);
236                 }
237                 if (stat(devname, &mntdevstat) == 0 &&
238                     mntdevstat.st_rdev == devstat.st_rdev)
239                         return (statfsp);
240         }
241         statfsp = NULL;
242         return (statfsp);
243 }
244
245
246 void *
247 emalloc(size_t s)
248 {
249         void *p;
250
251         p = malloc(s);
252         if (p == NULL)
253                 err(1, "malloc failed");
254         return (p);
255 }
256
257
258 void *
259 erealloc(void *p, size_t s)
260 {
261         void *q;
262
263         q = realloc(p, s);
264         if (q == NULL)
265                 err(1, "realloc failed");
266         return (q);
267 }
268
269
270 char *
271 estrdup(const char *s)
272 {
273         char *p;
274
275         p = strdup(s);
276         if (p == NULL)
277                 err(1, "strdup failed");
278         return (p);
279 }