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