aboutsummaryrefslogtreecommitdiffstats
path: root/modules/parse_hesiod.c
diff options
context:
space:
mode:
Diffstat (limited to 'modules/parse_hesiod.c')
-rw-r--r--modules/parse_hesiod.c207
1 files changed, 207 insertions, 0 deletions
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);
+}