getmntopts.c revision 138095
1139743Simp/*- 2123474Swpaul * Copyright (c) 1994 3123474Swpaul * The Regents of the University of California. All rights reserved. 4123474Swpaul * 5123474Swpaul * Redistribution and use in source and binary forms, with or without 6123474Swpaul * modification, are permitted provided that the following conditions 7123474Swpaul * are met: 8123474Swpaul * 1. Redistributions of source code must retain the above copyright 9123474Swpaul * notice, this list of conditions and the following disclaimer. 10123474Swpaul * 2. Redistributions in binary form must reproduce the above copyright 11123474Swpaul * notice, this list of conditions and the following disclaimer in the 12123474Swpaul * documentation and/or other materials provided with the distribution. 13123474Swpaul * 4. Neither the name of the University nor the names of its contributors 14123474Swpaul * may be used to endorse or promote products derived from this software 15123474Swpaul * without specific prior written permission. 16123474Swpaul * 17123474Swpaul * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 18123474Swpaul * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19123474Swpaul * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20123474Swpaul * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 21123474Swpaul * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22123474Swpaul * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23123474Swpaul * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24123474Swpaul * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25123474Swpaul * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26123474Swpaul * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27123474Swpaul * SUCH DAMAGE. 28123474Swpaul */ 29123474Swpaul 30123474Swpaul#if 0 31123474Swpaul#ifndef lint 32123474Swpaulstatic char sccsid[] = "@(#)getmntopts.c 8.3 (Berkeley) 3/29/95"; 33123474Swpaul#endif /* not lint */ 34123474Swpaul#endif 35123474Swpaul#include <sys/cdefs.h> 36124231Swpaul__FBSDID("$FreeBSD: head/sbin/mount/getmntopts.c 138095 2004-11-25 13:31:46Z phk $"); 37125551Swpaul 38123474Swpaul#include <sys/param.h> 39123474Swpaul#include <sys/stat.h> 40123474Swpaul#include <sys/uio.h> 41123474Swpaul 42123474Swpaul#include <err.h> 43123474Swpaul#include <errno.h> 44123474Swpaul#include <stdlib.h> 45123474Swpaul#include <string.h> 46123474Swpaul#include <sysexits.h> 47131909Smarcel 48123474Swpaul#include "mntopts.h" 49125551Swpaul 50151207Swpaulint getmnt_silent = 0; 51125551Swpaul 52141524Swpaulvoid 53145895Swpaulgetmntopts(options, m0, flagp, altflagp) 54145895Swpaul const char *options; 55151451Swpaul const struct mntopt *m0; 56123474Swpaul int *flagp; 57124203Swpaul int *altflagp; 58123474Swpaul{ 59123474Swpaul const struct mntopt *m; 60151207Swpaul int negative, len; 61123474Swpaul char *opt, *optbuf, *p; 62123474Swpaul int *thisflagp; 63123474Swpaul 64123474Swpaul /* Copy option string, since it is about to be torn asunder... */ 65140751Swpaul if ((optbuf = strdup(options)) == NULL) 66140751Swpaul err(1, NULL); 67140751Swpaul 68142530Swpaul for (opt = optbuf; (opt = strtok(opt, ",")) != NULL; opt = NULL) { 69145895Swpaul /* Check for "no" prefix. */ 70145895Swpaul if (opt[0] == 'n' && opt[1] == 'o') { 71215419Sbschmidt negative = 1; 72140751Swpaul opt += 2; 73123474Swpaul } else 74145485Swpaul negative = 0; 75145485Swpaul 76132973Swpaul /* 77124576Swpaul * for options with assignments in them (ie. quotas) 78123474Swpaul * ignore the assignment as it's handled elsewhere 79123474Swpaul */ 80151451Swpaul p = strchr(opt, '='); 81151451Swpaul if (p != NULL) 82151451Swpaul *++p = '\0'; 83217566Smdf 84217566Smdf /* Scan option table. */ 85217566Smdf for (m = m0; m->m_option != NULL; ++m) { 86151451Swpaul len = strlen(m->m_option); 87151451Swpaul if (strncasecmp(opt, m->m_option, len) == 0) 88145895Swpaul if (opt[len] == '\0' || opt[len] == '=') 89151207Swpaul break; 90145895Swpaul } 91145895Swpaul 92145895Swpaul /* Save flag, or fail if option is not recognized. */ 93151451Swpaul if (m->m_option) { 94151451Swpaul thisflagp = m->m_altloc ? altflagp : flagp; 95145895Swpaul if (negative == m->m_inverse) 96145895Swpaul *thisflagp |= m->m_flag; 97145895Swpaul else 98145895Swpaul *thisflagp &= ~m->m_flag; 99145895Swpaul } else if (!getmnt_silent) { 100145895Swpaul errx(1, "-o %s: option not supported", opt); 101151207Swpaul } 102151207Swpaul } 103151207Swpaul 104151207Swpaul free(optbuf); 105151207Swpaul} 106151207Swpaul 107151207Swpaulvoid 108151207Swpaulrmslashes(rrpin, rrpout) 109151451Swpaul char *rrpin; 110151451Swpaul char *rrpout; 111151451Swpaul{ 112151451Swpaul char *rrpoutstart; 113151451Swpaul 114151451Swpaul *rrpout = *rrpin; 115151207Swpaul for (rrpoutstart = rrpout; *rrpin != '\0'; *rrpout++ = *rrpin++) { 116151451Swpaul 117151451Swpaul /* skip all double slashes */ 118151451Swpaul while (*rrpin == '/' && *(rrpin + 1) == '/') 119151451Swpaul rrpin++; 120151451Swpaul } 121151451Swpaul 122151451Swpaul /* remove trailing slash if necessary */ 123151451Swpaul if (rrpout - rrpoutstart > 1 && *(rrpout - 1) == '/') 124151451Swpaul *(rrpout - 1) = '\0'; 125215708Sbschmidt else 126151451Swpaul *rrpout = '\0'; 127151451Swpaul} 128151451Swpaul 129151451Swpaulvoid 130151207Swpaulcheckpath(path, resolved) 131151207Swpaul const char *path; 132215779Sbschmidt char *resolved; 133151207Swpaul{ 134151207Swpaul struct stat sb; 135144888Swpaul 136141524Swpaul if (realpath(path, resolved) != NULL && stat(resolved, &sb) == 0) { 137144888Swpaul if (!S_ISDIR(sb.st_mode)) 138141524Swpaul errx(EX_USAGE, "%s: not a directory", resolved); 139144888Swpaul } else 140141524Swpaul errx(EX_USAGE, "%s: %s", resolved, strerror(errno)); 141141524Swpaul} 142144888Swpaul 143144888Swpaulvoid 144144888Swpaulbuild_iovec(struct iovec **iov, int *iovlen, const char *name, void *val, int len) 145144888Swpaul{ 146144888Swpaul int i; 147144888Swpaul 148125551Swpaul if (iovlen < 0) 149125551Swpaul return; 150151207Swpaul i = *iovlen; 151151207Swpaul *iov = realloc(*iov, sizeof **iov * (i + 2)); 152151207Swpaul if (*iov == NULL) { 153151207Swpaul *iovlen = -1; 154151451Swpaul return; 155151451Swpaul } 156151451Swpaul (*iov)[i].iov_base = strdup(name); 157151451Swpaul (*iov)[i].iov_len = strlen(name) + 1; 158151451Swpaul i++; 159126620Swpaul (*iov)[i].iov_base = val; 160145895Swpaul if (len < 0) 161145895Swpaul len = strlen(val) + 1; 162146364Swpaul (*iov)[i].iov_len = len; 163145895Swpaul *iovlen = ++i; 164145895Swpaul} 165151207Swpaul