1*9558e6acSTreehugger Robot /* $NetBSD: fsutil.c,v 1.15 2006/06/05 16:52:05 christos Exp $ */
2*9558e6acSTreehugger Robot
3*9558e6acSTreehugger Robot /*-
4*9558e6acSTreehugger Robot * SPDX-License-Identifier: BSD-3-Clause
5*9558e6acSTreehugger Robot *
6*9558e6acSTreehugger Robot * Copyright (c) 1990, 1993
7*9558e6acSTreehugger Robot * The Regents of the University of California. All rights reserved.
8*9558e6acSTreehugger Robot *
9*9558e6acSTreehugger Robot * Redistribution and use in source and binary forms, with or without
10*9558e6acSTreehugger Robot * modification, are permitted provided that the following conditions
11*9558e6acSTreehugger Robot * are met:
12*9558e6acSTreehugger Robot * 1. Redistributions of source code must retain the above copyright
13*9558e6acSTreehugger Robot * notice, this list of conditions and the following disclaimer.
14*9558e6acSTreehugger Robot * 2. Redistributions in binary form must reproduce the above copyright
15*9558e6acSTreehugger Robot * notice, this list of conditions and the following disclaimer in the
16*9558e6acSTreehugger Robot * documentation and/or other materials provided with the distribution.
17*9558e6acSTreehugger Robot * 3. Neither the name of the University nor the names of its contributors
18*9558e6acSTreehugger Robot * may be used to endorse or promote products derived from this software
19*9558e6acSTreehugger Robot * without specific prior written permission.
20*9558e6acSTreehugger Robot *
21*9558e6acSTreehugger Robot * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22*9558e6acSTreehugger Robot * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23*9558e6acSTreehugger Robot * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24*9558e6acSTreehugger Robot * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25*9558e6acSTreehugger Robot * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26*9558e6acSTreehugger Robot * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27*9558e6acSTreehugger Robot * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28*9558e6acSTreehugger Robot * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29*9558e6acSTreehugger Robot * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30*9558e6acSTreehugger Robot * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31*9558e6acSTreehugger Robot * SUCH DAMAGE.
32*9558e6acSTreehugger Robot */
33*9558e6acSTreehugger Robot
34*9558e6acSTreehugger Robot #include <sys/cdefs.h>
35*9558e6acSTreehugger Robot #ifndef lint
36*9558e6acSTreehugger Robot __RCSID("$NetBSD: fsutil.c,v 1.15 2006/06/05 16:52:05 christos Exp $");
37*9558e6acSTreehugger Robot #endif /* not lint */
38*9558e6acSTreehugger Robot __FBSDID("$FreeBSD$");
39*9558e6acSTreehugger Robot
40*9558e6acSTreehugger Robot #include <sys/param.h>
41*9558e6acSTreehugger Robot #include <sys/stat.h>
42*9558e6acSTreehugger Robot #include <sys/mount.h>
43*9558e6acSTreehugger Robot
44*9558e6acSTreehugger Robot #include <err.h>
45*9558e6acSTreehugger Robot #include <errno.h>
46*9558e6acSTreehugger Robot #ifndef __ANDROID__
47*9558e6acSTreehugger Robot #include <fstab.h>
48*9558e6acSTreehugger Robot #endif
49*9558e6acSTreehugger Robot #include <paths.h>
50*9558e6acSTreehugger Robot #include <stdarg.h>
51*9558e6acSTreehugger Robot #include <stdio.h>
52*9558e6acSTreehugger Robot #include <stdlib.h>
53*9558e6acSTreehugger Robot #include <string.h>
54*9558e6acSTreehugger Robot
55*9558e6acSTreehugger Robot #include "fsutil.h"
56*9558e6acSTreehugger Robot
57*9558e6acSTreehugger Robot static const char *dev = NULL;
58*9558e6acSTreehugger Robot static int preen = 0;
59*9558e6acSTreehugger Robot
60*9558e6acSTreehugger Robot static void vmsg(int, const char *, va_list) __printflike(2, 0);
61*9558e6acSTreehugger Robot
62*9558e6acSTreehugger Robot void
setcdevname(const char * cd,int pr)63*9558e6acSTreehugger Robot setcdevname(const char *cd, int pr)
64*9558e6acSTreehugger Robot {
65*9558e6acSTreehugger Robot dev = cd;
66*9558e6acSTreehugger Robot preen = pr;
67*9558e6acSTreehugger Robot }
68*9558e6acSTreehugger Robot
69*9558e6acSTreehugger Robot const char *
cdevname(void)70*9558e6acSTreehugger Robot cdevname(void)
71*9558e6acSTreehugger Robot {
72*9558e6acSTreehugger Robot return dev;
73*9558e6acSTreehugger Robot }
74*9558e6acSTreehugger Robot
75*9558e6acSTreehugger Robot static void
vmsg(int fatal,const char * fmt,va_list ap)76*9558e6acSTreehugger Robot vmsg(int fatal, const char *fmt, va_list ap)
77*9558e6acSTreehugger Robot {
78*9558e6acSTreehugger Robot if (!fatal && preen)
79*9558e6acSTreehugger Robot (void) printf("%s: ", dev);
80*9558e6acSTreehugger Robot
81*9558e6acSTreehugger Robot (void) vprintf(fmt, ap);
82*9558e6acSTreehugger Robot
83*9558e6acSTreehugger Robot if (fatal && preen)
84*9558e6acSTreehugger Robot (void) printf("\n");
85*9558e6acSTreehugger Robot
86*9558e6acSTreehugger Robot if (fatal && preen) {
87*9558e6acSTreehugger Robot (void) printf(
88*9558e6acSTreehugger Robot "%s: UNEXPECTED INCONSISTENCY; RUN %s MANUALLY.\n",
89*9558e6acSTreehugger Robot dev, getprogname());
90*9558e6acSTreehugger Robot exit(8);
91*9558e6acSTreehugger Robot }
92*9558e6acSTreehugger Robot }
93*9558e6acSTreehugger Robot
94*9558e6acSTreehugger Robot /*VARARGS*/
95*9558e6acSTreehugger Robot void
pfatal(const char * fmt,...)96*9558e6acSTreehugger Robot pfatal(const char *fmt, ...)
97*9558e6acSTreehugger Robot {
98*9558e6acSTreehugger Robot va_list ap;
99*9558e6acSTreehugger Robot
100*9558e6acSTreehugger Robot va_start(ap, fmt);
101*9558e6acSTreehugger Robot vmsg(1, fmt, ap);
102*9558e6acSTreehugger Robot va_end(ap);
103*9558e6acSTreehugger Robot }
104*9558e6acSTreehugger Robot
105*9558e6acSTreehugger Robot /*VARARGS*/
106*9558e6acSTreehugger Robot void
pwarn(const char * fmt,...)107*9558e6acSTreehugger Robot pwarn(const char *fmt, ...)
108*9558e6acSTreehugger Robot {
109*9558e6acSTreehugger Robot va_list ap;
110*9558e6acSTreehugger Robot
111*9558e6acSTreehugger Robot va_start(ap, fmt);
112*9558e6acSTreehugger Robot vmsg(0, fmt, ap);
113*9558e6acSTreehugger Robot va_end(ap);
114*9558e6acSTreehugger Robot }
115*9558e6acSTreehugger Robot
116*9558e6acSTreehugger Robot void
perr(const char * fmt,...)117*9558e6acSTreehugger Robot perr(const char *fmt, ...)
118*9558e6acSTreehugger Robot {
119*9558e6acSTreehugger Robot va_list ap;
120*9558e6acSTreehugger Robot
121*9558e6acSTreehugger Robot va_start(ap, fmt);
122*9558e6acSTreehugger Robot vmsg(1, fmt, ap);
123*9558e6acSTreehugger Robot va_end(ap);
124*9558e6acSTreehugger Robot }
125*9558e6acSTreehugger Robot
126*9558e6acSTreehugger Robot void
panic(const char * fmt,...)127*9558e6acSTreehugger Robot panic(const char *fmt, ...)
128*9558e6acSTreehugger Robot {
129*9558e6acSTreehugger Robot va_list ap;
130*9558e6acSTreehugger Robot
131*9558e6acSTreehugger Robot va_start(ap, fmt);
132*9558e6acSTreehugger Robot vmsg(1, fmt, ap);
133*9558e6acSTreehugger Robot va_end(ap);
134*9558e6acSTreehugger Robot exit(8);
135*9558e6acSTreehugger Robot }
136*9558e6acSTreehugger Robot
137*9558e6acSTreehugger Robot const char *
devcheck(const char * origname)138*9558e6acSTreehugger Robot devcheck(const char *origname)
139*9558e6acSTreehugger Robot {
140*9558e6acSTreehugger Robot struct stat stslash, stchar;
141*9558e6acSTreehugger Robot
142*9558e6acSTreehugger Robot if (stat("/", &stslash) < 0) {
143*9558e6acSTreehugger Robot perr("Can't stat `/'");
144*9558e6acSTreehugger Robot return (origname);
145*9558e6acSTreehugger Robot }
146*9558e6acSTreehugger Robot if (stat(origname, &stchar) < 0) {
147*9558e6acSTreehugger Robot perr("Can't stat %s\n", origname);
148*9558e6acSTreehugger Robot return (origname);
149*9558e6acSTreehugger Robot }
150*9558e6acSTreehugger Robot if (!S_ISCHR(stchar.st_mode)) {
151*9558e6acSTreehugger Robot perr("%s is not a char device\n", origname);
152*9558e6acSTreehugger Robot }
153*9558e6acSTreehugger Robot return (origname);
154*9558e6acSTreehugger Robot }
155*9558e6acSTreehugger Robot
156*9558e6acSTreehugger Robot #ifndef __ANDROID__
157*9558e6acSTreehugger Robot /*
158*9558e6acSTreehugger Robot * Get the mount point information for name.
159*9558e6acSTreehugger Robot */
160*9558e6acSTreehugger Robot struct statfs *
getmntpt(const char * name)161*9558e6acSTreehugger Robot getmntpt(const char *name)
162*9558e6acSTreehugger Robot {
163*9558e6acSTreehugger Robot struct stat devstat, mntdevstat;
164*9558e6acSTreehugger Robot char device[sizeof(_PATH_DEV) - 1 + MNAMELEN];
165*9558e6acSTreehugger Robot char *dev_name;
166*9558e6acSTreehugger Robot struct statfs *mntbuf, *statfsp;
167*9558e6acSTreehugger Robot int i, mntsize, isdev;
168*9558e6acSTreehugger Robot
169*9558e6acSTreehugger Robot if (stat(name, &devstat) != 0)
170*9558e6acSTreehugger Robot return (NULL);
171*9558e6acSTreehugger Robot if (S_ISCHR(devstat.st_mode) || S_ISBLK(devstat.st_mode))
172*9558e6acSTreehugger Robot isdev = 1;
173*9558e6acSTreehugger Robot else
174*9558e6acSTreehugger Robot isdev = 0;
175*9558e6acSTreehugger Robot mntsize = getmntinfo(&mntbuf, MNT_NOWAIT);
176*9558e6acSTreehugger Robot for (i = 0; i < mntsize; i++) {
177*9558e6acSTreehugger Robot statfsp = &mntbuf[i];
178*9558e6acSTreehugger Robot dev_name = statfsp->f_mntfromname;
179*9558e6acSTreehugger Robot if (*dev_name != '/') {
180*9558e6acSTreehugger Robot if (strlen(_PATH_DEV) + strlen(dev_name) + 1 >
181*9558e6acSTreehugger Robot sizeof(statfsp->f_mntfromname))
182*9558e6acSTreehugger Robot continue;
183*9558e6acSTreehugger Robot strcpy(device, _PATH_DEV);
184*9558e6acSTreehugger Robot strcat(device, dev_name);
185*9558e6acSTreehugger Robot strcpy(statfsp->f_mntfromname, device);
186*9558e6acSTreehugger Robot }
187*9558e6acSTreehugger Robot if (isdev == 0) {
188*9558e6acSTreehugger Robot if (strcmp(name, statfsp->f_mntonname))
189*9558e6acSTreehugger Robot continue;
190*9558e6acSTreehugger Robot return (statfsp);
191*9558e6acSTreehugger Robot }
192*9558e6acSTreehugger Robot if (stat(dev_name, &mntdevstat) == 0 &&
193*9558e6acSTreehugger Robot mntdevstat.st_rdev == devstat.st_rdev)
194*9558e6acSTreehugger Robot return (statfsp);
195*9558e6acSTreehugger Robot }
196*9558e6acSTreehugger Robot statfsp = NULL;
197*9558e6acSTreehugger Robot return (statfsp);
198*9558e6acSTreehugger Robot }
199*9558e6acSTreehugger Robot #endif
200*9558e6acSTreehugger Robot
201*9558e6acSTreehugger Robot void *
emalloc(size_t s)202*9558e6acSTreehugger Robot emalloc(size_t s)
203*9558e6acSTreehugger Robot {
204*9558e6acSTreehugger Robot void *p;
205*9558e6acSTreehugger Robot
206*9558e6acSTreehugger Robot p = malloc(s);
207*9558e6acSTreehugger Robot if (p == NULL)
208*9558e6acSTreehugger Robot err(1, "malloc failed");
209*9558e6acSTreehugger Robot return (p);
210*9558e6acSTreehugger Robot }
211*9558e6acSTreehugger Robot
212*9558e6acSTreehugger Robot
213*9558e6acSTreehugger Robot void *
erealloc(void * p,size_t s)214*9558e6acSTreehugger Robot erealloc(void *p, size_t s)
215*9558e6acSTreehugger Robot {
216*9558e6acSTreehugger Robot void *q;
217*9558e6acSTreehugger Robot
218*9558e6acSTreehugger Robot q = realloc(p, s);
219*9558e6acSTreehugger Robot if (q == NULL)
220*9558e6acSTreehugger Robot err(1, "realloc failed");
221*9558e6acSTreehugger Robot return (q);
222*9558e6acSTreehugger Robot }
223*9558e6acSTreehugger Robot
224*9558e6acSTreehugger Robot
225*9558e6acSTreehugger Robot char *
estrdup(const char * s)226*9558e6acSTreehugger Robot estrdup(const char *s)
227*9558e6acSTreehugger Robot {
228*9558e6acSTreehugger Robot char *p;
229*9558e6acSTreehugger Robot
230*9558e6acSTreehugger Robot p = strdup(s);
231*9558e6acSTreehugger Robot if (p == NULL)
232*9558e6acSTreehugger Robot err(1, "strdup failed");
233*9558e6acSTreehugger Robot return (p);
234*9558e6acSTreehugger Robot }
235