138494Sobrien/* 2310490Scy * Copyright (c) 1997-2014 Erez Zadok 338494Sobrien * Copyright (c) 1989 Jan-Simon Pendry 438494Sobrien * Copyright (c) 1989 Imperial College of Science, Technology & Medicine 538494Sobrien * Copyright (c) 1989 The Regents of the University of California. 638494Sobrien * All rights reserved. 738494Sobrien * 838494Sobrien * This code is derived from software contributed to Berkeley by 938494Sobrien * Jan-Simon Pendry at Imperial College, London. 1038494Sobrien * 1138494Sobrien * Redistribution and use in source and binary forms, with or without 1238494Sobrien * modification, are permitted provided that the following conditions 1338494Sobrien * are met: 1438494Sobrien * 1. Redistributions of source code must retain the above copyright 1538494Sobrien * notice, this list of conditions and the following disclaimer. 1638494Sobrien * 2. Redistributions in binary form must reproduce the above copyright 1738494Sobrien * notice, this list of conditions and the following disclaimer in the 1838494Sobrien * documentation and/or other materials provided with the distribution. 19310490Scy * 3. Neither the name of the University nor the names of its contributors 2038494Sobrien * may be used to endorse or promote products derived from this software 2138494Sobrien * without specific prior written permission. 2238494Sobrien * 2338494Sobrien * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 2438494Sobrien * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2538494Sobrien * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2638494Sobrien * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 2738494Sobrien * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2838494Sobrien * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2938494Sobrien * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 3038494Sobrien * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 3138494Sobrien * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3238494Sobrien * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3338494Sobrien * SUCH DAMAGE. 3438494Sobrien * 3538494Sobrien * 36174294Sobrien * File: am-utils/libamu/mtab.c 3738494Sobrien * 3838494Sobrien */ 3938494Sobrien 4038494Sobrien#ifdef HAVE_CONFIG_H 4138494Sobrien# include <config.h> 4238494Sobrien#endif /* HAVE_CONFIG_H */ 4338494Sobrien#include <am_defs.h> 4438494Sobrien#include <amu.h> 4538494Sobrien 4638494Sobrien 4738494Sobrien/* 4838494Sobrien * Firewall /etc/mtab entries 4938494Sobrien */ 5038494Sobrienvoid 5138494Sobrienmnt_free(mntent_t *mp) 5238494Sobrien{ 5338494Sobrien XFREE(mp->mnt_fsname); 5438494Sobrien XFREE(mp->mnt_dir); 5538494Sobrien XFREE(mp->mnt_type); 5638494Sobrien XFREE(mp->mnt_opts); 5738494Sobrien 58119679Smbr#ifdef HAVE_MNTENT_T_MNT_TIME 59119679Smbr# ifdef HAVE_MNTENT_T_MNT_TIME_STRING 6038494Sobrien XFREE(mp->mnt_time); 61119679Smbr# endif /* HAVE_MNTENT_T_MNT_TIME_STRING */ 62119679Smbr#endif /* HAVE_MNTENT_T_MNT_TIME */ 6338494Sobrien 6438494Sobrien XFREE(mp); 6538494Sobrien} 6638494Sobrien 6738494Sobrien 6838494Sobrien/* 6938494Sobrien * Discard memory allocated for mount list 7038494Sobrien */ 7138494Sobrienvoid 7238494Sobriendiscard_mntlist(mntlist *mp) 7338494Sobrien{ 7438494Sobrien mntlist *mp2; 7538494Sobrien 7638494Sobrien while ((mp2 = mp)) { 7738494Sobrien mp = mp->mnext; 7838494Sobrien if (mp2->mnt) 7938494Sobrien mnt_free(mp2->mnt); 8038494Sobrien XFREE(mp2); 8138494Sobrien } 8238494Sobrien} 8338494Sobrien 8438494Sobrien 8538494Sobrien/* 8638494Sobrien * Throw away a mount list 8738494Sobrien */ 8838494Sobrienvoid 8938494Sobrienfree_mntlist(mntlist *mp) 9038494Sobrien{ 9138494Sobrien discard_mntlist(mp); 9238494Sobrien#ifdef MOUNT_TABLE_ON_FILE 9338494Sobrien unlock_mntlist(); 9438494Sobrien#endif /* MOUNT_TABLE_ON_FILE */ 9538494Sobrien} 9638494Sobrien 9738494Sobrien 9838494Sobrien/* 9982794Sobrien * Utility routine which returns a pointer to whatever follows an = in a 10082794Sobrien * string. Returns null if = is not found in the string. 10182794Sobrien */ 10282794Sobrienchar * 10382794Sobrienhaseq(char *instr) 10482794Sobrien{ 10582794Sobrien if (instr) { 10682794Sobrien char *eq = strchr(instr, '='); 10782794Sobrien if (eq) return ++eq; 10882794Sobrien } 10982794Sobrien return NULL; 11082794Sobrien} 11182794Sobrien 11282794Sobrien 11382794Sobrien/* 11482794Sobrien * Utility routine which returns a pointer to whatever 11582794Sobrien * follows an = in a mount option. Returns null if option 116174294Sobrien * doesn't exist or doesn't have an '='. Won't fail for opt,foo=. 11782794Sobrien */ 11882794Sobrienchar * 11982794Sobrienhasmnteq(mntent_t *mnt, char *opt) 12082794Sobrien{ 12182794Sobrien if (mnt && opt) { /* disallow null input pointers */ 12282794Sobrien if ( *opt ) { /* disallow the null string as an opt */ 123174294Sobrien char *str = amu_hasmntopt(mnt, opt); 12482794Sobrien if ( str ) { /* option was there */ 12582794Sobrien char *eq = str + strlen(opt); /* Look at char just after option */ 12682794Sobrien if (*eq == '=') /* Is it '=' ? */ 12782794Sobrien return ++eq; /* If so, return pointer to remaining str */ 12882794Sobrien } 12982794Sobrien } 13082794Sobrien } 13182794Sobrien return NULL; 13282794Sobrien} 13382794Sobrien 13482794Sobrien 13582794Sobrien/* 136174294Sobrien * Wrapper around hasmntvalerr(), which retains backwards compatibiliy with 137174294Sobrien * older use of hasmntval(). 138174294Sobrien * 139174294Sobrien * XXX: eventually, all use of hasmntval() should be replaced with 140174294Sobrien * hasmntvalerr(). 14138494Sobrien */ 14238494Sobrienint 14338494Sobrienhasmntval(mntent_t *mnt, char *opt) 14438494Sobrien{ 145174294Sobrien int err, val = 0; 14638494Sobrien 147174294Sobrien err = hasmntvalerr(mnt, opt, &val); 148174294Sobrien if (err) /* if there was an error (hasmntvalerr returned 1) */ 149174294Sobrien return 0; /* redundant: val==0 above, but leave here for clarity */ 150174294Sobrien /* otherwise there was no error */ 151174294Sobrien return val; 152174294Sobrien} 153174294Sobrien 154174294Sobrien 155174294Sobrien/* 156174294Sobrien * Utility routine which determines the value of a numeric option in the 157174294Sobrien * mount options (such as port=%d), and fills in the value in the argument 158174294Sobrien * valp (argument won't be touched if no value is set, for example due to an 159174294Sobrien * error). 160174294Sobrien * 161174294Sobrien * Returns non-zero (1) on error; returns 0 on success. 162174294Sobrien * 163174294Sobrien * XXX: eventually, all use of hasmntval() should be replaced with 164174294Sobrien * hasmntvalerr(). 165174294Sobrien */ 166174294Sobrienunsigned int 167174294Sobrienhasmntvalerr(mntent_t *mnt, char *opt, int *valp) 168174294Sobrien{ 169174294Sobrien char *str = amu_hasmntopt(mnt, opt); 170174294Sobrien int err = 1; /* 1 means no good value was set (an error) */ 171174294Sobrien char *eq, *endptr; 172174294Sobrien long int i; 173174294Sobrien 174174294Sobrien /* exit if no option specificed */ 175174294Sobrien if (!str) { 176174294Sobrien goto out; 177174294Sobrien } 178174294Sobrien 179174294Sobrien eq = hasmnteq(mnt, opt); 180174294Sobrien 181174294Sobrien if (!eq) { /* no argument to option ('=' sign was missing) */ 182174294Sobrien plog(XLOG_MAP, "numeric option to \"%s\" missing", opt); 183174294Sobrien goto out; 184174294Sobrien } 185174294Sobrien 186174294Sobrien /* if got here, then we had an '=' after option name */ 187174294Sobrien endptr = NULL; 188174294Sobrien i = strtol(eq, &endptr, 0); /* hex and octal allowed ;-) */ 189174294Sobrien if (!endptr || 190174294Sobrien (endptr != eq && (*endptr == ',' || *endptr == '\0'))) { 191174294Sobrien /* 192174294Sobrien * endptr set means strtol saw a non-digit. If the non-digit is a 193174294Sobrien * comma, it's probably the start of the next option. If the comma is 194174294Sobrien * the first char though, complain about it (foo=,bar is made 195174294Sobrien * noticeable by this). 196174294Sobrien * 197174294Sobrien * Similar reasoning for '\0' instead of comma, it's the end of the 198174294Sobrien * string. 199174294Sobrien */ 200174294Sobrien *valp = (int) i; /* set good value */ 201174294Sobrien err = 0; /* no error */ 202174294Sobrien } else { 203174294Sobrien /* whatever was after the '=' sign wasn't a number */ 204174294Sobrien plog(XLOG_MAP, "invalid numeric option in \"%s\": \"%s\"", opt, str); 205174294Sobrien /* fall through to error/exit processing */ 206174294Sobrien } 207174294Sobrien 208174294Sobrien out: 209174294Sobrien return err; 210174294Sobrien} 211174294Sobrien 212174294Sobrien 213174294Sobrien/* 214174294Sobrien * Utility routine which returns the string value of 215174294Sobrien * an option in the mount options (such as proto=udp). 216174294Sobrien * Returns NULL if the option is not specified. 217174294Sobrien * Returns malloc'ed string (caller must free!) 218174294Sobrien */ 219174294Sobrienchar * 220174294Sobrienhasmntstr(mntent_t *mnt, char *opt) 221174294Sobrien{ 222174294Sobrien char *str = amu_hasmntopt(mnt, opt); 223174294Sobrien 22482794Sobrien if (str) { /* The option was there */ 22582794Sobrien 22682794Sobrien char *eq = hasmnteq(mnt, opt); 22782794Sobrien 22882794Sobrien if (eq) { /* and had an = after it */ 22982794Sobrien 230174294Sobrien char *endptr = strchr(eq, ','); 23182794Sobrien 232310490Scy /* if saw no comma, return xstrdup'd string */ 233174294Sobrien if (!endptr) 234310490Scy return xstrdup(eq); 235174294Sobrien else { 236174294Sobrien /* else we need to copy only the chars needed */ 237174294Sobrien int len = endptr - eq; 238174294Sobrien char *buf = xmalloc(len + 1); 239174294Sobrien strncpy(buf, eq, len); 240174294Sobrien buf[len] = '\0'; 241174294Sobrien return buf; 242174294Sobrien } 24382794Sobrien } 24438494Sobrien } 245174294Sobrien return NULL; 24638494Sobrien} 247