getmntopts.c revision 123268
176633Stshiozak/*-
276633Stshiozak * Copyright (c) 1994
376633Stshiozak *	The Regents of the University of California.  All rights reserved.
476633Stshiozak *
576633Stshiozak * Redistribution and use in source and binary forms, with or without
676633Stshiozak * modification, are permitted provided that the following conditions
776633Stshiozak * are met:
876633Stshiozak * 1. Redistributions of source code must retain the above copyright
976633Stshiozak *    notice, this list of conditions and the following disclaimer.
1076633Stshiozak * 2. Redistributions in binary form must reproduce the above copyright
1176633Stshiozak *    notice, this list of conditions and the following disclaimer in the
1276633Stshiozak *    documentation and/or other materials provided with the distribution.
1376633Stshiozak * 3. All advertising materials mentioning features or use of this software
1476633Stshiozak *    must display the following acknowledgement:
1576633Stshiozak *	This product includes software developed by the University of
1676633Stshiozak *	California, Berkeley and its contributors.
1776633Stshiozak * 4. Neither the name of the University nor the names of its contributors
1876633Stshiozak *    may be used to endorse or promote products derived from this software
1976633Stshiozak *    without specific prior written permission.
2076633Stshiozak *
2176633Stshiozak * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
2276633Stshiozak * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2376633Stshiozak * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2476633Stshiozak * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2576633Stshiozak * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2676633Stshiozak * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2776633Stshiozak * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2876633Stshiozak * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2976633Stshiozak * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3076633Stshiozak * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3176633Stshiozak * SUCH DAMAGE.
3276633Stshiozak */
3376633Stshiozak
3476633Stshiozak#if 0
3576633Stshiozak#ifndef lint
3676633Stshiozakstatic char sccsid[] = "@(#)getmntopts.c	8.3 (Berkeley) 3/29/95";
3776633Stshiozak#endif /* not lint */
3876633Stshiozak#endif
3976633Stshiozak#include <sys/cdefs.h>
4076633Stshiozak__FBSDID("$FreeBSD: head/sbin/mount/getmntopts.c 123268 2003-12-07 23:02:16Z trhodes $");
4176633Stshiozak
4276633Stshiozak#include <sys/param.h>
4376633Stshiozak#include <sys/stat.h>
4476633Stshiozak
4576633Stshiozak#include <err.h>
4676633Stshiozak#include <errno.h>
4776633Stshiozak#include <stdlib.h>
4876633Stshiozak#include <string.h>
4976633Stshiozak#include <sysexits.h>
5076633Stshiozak
5176633Stshiozak#include "mntopts.h"
5276633Stshiozak
5376633Stshiozakint getmnt_silent = 0;
5476633Stshiozak
5576633Stshiozakvoid
5676633Stshiozakgetmntopts(options, m0, flagp, altflagp)
5776633Stshiozak	const char *options;
5876633Stshiozak	const struct mntopt *m0;
5976633Stshiozak	int *flagp;
6076633Stshiozak	int *altflagp;
6176633Stshiozak{
6276633Stshiozak	const struct mntopt *m;
6379555Sobrien	int negative, len;
6479555Sobrien	char *opt, *optbuf, *p;
6576633Stshiozak	int *thisflagp;
6676633Stshiozak
6776633Stshiozak	/* Copy option string, since it is about to be torn asunder... */
6876633Stshiozak	if ((optbuf = strdup(options)) == NULL)
6976633Stshiozak		err(1, NULL);
7076633Stshiozak
71102227Smike	for (opt = optbuf; (opt = strtok(opt, ",")) != NULL; opt = NULL) {
72101776Stjr		/* Check for "no" prefix. */
7376636Stshiozak		if (opt[0] == 'n' && opt[1] == 'o') {
74103269Stjr			negative = 1;
7576636Stshiozak			opt += 2;
7676633Stshiozak		} else
77102227Smike			negative = 0;
78102227Smike
79102227Smike		/*
80101409Stjr		 * for options with assignments in them (ie. quotas)
81101409Stjr		 * ignore the assignment as it's handled elsewhere
82102227Smike		 */
83102227Smike		p = strchr(opt, '=');
84102227Smike		if (p != NULL)
85101409Stjr			 *++p = '\0';
86101409Stjr
8799640Sobrien		/* Scan option table. */
88102227Smike		for (m = m0; m->m_option != NULL; ++m) {
89102227Smike			len = strlen(m->m_option);
90102227Smike			if (strncasecmp(opt, m->m_option, len) == 0)
9176633Stshiozak				if (   m->m_option[len]	== '\0'
9299640Sobrien				    || m->m_option[len]	== '='
9376633Stshiozak				   )
94102227Smike				break;
95102227Smike		}
96102227Smike
9776633Stshiozak		/* Save flag, or fail if option is not recognized. */
9876633Stshiozak		if (m->m_option) {
9976633Stshiozak			thisflagp = m->m_altloc ? altflagp : flagp;
10076633Stshiozak			if (negative == m->m_inverse)
10176633Stshiozak				*thisflagp |= m->m_flag;
10276633Stshiozak			else
103103177Stjr				*thisflagp &= ~m->m_flag;
104103218Stjr		} else if (!getmnt_silent) {
105103177Stjr			errx(1, "-o %s: option not supported", opt);
10676633Stshiozak		}
107101411Stjr	}
108103177Stjr
109101776Stjr	free(optbuf);
110103177Stjr}
111103177Stjr
112103177Stjrvoid
113103177Stjrrmslashes(rrpin, rrpout)
114103177Stjr	char *rrpin;
115101776Stjr	char *rrpout;
11693032Simp{
11793032Simp	char *rrpoutstart;
11893032Simp
11993032Simp	*rrpout = *rrpin;
12093032Simp	for (rrpoutstart = rrpout; *rrpin != '\0'; *rrpout++ = *rrpin++) {
12193032Simp
122103177Stjr		/* skip all double slashes */
123101776Stjr		while (*rrpin == '/' && *(rrpin + 1) == '/')
124103177Stjr			 rrpin++;
12593032Simp	}
12693032Simp
12793032Simp	/* remove trailing slash if necessary */
12893032Simp	if (rrpout - rrpoutstart > 1 && *(rrpout - 1) == '/')
12993032Simp		*(rrpout - 1) = '\0';
13093032Simp	else
131103218Stjr		*rrpout = '\0';
132103218Stjr}
13393032Simp
13493032Simpvoid
13593032Simpcheckpath(path, resolved)
13693032Simp	const char *path;
13793032Simp	char *resolved;
13893032Simp{
13993032Simp	struct stat sb;
14093032Simp
14193032Simp	if (realpath(path, resolved) != NULL && stat(resolved, &sb) == 0) {
14293032Simp		if (!S_ISDIR(sb.st_mode))
143103058Stjr			errx(EX_USAGE, "%s: not a directory", resolved);
144102142Sache	} else
145103339Stjr		errx(EX_USAGE, "%s: %s", resolved, strerror(errno));
146103067Stjr}
147103067Stjr