GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: sbin/fsck/fsutil.c Lines: 0 99 0.0 %
Date: 2016-12-06 Branches: 0 50 0.0 %

Line Branch Exec Source
1
/*	$OpenBSD: fsutil.c,v 1.22 2015/09/27 05:25:00 guenther Exp $	*/
2
/*	$NetBSD: fsutil.c,v 1.2 1996/10/03 20:06:31 christos Exp $	*/
3
4
/*
5
 * Copyright (c) 1990, 1993
6
 *	The Regents of the University of California.  All rights reserved.
7
 *
8
 * Redistribution and use in source and binary forms, with or without
9
 * modification, are permitted provided that the following conditions
10
 * are met:
11
 * 1. Redistributions of source code must retain the above copyright
12
 *    notice, this list of conditions and the following disclaimer.
13
 * 2. Redistributions in binary form must reproduce the above copyright
14
 *    notice, this list of conditions and the following disclaimer in the
15
 *    documentation and/or other materials provided with the distribution.
16
 * 3. Neither the name of the University nor the names of its contributors
17
 *    may be used to endorse or promote products derived from this software
18
 *    without specific prior written permission.
19
 *
20
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30
 * SUCH DAMAGE.
31
 */
32
33
#include <stdio.h>
34
#include <string.h>
35
#include <stdlib.h>
36
#include <stdarg.h>
37
#include <errno.h>
38
#include <fstab.h>
39
#include <limits.h>
40
#include <err.h>
41
42
#include <sys/types.h>
43
#include <sys/stat.h>
44
45
#include "fsutil.h"
46
47
static const char *dev = NULL;
48
static const char *origdev = NULL;
49
static int hot = 0;
50
static int preen = 0;
51
52
extern char *__progname;
53
54
static void vmsg(int, const char *, va_list);
55
56
void
57
setcdevname(const char *cd, const char *ocd, int pr)
58
{
59
	dev = cd;
60
	origdev = ocd;
61
	preen = pr;
62
}
63
64
const char *
65
cdevname(void)
66
{
67
	return dev;
68
}
69
70
int
71
hotroot(void)
72
{
73
	return hot;
74
}
75
76
void
77
errexit(const char *fmt, ...)
78
{
79
	va_list ap;
80
81
	va_start(ap, fmt);
82
	(void) vfprintf(stderr, fmt, ap);
83
	va_end(ap);
84
	exit(8);
85
}
86
87
static void
88
vmsg(int fatal, const char *fmt, va_list ap)
89
{
90
	if (!fatal && preen) {
91
		if (origdev)
92
			printf("%s (%s): ", dev, origdev);
93
		else
94
			printf("%s: ", dev);
95
	}
96
97
	(void) vprintf(fmt, ap);
98
99
	if (fatal && preen) {
100
		printf("\n");
101
		if (origdev)
102
			printf("%s (%s): ", dev, origdev);
103
		else
104
			printf("%s: ", dev);
105
		printf("UNEXPECTED INCONSISTENCY; RUN %s MANUALLY.\n",
106
		    __progname);
107
		exit(8);
108
	}
109
}
110
111
void
112
pfatal(const char *fmt, ...)
113
{
114
	va_list ap;
115
116
	va_start(ap, fmt);
117
	vmsg(1, fmt, ap);
118
	va_end(ap);
119
}
120
121
void
122
pwarn(const char *fmt, ...)
123
{
124
	va_list ap;
125
126
	va_start(ap, fmt);
127
	vmsg(0, fmt, ap);
128
	va_end(ap);
129
}
130
131
void
132
xperror(const char *s)
133
{
134
	pfatal("%s (%s)", s, strerror(errno));
135
}
136
137
void
138
panic(const char *fmt, ...)
139
{
140
	va_list ap;
141
142
	va_start(ap, fmt);
143
	vmsg(1, fmt, ap);
144
	va_end(ap);
145
	exit(8);
146
}
147
148
char *
149
unrawname(char *name)
150
{
151
	char *dp;
152
	struct stat stb;
153
154
	if ((dp = strrchr(name, '/')) == NULL)
155
		return (name);
156
	if (stat(name, &stb) < 0)
157
		return (name);
158
	if (!S_ISCHR(stb.st_mode))
159
		return (name);
160
	if (dp[1] != 'r')
161
		return (name);
162
	(void)memmove(&dp[1], &dp[2], strlen(&dp[2]) + 1);
163
	return (name);
164
}
165
166
char *
167
rawname(char *name)
168
{
169
	static char rawbuf[PATH_MAX];
170
	char *dp;
171
172
	if ((dp = strrchr(name, '/')) == NULL)
173
		return (0);
174
	*dp = 0;
175
	(void)strlcpy(rawbuf, name, sizeof rawbuf);
176
	*dp = '/';
177
	(void)strlcat(rawbuf, "/r", sizeof rawbuf);
178
	(void)strlcat(rawbuf, &dp[1], sizeof rawbuf);
179
	return (rawbuf);
180
}
181
182
char *
183
blockcheck(char *origname)
184
{
185
	struct stat stslash, stblock, stchar;
186
	char *newname, *raw;
187
	struct fstab *fsp;
188
	int retried = 0;
189
190
	hot = 0;
191
	if (stat("/", &stslash) < 0) {
192
		xperror("/");
193
		printf("Can't stat root\n");
194
		return (origname);
195
	}
196
	newname = origname;
197
retry:
198
	if (stat(newname, &stblock) < 0)
199
		return (origname);
200
201
	if (S_ISBLK(stblock.st_mode)) {
202
		if (stslash.st_dev == stblock.st_rdev)
203
			hot++;
204
		raw = rawname(newname);
205
		if (stat(raw, &stchar) < 0) {
206
			xperror(raw);
207
			printf("Can't stat %s\n", raw);
208
			return (origname);
209
		}
210
		if (S_ISCHR(stchar.st_mode)) {
211
			return (raw);
212
		} else {
213
			printf("%s is not a character device\n", raw);
214
			return (origname);
215
		}
216
	} else if (S_ISCHR(stblock.st_mode) && !retried) {
217
		newname = unrawname(newname);
218
		retried++;
219
		goto retry;
220
	} else if ((fsp = getfsfile(newname)) != 0 && !retried) {
221
		newname = fsp->fs_spec;
222
		retried++;
223
		goto retry;
224
	}
225
	/*
226
	 * Not a block or character device, just return name and
227
	 * let the user decide whether to use it.
228
	 */
229
	return (origname);
230
}
231
232
233
void *
234
emalloc(size_t s)
235
{
236
	void *p;
237
238
	if (s == 0)
239
		err(1, "malloc failed");
240
	p = malloc(s);
241
	if (p == NULL)
242
		err(1, "malloc failed");
243
	return p;
244
}
245
246
247
void *
248
ereallocarray(void *p, size_t n, size_t s)
249
{
250
	void *newp;
251
252
	if (n == 0 || s == 0) {
253
		free(p);
254
		err(1, "realloc failed");
255
	}
256
	newp = reallocarray(p, n, s);
257
	if (newp == NULL) {
258
		free(p);
259
		err(1, "realloc failed");
260
	}
261
	return newp;
262
}
263
264
265
char *
266
estrdup(const char *s)
267
{
268
	char *p = strdup(s);
269
	if (p == NULL)
270
		err(1, "strdup failed");
271
	return p;
272
}