diff options
Diffstat (limited to 'modules/parse_hesiod.c')
-rw-r--r-- | modules/parse_hesiod.c | 207 |
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); +} |