197403Sobrien/* $NetBSD$ */ 297403Sobrien 3169691Skan/* 4132720Skan * Copyright (c) 1997-2014 Erez Zadok 597403Sobrien * Copyright (c) 1989 Jan-Simon Pendry 697403Sobrien * Copyright (c) 1989 Imperial College of Science, Technology & Medicine 797403Sobrien * Copyright (c) 1989 The Regents of the University of California. 897403Sobrien * All rights reserved. 997403Sobrien * 1097403Sobrien * This code is derived from software contributed to Berkeley by 1197403Sobrien * Jan-Simon Pendry at Imperial College, London. 1297403Sobrien * 1397403Sobrien * Redistribution and use in source and binary forms, with or without 1497403Sobrien * modification, are permitted provided that the following conditions 1597403Sobrien * are met: 1697403Sobrien * 1. Redistributions of source code must retain the above copyright 1797403Sobrien * notice, this list of conditions and the following disclaimer. 1897403Sobrien * 2. Redistributions in binary form must reproduce the above copyright 19169691Skan * notice, this list of conditions and the following disclaimer in the 2097403Sobrien * documentation and/or other materials provided with the distribution. 2197403Sobrien * 3. Neither the name of the University nor the names of its contributors 2297403Sobrien * may be used to endorse or promote products derived from this software 2397403Sobrien * without specific prior written permission. 2497403Sobrien * 2597403Sobrien * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 2697403Sobrien * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2797403Sobrien * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2897403Sobrien * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 2997403Sobrien * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 3097403Sobrien * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 3197403Sobrien * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 3297403Sobrien * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 3397403Sobrien * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3497403Sobrien * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3597403Sobrien * SUCH DAMAGE. 36169691Skan * 3797403Sobrien * 3897403Sobrien * File: am-utils/libamu/mtab.c 39132720Skan * 40132720Skan */ 4197403Sobrien 4297403Sobrien#ifdef HAVE_CONFIG_H 4397403Sobrien# include <config.h> 4497403Sobrien#endif /* HAVE_CONFIG_H */ 4597403Sobrien#include <am_defs.h> 4697403Sobrien#include <amu.h> 47169691Skan 48169691Skan 49117397Skan/* 50117397Skan * Firewall /etc/mtab entries 51117397Skan */ 52117397Skanvoid 53117397Skanmnt_free(mntent_t *mp) 54117397Skan{ 55117397Skan XFREE(mp->mnt_fsname); 56117397Skan XFREE(mp->mnt_dir); 5797403Sobrien XFREE(mp->mnt_type); 5897403Sobrien XFREE(mp->mnt_opts); 5997403Sobrien 6097403Sobrien#ifdef HAVE_MNTENT_T_MNT_TIME 6197403Sobrien# ifdef HAVE_MNTENT_T_MNT_TIME_STRING 6297403Sobrien XFREE(mp->mnt_time); 6397403Sobrien# endif /* HAVE_MNTENT_T_MNT_TIME_STRING */ 6497403Sobrien#endif /* HAVE_MNTENT_T_MNT_TIME */ 6597403Sobrien 6697403Sobrien XFREE(mp); 6797403Sobrien} 6897403Sobrien 6997403Sobrien 7097403Sobrien/* 7197403Sobrien * Discard memory allocated for mount list 72132720Skan */ 73132720Skanvoid 7497403Sobriendiscard_mntlist(mntlist *mp) 7597403Sobrien{ 76117397Skan mntlist *mp2; 77117397Skan 78117397Skan while ((mp2 = mp)) { 79117397Skan mp = mp->mnext; 80117397Skan if (mp2->mnt) 81117397Skan mnt_free(mp2->mnt); 82117397Skan XFREE(mp2); 83117397Skan } 8497403Sobrien} 8597403Sobrien 86117397Skan 87117397Skan/* 88117397Skan * Throw away a mount list 89117397Skan */ 90117397Skanvoid 91117397Skanfree_mntlist(mntlist *mp) 9297403Sobrien{ 9397403Sobrien discard_mntlist(mp); 9497403Sobrien#ifdef MOUNT_TABLE_ON_FILE 95117397Skan unlock_mntlist(); 96117397Skan#endif /* MOUNT_TABLE_ON_FILE */ 97117397Skan} 98117397Skan 99117397Skan 100117397Skan/* 101117397Skan * Utility routine which returns a pointer to whatever follows an = in a 102117397Skan * string. Returns null if = is not found in the string. 10397403Sobrien */ 104132720Skanchar * 105132720Skanhaseq(char *instr) 10697403Sobrien{ 107117397Skan if (instr) { 108117397Skan char *eq = strchr(instr, '='); 109117397Skan if (eq) return ++eq; 110117397Skan } 111117397Skan return NULL; 11297403Sobrien} 11397403Sobrien 11497403Sobrien 11597403Sobrien/* 116117397Skan * Utility routine which returns a pointer to whatever 11797403Sobrien * follows an = in a mount option. Returns null if option 11897403Sobrien * doesn't exist or doesn't have an '='. Won't fail for opt,foo=. 11997403Sobrien */ 120117397Skanchar * 121117397Skanhasmnteq(mntent_t *mnt, char *opt) 122117397Skan{ 123117397Skan if (mnt && opt) { /* disallow null input pointers */ 124117397Skan if ( *opt ) { /* disallow the null string as an opt */ 125117397Skan char *str = amu_hasmntopt(mnt, opt); 126117397Skan if ( str ) { /* option was there */ 127117397Skan char *eq = str + strlen(opt); /* Look at char just after option */ 128117397Skan if (*eq == '=') /* Is it '=' ? */ 129117397Skan return ++eq; /* If so, return pointer to remaining str */ 130169691Skan } 131169691Skan } 132169691Skan } 13397403Sobrien return NULL; 134169691Skan} 135169691Skan 136169691Skan 137169691Skan/* 138169691Skan * Wrapper around hasmntvalerr(), which retains backwards compatibiliy with 139169691Skan * older use of hasmntval(). 14097403Sobrien * 141169691Skan * XXX: eventually, all use of hasmntval() should be replaced with 142169691Skan * hasmntvalerr(). 143169691Skan */ 144169691Skanint 145169691Skanhasmntval(mntent_t *mnt, char *opt) 146169691Skan{ 147117397Skan int err, val = 0; 14897403Sobrien 149117397Skan err = hasmntvalerr(mnt, opt, &val); 150117397Skan if (err) /* if there was an error (hasmntvalerr returned 1) */ 151117397Skan return 0; /* redundant: val==0 above, but leave here for clarity */ 152117397Skan /* otherwise there was no error */ 153117397Skan return val; 154117397Skan} 155117397Skan 156117397Skan 157117397Skan/* 158117397Skan * Utility routine which determines the value of a numeric option in the 159117397Skan * mount options (such as port=%d), and fills in the value in the argument 160117397Skan * valp (argument won't be touched if no value is set, for example due to an 161117397Skan * error). 162117397Skan * 163117397Skan * Returns non-zero (1) on error; returns 0 on success. 164117397Skan * 165117397Skan * XXX: eventually, all use of hasmntval() should be replaced with 166117397Skan * hasmntvalerr(). 167117397Skan */ 168117397Skanunsigned int 169117397Skanhasmntvalerr(mntent_t *mnt, char *opt, int *valp) 170117397Skan{ 171117397Skan char *str = amu_hasmntopt(mnt, opt); 172117397Skan int err = 1; /* 1 means no good value was set (an error) */ 173117397Skan char *eq, *endptr; 174117397Skan long int i; 175117397Skan 176117397Skan /* exit if no option specificed */ 17797403Sobrien if (!str) { 178169691Skan goto out; 179169691Skan } 18097403Sobrien 18197403Sobrien eq = hasmnteq(mnt, opt); 18297403Sobrien 18397403Sobrien if (!eq) { /* no argument to option ('=' sign was missing) */ 18497403Sobrien plog(XLOG_MAP, "numeric option to \"%s\" missing", opt); 185169691Skan goto out; 186169691Skan } 18797403Sobrien 18897403Sobrien /* if got here, then we had an '=' after option name */ 18997403Sobrien endptr = NULL; 190169691Skan i = strtol(eq, &endptr, 0); /* hex and octal allowed ;-) */ 19197403Sobrien if (!endptr || 192169691Skan (endptr != eq && (*endptr == ',' || *endptr == '\0'))) { 193169691Skan /* 19497403Sobrien * endptr set means strtol saw a non-digit. If the non-digit is a 19597403Sobrien * comma, it's probably the start of the next option. If the comma is 196169691Skan * the first char though, complain about it (foo=,bar is made 197169691Skan * noticeable by this). 19897403Sobrien * 19997403Sobrien * Similar reasoning for '\0' instead of comma, it's the end of the 200169691Skan * string. 201169691Skan */ 20297403Sobrien *valp = (int) i; /* set good value */ 203132720Skan err = 0; /* no error */ 20497403Sobrien } else { 205169691Skan /* whatever was after the '=' sign wasn't a number */ 206169691Skan plog(XLOG_MAP, "invalid numeric option in \"%s\": \"%s\"", opt, str); 20797403Sobrien /* fall through to error/exit processing */ 20897403Sobrien } 209169691Skan 210169691Skan out: 21197403Sobrien return err; 21297403Sobrien} 21397403Sobrien 214169691Skan 215169691Skan/* 21697403Sobrien * Utility routine which returns the string value of 21797403Sobrien * an option in the mount options (such as proto=udp). 218169691Skan * Returns NULL if the option is not specified. 219169691Skan * Returns malloc'ed string (caller must free!) 22097403Sobrien */ 22197403Sobrienchar * 222169691Skanhasmntstr(mntent_t *mnt, char *opt) 223169691Skan{ 22497403Sobrien char *str = amu_hasmntopt(mnt, opt); 22597403Sobrien 226169691Skan if (str) { /* The option was there */ 227169691Skan 22897403Sobrien char *eq = hasmnteq(mnt, opt); 229117397Skan 230117397Skan if (eq) { /* and had an = after it */ 231117397Skan 232117397Skan char *endptr = strchr(eq, ','); 233117397Skan 234132720Skan /* if saw no comma, return xstrdup'd string */ 235117397Skan if (!endptr) 236117397Skan return xstrdup(eq); 237117397Skan else { 238117397Skan /* else we need to copy only the chars needed */ 239117397Skan int len = endptr - eq; 240117397Skan char *buf = xmalloc(len + 1); 241117397Skan strncpy(buf, eq, len); 242117397Skan buf[len] = '\0'; 243117397Skan return buf; 244117397Skan } 245117397Skan } 246117397Skan } 247117397Skan return NULL; 248117397Skan} 24997403Sobrien