1/* $NetBSD$ */ 2 3/* 4 * Copyright (c) 1997-2014 Erez Zadok 5 * Copyright (c) 1989 Jan-Simon Pendry 6 * Copyright (c) 1989 Imperial College of Science, Technology & Medicine 7 * Copyright (c) 1989 The Regents of the University of California. 8 * All rights reserved. 9 * 10 * This code is derived from software contributed to Berkeley by 11 * Jan-Simon Pendry at Imperial College, London. 12 * 13 * Redistribution and use in source and binary forms, with or without 14 * modification, are permitted provided that the following conditions 15 * are met: 16 * 1. Redistributions of source code must retain the above copyright 17 * notice, this list of conditions and the following disclaimer. 18 * 2. Redistributions in binary form must reproduce the above copyright 19 * notice, this list of conditions and the following disclaimer in the 20 * documentation and/or other materials provided with the distribution. 21 * 3. Neither the name of the University nor the names of its contributors 22 * may be used to endorse or promote products derived from this software 23 * without specific prior written permission. 24 * 25 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 28 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 29 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 30 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 31 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 34 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 35 * SUCH DAMAGE. 36 * 37 * 38 * File: am-utils/libamu/mtab.c 39 * 40 */ 41 42#ifdef HAVE_CONFIG_H 43# include <config.h> 44#endif /* HAVE_CONFIG_H */ 45#include <am_defs.h> 46#include <amu.h> 47 48 49/* 50 * Firewall /etc/mtab entries 51 */ 52void 53mnt_free(mntent_t *mp) 54{ 55 XFREE(mp->mnt_fsname); 56 XFREE(mp->mnt_dir); 57 XFREE(mp->mnt_type); 58 XFREE(mp->mnt_opts); 59 60#ifdef HAVE_MNTENT_T_MNT_TIME 61# ifdef HAVE_MNTENT_T_MNT_TIME_STRING 62 XFREE(mp->mnt_time); 63# endif /* HAVE_MNTENT_T_MNT_TIME_STRING */ 64#endif /* HAVE_MNTENT_T_MNT_TIME */ 65 66 XFREE(mp); 67} 68 69 70/* 71 * Discard memory allocated for mount list 72 */ 73void 74discard_mntlist(mntlist *mp) 75{ 76 mntlist *mp2; 77 78 while ((mp2 = mp)) { 79 mp = mp->mnext; 80 if (mp2->mnt) 81 mnt_free(mp2->mnt); 82 XFREE(mp2); 83 } 84} 85 86 87/* 88 * Throw away a mount list 89 */ 90void 91free_mntlist(mntlist *mp) 92{ 93 discard_mntlist(mp); 94#ifdef MOUNT_TABLE_ON_FILE 95 unlock_mntlist(); 96#endif /* MOUNT_TABLE_ON_FILE */ 97} 98 99 100/* 101 * Utility routine which returns a pointer to whatever follows an = in a 102 * string. Returns null if = is not found in the string. 103 */ 104char * 105haseq(char *instr) 106{ 107 if (instr) { 108 char *eq = strchr(instr, '='); 109 if (eq) return ++eq; 110 } 111 return NULL; 112} 113 114 115/* 116 * Utility routine which returns a pointer to whatever 117 * follows an = in a mount option. Returns null if option 118 * doesn't exist or doesn't have an '='. Won't fail for opt,foo=. 119 */ 120char * 121hasmnteq(mntent_t *mnt, char *opt) 122{ 123 if (mnt && opt) { /* disallow null input pointers */ 124 if ( *opt ) { /* disallow the null string as an opt */ 125 char *str = amu_hasmntopt(mnt, opt); 126 if ( str ) { /* option was there */ 127 char *eq = str + strlen(opt); /* Look at char just after option */ 128 if (*eq == '=') /* Is it '=' ? */ 129 return ++eq; /* If so, return pointer to remaining str */ 130 } 131 } 132 } 133 return NULL; 134} 135 136 137/* 138 * Wrapper around hasmntvalerr(), which retains backwards compatibiliy with 139 * older use of hasmntval(). 140 * 141 * XXX: eventually, all use of hasmntval() should be replaced with 142 * hasmntvalerr(). 143 */ 144int 145hasmntval(mntent_t *mnt, char *opt) 146{ 147 int err, val = 0; 148 149 err = hasmntvalerr(mnt, opt, &val); 150 if (err) /* if there was an error (hasmntvalerr returned 1) */ 151 return 0; /* redundant: val==0 above, but leave here for clarity */ 152 /* otherwise there was no error */ 153 return val; 154} 155 156 157/* 158 * Utility routine which determines the value of a numeric option in the 159 * mount options (such as port=%d), and fills in the value in the argument 160 * valp (argument won't be touched if no value is set, for example due to an 161 * error). 162 * 163 * Returns non-zero (1) on error; returns 0 on success. 164 * 165 * XXX: eventually, all use of hasmntval() should be replaced with 166 * hasmntvalerr(). 167 */ 168unsigned int 169hasmntvalerr(mntent_t *mnt, char *opt, int *valp) 170{ 171 char *str = amu_hasmntopt(mnt, opt); 172 int err = 1; /* 1 means no good value was set (an error) */ 173 char *eq, *endptr; 174 long int i; 175 176 /* exit if no option specificed */ 177 if (!str) { 178 goto out; 179 } 180 181 eq = hasmnteq(mnt, opt); 182 183 if (!eq) { /* no argument to option ('=' sign was missing) */ 184 plog(XLOG_MAP, "numeric option to \"%s\" missing", opt); 185 goto out; 186 } 187 188 /* if got here, then we had an '=' after option name */ 189 endptr = NULL; 190 i = strtol(eq, &endptr, 0); /* hex and octal allowed ;-) */ 191 if (!endptr || 192 (endptr != eq && (*endptr == ',' || *endptr == '\0'))) { 193 /* 194 * endptr set means strtol saw a non-digit. If the non-digit is a 195 * comma, it's probably the start of the next option. If the comma is 196 * the first char though, complain about it (foo=,bar is made 197 * noticeable by this). 198 * 199 * Similar reasoning for '\0' instead of comma, it's the end of the 200 * string. 201 */ 202 *valp = (int) i; /* set good value */ 203 err = 0; /* no error */ 204 } else { 205 /* whatever was after the '=' sign wasn't a number */ 206 plog(XLOG_MAP, "invalid numeric option in \"%s\": \"%s\"", opt, str); 207 /* fall through to error/exit processing */ 208 } 209 210 out: 211 return err; 212} 213 214 215/* 216 * Utility routine which returns the string value of 217 * an option in the mount options (such as proto=udp). 218 * Returns NULL if the option is not specified. 219 * Returns malloc'ed string (caller must free!) 220 */ 221char * 222hasmntstr(mntent_t *mnt, char *opt) 223{ 224 char *str = amu_hasmntopt(mnt, opt); 225 226 if (str) { /* The option was there */ 227 228 char *eq = hasmnteq(mnt, opt); 229 230 if (eq) { /* and had an = after it */ 231 232 char *endptr = strchr(eq, ','); 233 234 /* if saw no comma, return xstrdup'd string */ 235 if (!endptr) 236 return xstrdup(eq); 237 else { 238 /* else we need to copy only the chars needed */ 239 int len = endptr - eq; 240 char *buf = xmalloc(len + 1); 241 strncpy(buf, eq, len); 242 buf[len] = '\0'; 243 return buf; 244 } 245 } 246 } 247 return NULL; 248} 249