xref: /aosp_15_r20/external/fsck_msdos/fsutil.c (revision 9558e6ac2e10ab0fef46fdd14187b840555f86f4)
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