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