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