aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--COPYRIGHT2
-rw-r--r--Makefile.rules25
-rw-r--r--NEWS2
-rw-r--r--TODO17
-rw-r--r--daemon/mount.c2
-rw-r--r--include/automount.h18
-rw-r--r--man/automount.85
-rw-r--r--modules/Makefile33
-rw-r--r--modules/lookup_hesiod.c94
-rw-r--r--modules/lookup_nisplus.c107
-rw-r--r--modules/mount_afs.c55
-rw-r--r--modules/parse_hesiod.c207
12 files changed, 537 insertions, 30 deletions
diff --git a/COPYRIGHT b/COPYRIGHT
index 0352d56..e49c9b8 100644
--- a/COPYRIGHT
+++ b/COPYRIGHT
@@ -1,6 +1,6 @@
For all software in this distribution:
- Copyright 1997 Transmeta Corporation -- All Rights Reserved
+ Copyright 1997-1998 Transmeta Corporation -- All Rights Reserved
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/Makefile.rules b/Makefile.rules
index c47294d..e1618d8 100644
--- a/Makefile.rules
+++ b/Makefile.rules
@@ -4,6 +4,27 @@
# Makefile rules for autofs project
#
+# -------------------------------------------------------------------------- #
+# CHECK HERE TO MAKE SURE YOU HAVE ALL THE CORRECT OPTIONS SET #
+# -------------------------------------------------------------------------- #
+
+# Special parameters for glibc.
+# If you're compiling for glibc (libc 6), uncomment these.
+#YPLIBS = -lnsl
+#LIBRESOLV = -lresolv
+
+# Uncomment these to build hesiod support. HESIOD should point to the
+# hesiod base directory.
+#HESIOD =/usr/athena
+#HESIOD_LIBS = -Llib/$(HESIOD) -lhesiod $(LIBRESOLV)
+
+# Uncomment this to build NIS+ support.
+#NISPLUS=1
+
+# -------------------------------------------------------------------------- #
+# YOU PROBABLY DON'T HAVE TO SET ANY OPTIONS BELOW THIS POINT #
+# -------------------------------------------------------------------------- #
+
# Root directory contents
SUBDIRS = daemon modules man
INCDIRS = include samples
@@ -29,10 +50,6 @@ CXXFLAGS = $(CFLAGS)
LD = ld
SOLDFLAGS = -shared
-# Special parameters for glibc
-# If you're compiling for glibc (libc 6), uncomment these
-#YPLIBS = -lnsl
-
# Directory for autofs modules
autofslibdir = $(DESTDIR)/usr/lib/autofs
diff --git a/NEWS b/NEWS
index a55c75e..374df4a 100644
--- a/NEWS
+++ b/NEWS
@@ -5,6 +5,8 @@ Since autofs-0.3.14:
* Minor fix to the autofs(5) man page.
* Put entire source under CVS, so added ID tags to as many files as
practical; also cleaned up comment preambles.
+* AFS/Hesiod support by Nalin Dahyabhai.
+* NIS+ support by Thorsten Kukuk.
Since autofs-0.3.13:
--------------------
diff --git a/TODO b/TODO
index e79abe5..6747365 100644
--- a/TODO
+++ b/TODO
@@ -1,14 +1,15 @@
-autofs TODO list
-----------------
+autofs v3 TODO list
+-------------------
+* Additional lookup modules: [ng]dbm, db/hash...
+* Document the intermodule interface.
+
+autofs v4 TODO list
+-------------------
+* Completely rewritten kernel protocol, use multithreading rather than
+ processes in the daemon.
* Support multimount entries. (Quite messy: can't unmount the
tree as a unit, probably needs locking while constructing the tree,
and needs scaffolding if no entry for /. Appears *very* difficult
to do without threading!)
* /net support: need hostname resolver module (easy) as well as mountd
query (easy) plus all the multimount entry stuff...
-* Additional lookup modules: [ng]dbm, db/hash, (hesiod?)...
-* Document the intermodule interface.
-* Clean up the kernel protocol; it is a bit too confining at the
- moment to allow for independent releases of the daemon and the
- kernel code.
-
diff --git a/daemon/mount.c b/daemon/mount.c
index e75052a..3c52d47 100644
--- a/daemon/mount.c
+++ b/daemon/mount.c
@@ -24,7 +24,7 @@
#include "automount.h"
/* These filesystems are known not to work with the "generic" module */
-static char *not_generic[] = { "nfs", "smbfs", "ncpfs", "userfs",
+static char *not_generic[] = { "nfs", "smbfs", "ncpfs", "userfs", "afs",
"autofs", NULL };
int do_mount(const char *root, const char *name, int name_len,
diff --git a/include/automount.h b/include/automount.h
index 1e8a001..8054269 100644
--- a/include/automount.h
+++ b/include/automount.h
@@ -45,9 +45,9 @@ int lookup_init(const char *mapfmt, int argc, const char * const *argv,
int lookup_mount(const char *, const char *, int, void *);
int lookup_done(void *);
#endif
-typedef (*lookup_init_t)(const char *, int, const char * const *, void **);
-typedef (*lookup_mount_t)(const char *, const char *, int, void *);
-typedef (*lookup_done_t)(void *);
+typedef int (*lookup_init_t)(const char *, int, const char * const *, void **);
+typedef int (*lookup_mount_t)(const char *, const char *, int, void *);
+typedef int (*lookup_done_t)(void *);
struct lookup_mod {
lookup_init_t lookup_init;
lookup_mount_t lookup_mount;
@@ -70,9 +70,9 @@ int parse_mount(const char *root, const char *name,
int name_len, const char *mapent, void *context);
int parse_done(void *);
#endif
-typedef (*parse_init_t)(int, const char * const *,void **);
-typedef (*parse_mount_t)(const char *,const char *,int, const char *,void *);
-typedef (*parse_done_t)(void *);
+typedef int (*parse_init_t)(int, const char * const *,void **);
+typedef int (*parse_mount_t)(const char *,const char *,int, const char *,void *);
+typedef int (*parse_done_t)(void *);
struct parse_mod {
parse_init_t parse_init;
parse_mount_t parse_mount;
@@ -95,9 +95,9 @@ int mount_mount(const char *root, const char *name, int name_len,
void *context);
int mount_done(void *context);
#endif
-typedef (*mount_init_t)(void **);
-typedef (*mount_mount_t)(const char *, const char *, int, const char *, const char *, const char *, void *);
-typedef (*mount_done_t)(void *);
+typedef int (*mount_init_t)(void **);
+typedef int (*mount_mount_t)(const char *, const char *, int, const char *, const char *, const char *, void *);
+typedef int (*mount_done_t)(void *);
struct mount_mod {
mount_init_t mount_init;
mount_mount_t mount_mount;
diff --git a/man/automount.8 b/man/automount.8
index 7bbed2b..ee0fa1c 100644
--- a/man/automount.8
+++ b/man/automount.8
@@ -55,6 +55,11 @@ line and returns an entry on stdout if successful.
.TP
.B yp
The map is an NIS (YP) database.
+.TP
+.B hesiod
+The map is a hesiod database whose
+.B filsys
+entries are used for maps.
.RE
.TP
\fBformat\fP
diff --git a/modules/Makefile b/modules/Makefile
index c2a709b..4e81be0 100644
--- a/modules/Makefile
+++ b/modules/Makefile
@@ -3,15 +3,26 @@
# Makefile for autofs
#
-SRCS = lookup_yp.c lookup_file.c lookup_program.c \
- parse_sun.c \
- mount_generic.c mount_nfs.c mount_smbfs.c
-MODS = lookup_yp.so lookup_file.so lookup_program.so \
- parse_sun.so \
- mount_generic.so mount_nfs.so mount_smbfs.so
-
include ../Makefile.rules
+SRCS = lookup_yp.c lookup_file.c lookup_program.c \
+ parse_sun.c \
+ mount_generic.c mount_nfs.c mount_smbfs.c mount_afs.c
+
+MODS = lookup_yp.so lookup_file.so lookup_program.so \
+ parse_sun.so \
+ mount_generic.so mount_nfs.so mount_smbfs.so mount_afs.so
+
+ifdef HESIOD
+ SRCS += lookup_hesiod.c parse_hesiod.c
+ MODS += lookup_hesiod.so parse_hesiod.so
+endif
+
+ifdef NISPLUS
+ SRCS += lookup_nisplus.c
+ MODS += lookup_nisplus.so
+endif
+
CFLAGS += -I../include -fpic -DAUTOFS_LIB_DIR=\"$(autofslibdir)\"
all: $(MODS)
@@ -29,3 +40,11 @@ install: all
lookup_yp.so: lookup_yp.c
$(CC) $(SOLDFLAGS) $(CFLAGS) -o lookup_yp.so lookup_yp.c $(YPLIBS)
$(STRIP) lookup_yp.so
+
+lookup_nisplus.so: lookup_nisplus.c
+ $(CC) $(SOLDFLAGS) $(CFLAGS) -o lookup_nisplus.so lookup_nisplus.c $(YPLIBS)
+ $(STRIP) lookup_nisplus.so
+
+lookup_hesiod.so: lookup_hesiod.c
+ $(CC) $(SOLDFLAGS) $(CFLAGS) -I$(HESIOD)/include -o lookup_hesiod.so \
+ lookup_hesiod.c $(HESIOD_LIBS)
diff --git a/modules/lookup_hesiod.c b/modules/lookup_hesiod.c
new file mode 100644
index 0000000..231377e
--- /dev/null
+++ b/modules/lookup_hesiod.c
@@ -0,0 +1,94 @@
+#ident "$Id$"
+/*
+ * lookup_hesiod.c
+ *
+ * Module for Linux automountd to access automount maps in hesiod filsys
+ * entries.
+ *
+ */
+
+#include <sys/types.h>
+#include <ctype.h>
+#include <string.h>
+#include <syslog.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <netinet/in.h>
+#include <arpa/nameser.h>
+#include <resolv.h>
+#include <hesiod.h>
+
+#define MODULE_LOOKUP
+#include "automount.h"
+
+#define MAPFMT_DEFAULT "hesiod"
+
+#define MODPREFIX "lookup(hesiod): "
+#define HESIOD_LEN 512
+
+struct lookup_context {
+ struct parse_mod *parser;
+};
+
+int lookup_version = AUTOFS_LOOKUP_VERSION; /* Required by protocol */
+
+/* This initializes a context (persistent non-global data) for queries to
+ this module. */
+int lookup_init(char *mapfmt, int argc, char **argv, void **context)
+{
+ struct lookup_context *ctxt = NULL;
+
+ /* If we can't build a context, bail. */
+ if((*context = ctxt = (struct lookup_context*)
+ malloc(sizeof(struct lookup_context))) == NULL) {
+ syslog(LOG_CRIT, MODPREFIX "malloc: %m");
+ return 1;
+ }
+
+ /* Initialize the resolver. */
+ res_init();
+
+ /* If a map type isn't explicitly given, parse it as hesiod entries. */
+ if ( !mapfmt )
+ mapfmt = MAPFMT_DEFAULT;
+
+ /* Open the parser, if we can. */
+ return !(ctxt->parser = open_parse(mapfmt,MODPREFIX,argc-1,argv+1));
+}
+
+/* Lookup and act on a filesystem name. In this case, lookup the "filsys"
+ record in hesiod. If it's an AFS or NFS filesyste, parse it out. If
+ it's an ERR filesystem, it's an error message we should log. Otherwise,
+ assume it's something we know how to deal with already (generic). */
+int lookup_mount(char *root, char *name, int name_len, void *context)
+{
+ char **hes_result, mapent[HESIOD_LEN + 1];
+ struct lookup_context *ctxt = (struct lookup_context *) context;
+
+ syslog(LOG_DEBUG, MODPREFIX "looking up root=\"%s\", name=\"%s\"",
+ root, name);
+
+ chdir("/"); /* If this is not here the filesystem stays
+ busy, for some reason... */
+
+ hes_result = hes_resolve(name, "filsys");
+
+ if(hes_result) {
+ strncpy(mapent, hes_result[0], sizeof(mapent) - 1);
+ syslog(LOG_DEBUG, MODPREFIX "lookup for \"%s\" gave \"%s\"",
+ name, mapent);
+ free(hes_result);
+ }
+
+ return ctxt->parser->parse_mount(root,name,name_len,mapent,ctxt->parser->context);
+}
+
+/* This destroys a context for queries to this module. It releases the parser
+ structure (unloading the module) and frees the memory used by the context. */
+int lookup_done(void *context)
+{
+ struct lookup_context *ctxt = (struct lookup_context *) context;
+ int rv = close_parse(ctxt->parser);
+ free(ctxt);
+ return rv;
+}
diff --git a/modules/lookup_nisplus.c b/modules/lookup_nisplus.c
new file mode 100644
index 0000000..dfaf675
--- /dev/null
+++ b/modules/lookup_nisplus.c
@@ -0,0 +1,107 @@
+#ident "$Id$"
+/*
+ * lookup_nisplus.c
+ *
+ * Module for Linux automountd to access a NIS+ automount map
+ */
+
+#include <stdio.h>
+#include <malloc.h>
+#include <errno.h>
+#include <unistd.h>
+#include <syslog.h>
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <rpc/rpc.h>
+#include <rpc/xdr.h>
+#include <rpcsvc/nis.h>
+#include <rpcsvc/ypclnt.h>
+
+#define MODULE_LOOKUP
+#include "automount.h"
+
+#define MAPFMT_DEFAULT "sun"
+
+#define MODPREFIX "lookup(nisplus): "
+
+struct lookup_context {
+ char *domainname;
+ char *mapname;
+ struct parse_mod *parse;
+};
+
+int lookup_version = AUTOFS_LOOKUP_VERSION; /* Required by protocol */
+
+int lookup_init(char *mapfmt, int argc, char **argv, void **context)
+{
+ struct lookup_context *ctxt;
+ int err;
+
+ if ( !(*context = ctxt = malloc(sizeof(struct lookup_context))) ) {
+ syslog(LOG_CRIT, MODPREFIX "%m");
+ return 1;
+ }
+
+ if ( argc < 1 ) {
+ syslog(LOG_CRIT, MODPREFIX "No map name");
+ return 1;
+ }
+ ctxt->mapname = argv[0];
+
+ err = yp_get_default_domain(&ctxt->domainname);
+ if ( err ) {
+ syslog(LOG_CRIT, MODPREFIX "map %s: %s\n", ctxt->mapname, yperr_string(err));
+ return 1;
+ }
+
+ if ( !mapfmt )
+ mapfmt = MAPFMT_DEFAULT;
+
+ return !(ctxt->parse = open_parse(mapfmt,MODPREFIX,argc-1,argv+1));
+}
+
+int lookup_mount(char *root, char *name, int name_len, void *context)
+{
+ struct lookup_context *ctxt = (struct lookup_context *) context;
+ char tablename[strlen (name) + strlen (ctxt->mapname) +
+ strlen (ctxt->domainname) + 20];
+ nis_result *result;
+ int rv;
+
+ syslog(LOG_DEBUG, MODPREFIX "looking up %s", name);
+
+ sprintf (tablename, "[key=%s],%s.org_dir.%s.", name, ctxt->mapname,
+ ctxt->domainname);
+
+
+ result = nis_list (tablename, FOLLOW_PATH | FOLLOW_LINKS, NULL, NULL);
+ if (result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS) {
+ /* Try to get the "*" entry if there is one - note that we *don't*
+ modify "name" so & -> the name we used, not "*" */
+ sprintf (tablename, "[key=*],%s.org_dir.%s.", ctxt->mapname,
+ ctxt->domainname);
+ result = nis_list (tablename, FOLLOW_PATH | FOLLOW_LINKS, NULL, NULL);
+ }
+ if (result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS) {
+ syslog(LOG_NOTICE, MODPREFIX "lookup for %s failed: %s", name,
+ nis_sperrno (result->status));
+ return 1;
+ }
+
+ syslog(LOG_DEBUG, MODPREFIX "%s -> %s", name,
+ NIS_RES_OBJECT(result)->EN_data.en_cols.en_cols_val[1].ec_value.ec_value_val);
+
+ rv = ctxt->parse->parse_mount(root,name,name_len,
+ NIS_RES_OBJECT(result)->EN_data.en_cols.en_cols_val[1].ec_value.ec_value_val,
+ ctxt->parse->context);
+ return rv;
+}
+
+int lookup_done(void *context)
+{
+ struct lookup_context *ctxt = (struct lookup_context *) context;
+ int rv = close_parse(ctxt->parse);
+ free(ctxt);
+ return rv;
+}
diff --git a/modules/mount_afs.c b/modules/mount_afs.c
new file mode 100644
index 0000000..71de705
--- /dev/null
+++ b/modules/mount_afs.c
@@ -0,0 +1,55 @@
+#ident "$Id$"
+/*
+ * mount_afs.c
+ *
+ * Module for Linux automountd to "mount" AFS filesystems. We don't bother
+ * with any of the things "attach" would do (making sure there are tokens,
+ * subscribing to ops messages if Zephyr is installed), but it works for me.
+ *
+ */
+
+#include <stdio.h>
+#include <malloc.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <syslog.h>
+#include <string.h>
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#define MODULE_MOUNT
+#include "automount.h"
+
+#define MODPREFIX "mount(afs): "
+int mount_version = AUTOFS_MOUNT_VERSION; /* Required by protocol */
+
+int mount_init(void **context)
+{
+ return 0;
+}
+
+int mount_mount(const char *root, const char *name, int name_len,
+ const char *what, const char *fstype, const char *options,
+ void *context)
+{
+ char dest[PATH_MAX * 2];
+
+ strcpy(dest, root); /* Convert the name to a mount point. */
+ strncat(dest, "/", sizeof(dest));
+ strncat(dest, name, sizeof(dest));
+
+ /* This was here just so I could figure out how this worked.
+ syslog(LOG_DEBUG, MODPREFIX "mount_mount called with root=\"%s\", "
+ "name=\"%s\", namelen=\"%d, what=\"%s\", fstype=\"%s\", options=\"%s\"",+ root, name, name_len, what, fstype, options); */
+
+ syslog(LOG_DEBUG, MODPREFIX "mounting AFS %s -> %s", dest, what);
+
+ return symlink(what, dest); /* Try it. If it fails, return the error. */
+}
+
+int mount_done(void *context)
+{
+ return 0;
+}
diff --git a/modules/parse_hesiod.c b/modules/parse_hesiod.c
new file mode 100644
index 0000000..084f3a0
--- /dev/null
+++ b/modules/parse_hesiod.c
@@ -0,0 +1,207 @@
+#ident "$Id$"
+/*
+ * parse_hesiod.c
+ *
+ * Module for Linux automountd to parse a hesiod filesystem entry.
+ */
+
+#include <sys/types.h>
+#include <ctype.h>
+#include <string.h>
+#include <syslog.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <netinet/in.h>
+#include <arpa/nameser.h>
+#include <resolv.h>
+
+#define MODULE_PARSE
+#include "automount.h"
+
+#define MODPREFIX "parse(hesiod): "
+int parse_version = AUTOFS_PARSE_VERSION; /* Required by protocol */
+
+#define HESIOD_LEN 512
+
+/* Break out the fields in an AFS record of the form:
+ "AFS /afs/athena/mit/tytso w /mit/tytso-afs" */
+static int parse_afs(char *filsysline, char *name, int name_len,
+ char *source, int source_len,
+ char *options, int options_len)
+{
+ char *p;
+ int i;
+
+ p = filsysline;
+
+ while(isspace(*p)) p++; /* Skip whitespace. */
+ while(!isspace(*p)) p++; /* Skip the filesystem type. */
+ while(isspace(*p)) p++; /* Skip whitespace. */
+
+ /* Isolate the source for this AFS fs. */
+ for(i = 0; (!isspace(p[i]) && i < source_len); i++) {
+ source[i] = p[i];
+ }
+ source[i] = 0;
+ p += i;
+
+ while((*p) && (isspace(*p))) p++; /* Skip whitespace. */
+
+ /* Isolate the source for this AFS fs. */
+ for(i = 0; (!isspace(p[i]) && i < options_len); i++) {
+ options[i] = p[i];
+ }
+ options[i] = 0;
+
+ if(!strcmp(options, "r")) /* Hack for "r" or "w" options. */
+ strcpy(options, "ro");
+ if(!strcmp(options, "w"))
+ strcpy(options, "rw");
+
+ syslog(LOG_DEBUG, MODPREFIX "parsing AFS record gives '%s'->'%s' with options" " '%s'", name, source, options);
+
+ return 0;
+}
+
+/* Break out the fields in an NFS record of the form:
+ "NFS /export/src nelson.tx.ncsu.edu w /ncsu/tx-src" */
+static int parse_nfs(char *filsysline, char *name, int name_len,
+ char *source, int source_len,
+ char *options, int options_len)
+{
+ char *p;
+ char mount[HESIOD_LEN + 1];
+ int i;
+
+ p = filsysline;
+
+ while(isspace(*p)) p++; /* Skip whitespace. */
+ while(!isspace(*p)) p++; /* Skip the filesystem type. */
+ while(isspace(*p)) p++; /* Skip whitespace. */
+
+ /* Isolate the remote mountpoint for this NFS fs. */
+ for(i = 0; (!isspace(p[i]) && i < sizeof(mount)); i++) {
+ mount[i] = p[i];
+ }
+ mount[i] = 0;
+ p += i;
+
+ while((*p) && (isspace(*p))) p++; /* Skip whitespace. */
+
+ /* Isolate the remote host. */
+ for(i = 0; (!isspace(p[i]) && i < source_len); i++) {
+ source[i] = p[i];
+ }
+ source[i] = 0;
+ p += i;
+
+ /* Append ":mountpoint" to the source to get "host:mountpoint". */
+ strncat(source, ":", source_len);
+ strncat(source, mount, source_len);
+
+ while((*p) && (isspace(*p))) p++; /* Skip whitespace. */
+
+ /* Isolate the mount options. */
+ for(i = 0; (!isspace(p[i]) && i < options_len); i++) {
+ options[i] = p[i];
+ }
+ options[i] = 0;
+
+ if(!strcmp(options, "r")) /* Hack for "r" or "w" options. */
+ strcpy(options, "ro");
+ if(!strcmp(options, "w"))
+ strcpy(options, "rw");
+
+ syslog(LOG_DEBUG, MODPREFIX "parsing NFS record gives '%s'->'%s' with options" "'%s'", name, source, options);
+
+ return 0;
+}
+
+/* Break out the fields in a generic record of the form:
+ "UFS /dev/ra0g w /site" */
+static int parse_generic(char *filsysline, char *name, int name_len,
+ char *source, int source_len,
+ char *options, int options_len)
+{
+ char *p;
+ int i;
+
+ p = filsysline;
+
+ while(isspace(*p)) p++; /* Skip whitespace. */
+ while(!isspace(*p)) p++; /* Skip the filesystem type. */
+ while(isspace(*p)) p++; /* Skip whitespace. */
+
+ /* Isolate the source for this fs. */
+ for(i = 0; (!isspace(p[i]) && i < source_len); i++) {
+ source[i] = p[i];
+ }
+ source[i] = 0;
+ p += i;
+
+ while((*p) && (isspace(*p))) p++; /* Skip whitespace. */
+
+ /* Isolate the mount options. */
+ for(i = 0; (!isspace(p[i]) && i < options_len); i++) {
+ options[i] = p[i];
+ }
+ options[i] = 0;
+
+ if(!strcmp(options, "r")) /* Hack for "r" or "w" options. */
+ strcpy(options, "ro");
+ if(!strcmp(options, "w"))
+ strcpy(options, "rw");
+
+ syslog(LOG_DEBUG, MODPREFIX "parsing generic record gives '%s'->'%s' "
+ "with options '%s'", name, source, options);
+ return 0;
+}
+
+int parse_init(int argc, char **argv, void **context)
+{
+ return 0;
+}
+
+int parse_done(void *context)
+{
+ return 0;
+}
+
+int parse_mount(char *root, char *name, int name_len, char *mapent, void *context)
+{
+ char source[HESIOD_LEN+1],
+ fstype[HESIOD_LEN+1],
+ options[HESIOD_LEN+1],
+ *p, *q;
+
+ p = mapent;
+ q = fstype;
+
+ while(isspace(*p)) p++; /* Skip any initial whitespace... */
+
+ while(!isspace(*p)) { /* Isolate the filesystem type... */
+ *q++ = tolower(*p++);
+ }
+ *q = 0;
+
+ if(!strcasecmp(fstype, "err")) { /* If it's an error message... */
+ syslog(LOG_DEBUG, MODPREFIX "%s", mapent);
+ return 1;
+ }
+ else /* If it's an AFS fs... */
+ if(!strcasecmp(fstype, "afs")) parse_afs(mapent, name, name_len,
+ source, sizeof(source),
+ options, sizeof(options));
+ else /* If it's NFS... */
+ if(!strcasecmp(fstype, "nfs")) parse_nfs(mapent, name, name_len,
+ source, sizeof(source),
+ options, sizeof(options));
+ else /* Punt. */
+ parse_generic(mapent, name, name_len, source, sizeof(source),
+ options, sizeof(options));
+
+ syslog(LOG_DEBUG, MODPREFIX "mount %s is type %s from %s",
+ name, fstype, source);
+
+ return do_mount(root, name, name_len, source, fstype, options);
+}