getmntopts.c revision 152354
133965Sjdp/*- 233965Sjdp * Copyright (c) 1994 333965Sjdp * The Regents of the University of California. All rights reserved. 433965Sjdp * 533965Sjdp * Redistribution and use in source and binary forms, with or without 660517Sobrien * modification, are permitted provided that the following conditions 733965Sjdp * are met: 838891Sjdp * 1. Redistributions of source code must retain the above copyright 960517Sobrien * notice, this list of conditions and the following disclaimer. 1038891Sjdp * 2. Redistributions in binary form must reproduce the above copyright 1138891Sjdp * notice, this list of conditions and the following disclaimer in the 1238891Sjdp * documentation and/or other materials provided with the distribution. 1377310Sobrien * 4. Neither the name of the University nor the names of its contributors 1438891Sjdp * may be used to endorse or promote products derived from this software 1577310Sobrien * without specific prior written permission. 1638891Sjdp * 1738891Sjdp * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 1838891Sjdp * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1933965Sjdp * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2033965Sjdp * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 2133965Sjdp * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2233965Sjdp * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2333965Sjdp * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2433965Sjdp * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2533965Sjdp * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2633965Sjdp * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2733965Sjdp * SUCH DAMAGE. 2833965Sjdp */ 2933965Sjdp 3033965Sjdp#if 0 3133965Sjdp#ifndef lint 3233965Sjdpstatic char sccsid[] = "@(#)getmntopts.c 8.3 (Berkeley) 3/29/95"; 3333965Sjdp#endif /* not lint */ 3433965Sjdp#endif 3533965Sjdp#include <sys/cdefs.h> 3633965Sjdp__FBSDID("$FreeBSD: head/sbin/mount/getmntopts.c 152354 2005-11-13 01:27:57Z rodrigc $"); 3733965Sjdp 3833965Sjdp#include <sys/param.h> 3933965Sjdp#include <sys/mount.h> 4033965Sjdp#include <sys/stat.h> 4133965Sjdp#include <sys/uio.h> 4233965Sjdp 4360517Sobrien#include <assert.h> 4460517Sobrien#include <err.h> 4577310Sobrien#include <errno.h> 4677310Sobrien#include <stdarg.h> 4777310Sobrien#include <stdio.h> 4877310Sobrien#include <stdlib.h> 4977310Sobrien#include <string.h> 5077310Sobrien#include <sysexits.h> 5177310Sobrien 5277310Sobrien#include "mntopts.h" 5377310Sobrien 5477310Sobrienint getmnt_silent = 0; 5577310Sobrien 5677310Sobrienvoid 5777310Sobriengetmntopts(const char *options, const struct mntopt *m0, int *flagp, 5877310Sobrien int *altflagp) 5977310Sobrien{ 6077310Sobrien const struct mntopt *m; 6177310Sobrien int negative, len; 6277310Sobrien char *opt, *optbuf, *p; 6377310Sobrien int *thisflagp; 6477310Sobrien 6577310Sobrien /* Copy option string, since it is about to be torn asunder... */ 6638891Sjdp if ((optbuf = strdup(options)) == NULL) 6738891Sjdp err(1, NULL); 6833965Sjdp 6960517Sobrien for (opt = optbuf; (opt = strtok(opt, ",")) != NULL; opt = NULL) { 7060517Sobrien /* Check for "no" prefix. */ 7160517Sobrien if (opt[0] == 'n' && opt[1] == 'o') { 7260517Sobrien negative = 1; 7360517Sobrien opt += 2; 7460517Sobrien } else 7560517Sobrien negative = 0; 7660517Sobrien 7760517Sobrien /* 7860517Sobrien * for options with assignments in them (ie. quotas) 7933965Sjdp * ignore the assignment as it's handled elsewhere 8033965Sjdp */ 8160517Sobrien p = strchr(opt, '='); 8260517Sobrien if (p != NULL) 8360517Sobrien *++p = '\0'; 8433965Sjdp 8560517Sobrien /* Scan option table. */ 8633965Sjdp for (m = m0; m->m_option != NULL; ++m) { 8733965Sjdp len = strlen(m->m_option); 8860517Sobrien if (strncasecmp(opt, m->m_option, len) == 0) 8960517Sobrien if (opt[len] == '\0' || opt[len] == '=') 9060517Sobrien break; 9160517Sobrien } 9260517Sobrien 9333965Sjdp /* Save flag, or fail if option is not recognized. */ 9433965Sjdp if (m->m_option) { 9533965Sjdp thisflagp = m->m_altloc ? altflagp : flagp; 9633965Sjdp if (negative == m->m_inverse) 9733965Sjdp *thisflagp |= m->m_flag; 9833965Sjdp else 9933965Sjdp *thisflagp &= ~m->m_flag; 10033965Sjdp } else if (!getmnt_silent) { 10133965Sjdp errx(1, "-o %s: option not supported", opt); 10233965Sjdp } 10333965Sjdp } 10433965Sjdp 10533965Sjdp free(optbuf); 10633965Sjdp} 10733965Sjdp 10833965Sjdpvoid 10933965Sjdprmslashes(char *rrpin, char *rrpout) 11033965Sjdp{ 11133965Sjdp char *rrpoutstart; 11238891Sjdp 11338891Sjdp *rrpout = *rrpin; 11433965Sjdp for (rrpoutstart = rrpout; *rrpin != '\0'; *rrpout++ = *rrpin++) { 11538891Sjdp 11633965Sjdp /* skip all double slashes */ 11733965Sjdp while (*rrpin == '/' && *(rrpin + 1) == '/') 11860517Sobrien rrpin++; 11960517Sobrien } 12060517Sobrien 12177310Sobrien /* remove trailing slash if necessary */ 12260517Sobrien if (rrpout - rrpoutstart > 1 && *(rrpout - 1) == '/') 12338891Sjdp *(rrpout - 1) = '\0'; 12433965Sjdp else 12533965Sjdp *rrpout = '\0'; 12677310Sobrien} 12777310Sobrien 12877310Sobrienvoid 12977310Sobriencheckpath(const char *path, char *resolved) 13033965Sjdp{ 13160517Sobrien struct stat sb; 13233965Sjdp 13333965Sjdp if (realpath(path, resolved) != NULL && stat(resolved, &sb) == 0) { 13460517Sobrien if (!S_ISDIR(sb.st_mode)) 13533965Sjdp errx(EX_USAGE, "%s: not a directory", resolved); 13633965Sjdp } else 13733965Sjdp errx(EX_USAGE, "%s: %s", resolved, strerror(errno)); 13860517Sobrien} 13960517Sobrien 14033965Sjdpvoid 14133965Sjdpbuild_iovec(struct iovec **iov, int *iovlen, const char *name, void *val, 14233965Sjdp size_t len) 14338891Sjdp{ 14438891Sjdp int i; 14538891Sjdp 14660517Sobrien if (*iovlen < 0) 14738891Sjdp return; 14838891Sjdp i = *iovlen; 14933965Sjdp *iov = realloc(*iov, sizeof **iov * (i + 2)); 15033965Sjdp if (*iov == NULL) { 15133965Sjdp *iovlen = -1; 15233965Sjdp return; 15333965Sjdp } 15433965Sjdp (*iov)[i].iov_base = strdup(name); 15533965Sjdp (*iov)[i].iov_len = strlen(name) + 1; 15633965Sjdp i++; 15733965Sjdp (*iov)[i].iov_base = val; 15833965Sjdp if (len == (size_t)-1) 15933965Sjdp len = strlen(val) + 1; 16033965Sjdp (*iov)[i].iov_len = (int)len; 16133965Sjdp *iovlen = ++i; 16233965Sjdp} 16333965Sjdp 16433965Sjdp/* 16538891Sjdp * This function is needed for compatibility with parameters 16638891Sjdp * which used to use the mount_argf() command for the old mount() syscall. 16738891Sjdp */ 16838891Sjdpvoid 16977310Sobrienbuild_iovec_argf(struct iovec **iov, int *iovlen, const char *name, 17033965Sjdp const char *fmt, ...) 17133965Sjdp{ 17238891Sjdp va_list ap; 17338891Sjdp char val[255] = { 0 }; 17438891Sjdp 17538891Sjdp va_start(ap, fmt); 17638891Sjdp vsnprintf(val, sizeof(val), fmt, ap); 17738891Sjdp va_end(ap); 17838891Sjdp build_iovec(iov, iovlen, name, strdup(val), (size_t)-1); 17933965Sjdp} 18038891Sjdp