--- Makefile-dist	Tue Apr 18 19:54:44 2000
+++ Makefile	Sun Sep 24 21:11:38 2000
@@ -12,26 +12,26 @@
 all:	daemon samples
 
 daemon:
-	for i in $(SUBDIRS); do $(MAKE) -C $$i all; done 
+	for i in $(SUBDIRS); do $(MAKE) $(MFLAGS) -C $$i all; done 
 
 kernel:
-	if [ -d kernel ]; then $(MAKE) -C kernel all; fi
+	if [ -d kernel ]; then $(MAKE) $(MFLAGS) -C kernel all; fi
 
 samples:
-	if [ -d samples ]; then $(MAKE) -C samples all; fi
+	if [ -d samples ]; then $(MAKE) $(MFLAGS) -C samples all; fi
 
 clean:
 	for i in $(SUBDIRS) samples kernel; do \
-		if [ -d $$i ]; then $(MAKE) -C $$i clean; fi; done 	
+		if [ -d $$i ]; then $(MAKE) $(MFLAGS) -C $$i clean; fi; done 	
 
 install:
-	for i in $(SUBDIRS); do $(MAKE) -C $$i install; done 	
+	for i in $(SUBDIRS); do $(MAKE) $(MFLAGS) -C $$i install; done 	
 
 install_kernel:
-	if [ -d kernel ]; then $(MAKE) -C kernel install; fi
+	if [ -d kernel ]; then $(MAKE) $(MFLAGS) -C kernel install; fi
 
 install_samples:
-	if [ -d samples ]; then $(MAKE) -C samples install; fi
+	if [ -d samples ]; then $(MAKE) $(MFLAGS) -C samples install; fi
 
 mrproper distclean: clean
 	find . -noleaf \( -name '*~' -o -name '#*' -o -name '*.orig' -o -name '*.rej' -o -name '*.old' \) -print0 | xargs -0 rm -f
@@ -40,7 +40,7 @@
 	sed -e "s/(\.autofs-[0-9.]\+)/(.autofs-`cat .version`)/" < configure.in > configure.in.tmp
 	mv -f configure.in.tmp configure.in
 	rm -f configure
-	$(MAKE) configure
+	$(MAKE) $(MFLAGS) configure
 
 TODAY := $(shell date +'%Y%m%d')
 
--- Makefile.rules-dist	Tue Apr 18 19:54:44 2000
+++ Makefile.rules	Sun Sep 24 21:10:40 2000
@@ -20,14 +20,14 @@
 STRIP     = :
 else
 CFLAGS    = -O3 -fomit-frame-pointer -Wall
-LDFLAGS   = -s
+LDFLAGS   = # -s
 STRIP     = strip --strip-debug
 endif
 
-CC        = gcc
-CXX       = g++
+#CC        = gcc
+#CXX       = g++
 CXXFLAGS  = $(CFLAGS)
-LD        = ld
+#LD        = ld
 SOLDFLAGS = -shared
 
 # Kernel compilation rules (this is for "make kernel" to work; not needed
@@ -36,11 +36,11 @@
 # directory; not included with the autofs distribution.)
 
 # 1. Comment this out if your kernel is *not* SMP
-KFLAGS   = -D__SMP__
+#KFLAGS   = -D__SMP__
 # 2. Set this to your kernel include files
-KINCLUDE = /usr/src/linux/include
+KINCLUDE = $(KERNDIR)/include
 # 3. Comment this out if you do *not* use versioned modules
-MODFLAGS = -DMODVERSIONS -include $(KINCLUDE)/linux/modversions.h
+#MODFLAGS = -DMODVERSIONS -include $(KINCLUDE)/linux/modversions.h
 
 # Directory to install modules
 moddir = $(INSTALLROOT)/lib/modules/`uname -r`
--- daemon/Makefile-dist	Tue Apr 18 19:54:44 2000
+++ daemon/Makefile	Wed Jun  6 11:31:43 2001
@@ -25,6 +25,7 @@
 	rm -f *.o *.s automount
 
 install: all
+	install -d -m 755 $(INSTALLROOT)$(sbindir)
 	install -c automount -m 755 $(INSTALLROOT)$(sbindir)
 
 
--- daemon/automount.c-dist	Tue Apr 18 19:54:44 2000
+++ daemon/automount.c	Wed May 15 12:11:13 2002
@@ -39,6 +39,8 @@
 #include <sys/time.h>
 #include <sys/poll.h>
 #include <linux/auto_fs4.h>
+#include <ctype.h>
+#include <time.h>
 
 #ifndef NDEBUG
 #define assert(x)	do { if (!(x)) { syslog(LOG_CRIT, __FILE__ ":%d: assertion failed: " #x, __LINE__); } } while(0)
@@ -68,6 +70,7 @@
 int kproto_version;		        /* Kernel protocol version used */
 
 static int submount = 0;
+static int master = 0;
 
 /*
  * State machine for daemon
@@ -1139,11 +1142,12 @@
   return -1;
 }
 
-static void become_daemon(void)
+static pid_t become_daemon(int master)
 {
   FILE *pidfp;
   pid_t pid;
   int nullfd;
+  char *logid;
   
   /* Don't BUSY any directories unnecessarily */
   chdir("/");
@@ -1151,16 +1155,23 @@
   /* Detach from foreground process */
   if ( !submount ) {
     pid = fork();
-    if ( pid > 0 )
+    if ( pid > 0 ) {
+      if (master == 0)
+	return (pid);
       exit(0);
+    }
     else if ( pid < 0 ) {
+      if (master == 0)
+	return (pid);
       fprintf(stderr, "%s: Could not detach process\n", program);
       exit(1);
     }
   }
   
   /* Open syslog */ 
-  openlog("automount", LOG_PID, LOG_DAEMON);
+  logid = master < 0 ? "automount" : \
+    (master != 0 ? "automount[master]" : "automount[child]");
+  openlog(logid, LOG_PID, LOG_DAEMON);
 
   /* Initialize global data */
   my_pid = getpid();
@@ -1191,7 +1202,7 @@
   close(nullfd);
 
   /* Write pid file if requested */
-  if ( pid_file ) {
+  if ( pid_file && master != 0 ) {
     if ( (pidfp = fopen(pid_file, "wt")) ) {
       fprintf(pidfp, "%lu\n", (unsigned long) my_pid);
       fclose(pidfp);
@@ -1200,6 +1211,8 @@
       pid_file = NULL;
     }
   }
+
+  return ((pid_t)0);
 }
 
 /*
@@ -1236,6 +1249,203 @@
 static void usage(void)
 {
   fprintf(stderr, "Usage: %s [options] path map_type [args...]\n", program);
+  fprintf(stderr, "   or: %s [options] --master filename\n", program);
+  fprintf(stderr, "(note: can't use --submount with --master)\n", program);
+}
+
+#define MINSPAWNTIME 5
+
+#define MAXAMAPS 32
+#define MAXMARGS 31
+
+struct amap {
+  pid_t pid;
+  int mac, running;
+  time_t lastrun;
+  char *path, *map;
+  const char *mav[MAXMARGS+1];
+};
+
+static struct amap amaps[MAXAMAPS];
+static int namaps, had_chld, had_hup, had_term, alrm_isset;
+static char *masterfile;
+
+static char *
+xstrdup(char *s)
+{
+  char *p;
+
+  if ((p = strdup(s)) == NULL) {
+    fprintf(stderr, "%s: out of memory in xstrdup\n", program);
+    exit(1);
+  }
+
+  return (p);
+}
+
+static int
+amapcmp(struct amap *amp1, struct amap *amp2)
+{
+  int n, i;
+
+  if ((n = strcmp(amp1->path, amp2->path)) != 0)
+    return (n);
+
+  if ((n = strcmp(amp1->map, amp2->map)) != 0)
+    return (n);
+
+  if ((n = amp1->mac - amp2->mac) != 0)
+    return (n);
+
+  for (i = 0; i < amp1->mac; i++)
+    if ((n = strcmp(amp1->mav[i], amp2->mav[i])) != 0)
+      return (n);
+
+  return (0);
+}
+
+static void
+amapfree(struct amap *amp)
+{
+  int i;
+
+  free(amp->path);
+
+  free(amp->map);
+
+  for (i = 0; i < amp->mac; i++)
+    free((char *)amp->mav[i]);
+}
+
+static void
+read_master(void)
+{
+  FILE *fp;
+  char buf[BUFSIZ];
+  int lineno, noamaps;
+  struct amap oamaps[MAXAMAPS], *amp, *oamp;
+
+  if ((fp = fopen(masterfile, "r")) == NULL) {
+    fprintf(stderr, "%s[master]: can't open '%s'\n", program, masterfile);
+    exit(1);
+  }
+
+  /* save the old ones (if any) */
+  if ((noamaps = namaps) > 0)
+    memcpy(&oamaps[0], &amaps[0], namaps * sizeof (struct amap));
+
+  namaps = 0;
+
+  for (lineno = 1; fgets(buf, BUFSIZ, fp) != NULL; lineno++) {
+    char *p, *q;
+
+    /* kill comments and newline */
+    if ((p = strchr(buf, '#')) != NULL) *p = '\0';
+    if ((p = strrchr(buf, '\n')) != NULL) *p = '\0';
+
+    /* skip empty lines */
+    for (p = buf; *p != '\0' && isspace(*p); p++)
+      ;
+    if (*p == '\0')
+      continue;
+
+    if (namaps == MAXAMAPS) {
+      fprintf(stderr, "%s[master]: \"%s\", line %d: too many map entries\n",
+	program, masterfile, lineno);
+      break;
+    }
+    amp = &amaps[namaps];
+
+    /* grab path and map */
+    if ((p = strtok(p, " \t")) == NULL || \
+     (q = strtok(NULL, " \t")) == NULL) {
+      fprintf(stderr, "%s[master]: \"%s\", line %d: bogus map entry\n",
+	program, masterfile, lineno);
+      continue;
+    }
+    amp->path = xstrdup(p);
+    amp->map = xstrdup(q);
+
+    /* grab map args */
+    amp->mac = 0;
+    while ((p = strtok(NULL, " \t")) != NULL && amp->mac < MAXMARGS)
+      amp->mav[amp->mac++] = xstrdup(p);
+    if (p != NULL) {
+      amapfree(amp);
+      fprintf(stderr, "%s[master]: \"%s\", line %d: too many map args\n",
+	program, masterfile, lineno);
+      continue;
+    }
+    amp->mav[amp->mac] = NULL;
+
+    amp->pid = 0;
+    amp->running = 0;
+
+    /* this ones ok */
+    namaps++;
+  }
+
+  fclose(fp);
+
+  /* go through the old ones and kill any that have been changed/removed */
+  for (oamp = &oamaps[0]; oamp < &oamaps[noamaps]; oamp++) {
+
+    /* see if this entry is still there */
+    for (amp = &amaps[0]; amp < &amaps[namaps]; amp++)
+      if (amapcmp(amp, oamp) == 0)
+	break;
+
+    if (amp < &amaps[namaps]) {
+      /* yep it is, pass on the pid, running flag and last run time */
+      amp->pid = oamp->pid;
+      amp->running = oamp->running;
+      amp->lastrun = oamp->lastrun;
+    }
+    else {
+      /* not there anymore - kill it if needed */
+      if (oamp->running)
+	kill(oamp->pid, SIGTERM);
+    }
+
+    amapfree(oamp);
+  }
+}
+
+static void
+master_sigchld(int sig)
+{
+  pid_t pid;
+  int status;
+
+  while ((pid = waitpid((pid_t)-1, &status, WNOHANG)) > 0) {
+    struct amap *amp;
+
+    for (amp = &amaps[0]; amp < &amaps[namaps]; amp++)
+      if (pid == amp->pid) {
+	amp->running = 0;
+	break;
+      }
+  }
+
+  had_chld++;
+}
+
+static void
+master_sighup(int sig)
+{
+  had_hup++;
+}
+
+static void
+master_sigterm(int sig)
+{
+  had_term++;
+}
+
+static void
+master_sigalrm(int sig)
+{
+  alrm_isset = 0;
 }
 
 int main(int argc, char *argv[])
@@ -1250,6 +1460,7 @@
     {"timeout",  1, 0, 't'},
     {"version",  0, 0, 'v'},
     {"submount", 0, &submount, 1},
+    {"master",   0, &master, 1},
     {0,0,0,0}
   };
   
@@ -1285,6 +1496,111 @@
     fprintf(stderr, "%s: This program must be run by root.\n", program);
     exit(1);
   }
+
+if (master) {
+  sigset_t ss, ess, oss;
+  struct amap *amp;
+
+  if (argc - optind != 1 || \
+   strcmp(argv[optind - 1], "--master") != 0 || \
+   submount) {
+    usage();
+    exit(1);
+  }
+  masterfile = xstrdup(argv[optind]);
+
+  become_daemon(1);
+
+  sigemptyset(&ess);
+
+  /* block all the signals we are interested in */
+  sigemptyset(&ss);
+  sigaddset(&ss, SIGHUP);
+  sigaddset(&ss, SIGCHLD);
+  sigaddset(&ss, SIGALRM);
+  sigaddset(&ss, SIGTERM);
+  sigprocmask(SIG_BLOCK, &ss, &oss);
+
+  /* set up handlers for them */
+  sa.sa_handler = master_sighup; sa.sa_flags = 0; sa.sa_mask = ss;
+  sigaction(SIGHUP, &sa, NULL);
+
+  sa.sa_handler = master_sigchld; sa.sa_flags = SA_NOCLDSTOP; sa.sa_mask = ss;
+  sigaction(SIGCHLD, &sa, NULL);
+
+  sa.sa_handler = master_sigalrm; sa.sa_flags = 0; sa.sa_mask = ss;
+  sigaction(SIGALRM, &sa, NULL);
+
+  sa.sa_handler = master_sigterm; sa.sa_flags = 0; sa.sa_mask = ss;
+  sigaction(SIGTERM, &sa, NULL);
+
+  had_chld = had_term = alrm_isset = 0;
+  had_hup = 1;
+
+  do {
+    time_t now;
+
+    /* read the master map file if needed */
+    if (had_hup)
+      read_master();
+
+    now = time(0);
+
+    /* start any automounts that aren't running */
+    for (amp = &amaps[0]; amp < &amaps[namaps]; amp++)
+      if (!amp->running) {
+	unsigned long n = now - amp->lastrun;
+
+	/* don't try to start them again too quickly */
+	if (n < MINSPAWNTIME) {
+	  if (!alrm_isset) {
+	    alarm(MINSPAWNTIME - n + 1);
+	    alrm_isset = 1;
+	  }
+	  continue;
+	}
+
+	if ((amp->pid = become_daemon(0)) == 0) {
+	  char *p;
+	  int l;
+
+	  /* this is the child */
+
+	  p = argv[optind - 1]; l = strlen(p) - 1;
+	  strncpy(p, "--child", l); p[l] = '\0';
+	  p = argv[optind]; l = strlen(p) - 1;
+	  strncpy(p, amp->path, l); p[l] = '\0';
+
+	  path = amp->path;
+	  map = amp->map;
+	  mapargc = amp->mac;
+	  mapargv = amp->mav;
+
+	  alarm(0);
+	  sigprocmask(SIG_SETMASK, &oss, NULL);
+	  goto out;
+	}
+
+	if (amp->pid > 0)
+	  amp->running = 1;
+	amp->lastrun = now;
+      }
+
+    /* release all signals and wait for something to happen ... */
+    had_hup = had_chld = had_term = 0;
+    sigsuspend(&ess);
+
+  } while (!had_term);
+
+  /* kill off all running children */
+  for (amp = &amaps[0]; amp < &amaps[namaps]; amp++)
+    if (amp->running)
+      kill(amp->pid, SIGTERM);
+
+  /* we're done! */
+  exit(0);
+}
+else {
   
   /* Remove the options */
   argv += optind;
@@ -1295,12 +1611,15 @@
     exit(1);
   }
   
-  become_daemon();
+  become_daemon(-1);
   
   path    = argv[0];
   map     = argv[1];
   mapargv = (const char **) &argv[2];
   mapargc = argc-2;
+
+}
+out:
   
   syslog(LOG_INFO, "starting automounter version %s, path = %s, "
 	 "maptype = %s, mapname = %s", version, path, map,
--- man/Makefile-dist	Tue Apr 18 19:54:44 2000
+++ man/Makefile	Wed Jun  6 11:33:04 2001
@@ -13,7 +13,9 @@
 all: $(GENFILES)
 
 install: all
+	install -d -m 755 $(INSTALLROOT)$(mandir)/man5
 	install -c *.5 -m 644 $(INSTALLROOT)$(mandir)/man5
+	install -d -m 755 $(INSTALLROOT)$(mandir)/man8
 	install -c *.8 -m 644 $(INSTALLROOT)$(mandir)/man8
 
 clean:
--- modules/lookup_program.c-dist	Tue Apr 18 19:54:44 2000
+++ modules/lookup_program.c	Sun Sep 24 21:16:37 2000
@@ -143,6 +143,9 @@
 
   while (files_left != 0) {
     readfds = ourfds;
+#if !defined(OPEN_MAX) && defined(__linux__)
+#define OPEN_MAX 256
+#endif
     if ( select(OPEN_MAX, &readfds, NULL, NULL, NULL) < 0 && 
 	 errno != EINTR )
       break;
--- modules/parse_sun.c-dist	Tue Apr 18 19:54:44 2000
+++ modules/parse_sun.c	Wed May 15 12:19:57 2002
@@ -483,7 +483,7 @@
 	fstype = alloca(typelen+1);
 	memcpy(fstype, cp+7, typelen);
 	fstype[typelen] = '\0';
-      } else {
+      } else if (strcmp("grpid", cp) != 0) {
 	memcpy(np, cp, comma-cp+1);
 	np += comma-cp+1;
       }
--- samples/Makefile-dist	Tue Apr 18 19:54:44 2000
+++ samples/Makefile	Wed Jun  6 11:36:32 2001
@@ -9,11 +9,13 @@
 	rm -f rc.autofs
 
 install: all
+	install -d -m 755 $(INSTALLROOT)/etc
 	-mv -f $(INSTALLROOT)/etc/auto.master $(INSTALLROOT)/etc/auto.master.old
 	install -c auto.master -m 644 $(INSTALLROOT)/etc
 	-mv -f $(INSTALLROOT)/etc/auto.misc $(INSTALLROOT)/etc/auto.misc.old
 	install -c auto.misc   -m 644 $(INSTALLROOT)/etc
 	install -c auto.net    -m 755 $(INSTALLROOT)/etc
+	install -d -m 755 $(INSTALLROOT)$(initdir)
 	install -c rc.autofs   -m 755 $(INSTALLROOT)$(initdir)/autofs
 
 rc.autofs: rc.autofs.in
