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