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