diff -urN autofs-0.3.14/.version autofs-0.3.15-pre5/.version --- autofs-0.3.14/.version Sat Sep 20 18:38:50 1997 +++ autofs-0.3.15-pre5/.version Sat Mar 28 18:03:17 1998 @@ -1 +1 @@ -0.3.14 +0.3.15 diff -urN autofs-0.3.14/COPYRIGHT autofs-0.3.15-pre5/COPYRIGHT --- autofs-0.3.14/COPYRIGHT Sat Sep 20 18:38:50 1997 +++ autofs-0.3.15-pre5/COPYRIGHT Sat Mar 28 18:03:17 1998 @@ -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 -urN autofs-0.3.14/Makefile autofs-0.3.15-pre5/Makefile --- autofs-0.3.14/Makefile Sat Sep 20 18:38:50 1997 +++ autofs-0.3.15-pre5/Makefile Sat Mar 28 18:03:17 1998 @@ -1,7 +1,9 @@ -SUBDIRS = daemon modules man -INCDIRS = include samples -INCFILES = COPYING COPYRIGHT NEWS README TODO Makefile Makefile.rules \ - .version *.diff +# $Id: Makefile,v 1.4 1997/10/06 21:58:21 hpa Exp $ +# +# Main Makefile for the autofs user-space tools +# + +include Makefile.rules .PHONY: daemon all kernel clean install install_kernel mrproper .PHONY: distclean backup @@ -27,41 +29,9 @@ mrproper distclean: clean find . -noleaf \( -name '*~' -o -name '#*' -o -name '*.orig' -o -name '*.rej' -o -name '*.old' \) -print0 | xargs -0 rm -f +TODAY := $(shell date +'%Y%m%d') + backup: mrproper cd .. ; tar cf - autofs | gzip -9 > autofs-bu-$(TODAY).tar.gz - -RELEASE := $(shell cat .version) - -.PHONY: release newrelease - -reldir: - -rm -rf autofs-$(RELEASE) autofs-$(RELEASE).tar.gz - mkdir autofs-$(RELEASE) - cp -R $(SUBDIRS) $(INCDIRS) $(INCFILES) autofs-$(RELEASE) - $(MAKE) -C autofs-$(RELEASE) distclean - find autofs-$(RELEASE) -noleaf -name \*norel -print0 | xargs -0 rm -rf - -release: reldir - -rm -f .prerel .lastrel - cp .version .lastrel - tar cvvf - autofs-$(RELEASE) | gzip -9 > autofs-$(RELEASE).tar.gz - -since: - mv -f NEWS NEWS.old - echo 'Since autofs-$(RELEASE):' > NEWS - echo 'Since autofs-$(RELEASE):' | sed -e 's/./-/g' >> NEWS - echo '' >> NEWS - cat NEWS.old >> NEWS - -newrelease: clean since - echo `cut -d. -f1-2 < .version`.`expr \`cut -d. -f3 < .version\` + 1` \ - > .version - -newminorrelease: clean since - echo `cut -d. -f1 < .version`.`expr \`cut -d. -f2 < .version\` + 1`.0 \ - > .version - -newmajorrelease: clean since - echo `expr \`cut -d. -f1 < .version\` + 1`.0.0 > .version -include Makefile.private diff -urN autofs-0.3.14/Makefile.rules autofs-0.3.15-pre5/Makefile.rules --- autofs-0.3.14/Makefile.rules Sat Sep 20 18:38:50 1997 +++ autofs-0.3.15-pre5/Makefile.rules Sat Mar 28 18:03:17 1998 @@ -1,8 +1,36 @@ # -*- makefile -*- +# $Id: Makefile.rules,v 1.7 1998/03/29 02:02:55 hpa Exp $ # -# Makefile rules +# 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. +#LIBNSL = -lnsl +#LIBRESOLV = -lresolv + +# Uncomment these to build hesiod support. HESIOD should point to the +# hesiod base directory. +#HESIOD =/usr/athena +#HESIOD_LIBS = -L$(HESIOD)/lib -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 +INCFILES = COPYING COPYRIGHT NEWS README TODO Makefile Makefile.rules \ + .version + # Compilers, linkers and flags # The STRIP defined here *must not* remove any dynamic-loading symbols @@ -21,10 +49,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 -urN autofs-0.3.14/NEWS autofs-0.3.15-pre5/NEWS --- autofs-0.3.14/NEWS Sat Sep 20 18:38:50 1997 +++ autofs-0.3.15-pre5/NEWS Sat Mar 28 18:03:17 1998 @@ -1,3 +1,16 @@ +Since autofs-0.3.14: +-------------------- +* "const-ipated" the source at all module interface points, to keep me + from doing stupid things like calling strtok() on a string constant. +* 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. +* mount_ext2 module that runs e2fsck -p on the filesystem first. +* Recursive autofs mounts support by Richard Henderson. For + unmounting to work, kernel 2.1.92 or later is required. + Since autofs-0.3.13: -------------------- * Simplified the signalling/forking structure. diff -urN autofs-0.3.14/README autofs-0.3.15-pre5/README --- autofs-0.3.14/README Sat Sep 20 18:38:50 1997 +++ autofs-0.3.15-pre5/README Sat Mar 28 18:03:17 1998 @@ -1,3 +1,5 @@ +$Id: README,v 1.3 1998/03/27 04:23:26 hpa Exp $ + autofs is a kernel-based automounter for Linux. It is still under development, although it seems to be stabilizing relatively quickly. @@ -7,10 +9,16 @@ make ... make the daemon and modules make install ... install the daemon and modules +IMPORTANT: If you are building on a glibc system, or want to build +hesiod or NIS+ support, you *MUST* change the options at the top of +Makefile.rules. + The kernel code is no longer distributed with the autofs daemon; it is now only distributed with the kernel code. A diff is included for kernel version 2.0.30; autofs will be included directly into 2.0.31 -when that version is released. +when that version is released. The kernel source code for the 2.0 and +2.1 kernels are now dissociated; the 2.1 VFS has diverged so +drastically that keeping the code synchronized is no longer a possibility. autofs was written by H. Peter Anvin of Transmeta Corporation, see the COPYRIGHT file. diff -urN autofs-0.3.14/TODO autofs-0.3.15-pre5/TODO --- autofs-0.3.14/TODO Sat Sep 20 18:38:50 1997 +++ autofs-0.3.15-pre5/TODO Sat Mar 28 18:03:17 1998 @@ -1,14 +1,16 @@ -autofs TODO list ----------------- +autofs v3 TODO list +------------------- +* Additional lookup modules: [ng]dbm, db/hash... +* Document the intermodule interface. +* Use autoconf to set all the bloody options. + +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 -urN autofs-0.3.14/daemon/Makefile autofs-0.3.15-pre5/daemon/Makefile --- autofs-0.3.14/daemon/Makefile Sat Sep 20 18:38:49 1997 +++ autofs-0.3.15-pre5/daemon/Makefile Sat Mar 28 18:03:16 1998 @@ -1,3 +1,4 @@ +# $Id: Makefile,v 1.2 1997/10/06 21:44:06 hpa Exp $ # # Makefile for autofs # diff -urN autofs-0.3.14/daemon/automount.c autofs-0.3.15-pre5/daemon/automount.c --- autofs-0.3.14/daemon/automount.c Sat Sep 20 18:38:49 1997 +++ autofs-0.3.15-pre5/daemon/automount.c Sat Mar 28 18:03:16 1998 @@ -1,3 +1,4 @@ +#ident "$Id: automount.c,v 1.4 1998/03/27 06:14:10 hpa Exp $" /* ----------------------------------------------------------------------- * * * automount.c - Linux automounter daemon @@ -48,6 +49,7 @@ int kproto_version; /* Kernel protocol version used */ static int mounted = 0; +static int submount = 0; struct pending_mount { pid_t pid; /* Which process is mounting for us */ @@ -72,6 +74,9 @@ #define DEFAULT_TIMEOUT (5*60) /* 5 minutes */ #define CHECK_RATIO 4 /* exp_runfreq = exp_timeout/CHECK_RATIO */ +static void cleanup_exit(int exit_code); + + static int umount_ent(char *root, char *name) { char path_buf[PATH_MAX]; @@ -131,16 +136,10 @@ return left; } -static int umount_autofs(int force) +static int do_umount_autofs(void) { int rv; - if ( !mounted ) - return -1; - - if ( umount_all(force) && !force ) - return -1; - if (ap.ioctlfd >= 0) { ioctl(ap.ioctlfd, AUTOFS_IOC_CATATONIC, 0); close(ap.ioctlfd); @@ -148,11 +147,63 @@ if (ap.pipefd >= 0) close(ap.pipefd); rv = spawnl(LOG_ERR, _PATH_UMOUNT, _PATH_UMOUNT, ap.path, NULL); + if (rv == 0 && submount) + rmdir(ap.path); + free(ap.path); mounted = 0; return rv; } +static int umount_autofs(int force) +{ + if ( !mounted ) + return -1; + if ( umount_all(force) && !force ) + return -1; + return do_umount_autofs(); +} + +static void maybe_umount_autofs_and_exit(void) +{ + char path_buf[PATH_MAX]; + struct stat st; + struct dirent *de; + DIR *dp; + int left; + + /* If we are expiring, wait til next round to exit. */ + if ( ap.exp_process ) + return; + + chdir("/"); + + dp = opendir(ap.path); + if ( !dp ) { + syslog(LOG_ERR, "maybe_umount_autofs: opendir: %m"); + return; + } + + left = 0; + while ( (de = readdir(dp)) != NULL ) { + if ( strcmp(de->d_name,".") && strcmp(de->d_name,"..") ) { + sprintf(path_buf, "%s/%s", ap.path, de->d_name); + if ( !lstat(path_buf,&st) ) { + if ( S_ISDIR(st.st_mode) ) { + if ( st.st_dev != ap.dev ) + left++; + } + } + } + } + closedir(dp); + + if (!left) { + if (do_umount_autofs() == 0) + cleanup_exit(0); + } +} + static int mount_autofs(char *path) { int pipefd[2]; @@ -218,15 +269,20 @@ static void run_expire(void) { - pid_t f; struct autofs_packet_expire pkt; sigset_t s, olds; + pid_t f; if ( ap.exp_process ) /* Another process is already expiring */ return; /* Try again next interval */ - if ( ioctl(ap.ioctlfd, AUTOFS_IOC_EXPIRE, &pkt) ) - return; /* Don't fork if there is nothing do expire */ + if ( ioctl(ap.ioctlfd, AUTOFS_IOC_EXPIRE, &pkt) ) { + /* Don't fork if there is nothing do expire, but if we are a submount, + see if maybe we shouldn't exit. */ + if (submount) + maybe_umount_autofs_and_exit(); + return; + } /* Temporarily block SIGCHLD and SIGALRM between forking and setting ap.exp_process */ @@ -251,7 +307,7 @@ close(ap.pipefd); syslog(LOG_DEBUG, "running expiration on path %s", ap.path); - + do { if ( pkt.hdr.type == autofs_ptype_expire ) { if ( !umount_ent(ap.path,pkt.name) ) @@ -414,6 +470,8 @@ while ( (pid = waitpid(-1, &status, WNOHANG)) > 0 ) { if ( pid == ap.exp_process ) { ap.exp_process = 0; + if (submount) + maybe_umount_autofs_and_exit(); } else { for ( mtp = &ap.mounts ; (mt = *mtp) ; mtp = &mt->next ) { if ( mt->pid == pid ) { @@ -443,37 +501,36 @@ int nullfd; /* Don't BUSY any directories unneccessarily */ - chdir("/"); /* Detach from foreground process */ - - pid = fork(); - if ( pid > 0 ) - exit(0); - else if ( pid < 0 ) { - fprintf(stderr, "%s: Could not detach process\n", program); - exit(1); + if ( !submount ) { + pid = fork(); + if ( pid > 0 ) + exit(0); + else if ( pid < 0 ) { + fprintf(stderr, "%s: Could not detach process\n", program); + exit(1); + } } /* Open syslog */ - openlog("automount", LOG_PID, LOG_DAEMON); /* Initialize global data */ - my_pid = getpid(); - /* Make our own process group for "magic" reason */ - - if ( setpgrp() ) { + /* Make our own process group for "magic" reason: processes that share + our pgrp see the raw filesystem behine the magic. So if we are a + submount, don't change -- otherwise we won't be able to actually + perform the mount. */ + if ( !submount && setpgrp() ) { syslog(LOG_CRIT, "setpgrp: %m"); exit(1); } my_pgrp = getpgrp(); - - /* Redirect all our file descriptors to /dev/null */ + /* Redirect all our file descriptors to /dev/null */ if ( (nullfd = open("/dev/null", O_RDWR)) < 0 ) { syslog(LOG_CRIT, "cannot open /dev/null: %m"); exit(1); @@ -488,7 +545,6 @@ close(nullfd); /* Write pid file if requested */ - if ( pid_file ) { if ( (pidfp = fopen(pid_file, "wt")) ) { fprintf(pidfp, "%lu\n", (unsigned long) my_pid); @@ -538,7 +594,8 @@ int main(int argc, char *argv[]) { - char *path, *map, *mapfmt, **mapargv; + char *path, *map, *mapfmt; + const char **mapargv; struct sigaction sa; int mapargc, opt; static const struct option long_options[] = { @@ -546,6 +603,7 @@ {"pid-file", 1, 0, 'p'}, {"timeout", 1, 0, 't'}, {"version", 0, 0, 'v'}, + {"submount", 0, &submount, 1}, {0,0,0,0} }; @@ -595,7 +653,7 @@ path = argv[0]; map = argv[1]; - mapargv = &argv[2]; + mapargv = (const char **) &argv[2]; mapargc = argc-2; syslog(LOG_INFO, "starting automounter version %s, path = %s, " @@ -619,7 +677,7 @@ syslog(LOG_CRIT, "%s: mount failed!", path); cleanup_exit(1); } - + /* The following signals cause a shutdown event to occur */ sa.sa_handler = sig_shutdown; sigemptyset(&sa.sa_mask); @@ -721,6 +779,11 @@ if ( ap.exp_timeout ) alarm(ap.exp_timeout + my_pid % ap.exp_runfreq); } + + /* Initialization successful. If we're a submount, send outself SIGSTOP to let + our parent know that we have grown up and don't need supervision anymore. */ + if ( submount ) + kill(my_pid, SIGSTOP); while ( !shutdown ) { if (handle_packet() && errno != EINTR) diff -urN autofs-0.3.14/daemon/module.c autofs-0.3.15-pre5/daemon/module.c --- autofs-0.3.14/daemon/module.c Sat Sep 20 18:38:49 1997 +++ autofs-0.3.15-pre5/daemon/module.c Sat Mar 28 18:03:16 1998 @@ -1,8 +1,17 @@ -/* - * module.c +#ident "$Id: module.c,v 1.2 1997/10/06 21:44:07 hpa Exp $" +/* ----------------------------------------------------------------------- * * - * Common module-management functions - */ + * module.c - common module-management functions + * + * Copyright 1997 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 + * the Free Software Foundation, Inc., 675 Mass Ave, Cambridge MA 02139, + * USA; either version 2 of the License, or (at your option) any later + * version; incorporated herein by reference. + * + * ----------------------------------------------------------------------- */ #include #include @@ -11,8 +20,9 @@ #include #include "automount.h" -struct lookup_mod *open_lookup(char *name, char *err_prefix, - char *mapfmt, int argc, char **argv) +struct lookup_mod *open_lookup(const char *name, const char *err_prefix, + const char *mapfmt, + int argc, const char * const *argv) { struct lookup_mod *mod; char *fnbuf; @@ -76,8 +86,8 @@ return rv; } -struct parse_mod *open_parse(char *name, char *err_prefix, - int argc, char **argv) +struct parse_mod *open_parse(const char *name, const char *err_prefix, + int argc, const char * const *argv) { struct parse_mod *mod; char *fnbuf; @@ -141,7 +151,7 @@ return rv; } -struct mount_mod *open_mount(char *name, char *err_prefix) +struct mount_mod *open_mount(const char *name, const char *err_prefix) { struct mount_mod *mod; char *fnbuf; diff -urN autofs-0.3.14/daemon/mount.c autofs-0.3.15-pre5/daemon/mount.c --- autofs-0.3.14/daemon/mount.c Sat Sep 20 18:38:49 1997 +++ autofs-0.3.15-pre5/daemon/mount.c Sat Mar 28 18:03:16 1998 @@ -1,3 +1,4 @@ +#ident "$Id: mount.c,v 1.3 1998/03/27 04:15:48 hpa Exp $" /* ----------------------------------------------------------------------- * * * mount.c - Abstract mount code used by modules for an unexpected @@ -23,14 +24,15 @@ #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(char *root, char *name, int name_len, char *what, char *fstype, - char *options) +int do_mount(const char *root, const char *name, int name_len, + const char *what, const char *fstype, const char *options) { struct mount_mod *mod; - char **ngp, *modstr; + const char *modstr; + char **ngp; int rv; mod = open_mount(modstr = fstype, NULL); diff -urN autofs-0.3.14/daemon/spawn.c autofs-0.3.15-pre5/daemon/spawn.c --- autofs-0.3.14/daemon/spawn.c Sat Sep 20 18:38:49 1997 +++ autofs-0.3.15-pre5/daemon/spawn.c Sat Mar 28 18:03:16 1998 @@ -1,6 +1,7 @@ +#ident "$Id: spawn.c,v 1.2 1997/10/06 21:44:07 hpa Exp $" /* ----------------------------------------------------------------------- * * - * spawn.c - run programs synchronously with output redirected to syslog + * spawn.c - run programs synchronously with output redirected to syslog * * Copyright 1997 Transmeta Corporation - All Rights Reserved * @@ -47,7 +48,7 @@ #define ERRBUFSIZ 2047 /* Max length of error string excl \0 */ -int spawnv(int logpri, char *prog, char **argv) { +int spawnv(int logpri, const char *prog, const char * const *argv) { pid_t f; int status, pipefd[2]; char errbuf[ERRBUFSIZ+1], *p, *sp; @@ -70,7 +71,7 @@ dup2(pipefd[1], STDOUT_FILENO); dup2(pipefd[1], STDERR_FILENO); close(pipefd[1]); - execv(prog, argv); + execv(prog, (char * const *)argv); _exit(255); /* execv() failed */ } else { /* Careful here -- if we enable SIGCHLD yet we may not receive the @@ -133,7 +134,7 @@ } } -int spawnl(int logpri, char *prog, ...) +int spawnl(int logpri, const char *prog, ...) { va_list arg; int argc; @@ -151,6 +152,6 @@ while ((*p++ = va_arg(arg,char *))); va_end(arg); - return spawnv(logpri, prog, argv); + return spawnv(logpri, prog, (const char **)argv); } diff -urN autofs-0.3.14/include/automount.h autofs-0.3.15-pre5/include/automount.h --- autofs-0.3.14/include/automount.h Sat Sep 20 18:38:50 1997 +++ autofs-0.3.15-pre5/include/automount.h Sat Mar 28 18:03:17 1998 @@ -1,3 +1,4 @@ +#ident "$Id: automount.h,v 1.5 1998/03/27 05:37:44 hpa Exp $" /* * automount.h * @@ -13,23 +14,31 @@ #ifndef _PATH_MOUNT #define _PATH_MOUNT "/bin/mount" #endif + #ifndef _PATH_UMOUNT #define _PATH_UMOUNT "/bin/umount" #endif +#ifndef _PATH_AUTOMOUNT +#define _PATH_AUTOMOUNT "/usr/sbin/automount" +#endif -/* If smbmount is unavailable, remote the mount_smbfs module from - modules/Makefile */ +#ifndef _PATH_E2FSCK +#define _PATH_E2FSCK "/sbin/fsck.ext2" +#endif +/* If smbmount is unavailable, remove the mount_smbfs module from + modules/Makefile */ #ifndef _PATH_SMBMOUNT #define _PATH_SMBMOUNT "/usr/bin/smbmount" #endif /* Standard function used by daemon or modules */ -int spawnl(int, char *, ...); -int spawnv(int, char *, char **); +int spawnl(int logpri, const char *prog, ...); +int spawnv(int logpri, const char *prog, const char * const *argv); void reset_signals(void); -int do_mount(char *, char *, int, char *, char *, char *); +int do_mount(const char *root, const char *name, int name_len, + const char *what, const char *fstype, const char *options); /* Prototype for module functions */ @@ -38,13 +47,14 @@ #define AUTOFS_LOOKUP_VERSION 4 #ifdef MODULE_LOOKUP -int lookup_init(char *, int, char **, void **); -int lookup_mount(char *, char *, int, void *); +int lookup_init(const char *mapfmt, int argc, const char * const *argv, + void **context); +int lookup_mount(const char *, const char *, int, void *); int lookup_done(void *); #endif -typedef (*lookup_init_t)(char *, int, char **, void **); -typedef (*lookup_mount_t)(char *, 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; @@ -52,7 +62,9 @@ void *dlhandle; void *context; }; -struct lookup_mod *open_lookup(char *, char *, char *, int, char **); +struct lookup_mod *open_lookup(const char *name, const char *err_prefix, + const char *mapfmt, + int argc, const char * const *argv); int close_lookup(struct lookup_mod *); /* parse module */ @@ -60,13 +72,14 @@ #define AUTOFS_PARSE_VERSION 3 #ifdef MODULE_PARSE -int parse_init(int, char **, void **); -int parse_mount(char *, char *, int, char *, void *); +int parse_init(int argc, const char * const *argv, void **context); +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, char **, void **); -typedef (*parse_mount_t)(char *, char *, int, 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; @@ -74,7 +87,8 @@ void *dlhandle; void *context; }; -struct parse_mod *open_parse(char *, char *, int, char **); +struct parse_mod *open_parse(const char *name, const char *err_prefix, + int argc, const char * const *argv); int close_parse(struct parse_mod *); /* mount module */ @@ -82,13 +96,15 @@ #define AUTOFS_MOUNT_VERSION 4 #ifdef MODULE_MOUNT -int mount_init(void **); -int mount_mount(char *, char *, int, char *, char *, char *, void *); -int mount_done(void *); -#endif -typedef (*mount_init_t)(void **); -typedef (*mount_mount_t)(char *, char *, int, char *, char *, char *, void *); -typedef (*mount_done_t)(void *); +int mount_init(void **context); +int mount_mount(const char *root, const char *name, int name_len, + const char *what, const char *fstype, const char *options, + void *context); +int mount_done(void *context); +#endif +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; @@ -96,9 +112,8 @@ void *dlhandle; void *context; }; -struct mount_mod *open_mount(char *, char *); +struct mount_mod *open_mount(const char *name, const char *err_prefix); int close_mount(struct mount_mod *); #endif /* AUTOMOUNT_H */ - diff -urN autofs-0.3.14/include/linux/auto_fs.h autofs-0.3.15-pre5/include/linux/auto_fs.h --- autofs-0.3.14/include/linux/auto_fs.h Sat Sep 20 18:38:50 1997 +++ autofs-0.3.15-pre5/include/linux/auto_fs.h Sat Mar 28 18:03:17 1998 @@ -1,3 +1,4 @@ +#ident "$Id: auto_fs.h,v 1.2 1997/10/06 21:52:01 hpa Exp $" /* -*- linux-c -*- ------------------------------------------------------- * * * linux/include/linux/auto_fs.h diff -urN autofs-0.3.14/kernel-2.0.30.diff autofs-0.3.15-pre5/kernel-2.0.30.diff --- autofs-0.3.14/kernel-2.0.30.diff Sat Sep 20 18:38:50 1997 +++ autofs-0.3.15-pre5/kernel-2.0.30.diff Wed Dec 31 16:00:00 1969 @@ -1,1816 +0,0 @@ -diff -urN 2.0.30/linux/Documentation/Configure.help linux/Documentation/Configure.help ---- 2.0.30/linux/Documentation/Configure.help Tue Apr 8 08:47:45 1997 -+++ linux/Documentation/Configure.help Thu May 1 12:35:18 1997 -@@ -3112,6 +3112,17 @@ - Documentation/modules.txt. If you haven't heard about all of this - before, it's safe to say N. - -+Kernel automounter support (experimental) -+CONFIG_AUTOFS_FS -+ The automounter is a tool to automatically mount remote filesystems -+ on demand. This implementation is partially kernel-based to reduce -+ overhead in the already-mounted case; this is unlike the BSD -+ automounter (amd), which is only in user space. To use the -+ automounter you also need the user-space tools from -+ ftp.kernel.org:/pub/linux/daemons/autofs. If you are not a part of -+ a fairly large, distributed network, you probably do not need an -+ automounter, and can say N here. -+ - BSD UFS filesystem support (read only) - CONFIG_UFS_FS - BSD and derivate versions of Unix (such as SunOS, FreeBSD, NetBSD -diff -urN 2.0.30/linux/MAINTAINERS linux/MAINTAINERS ---- 2.0.30/linux/MAINTAINERS Tue Apr 8 08:47:45 1997 -+++ linux/MAINTAINERS Thu May 1 12:35:18 1997 -@@ -363,6 +363,18 @@ - M: jam@acm.org - S: Maintained - -+KERNEL AUTOMOUNTER (AUTOFS) -+P: H. Peter Anvin -+M: hpa@zytor.com -+L: autofs@linux.kernel.org -+S: Maintained -+ -+DEVICE NUMBER REGISTRY -+P: H. Peter Anvin -+M: hpa@zytor.com -+L: linux-kernel@vger.rutgers.edu -+S: Maintained -+ - REST: - P: Linus Torvalds - S: Buried alive in email -diff -urN 2.0.30/linux/arch/alpha/defconfig linux/arch/alpha/defconfig ---- 2.0.30/linux/arch/alpha/defconfig Tue Oct 29 17:42:40 1996 -+++ linux/arch/alpha/defconfig Thu May 1 12:35:18 1997 -@@ -196,6 +196,7 @@ - # CONFIG_HPFS_FS is not set - # CONFIG_SYSV_FS is not set - # CONFIG_UFS_FS is not set -+# CONFIG_AUTOFS_FS is not set - - # - # Character devices -diff -urN 2.0.30/linux/arch/i386/defconfig linux/arch/i386/defconfig ---- 2.0.30/linux/arch/i386/defconfig Tue Oct 29 17:42:40 1996 -+++ linux/arch/i386/defconfig Thu May 1 12:35:18 1997 -@@ -146,6 +146,7 @@ - # CONFIG_HPFS_FS is not set - # CONFIG_SYSV_FS is not set - # CONFIG_UFS_FS is not set -+# CONFIG_AUTOFS_FS is not set - - # - # Character devices -diff -urN 2.0.30/linux/arch/m68k/defconfig linux/arch/m68k/defconfig ---- 2.0.30/linux/arch/m68k/defconfig Mon May 6 02:44:30 1996 -+++ linux/arch/m68k/defconfig Thu May 1 12:35:18 1997 -@@ -122,6 +122,7 @@ - # CONFIG_ISO9660_FS is not set - # CONFIG_HPFS_FS is not set - # CONFIG_SYSV_FS is not set -+# CONFIG_AUTOFS_FS is not set - # CONFIG_AFFS_FS is not set - # CONFIG_UFS_FS is not set - -diff -urN 2.0.30/linux/arch/mips/defconfig linux/arch/mips/defconfig ---- 2.0.30/linux/arch/mips/defconfig Wed Feb 7 19:41:50 1996 -+++ linux/arch/mips/defconfig Thu May 1 12:35:18 1997 -@@ -61,6 +61,7 @@ - # CONFIG_ISO9660_FS is not set - # CONFIG_HPFS_FS is not set - # CONFIG_SYSV_FS is not set -+# CONFIG_AUTOFS_FS is not set - # CONFIG_SMB_FS is not set - - # -diff -urN 2.0.30/linux/arch/sparc/defconfig linux/arch/sparc/defconfig ---- 2.0.30/linux/arch/sparc/defconfig Thu Apr 25 03:22:05 1996 -+++ linux/arch/sparc/defconfig Thu May 1 12:35:18 1997 -@@ -114,6 +114,7 @@ - # CONFIG_HPFS_FS is not set - # CONFIG_SYSV_FS is not set - # CONFIG_AFFS_FS is not set -+# CONFIG_AUTOFS_FS is not set - CONFIG_UFS_FS=y - - # -diff -urN 2.0.30/linux/drivers/sound/Config.in linux/drivers/sound/Config.in ---- 2.0.30/linux/drivers/sound/Config.in Wed Jul 10 04:34:03 1996 -+++ linux/drivers/sound/Config.in Fri May 2 11:33:47 1997 -@@ -2,10 +2,10 @@ - # Sound driver configuration - # - #-------- --# There is another confic script which is compatible with rest of -+# There is another config script which is compatible with rest of - # the kernel. It can be activated by running 'make mkscript' in this - # directory. Please note that this is an _experimental_ feature which --# doesn't work with all cards (PSS, SM Wave, AudioTriX Pro, Maui). -+# doesn't work with all cards (PSS, SM Wave, AudioTrix Pro, Maui). - #-------- - # - $MAKE -C drivers/sound config || exit 1 -diff -urN 2.0.30/linux/fs/Config.in linux/fs/Config.in ---- 2.0.30/linux/fs/Config.in Sun Dec 1 05:58:05 1996 -+++ linux/fs/Config.in Thu May 1 12:35:18 1997 -@@ -39,6 +39,9 @@ - tristate 'OS/2 HPFS filesystem support (read only)' CONFIG_HPFS_FS - tristate 'System V and Coherent filesystem support' CONFIG_SYSV_FS - if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then -+ tristate 'Kernel automounter support (experimental)' CONFIG_AUTOFS_FS -+fi -+if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then - tristate 'Amiga FFS filesystem support (EXPERIMENTAL)' CONFIG_AFFS_FS - if [ "$CONFIG_AFFS_FS" != "n" ]; then - define_bool CONFIG_AMIGA_PARTITION y -diff -urN 2.0.30/linux/fs/Makefile linux/fs/Makefile ---- 2.0.30/linux/fs/Makefile Wed May 8 08:28:01 1996 -+++ linux/fs/Makefile Thu May 1 12:35:18 1997 -@@ -17,7 +17,7 @@ - - MOD_LIST_NAME := FS_MODULES - ALL_SUB_DIRS = minix ext ext2 fat msdos vfat proc isofs nfs xiafs umsdos \ -- hpfs sysv smbfs ncpfs ufs affs -+ hpfs sysv smbfs ncpfs ufs affs autofs - - ifeq ($(CONFIG_QUOTA),y) - O_OBJS += dquot.o -@@ -154,6 +154,14 @@ - else - ifeq ($(CONFIG_AFFS_FS),m) - MOD_SUB_DIRS += affs -+ endif -+endif -+ -+ifeq ($(CONFIG_AUTOFS_FS),y) -+SUB_DIRS += autofs -+else -+ ifeq ($(CONFIG_AUTOFS_FS),m) -+ MOD_SUB_DIRS += autofs - endif - endif - -diff -urN 2.0.30/linux/fs/autofs/Makefile linux/fs/autofs/Makefile ---- 2.0.30/linux/fs/autofs/Makefile Wed Dec 31 16:00:00 1969 -+++ linux/fs/autofs/Makefile Wed May 28 21:38:35 1997 -@@ -0,0 +1,35 @@ -+# -+# Makefile for the linux autofs-filesystem routines. -+# -+# We can build this either out of the kernel tree or the autofs tools tree. -+# -+ -+O_TARGET := autofs.o -+O_OBJS := dir.o dirhash.o init.o inode.o root.o symlink.o waitq.o -+ -+M_OBJS := $(O_TARGET) -+ -+ifdef TOPDIR -+# -+# Part of the kernel code -+# -+include $(TOPDIR)/Rules.make -+else -+# -+# Standalone (handy for development) -+# -+include ../Makefile.rules -+ -+CFLAGS += -D__KERNEL__ -DMODULE $(KFLAGS) -I../include -I$(KINCLUDE) $(MODFLAGS) -+ -+all: $(O_TARGET) -+ -+$(O_TARGET): $(O_OBJS) -+ $(LD) -r -o $(O_TARGET) $(O_OBJS) -+ -+install: $(O_TARGET) -+ install -c $(O_TARGET) /lib/modules/`uname -r`/fs -+ -+clean: -+ rm -f *.o *.s -+endif -diff -urN 2.0.30/linux/fs/autofs/autofs_i.h linux/fs/autofs/autofs_i.h ---- 2.0.30/linux/fs/autofs/autofs_i.h Wed Dec 31 16:00:00 1969 -+++ linux/fs/autofs/autofs_i.h Wed May 28 21:38:35 1997 -@@ -0,0 +1,187 @@ -+/* -*- linux-c -*- ------------------------------------------------------- * -+ * -+ * linux/fs/autofs/autofs_i.h -+ * -+ * Copyright 1997 Transmeta Corporation - All Rights Reserved -+ * -+ * This file is part of the Linux kernel and is made available under -+ * the terms of the GNU General Public License, version 2, or at your -+ * option, any later version, incorporated herein by reference. -+ * -+ * ----------------------------------------------------------------------- */ -+ -+/* Internal header file for autofs */ -+ -+#include -+ -+/* This is the range of ioctl() numbers we claim as ours */ -+#define AUTOFS_IOC_FIRST AUTOFS_IOC_READY -+#define AUTOFS_IOC_COUNT 32 -+ -+#include -+#include -+#include -+#include -+#include -+ -+#define kver(a,b,c) (((a) << 16) + ((b) << 8) + (c)) -+ -+#if LINUX_VERSION_CODE < kver(2,1,0) -+ -+/* Segmentation stuff for pre-2.1 kernels */ -+#include -+ -+static inline int copy_to_user(void *dst, void *src, unsigned long len) -+{ -+ int rv = verify_area(VERIFY_WRITE, dst, len); -+ if ( rv ) -+ return -1; -+ memcpy_tofs(dst,src,len); -+ return 0; -+} -+ -+static inline int copy_from_user(void *dst, void *src, unsigned long len) -+{ -+ int rv = verify_area(VERIFY_READ, src, len); -+ if ( rv ) -+ return -1; -+ memcpy_fromfs(dst,src,len); -+ return 0; -+} -+ -+#else -+ -+/* Segmentation stuff for post-2.1 kernels */ -+#include -+#define register_symtab(x) ((void)0) -+ -+#endif -+ -+#ifdef DEBUG -+#define DPRINTK(D) printk D; -+#else -+#define DPRINTK(D) -+#endif -+ -+#define AUTOFS_SUPER_MAGIC 0x0187 -+ -+/* Structures associated with the root directory hash */ -+ -+#define AUTOFS_HASH_SIZE 67 -+ -+typedef u32 autofs_hash_t; /* Type returned by autofs_hash() */ -+ -+struct autofs_dir_ent { -+ autofs_hash_t hash; -+ struct autofs_dir_ent *next; -+ struct autofs_dir_ent **back; -+ char *name; -+ int len; -+ ino_t ino; -+ /* The following entries are for the expiry system */ -+ unsigned long last_usage; -+ struct autofs_dir_ent *exp_next; -+ struct autofs_dir_ent *exp_prev; -+}; -+ -+struct autofs_dirhash { -+ struct autofs_dir_ent *h[AUTOFS_HASH_SIZE]; -+ struct autofs_dir_ent expiry_head; -+}; -+ -+struct autofs_wait_queue { -+ unsigned long wait_queue_token; -+ struct wait_queue *queue; -+ struct autofs_wait_queue *next; -+ /* We use the following to see what we are waiting for */ -+ autofs_hash_t hash; -+ int len; -+ char *name; -+ /* This is for status reporting upon return */ -+ int status; -+ int wait_ctr; -+}; -+ -+struct autofs_symlink { -+ int len; -+ char *data; -+ time_t mtime; -+}; -+ -+#define AUTOFS_MAX_SYMLINKS 256 -+ -+#define AUTOFS_ROOT_INO 1 -+#define AUTOFS_FIRST_SYMLINK 2 -+#define AUTOFS_FIRST_DIR_INO (AUTOFS_FIRST_SYMLINK+AUTOFS_MAX_SYMLINKS) -+ -+#define AUTOFS_SYMLINK_BITMAP_LEN ((AUTOFS_MAX_SYMLINKS+31)/32) -+ -+#ifndef END_OF_TIME -+#define END_OF_TIME ((time_t)((unsigned long)((time_t)(~0UL)) >> 1)) -+#endif -+ -+#define AUTOFS_SBI_MAGIC 0x6d4a556d -+ -+struct autofs_sb_info { -+ u32 magic; -+ struct file *pipe; -+ pid_t oz_pgrp; -+ int catatonic; -+ unsigned long exp_timeout; -+ ino_t next_dir_ino; -+ struct autofs_wait_queue *queues; /* Wait queue pointer */ -+ struct autofs_dirhash dirhash; /* Root directory hash */ -+ struct autofs_symlink symlink[AUTOFS_MAX_SYMLINKS]; -+ u32 symlink_bitmap[AUTOFS_SYMLINK_BITMAP_LEN]; -+}; -+ -+/* autofs_oz_mode(): do we see the man behind the curtain? */ -+static inline int autofs_oz_mode(struct autofs_sb_info *sbi) { -+ return sbi->catatonic || current->pgrp == sbi->oz_pgrp; -+} -+ -+/* Debug the mysteriously disappearing wait list */ -+ -+#ifdef DEBUG_WAITLIST -+#define CHECK_WAITLIST(S,O) autofs_check_waitlist_integrity(S,O) -+void autofs_check_waitlist_integrity(struct autofs_sb_info *,char *); -+#else -+#define CHECK_WAITLIST(S,O) -+#endif -+ -+/* Hash operations */ -+ -+autofs_hash_t autofs_hash(const char *,int); -+void autofs_initialize_hash(struct autofs_dirhash *); -+struct autofs_dir_ent *autofs_hash_lookup(const struct autofs_dirhash *,autofs_hash_t,const char *,int); -+void autofs_hash_insert(struct autofs_dirhash *,struct autofs_dir_ent *); -+void autofs_hash_delete(struct autofs_dir_ent *); -+struct autofs_dir_ent *autofs_hash_enum(const struct autofs_dirhash *,off_t *); -+void autofs_hash_nuke(struct autofs_dirhash *); -+ -+/* Expiration-handling functions */ -+ -+void autofs_update_usage(struct autofs_dirhash *,struct autofs_dir_ent *); -+struct autofs_dir_ent *autofs_expire(struct autofs_dirhash *,unsigned long); -+ -+/* Operations structures */ -+ -+extern struct inode_operations autofs_root_inode_operations; -+extern struct inode_operations autofs_symlink_inode_operations; -+extern struct inode_operations autofs_dir_inode_operations; -+ -+/* Initializing function */ -+ -+struct super_block *autofs_read_super(struct super_block *, void *,int); -+ -+/* Queue management functions */ -+ -+int autofs_wait(struct autofs_sb_info *,autofs_hash_t,const char *,int); -+int autofs_wait_release(struct autofs_sb_info *,unsigned long,int); -+void autofs_catatonic_mode(struct autofs_sb_info *); -+ -+#ifdef DEBUG -+void autofs_say(const char *name, int len); -+#else -+#define autofs_say(n,l) -+#endif -diff -urN 2.0.30/linux/fs/autofs/dir.c linux/fs/autofs/dir.c ---- 2.0.30/linux/fs/autofs/dir.c Wed Dec 31 16:00:00 1969 -+++ linux/fs/autofs/dir.c Wed May 28 21:38:35 1997 -@@ -0,0 +1,90 @@ -+/* -*- linux-c -*- --------------------------------------------------------- * -+ * -+ * linux/fs/autofs/dir.c -+ * -+ * Copyright 1997 Transmeta Corporation -- All Rights Reserved -+ * -+ * This file is part of the Linux kernel and is made available under -+ * the terms of the GNU General Public License, version 2, or at your -+ * option, any later version, incorporated herein by reference. -+ * -+ * ------------------------------------------------------------------------- */ -+ -+#include "autofs_i.h" -+ -+static int autofs_dir_readdir(struct inode *inode, struct file *filp, -+ void *dirent, filldir_t filldir) -+{ -+ if (!inode || !S_ISDIR(inode->i_mode)) -+ return -ENOTDIR; -+ -+ switch((unsigned long) filp->f_pos) -+ { -+ case 0: -+ if (filldir(dirent, ".", 1, 0, inode->i_ino) < 0) -+ return 0; -+ filp->f_pos++; -+ /* fall through */ -+ case 1: -+ if (filldir(dirent, "..", 2, 1, AUTOFS_ROOT_INO) < 0) -+ return 0; -+ filp->f_pos++; -+ /* fall through */ -+ } -+ return 1; -+} -+ -+static int autofs_dir_lookup(struct inode *dir, const char *name, int len, -+ struct inode **result) -+{ -+ *result = dir; -+ if (!len) -+ return 0; -+ if (name[0] == '.') { -+ if (len == 1) -+ return 0; -+ if (name[1] == '.' && len == 2) { -+ /* Return the root directory */ -+ *result = iget(dir->i_sb,AUTOFS_ROOT_INO); -+ iput(dir); -+ return 0; -+ } -+ } -+ *result = NULL; -+ iput(dir); -+ return -ENOENT; /* No other entries */ -+} -+ -+static struct file_operations autofs_dir_operations = { -+ NULL, /* lseek */ -+ NULL, /* read */ -+ NULL, /* write */ -+ autofs_dir_readdir, /* readdir */ -+ NULL, /* select */ -+ NULL, /* ioctl */ -+ NULL, /* mmap */ -+ NULL, /* open */ -+ NULL, /* release */ -+ NULL /* fsync */ -+}; -+ -+struct inode_operations autofs_dir_inode_operations = { -+ &autofs_dir_operations, /* file operations */ -+ NULL, /* create */ -+ autofs_dir_lookup, /* lookup */ -+ NULL, /* link */ -+ NULL, /* unlink */ -+ NULL, /* symlink */ -+ NULL, /* mkdir */ -+ NULL, /* rmdir */ -+ NULL, /* mknod */ -+ NULL, /* rename */ -+ NULL, /* readlink */ -+ NULL, /* follow_link */ -+ NULL, /* read_page */ -+ NULL, /* writepage */ -+ NULL, /* bmap */ -+ NULL, /* truncate */ -+ NULL /* permission */ -+}; -+ -diff -urN 2.0.30/linux/fs/autofs/dirhash.c linux/fs/autofs/dirhash.c ---- 2.0.30/linux/fs/autofs/dirhash.c Wed Dec 31 16:00:00 1969 -+++ linux/fs/autofs/dirhash.c Wed May 28 21:38:35 1997 -@@ -0,0 +1,172 @@ -+/* -*- linux-c -*- --------------------------------------------------------- * -+ * -+ * linux/fs/autofs/dirhash.c -+ * -+ * Copyright 1997 Transmeta Corporation -- All Rights Reserved -+ * -+ * This file is part of the Linux kernel and is made available under -+ * the terms of the GNU General Public License, version 2, or at your -+ * option, any later version, incorporated herein by reference. -+ * -+ * ------------------------------------------------------------------------- */ -+ -+#include "autofs_i.h" -+ -+/* Functions for maintenance of expiry queue */ -+ -+static void autofs_init_usage(struct autofs_dirhash *dh, -+ struct autofs_dir_ent *ent) -+{ -+ ent->exp_next = &dh->expiry_head; -+ ent->exp_prev = dh->expiry_head.exp_prev; -+ dh->expiry_head.exp_prev->exp_next = ent; -+ dh->expiry_head.exp_prev = ent; -+ ent->last_usage = jiffies; -+} -+ -+static void autofs_delete_usage(struct autofs_dir_ent *ent) -+{ -+ ent->exp_prev->exp_next = ent->exp_next; -+ ent->exp_next->exp_prev = ent->exp_prev; -+} -+ -+void autofs_update_usage(struct autofs_dirhash *dh, -+ struct autofs_dir_ent *ent) -+{ -+ autofs_delete_usage(ent); /* Unlink from current position */ -+ autofs_init_usage(dh,ent); /* Relink at queue tail */ -+} -+ -+struct autofs_dir_ent *autofs_expire(struct autofs_dirhash *dh, -+ unsigned long timeout) -+{ -+ struct autofs_dir_ent *ent; -+ -+ ent = dh->expiry_head.exp_next; -+ -+ if ( ent == &(dh->expiry_head) ) return NULL; -+ return (jiffies - ent->last_usage >= timeout) ? ent : NULL; -+} -+ -+/* Adapted from the Dragon Book, page 436 */ -+/* This particular hashing algorithm requires autofs_hash_t == u32 */ -+autofs_hash_t autofs_hash(const char *name, int len) -+{ -+ autofs_hash_t h = 0; -+ while ( len-- ) { -+ h = (h << 4) + (unsigned char) (*name++); -+ h ^= ((h & 0xf0000000) >> 24); -+ } -+ return h; -+} -+ -+void autofs_initialize_hash(struct autofs_dirhash *dh) { -+ memset(&dh->h, 0, AUTOFS_HASH_SIZE*sizeof(struct autofs_dir_ent *)); -+ dh->expiry_head.exp_next = dh->expiry_head.exp_prev = -+ &dh->expiry_head; -+} -+ -+struct autofs_dir_ent *autofs_hash_lookup(const struct autofs_dirhash *dh, autofs_hash_t hash, const char *name, int len) -+{ -+ struct autofs_dir_ent *dhn; -+ -+ DPRINTK(("autofs_hash_lookup: hash = 0x%08x, name = ", hash)); -+ autofs_say(name,len); -+ -+ for ( dhn = dh->h[hash % AUTOFS_HASH_SIZE] ; dhn ; dhn = dhn->next ) { -+ if ( hash == dhn->hash && -+ len == dhn->len && -+ !memcmp(name, dhn->name, len) ) -+ break; -+ } -+ -+ return dhn; -+} -+ -+void autofs_hash_insert(struct autofs_dirhash *dh, struct autofs_dir_ent *ent) -+{ -+ struct autofs_dir_ent **dhnp; -+ -+ DPRINTK(("autofs_hash_insert: hash = 0x%08x, name = ", ent->hash)); -+ autofs_say(ent->name,ent->len); -+ -+ autofs_init_usage(dh,ent); -+ -+ dhnp = &dh->h[ent->hash % AUTOFS_HASH_SIZE]; -+ ent->next = *dhnp; -+ ent->back = dhnp; -+ *dhnp = ent; -+} -+ -+void autofs_hash_delete(struct autofs_dir_ent *ent) -+{ -+ *(ent->back) = ent->next; -+ -+ autofs_delete_usage(ent); -+ -+ kfree(ent->name); -+ kfree(ent); -+} -+ -+/* -+ * Used by readdir(). We must validate "ptr", so we can't simply make it -+ * a pointer. Values below 0xffff are reserved; calling with any value -+ * <= 0x10000 will return the first entry found. -+ */ -+struct autofs_dir_ent *autofs_hash_enum(const struct autofs_dirhash *dh, off_t *ptr) -+{ -+ int bucket, ecount, i; -+ struct autofs_dir_ent *ent; -+ -+ bucket = (*ptr >> 16) - 1; -+ ecount = *ptr & 0xffff; -+ -+ if ( bucket < 0 ) { -+ bucket = ecount = 0; -+ } -+ -+ DPRINTK(("autofs_hash_enum: bucket %d, entry %d\n", bucket, ecount)); -+ -+ ent = NULL; -+ -+ while ( bucket < AUTOFS_HASH_SIZE ) { -+ ent = dh->h[bucket]; -+ for ( i = ecount ; ent && i ; i-- ) -+ ent = ent->next; -+ -+ if (ent) { -+ ecount++; /* Point to *next* entry */ -+ break; -+ } -+ -+ bucket++; ecount = 0; -+ } -+ -+#ifdef DEBUG -+ if ( !ent ) -+ printk("autofs_hash_enum: nothing found\n"); -+ else { -+ printk("autofs_hash_enum: found hash %08x, name", ent->hash); -+ autofs_say(ent->name,ent->len); -+ } -+#endif -+ -+ *ptr = ((bucket+1) << 16) + ecount; -+ return ent; -+} -+ -+/* Delete everything. This is used on filesystem destruction, so we -+ make no attempt to keep the pointers valid */ -+void autofs_hash_nuke(struct autofs_dirhash *dh) -+{ -+ int i; -+ struct autofs_dir_ent *ent, *nent; -+ -+ for ( i = 0 ; i < AUTOFS_HASH_SIZE ; i++ ) { -+ for ( ent = dh->h[i] ; ent ; ent = nent ) { -+ nent = ent->next; -+ kfree(ent->name); -+ kfree(ent); -+ } -+ } -+} -diff -urN 2.0.30/linux/fs/autofs/init.c linux/fs/autofs/init.c ---- 2.0.30/linux/fs/autofs/init.c Wed Dec 31 16:00:00 1969 -+++ linux/fs/autofs/init.c Wed May 28 21:38:35 1997 -@@ -0,0 +1,58 @@ -+/* -*- linux-c -*- --------------------------------------------------------- * -+ * -+ * linux/fs/autofs/init.c -+ * -+ * Copyright 1997 Transmeta Corporation -- All Rights Reserved -+ * -+ * This file is part of the Linux kernel and is made available under -+ * the terms of the GNU General Public License, version 2, or at your -+ * option, any later version, incorporated herein by reference. -+ * -+ * ------------------------------------------------------------------------- */ -+ -+#include -+#include "autofs_i.h" -+ -+#if LINUX_VERSION_CODE < kver(2,1,36) -+#define __initfunc(X) X -+#else -+#include -+#endif -+ -+static struct file_system_type autofs_fs_type = { -+ autofs_read_super, "autofs", 0, NULL -+}; -+ -+#ifdef MODULE -+int init_module(void) -+{ -+ int status; -+ -+ if ((status = register_filesystem(&autofs_fs_type)) == 0) -+ register_symtab(0); -+ return status; -+} -+ -+void cleanup_module(void) -+{ -+ unregister_filesystem(&autofs_fs_type); -+} -+ -+#else /* MODULE */ -+ -+__initfunc(int init_autofs_fs(void)) -+{ -+ return register_filesystem(&autofs_fs_type); -+} -+ -+#endif /* !MODULE */ -+ -+#ifdef DEBUG -+void autofs_say(const char *name, int len) -+{ -+ printk("(%d: ", len); -+ while ( len-- ) -+ printk("%c", *name++); -+ printk(")\n"); -+} -+#endif -diff -urN 2.0.30/linux/fs/autofs/inode.c linux/fs/autofs/inode.c ---- 2.0.30/linux/fs/autofs/inode.c Wed Dec 31 16:00:00 1969 -+++ linux/fs/autofs/inode.c Wed May 28 21:38:35 1997 -@@ -0,0 +1,277 @@ -+/* -*- linux-c -*- --------------------------------------------------------- * -+ * -+ * linux/fs/autofs/inode.c -+ * -+ * Copyright 1997 Transmeta Corporation -- All Rights Reserved -+ * -+ * This file is part of the Linux kernel and is made available under -+ * the terms of the GNU General Public License, version 2, or at your -+ * option, any later version, incorporated herein by reference. -+ * -+ * ------------------------------------------------------------------------- */ -+ -+#include -+#include -+#include -+#include -+#include -+#include "autofs_i.h" -+#define __NO_VERSION__ -+#include -+ -+static void autofs_put_inode(struct inode *inode) -+{ -+ if (inode->i_nlink) -+ return; -+ inode->i_size = 0; -+} -+ -+static void autofs_put_super(struct super_block *sb) -+{ -+ struct autofs_sb_info *sbi = -+ (struct autofs_sb_info *) sb->u.generic_sbp; -+ unsigned int n; -+ -+ if ( !sbi->catatonic ) -+ autofs_catatonic_mode(sbi); /* Free wait queues, close pipe */ -+ -+ lock_super(sb); -+ autofs_hash_nuke(&sbi->dirhash); -+ for ( n = 0 ; n < AUTOFS_MAX_SYMLINKS ; n++ ) { -+ if ( test_bit(n, sbi->symlink_bitmap) ) -+ kfree(sbi->symlink[n].data); -+ } -+ -+ sb->s_dev = 0; -+ kfree(sb->u.generic_sbp); -+ unlock_super(sb); -+ -+ DPRINTK(("autofs: shutting down\n")); -+ -+#ifdef MODULE -+ MOD_DEC_USE_COUNT; -+#endif -+} -+ -+static void autofs_statfs(struct super_block *sb, struct statfs *buf, int bufsiz); -+static void autofs_read_inode(struct inode *inode); -+static void autofs_write_inode(struct inode *inode); -+ -+static struct super_operations autofs_sops = { -+ autofs_read_inode, -+ NULL, -+ autofs_write_inode, -+ autofs_put_inode, -+ autofs_put_super, -+ NULL, -+ autofs_statfs, -+ NULL -+}; -+ -+static int parse_options(char *options, int *pipefd, uid_t *uid, gid_t *gid, pid_t *pgrp, int *minproto, int *maxproto) -+{ -+ char *this_char, *value; -+ -+ *uid = current->uid; -+ *gid = current->gid; -+ *pgrp = current->pgrp; -+ -+ *minproto = *maxproto = AUTOFS_PROTO_VERSION; -+ -+ *pipefd = -1; -+ -+ if ( !options ) return 1; -+ for (this_char = strtok(options,","); this_char; this_char = strtok(NULL,",")) { -+ if ((value = strchr(this_char,'=')) != NULL) -+ *value++ = 0; -+ if (!strcmp(this_char,"fd")) { -+ if (!value || !*value) -+ return 1; -+ *pipefd = simple_strtoul(value,&value,0); -+ if (*value) -+ return 1; -+ } -+ else if (!strcmp(this_char,"uid")) { -+ if (!value || !*value) -+ return 1; -+ *uid = simple_strtoul(value,&value,0); -+ if (*value) -+ return 1; -+ } -+ else if (!strcmp(this_char,"gid")) { -+ if (!value || !*value) -+ return 1; -+ *gid = simple_strtoul(value,&value,0); -+ if (*value) -+ return 1; -+ } -+ else if (!strcmp(this_char,"pgrp")) { -+ if (!value || !*value) -+ return 1; -+ *pgrp = simple_strtoul(value,&value,0); -+ if (*value) -+ return 1; -+ } -+ else if (!strcmp(this_char,"minproto")) { -+ if (!value || !*value) -+ return 1; -+ *minproto = simple_strtoul(value,&value,0); -+ if (*value) -+ return 1; -+ } -+ else if (!strcmp(this_char,"maxproto")) { -+ if (!value || !*value) -+ return 1; -+ *maxproto = simple_strtoul(value,&value,0); -+ if (*value) -+ return 1; -+ } -+ else break; -+ } -+ return (*pipefd < 0); -+} -+ -+struct super_block *autofs_read_super(struct super_block *s, void *data, -+ int silent) -+{ -+ int pipefd; -+ struct autofs_sb_info *sbi; -+ int minproto, maxproto; -+ -+ MOD_INC_USE_COUNT; -+ -+ lock_super(s); -+ sbi = (struct autofs_sb_info *) kmalloc(sizeof(struct autofs_sb_info), GFP_KERNEL); -+ if ( !sbi ) { -+ s->s_dev = 0; -+ MOD_DEC_USE_COUNT; -+ return NULL; -+ } -+ DPRINTK(("autofs: starting up, sbi = %p\n",sbi)); -+ -+ s->u.generic_sbp = sbi; -+ sbi->magic = AUTOFS_SBI_MAGIC; -+ sbi->catatonic = 0; -+ sbi->exp_timeout = 0; -+ sbi->oz_pgrp = current->pgrp; -+ autofs_initialize_hash(&sbi->dirhash); -+ sbi->queues = NULL; -+ memset(sbi->symlink_bitmap, 0, sizeof(u32)*AUTOFS_SYMLINK_BITMAP_LEN); -+ sbi->next_dir_ino = AUTOFS_FIRST_DIR_INO; -+ s->s_blocksize = 1024; -+ s->s_blocksize_bits = 10; -+ s->s_magic = AUTOFS_SUPER_MAGIC; -+ s->s_op = &autofs_sops; -+ unlock_super(s); -+ if (!(s->s_mounted = iget(s, AUTOFS_ROOT_INO))) { -+ s->s_dev = 0; -+ kfree(sbi); -+ printk("autofs: get root inode failed\n"); -+ MOD_DEC_USE_COUNT; -+ return NULL; -+ } -+ -+ if ( parse_options(data,&pipefd,&s->s_mounted->i_uid,&s->s_mounted->i_gid,&sbi->oz_pgrp,&minproto,&maxproto) ) { -+ iput(s->s_mounted); -+ s->s_dev = 0; -+ kfree(sbi); -+ printk("autofs: called with bogus options\n"); -+ MOD_DEC_USE_COUNT; -+ return NULL; -+ } -+ -+ if ( minproto > AUTOFS_PROTO_VERSION || maxproto < AUTOFS_PROTO_VERSION ) { -+ iput(s->s_mounted); -+ s->s_dev = 0; -+ kfree(sbi); -+ printk("autofs: kernel does not match daemon version\n"); -+ MOD_DEC_USE_COUNT; -+ return NULL; -+ } -+ -+ DPRINTK(("autofs: pipe fd = %d, pgrp = %u\n", pipefd, sbi->oz_pgrp)); -+ sbi->pipe = fget(pipefd); -+ if ( !sbi->pipe || !sbi->pipe->f_op || !sbi->pipe->f_op->write ) { -+ if ( sbi->pipe ) { -+ fput(sbi->pipe, sbi->pipe->f_inode); -+ printk("autofs: pipe file descriptor does not contain proper ops\n"); -+ } else { -+ printk("autofs: could not open pipe file descriptor\n"); -+ } -+ iput(s->s_mounted); -+ s->s_dev = 0; -+ kfree(sbi); -+ MOD_DEC_USE_COUNT; -+ return NULL; -+ } -+ return s; -+} -+ -+static void autofs_statfs(struct super_block *sb, struct statfs *buf, int bufsiz) -+{ -+ struct statfs tmp; -+ -+ tmp.f_type = AUTOFS_SUPER_MAGIC; -+ tmp.f_bsize = 1024; -+ tmp.f_blocks = 0; -+ tmp.f_bfree = 0; -+ tmp.f_bavail = 0; -+ tmp.f_files = 0; -+ tmp.f_ffree = 0; -+ tmp.f_namelen = NAME_MAX; -+ copy_to_user(buf, &tmp, bufsiz); -+} -+ -+static void autofs_read_inode(struct inode *inode) -+{ -+ ino_t ino = inode->i_ino; -+ unsigned int n; -+ struct autofs_sb_info *sbi = -+ (struct autofs_sb_info *) inode->i_sb->u.generic_sbp; -+ -+ inode->i_op = NULL; -+ inode->i_mode = 0; -+ inode->i_nlink = 2; -+ inode->i_size = 0; -+ inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; -+ inode->i_blocks = 0; -+ inode->i_blksize = 1024; -+ -+ if ( ino == AUTOFS_ROOT_INO ) { -+ inode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO | S_IWUSR; -+ inode->i_op = &autofs_root_inode_operations; -+ inode->i_uid = inode->i_gid = 0; /* Changed in read_super */ -+ return; -+ } -+ -+ inode->i_uid = inode->i_sb->s_mounted->i_uid; -+ inode->i_gid = inode->i_sb->s_mounted->i_gid; -+ -+ if ( ino >= AUTOFS_FIRST_SYMLINK && ino < AUTOFS_FIRST_DIR_INO ) { -+ /* Symlink inode - should be in symlink list */ -+ struct autofs_symlink *sl; -+ -+ n = ino - AUTOFS_FIRST_SYMLINK; -+ if ( n >= AUTOFS_MAX_SYMLINKS || !test_bit(n,sbi->symlink_bitmap)) { -+ printk("autofs: Looking for bad symlink inode 0x%08x\n", (unsigned int) ino); -+ return; -+ } -+ -+ inode->i_op = &autofs_symlink_inode_operations; -+ sl = &sbi->symlink[n]; -+ inode->u.generic_ip = sl; -+ inode->i_mode = S_IFLNK | S_IRWXUGO; -+ inode->i_mtime = inode->i_ctime = sl->mtime; -+ inode->i_size = sl->len; -+ inode->i_nlink = 1; -+ } else { -+ /* All non-root directory inodes look the same */ -+ inode->i_op = &autofs_dir_inode_operations; -+ inode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO; -+ } -+} -+ -+static void autofs_write_inode(struct inode *inode) -+{ -+ inode->i_dirt = 0; -+} -diff -urN 2.0.30/linux/fs/autofs/root.c linux/fs/autofs/root.c ---- 2.0.30/linux/fs/autofs/root.c Wed Dec 31 16:00:00 1969 -+++ linux/fs/autofs/root.c Wed May 28 21:38:35 1997 -@@ -0,0 +1,445 @@ -+/* -*- linux-c -*- --------------------------------------------------------- * -+ * -+ * linux/fs/autofs/root.c -+ * -+ * Copyright 1997 Transmeta Corporation -- All Rights Reserved -+ * -+ * This file is part of the Linux kernel and is made available under -+ * the terms of the GNU General Public License, version 2, or at your -+ * option, any later version, incorporated herein by reference. -+ * -+ * ------------------------------------------------------------------------- */ -+ -+#include -+#include -+#include -+#include "autofs_i.h" -+ -+static int autofs_root_readdir(struct inode *,struct file *,void *,filldir_t); -+static int autofs_root_lookup(struct inode *,const char *,int,struct inode **); -+static int autofs_root_symlink(struct inode *,const char *,int,const char *); -+static int autofs_root_unlink(struct inode *,const char *,int); -+static int autofs_root_rmdir(struct inode *,const char *,int); -+static int autofs_root_mkdir(struct inode *,const char *,int,int); -+static int autofs_root_ioctl(struct inode *, struct file *,unsigned int,unsigned long); -+ -+static struct file_operations autofs_root_operations = { -+ NULL, /* lseek */ -+ NULL, /* read */ -+ NULL, /* write */ -+ autofs_root_readdir, /* readdir */ -+ NULL, /* select */ -+ autofs_root_ioctl, /* ioctl */ -+ NULL, /* mmap */ -+ NULL, /* open */ -+ NULL, /* release */ -+ NULL /* fsync */ -+}; -+ -+struct inode_operations autofs_root_inode_operations = { -+ &autofs_root_operations, /* file operations */ -+ NULL, /* create */ -+ autofs_root_lookup, /* lookup */ -+ NULL, /* link */ -+ autofs_root_unlink, /* unlink */ -+ autofs_root_symlink, /* symlink */ -+ autofs_root_mkdir, /* mkdir */ -+ autofs_root_rmdir, /* rmdir */ -+ NULL, /* mknod */ -+ NULL, /* rename */ -+ NULL, /* readlink */ -+ NULL, /* follow_link */ -+ NULL, /* readpage */ -+ NULL, /* writepage */ -+ NULL, /* bmap */ -+ NULL, /* truncate */ -+ NULL /* permission */ -+}; -+ -+static int autofs_root_readdir(struct inode *inode, struct file *filp, -+ void *dirent, filldir_t filldir) -+{ -+ struct autofs_dir_ent *ent; -+ struct autofs_dirhash *dirhash; -+ off_t onr, nr; -+ -+ if (!inode || !S_ISDIR(inode->i_mode)) -+ return -ENOTDIR; -+ -+ dirhash = &((struct autofs_sb_info *)inode->i_sb->u.generic_sbp)->dirhash; -+ nr = filp->f_pos; -+ -+ switch(nr) -+ { -+ case 0: -+ if (filldir(dirent, ".", 1, nr, inode->i_ino) < 0) -+ return 0; -+ filp->f_pos = ++nr; -+ /* fall through */ -+ case 1: -+ if (filldir(dirent, "..", 2, nr, inode->i_ino) < 0) -+ return 0; -+ filp->f_pos = ++nr; -+ /* fall through */ -+ default: -+ while ( onr = nr, ent = autofs_hash_enum(dirhash,&nr) ) { -+ if (filldir(dirent,ent->name,ent->len,onr,ent->ino) < 0) -+ return 0; -+ filp->f_pos = nr; -+ } -+ break; -+ } -+ -+ return 0; -+} -+ -+static int autofs_root_lookup(struct inode *dir, const char *name, int len, -+ struct inode **result) -+{ -+ struct autofs_sb_info *sbi; -+ struct autofs_dir_ent *ent; -+ struct inode *res; -+ autofs_hash_t hash; -+ int status, oz_mode; -+ -+ DPRINTK(("autofs_root_lookup: name = ")); -+ autofs_say(name,len); -+ -+ *result = NULL; -+ if (!dir) -+ return -ENOENT; -+ if (!S_ISDIR(dir->i_mode)) { -+ iput(dir); -+ return -ENOTDIR; -+ } -+ -+ /* Handle special cases: . and ..; since this is a root directory, -+ they both point to the inode itself */ -+ *result = dir; -+ if (!len) -+ return 0; -+ if (name[0] == '.') { -+ if (len == 1) -+ return 0; -+ if (name[1] == '.' && len == 2) -+ return 0; -+ } -+ -+ *result = res = NULL; -+ sbi = (struct autofs_sb_info *) dir->i_sb->u.generic_sbp; -+ -+ hash = autofs_hash(name,len); -+ -+ oz_mode = autofs_oz_mode(sbi); -+ DPRINTK(("autofs_lookup: pid = %u, pgrp = %u, catatonic = %d, oz_mode = %d\n", current->pid, current->pgrp, sbi->catatonic, oz_mode)); -+ -+ do { -+ while ( !(ent = autofs_hash_lookup(&sbi->dirhash,hash,name,len)) ) { -+ DPRINTK(("lookup failed, pid = %u, pgrp = %u\n", current->pid, current->pgrp)); -+ -+ if ( oz_mode ) { -+ iput(dir); -+ return -ENOENT; -+ } else { -+ status = autofs_wait(sbi,hash,name,len); -+ DPRINTK(("autofs_wait returned %d\n", status)); -+ if ( status ) { -+ iput(dir); -+ return status; -+ } -+ } -+ } -+ -+ DPRINTK(("lookup successful, inode = %08x\n", (unsigned int)ent->ino)); -+ -+ if (!(res = iget(dir->i_sb,ent->ino))) { -+ printk("autofs: iget returned null!\n"); -+ iput(dir); -+ return -EACCES; -+ } -+ -+ if ( !oz_mode && S_ISDIR(res->i_mode) && res->i_sb == dir->i_sb ) { -+ /* Not a mount point yet, call 1-800-DAEMON */ -+ DPRINTK(("autofs: waiting on non-mountpoint dir, inode = %lu, pid = %u, pgrp = %u\n", res->i_ino, current->pid, current->pgrp)); -+ iput(res); -+ res = NULL; -+ status = autofs_wait(sbi,hash,name,len); -+ if ( status ) { -+ iput(dir); -+ return status; -+ } -+ } -+ } while(!res); -+ autofs_update_usage(&sbi->dirhash,ent); -+ -+ *result = res; -+ iput(dir); -+ return 0; -+} -+ -+static int autofs_root_symlink(struct inode *dir, const char *name, int len, const char *symname) -+{ -+ struct autofs_sb_info *sbi = (struct autofs_sb_info *) dir->i_sb->u.generic_sbp; -+ struct autofs_dirhash *dh = &sbi->dirhash; -+ autofs_hash_t hash = autofs_hash(name,len); -+ struct autofs_dir_ent *ent; -+ unsigned int n; -+ int slsize; -+ struct autofs_symlink *sl; -+ -+ DPRINTK(("autofs_root_symlink: %s <- ", symname)); -+ autofs_say(name,len); -+ -+ if ( !autofs_oz_mode(sbi) ) { -+ iput(dir); -+ return -EPERM; -+ } -+ if ( autofs_hash_lookup(dh,hash,name,len) ) { -+ iput(dir); -+ return -EEXIST; -+ } -+ n = find_first_zero_bit(sbi->symlink_bitmap,AUTOFS_MAX_SYMLINKS); -+ if ( n >= AUTOFS_MAX_SYMLINKS ) { -+ iput(dir); -+ return -ENOSPC; -+ } -+ set_bit(n,sbi->symlink_bitmap); -+ sl = &sbi->symlink[n]; -+ sl->len = strlen(symname); -+ sl->data = kmalloc(slsize = sl->len+1, GFP_KERNEL); -+ if ( !sl->data ) { -+ clear_bit(n,sbi->symlink_bitmap); -+ iput(dir); -+ return -ENOSPC; -+ } -+ ent = kmalloc(sizeof(struct autofs_dir_ent), GFP_KERNEL); -+ if ( !ent ) { -+ kfree(sl->data); -+ clear_bit(n,sbi->symlink_bitmap); -+ iput(dir); -+ return -ENOSPC; -+ } -+ ent->name = kmalloc(len, GFP_KERNEL); -+ if ( !ent->name ) { -+ kfree(sl->data); -+ kfree(ent); -+ clear_bit(n,sbi->symlink_bitmap); -+ iput(dir); -+ return -ENOSPC; -+ } -+ memcpy(sl->data,symname,slsize); -+ sl->mtime = CURRENT_TIME; -+ -+ ent->ino = AUTOFS_FIRST_SYMLINK + n; -+ ent->hash = hash; -+ memcpy(ent->name,name,ent->len = len); -+ -+ autofs_hash_insert(dh,ent); -+ iput(dir); -+ -+ return 0; -+} -+ -+static int autofs_root_unlink(struct inode *dir, const char *name, int len) -+{ -+ struct autofs_sb_info *sbi = (struct autofs_sb_info *) dir->i_sb->u.generic_sbp; -+ struct autofs_dirhash *dh = &sbi->dirhash; -+ autofs_hash_t hash = autofs_hash(name,len); -+ struct autofs_dir_ent *ent; -+ unsigned int n; -+ -+ iput(dir); /* Nothing below can sleep */ -+ -+ if ( !autofs_oz_mode(sbi) ) -+ return -EPERM; -+ -+ ent = autofs_hash_lookup(dh,hash,name,len); -+ if ( !ent ) -+ return -ENOENT; -+ -+ n = ent->ino - AUTOFS_FIRST_SYMLINK; -+ if ( n >= AUTOFS_MAX_SYMLINKS || !test_bit(n,sbi->symlink_bitmap) ) -+ return -EINVAL; /* Not a symlink inode, can't unlink */ -+ -+ autofs_hash_delete(ent); -+ clear_bit(n,sbi->symlink_bitmap); -+ kfree(sbi->symlink[n].data); -+ -+ return 0; -+} -+ -+static int autofs_root_rmdir(struct inode *dir, const char *name, int len) -+{ -+ struct autofs_sb_info *sbi = (struct autofs_sb_info *) dir->i_sb->u.generic_sbp; -+ struct autofs_dirhash *dh = &sbi->dirhash; -+ autofs_hash_t hash = autofs_hash(name,len); -+ struct autofs_dir_ent *ent; -+ -+ if ( !autofs_oz_mode(sbi) ) { -+ iput(dir); -+ return -EPERM; -+ } -+ ent = autofs_hash_lookup(dh,hash,name,len); -+ if ( !ent ) { -+ iput(dir); -+ return -ENOENT; -+ } -+ if ( (unsigned int)ent->ino < AUTOFS_FIRST_DIR_INO ) { -+ iput(dir); -+ return -ENOTDIR; /* Not a directory */ -+ } -+ autofs_hash_delete(ent); -+ dir->i_nlink--; -+ iput(dir); -+ -+ return 0; -+} -+ -+static int autofs_root_mkdir(struct inode *dir, const char *name, int len, int mode) -+{ -+ struct autofs_sb_info *sbi = (struct autofs_sb_info *) dir->i_sb->u.generic_sbp; -+ struct autofs_dirhash *dh = &sbi->dirhash; -+ autofs_hash_t hash = autofs_hash(name,len); -+ struct autofs_dir_ent *ent; -+ -+ if ( !autofs_oz_mode(sbi) ) { -+ iput(dir); -+ return -EPERM; -+ } -+ ent = autofs_hash_lookup(dh,hash,name,len); -+ if ( ent ) { -+ iput(dir); -+ return -EEXIST; -+ } -+ if ( sbi->next_dir_ino < AUTOFS_FIRST_DIR_INO ) { -+ printk("autofs: Out of inode numbers -- what the heck did you do??\n"); -+ iput(dir); -+ return -ENOSPC; -+ } -+ ent = kmalloc(sizeof(struct autofs_dir_ent), GFP_KERNEL); -+ if ( !ent ) { -+ iput(dir); -+ return -ENOSPC; -+ } -+ ent->name = kmalloc(len, GFP_KERNEL); -+ if ( !ent->name ) { -+ kfree(ent); -+ iput(dir); -+ return -ENOSPC; -+ } -+ ent->hash = hash; -+ memcpy(ent->name, name, ent->len = len); -+ ent->ino = sbi->next_dir_ino++; -+ autofs_hash_insert(dh,ent); -+ dir->i_nlink++; -+ iput(dir); -+ -+ return 0; -+} -+ -+/* Get/set timeout ioctl() operation */ -+static inline int autofs_get_set_timeout(struct autofs_sb_info *sbi, -+ unsigned long *p) -+{ -+ int rv; -+ unsigned long ntimeout; -+ -+#if LINUX_VERSION_CODE < kver(2,1,0) -+ if ( (rv = verify_area(VERIFY_WRITE, p, sizeof(unsigned long))) ) -+ return rv; -+ ntimeout = get_user(p); -+ put_user(sbi->exp_timeout/HZ, p); -+#else -+ if ( (rv = get_user(ntimeout, p)) || -+ (rv = put_user(sbi->exp_timeout/HZ, p)) ) -+ return rv; -+#endif -+ -+ if ( ntimeout > ULONG_MAX/HZ ) -+ sbi->exp_timeout = 0; -+ else -+ sbi->exp_timeout = ntimeout * HZ; -+ -+ return 0; -+} -+ -+/* Return protocol version */ -+static inline int autofs_get_protover(int *p) -+{ -+#if LINUX_VERSION_CODE < kver(2,1,0) -+ int rv; -+ if ( (rv = verify_area(VERIFY_WRITE, p, sizeof(int))) ) -+ return rv; -+ put_user(AUTOFS_PROTO_VERSION, p); -+ return 0; -+#else -+ return put_user(AUTOFS_PROTO_VERSION, p); -+#endif -+} -+ -+/* Perform an expiry operation */ -+static inline int autofs_expire_run(struct autofs_sb_info *sbi, -+ struct autofs_packet_expire *pkt_p) -+{ -+ struct autofs_dir_ent *ent; -+ struct autofs_packet_expire pkt; -+ struct autofs_dirhash *dh = &(sbi->dirhash); -+ -+ memset(&pkt,0,sizeof pkt); -+ -+ pkt.hdr.proto_version = AUTOFS_PROTO_VERSION; -+ pkt.hdr.type = autofs_ptype_expire; -+ -+ if ( !sbi->exp_timeout || -+ !(ent = autofs_expire(dh,sbi->exp_timeout)) ) -+ return -EAGAIN; -+ -+ pkt.len = ent->len; -+ memcpy(pkt.name, ent->name, pkt.len); -+ pkt.name[pkt.len] = '\0'; -+ -+ if ( copy_to_user(pkt_p, &pkt, sizeof(struct autofs_packet_expire)) ) -+ return -EFAULT; -+ -+ autofs_update_usage(dh,ent); -+ -+ return 0; -+} -+ -+/* -+ * ioctl()'s on the root directory is the chief method for the daemon to -+ * generate kernel reactions -+ */ -+static int autofs_root_ioctl(struct inode *inode, struct file *filp, -+ unsigned int cmd, unsigned long arg) -+{ -+ struct autofs_sb_info *sbi = -+ (struct autofs_sb_info *)inode->i_sb->u.generic_sbp; -+ -+ DPRINTK(("autofs_ioctl: cmd = 0x%08x, arg = 0x%08lx, sbi = %p, pgrp = %u\n",cmd,arg,sbi,current->pgrp)); -+ -+ if ( _IOC_TYPE(cmd) != _IOC_TYPE(AUTOFS_IOC_FIRST) || -+ _IOC_NR(cmd) - _IOC_NR(AUTOFS_IOC_FIRST) >= AUTOFS_IOC_COUNT ) -+ return -ENOTTY; -+ -+ if ( !autofs_oz_mode(sbi) && !fsuser() ) -+ return -EPERM; -+ -+ switch(cmd) { -+ case AUTOFS_IOC_READY: /* Wait queue: go ahead and retry */ -+ return autofs_wait_release(sbi,arg,0); -+ case AUTOFS_IOC_FAIL: /* Wait queue: fail with ENOENT */ -+ return autofs_wait_release(sbi,arg,-ENOENT); -+ case AUTOFS_IOC_CATATONIC: /* Enter catatonic mode (daemon shutdown) */ -+ autofs_catatonic_mode(sbi); -+ return 0; -+ case AUTOFS_IOC_PROTOVER: /* Get protocol version */ -+ return autofs_get_protover((int *)arg); -+ case AUTOFS_IOC_SETTIMEOUT: -+ return autofs_get_set_timeout(sbi,(unsigned long *)arg); -+ case AUTOFS_IOC_EXPIRE: -+ return autofs_expire_run(sbi,(struct autofs_packet_expire *)arg); -+ default: -+ return -ENOSYS; -+ } -+} -diff -urN 2.0.30/linux/fs/autofs/symlink.c linux/fs/autofs/symlink.c ---- 2.0.30/linux/fs/autofs/symlink.c Wed Dec 31 16:00:00 1969 -+++ linux/fs/autofs/symlink.c Wed May 28 21:38:35 1997 -@@ -0,0 +1,85 @@ -+/* -*- linux-c -*- --------------------------------------------------------- * -+ * -+ * linux/fs/autofs/symlink.c -+ * -+ * Copyright 1997 Transmeta Corporation -- All Rights Reserved -+ * -+ * This file is part of the Linux kernel and is made available under -+ * the terms of the GNU General Public License, version 2, or at your -+ * option, any later version, incorporated herein by reference. -+ * -+ * ------------------------------------------------------------------------- */ -+ -+#include -+#include -+#include "autofs_i.h" -+ -+static int autofs_follow_link(struct inode *dir, struct inode *inode, -+ int flag, int mode, struct inode **res_inode) -+{ -+ int error; -+ char *link; -+ -+ *res_inode = NULL; -+ if (!dir) { -+ dir = current->fs->root; -+ dir->i_count++; -+ } -+ if (!inode) { -+ iput(dir); -+ return -ENOENT; -+ } -+ if (!S_ISLNK(inode->i_mode)) { -+ iput(dir); -+ *res_inode = inode; -+ return 0; -+ } -+ if (current->link_count > 5) { -+ iput(dir); -+ iput(inode); -+ return -ELOOP; -+ } -+ link = ((struct autofs_symlink *)inode->u.generic_ip)->data; -+ current->link_count++; -+ error = open_namei(link,flag,mode,res_inode,dir); -+ current->link_count--; -+ iput(inode); -+ return error; -+} -+ -+static int autofs_readlink(struct inode *inode, char *buffer, int buflen) -+{ -+ struct autofs_symlink *sl; -+ int len; -+ -+ if (!S_ISLNK(inode->i_mode)) { -+ iput(inode); -+ return -EINVAL; -+ } -+ sl = (struct autofs_symlink *)inode->u.generic_ip; -+ len = sl->len; -+ if (len > buflen) len = buflen; -+ copy_to_user(buffer,sl->data,len); -+ iput(inode); -+ return len; -+} -+ -+struct inode_operations autofs_symlink_inode_operations = { -+ NULL, /* file operations */ -+ NULL, /* create */ -+ NULL, /* lookup */ -+ NULL, /* link */ -+ NULL, /* unlink */ -+ NULL, /* symlink */ -+ NULL, /* mkdir */ -+ NULL, /* rmdir */ -+ NULL, /* mknod */ -+ NULL, /* rename */ -+ autofs_readlink, /* readlink */ -+ autofs_follow_link, /* follow_link */ -+ NULL, /* readpage */ -+ NULL, /* writepage */ -+ NULL, /* bmap */ -+ NULL, /* truncate */ -+ NULL /* permission */ -+}; -diff -urN 2.0.30/linux/fs/autofs/waitq.c linux/fs/autofs/waitq.c ---- 2.0.30/linux/fs/autofs/waitq.c Wed Dec 31 16:00:00 1969 -+++ linux/fs/autofs/waitq.c Wed May 28 21:38:35 1997 -@@ -0,0 +1,171 @@ -+/* -*- linux-c -*- --------------------------------------------------------- * -+ * -+ * linux/fs/autofs/waitq.c -+ * -+ * Copyright 1997 Transmeta Corporation -- All Rights Reserved -+ * -+ * This file is part of the Linux kernel and is made available under -+ * the terms of the GNU General Public License, version 2, or at your -+ * option, any later version, incorporated herein by reference. -+ * -+ * ------------------------------------------------------------------------- */ -+ -+#include -+#include -+#include -+#include -+#include "autofs_i.h" -+ -+/* We make this a static variable rather than a part of the superblock; it -+ is better if we don't reassign numbers easily even across filesystems */ -+static int autofs_next_wait_queue = 1; -+ -+void autofs_catatonic_mode(struct autofs_sb_info *sbi) -+{ -+ struct autofs_wait_queue *wq, *nwq; -+ -+ DPRINTK(("autofs: entering catatonic mode\n")); -+ -+ sbi->catatonic = 1; -+ wq = sbi->queues; -+ sbi->queues = NULL; /* Erase all wait queues */ -+ while ( wq ) { -+ nwq = wq->next; -+ wq->status = -ENOENT; /* Magic is gone - report failure */ -+ kfree(wq->name); -+ wq->name = NULL; -+ wake_up(&wq->queue); -+ wq = nwq; -+ } -+ fput(sbi->pipe, sbi->pipe->f_inode); /* Close the pipe */ -+} -+ -+static int autofs_write(struct file *file, const void *addr, int bytes) -+{ -+ unsigned short fs; -+ unsigned long old_signal; -+ const char *data = (const char *)addr; -+ int written = 0; -+ -+ /** WARNING: this is not safe for writing more than PIPE_BUF bytes! **/ -+ -+ /* Save pointer to user space and point back to kernel space */ -+ fs = get_fs(); -+ set_fs(KERNEL_DS); -+ -+ old_signal = current->signal; -+ -+ while ( bytes && (written = file->f_op->write(file->f_inode,file,data,bytes)) > 0 ) { -+ data += written; -+ bytes -= written; -+ } -+ -+ if ( written == -EPIPE && !(old_signal & (1 << (SIGPIPE-1))) ) { -+ /* Keep the currently executing process from receiving a -+ SIGPIPE unless it was already supposed to get one */ -+ current->signal &= ~(1 << (SIGPIPE-1)); -+ } -+ set_fs(fs); -+ -+ return (bytes > 0); -+} -+ -+static void autofs_notify_daemon(struct autofs_sb_info *sbi, struct autofs_wait_queue *wq) -+{ -+ struct autofs_packet_missing pkt; -+ -+ DPRINTK(("autofs_wait: wait id = 0x%08lx, name = ", wq->wait_queue_token)); -+ autofs_say(wq->name,wq->len); -+ -+ memset(&pkt,0,sizeof pkt); /* For security reasons */ -+ -+ pkt.hdr.proto_version = AUTOFS_PROTO_VERSION; -+ pkt.hdr.type = autofs_ptype_missing; -+ pkt.wait_queue_token = wq->wait_queue_token; -+ pkt.len = wq->len; -+ memcpy(pkt.name, wq->name, pkt.len); -+ pkt.name[pkt.len] = '\0'; -+ -+ if ( autofs_write(sbi->pipe,&pkt,sizeof(struct autofs_packet_missing)) ) -+ autofs_catatonic_mode(sbi); -+} -+ -+int autofs_wait(struct autofs_sb_info *sbi, autofs_hash_t hash, const char *name, int len) -+{ -+ struct autofs_wait_queue *wq; -+ int status; -+ -+ for ( wq = sbi->queues ; wq ; wq = wq->next ) { -+ if ( wq->hash == hash && -+ wq->len == len && -+ wq->name && !memcmp(wq->name,name,len) ) -+ break; -+ } -+ -+ if ( !wq ) { -+ /* Create a new wait queue */ -+ wq = kmalloc(sizeof(struct autofs_wait_queue),GFP_KERNEL); -+ if ( !wq ) -+ return -ENOMEM; -+ -+ wq->name = kmalloc(len,GFP_KERNEL); -+ if ( !wq->name ) { -+ kfree(wq); -+ return -ENOMEM; -+ } -+ wq->wait_queue_token = autofs_next_wait_queue++; -+ init_waitqueue(&wq->queue); -+ wq->hash = hash; -+ wq->len = len; -+ wq->status = -EINTR; /* Status return if interrupted */ -+ memcpy(wq->name, name, len); -+ wq->next = sbi->queues; -+ sbi->queues = wq; -+ -+ /* autofs_notify_daemon() may block */ -+ wq->wait_ctr = 2; -+ autofs_notify_daemon(sbi,wq); -+ } else -+ wq->wait_ctr++; -+ -+ if ( wq->name ) { -+ /* wq->name is NULL if and only if the lock is released */ -+ interruptible_sleep_on(&wq->queue); -+ } else { -+ DPRINTK(("autofs_wait: skipped sleeping\n")); -+ } -+ -+ status = wq->status; -+ -+ if ( ! --wq->wait_ctr ) /* Are we the last process to need status? */ -+ kfree(wq); -+ -+ return status; -+} -+ -+ -+int autofs_wait_release(struct autofs_sb_info *sbi, unsigned long wait_queue_token, int status) -+{ -+ struct autofs_wait_queue *wq, **wql; -+ -+ for ( wql = &sbi->queues ; (wq = *wql) ; wql = &wq->next ) { -+ if ( wq->wait_queue_token == wait_queue_token ) -+ break; -+ } -+ if ( !wq ) -+ return -EINVAL; -+ -+ *wql = wq->next; /* Unlink from chain */ -+ kfree(wq->name); -+ wq->name = NULL; /* Do not wait on this queue */ -+ -+ wq->status = status; -+ -+ if ( ! --wq->wait_ctr ) /* Is anyone still waiting for this guy? */ -+ kfree(wq); -+ else -+ wake_up(&wq->queue); -+ -+ return 0; -+} -+ -diff -urN 2.0.30/linux/fs/filesystems.c linux/fs/filesystems.c ---- 2.0.30/linux/fs/filesystems.c Thu Apr 25 02:32:39 1996 -+++ linux/fs/filesystems.c Thu May 1 12:35:18 1997 -@@ -24,6 +24,7 @@ - #include - #include - #include -+#include - #include - - extern void device_setup(void); -@@ -110,6 +111,9 @@ - init_ufs_fs(); - #endif - -+#ifdef CONFIG_AUTOFS_FS -+ init_autofs_fs(); -+#endif - mount_root(); - return 0; - } -diff -urN 2.0.30/linux/include/linux/auto_fs.h linux/include/linux/auto_fs.h ---- 2.0.30/linux/include/linux/auto_fs.h Wed Dec 31 16:00:00 1969 -+++ linux/include/linux/auto_fs.h Wed May 28 21:38:59 1997 -@@ -0,0 +1,62 @@ -+/* -*- linux-c -*- ------------------------------------------------------- * -+ * -+ * linux/include/linux/auto_fs.h -+ * -+ * Copyright 1997 Transmeta Corporation - All Rights Reserved -+ * -+ * This file is part of the Linux kernel and is made available under -+ * the terms of the GNU General Public License, version 2, or at your -+ * option, any later version, incorporated herein by reference. -+ * -+ * ----------------------------------------------------------------------- */ -+ -+ -+#ifndef _LINUX_AUTO_FS_H -+#define _LINUX_AUTO_FS_H -+ -+#include -+#include -+#include -+#include -+#include -+ -+#define AUTOFS_PROTO_VERSION 3 -+ -+enum autofs_packet_type { -+ autofs_ptype_missing, /* Missing entry (mount request) */ -+ autofs_ptype_expire, /* Expire entry (umount request) */ -+}; -+ -+struct autofs_packet_hdr { -+ int proto_version; /* Protocol version */ -+ enum autofs_packet_type type; /* Type of packet */ -+}; -+ -+struct autofs_packet_missing { -+ struct autofs_packet_hdr hdr; -+ unsigned long wait_queue_token; -+ int len; -+ char name[NAME_MAX+1]; -+}; -+ -+struct autofs_packet_expire { -+ struct autofs_packet_hdr hdr; -+ int len; -+ char name[NAME_MAX+1]; -+}; -+ -+#define AUTOFS_IOC_READY _IO(0x93,0x60) -+#define AUTOFS_IOC_FAIL _IO(0x93,0x61) -+#define AUTOFS_IOC_CATATONIC _IO(0x93,0x62) -+#define AUTOFS_IOC_PROTOVER _IOR(0x93,0x63,int) -+#define AUTOFS_IOC_SETTIMEOUT _IOWR(0x93,0x64,unsigned long) -+#define AUTOFS_IOC_EXPIRE _IOR(0x93,0x65,struct autofs_packet_expire) -+ -+#ifdef __KERNEL__ -+ -+/* Init function */ -+int init_autofs_fs(void); -+ -+#endif /* __KERNEL__ */ -+ -+#endif /* _LINUX_AUTO_FS_H */ -diff -urN 2.0.30/linux/kernel/ksyms.c linux/kernel/ksyms.c ---- 2.0.30/linux/kernel/ksyms.c Tue Mar 11 14:37:16 1997 -+++ linux/kernel/ksyms.c Thu May 1 12:35:18 1997 -@@ -46,6 +46,7 @@ - #include - #include - #include -+#include - - extern unsigned char aux_device_present, kbd_read_mask; - -@@ -170,6 +171,7 @@ - X(generic_file_read), - X(generic_file_mmap), - X(generic_readpage), -+ X(__fput), - - /* device registration */ - X(register_chrdev), diff -urN autofs-0.3.14/man/Makefile autofs-0.3.15-pre5/man/Makefile --- autofs-0.3.14/man/Makefile Sat Sep 20 18:38:50 1997 +++ autofs-0.3.15-pre5/man/Makefile Sat Mar 28 18:03:17 1998 @@ -1,3 +1,5 @@ +# $Id: Makefile,v 1.2 1997/10/06 21:52:01 hpa Exp $ + include ../Makefile.rules install: diff -urN autofs-0.3.14/man/auto.master.5 autofs-0.3.15-pre5/man/auto.master.5 --- autofs-0.3.14/man/auto.master.5 Sat Sep 20 18:38:50 1997 +++ autofs-0.3.15-pre5/man/auto.master.5 Sat Mar 28 18:03:17 1998 @@ -1,4 +1,5 @@ .\" t +.\" $Id: auto.master.5,v 1.2 1997/10/06 21:52:01 hpa Exp $ .TH AUTO.MASTER 5 "9 Sep 1997" .SH NAME /etc/auto.master \- Master Map for automounter diff -urN autofs-0.3.14/man/autofs.5 autofs-0.3.15-pre5/man/autofs.5 --- autofs-0.3.14/man/autofs.5 Sat Sep 20 18:38:50 1997 +++ autofs-0.3.15-pre5/man/autofs.5 Sat Mar 28 18:03:17 1998 @@ -1,5 +1,6 @@ .\" t -.TH AUTOFS 5 "9 Sep 1997" +.\" $Id: autofs.5,v 1.2 1997/10/06 21:52:01 hpa Exp $ +.TH AUTOFS 5 "29 Sep 1997" .SH NAME autofs \- Format of the automounter maps .SH "DESCRIPTION" @@ -42,10 +43,11 @@ The location specifies from where the file system is to be mounted. In the most cases this will be an NFS volume and the usual notation .I host:pathname -is used to indicate the remote filesystem and path to be mounted. If a local -device needs to be specified as the location then a : needs to be prefixed -to the device name (e.g. :/dev/sda1) in order to let the automounter know -that no hostname will be following. +is used to indicate the remote filesystem and path to be mounted. If +the filesystem to be mounted begins with a / (such as local +.I /dev +entries or smbfs shares) a : needs to be prefixed (e.g. +.IR :/dev/sda1 ). .SH EXAMPLE .sp .RS +.2i @@ -53,6 +55,7 @@ .nf kernel -ro,soft,intr ftp.kernel.org:/pub/linux boot -fstype=ext2 :/dev/hda1 +windoze -fstype=smbfs ://windoze/c removable -fstype=ext2 :/dev/hdd cd -fstype=iso9660,ro :/dev/hdc floppy -fstype=auto :/dev/fd0 @@ -62,7 +65,9 @@ In the first line we have a NFS remote mount of the kernel directory on .IR ftp.kernel.org . This is mounted read-only. The second line mounts an ext2 volume on a -local ide drive. The rest should be fairly self explanatory. +local ide drive. The third makes a share exported from a Windows +machine available for automounting. The rest should be fairly +self-explanatory. .SH FEATURES .SS Map Key Substitution An & character in the diff -urN autofs-0.3.14/man/autofs.8 autofs-0.3.15-pre5/man/autofs.8 --- autofs-0.3.14/man/autofs.8 Sat Sep 20 18:38:50 1997 +++ autofs-0.3.15-pre5/man/autofs.8 Sat Mar 28 18:03:17 1998 @@ -1,3 +1,4 @@ +.\" $Id: autofs.8,v 1.2 1997/10/06 21:52:01 hpa Exp $ .TH AUTOFS 8 "9 Sep 1997" .SH NAME /etc/init.d/autofs \- Control Script for automounter diff -urN autofs-0.3.14/man/automount.8 autofs-0.3.15-pre5/man/automount.8 --- autofs-0.3.14/man/automount.8 Sat Sep 20 18:38:50 1997 +++ autofs-0.3.15-pre5/man/automount.8 Sat Mar 28 18:03:17 1998 @@ -6,6 +6,8 @@ .\" .\" This is free documentation. .\" +.\" $Id: automount.8,v 1.4 1998/03/29 02:02:58 hpa Exp $ +.\" .TH AUTOMOUNT 8 "17 Sep 1997" .SH NAME automount \- configure mount points for autofs @@ -52,7 +54,15 @@ line and returns an entry on stdout if successful. .TP .B yp -The map is an NIS (YP) database. +The map is a NIS (YP) database. +.TP +.B nisplus +The map is a NIS+ database. +.TP +.B hesiod +The map is a hesiod database whose +.B filsys +entries are used for maps. .RE .TP \fBformat\fP diff -urN autofs-0.3.14/modules/Makefile autofs-0.3.15-pre5/modules/Makefile --- autofs-0.3.14/modules/Makefile Sat Sep 20 18:38:50 1997 +++ autofs-0.3.15-pre5/modules/Makefile Sat Mar 28 18:03:17 1998 @@ -1,16 +1,30 @@ +# $Id: Makefile,v 1.6 1998/03/29 02:03:06 hpa Exp $ # # 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_ext2.c mount_nfs.c mount_smbfs.c \ + mount_afs.c mount_autofs.c + +MODS = lookup_yp.so lookup_file.so lookup_program.so \ + parse_sun.so \ + mount_generic.so mount_ext2.so mount_nfs.so mount_smbfs.so \ + mount_afs.so mount_autofs.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) @@ -26,5 +40,15 @@ # Ad hoc compilation rules for modules which need auxilliary libraries # lookup_yp.so: lookup_yp.c - $(CC) $(SOLDFLAGS) $(CFLAGS) -o lookup_yp.so lookup_yp.c $(YPLIBS) + $(CC) $(SOLDFLAGS) $(CFLAGS) -o lookup_yp.so lookup_yp.c $(LIBNSL) $(STRIP) lookup_yp.so + +lookup_nisplus.so: lookup_nisplus.c + $(CC) $(SOLDFLAGS) $(CFLAGS) -o lookup_nisplus.so lookup_nisplus.c \ + $(LIBNSL) + $(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) + $(STRIP) lookup_hesiod.so diff -urN autofs-0.3.14/modules/lookup_file.c autofs-0.3.15-pre5/modules/lookup_file.c --- autofs-0.3.14/modules/lookup_file.c Sat Sep 20 18:38:50 1997 +++ autofs-0.3.15-pre5/modules/lookup_file.c Sat Mar 28 18:03:16 1998 @@ -1,8 +1,18 @@ -/* - * lookup_file.c +#ident "$Id: lookup_file.c,v 1.2 1997/10/06 21:52:02 hpa Exp $" +/* ----------------------------------------------------------------------- * + * + * lookup_file.c - module for Linux automount to query a flat file map * - * Module for Linux automountd to access a plain file automount map - */ + * Copyright 1997 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 + * the Free Software Foundation, Inc., 675 Mass Ave, Cambridge MA 02139, + * USA; either version 2 of the License, or (at your option) any later + * version; incorporated herein by reference. + * + * ----------------------------------------------------------------------- */ + #include #include @@ -24,13 +34,14 @@ #define MAPENT_MAX_LEN 4095 struct lookup_context { - char *mapname; + const 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) +int lookup_init(const char *mapfmt, int argc, const char * const *argv, + void **context) { struct lookup_context *ctxt; @@ -61,11 +72,13 @@ return !(ctxt->parse = open_parse(mapfmt,MODPREFIX,argc-1,argv+1)); } -int lookup_mount(char *root, char *name, int name_len, void *context) +int lookup_mount(const char *root, const char *name, int name_len, + void *context) { struct lookup_context *ctxt = (struct lookup_context *) context; int ch, nch; - char mapent[MAPENT_MAX_LEN+1], *p, *nptr; + char mapent[MAPENT_MAX_LEN+1], *p; + const char *nptr; int mapent_len; FILE *f; enum { @@ -88,7 +101,7 @@ gotten = got_nothing; /* Shut up gcc */ - p = nptr = NULL; + nptr = p = NULL; mapent_len = 0; getting = got_nothing; escape = esc_none; diff -urN autofs-0.3.14/modules/lookup_hesiod.c autofs-0.3.15-pre5/modules/lookup_hesiod.c --- autofs-0.3.14/modules/lookup_hesiod.c Wed Dec 31 16:00:00 1969 +++ autofs-0.3.15-pre5/modules/lookup_hesiod.c Sat Mar 28 18:03:16 1998 @@ -0,0 +1,98 @@ +#ident "$Id: lookup_hesiod.c,v 1.3 1998/03/28 03:22:38 hpa Exp $" +/* + * lookup_hesiod.c + * + * Module for Linux automountd to access automount maps in hesiod filsys + * entries. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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(const char *mapfmt, int argc, const char * const *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(const char *root, const char *name, int name_len, void *context) +{ + char **hes_result; + struct lookup_context *ctxt = (struct lookup_context *) context; + int rv; + + 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 ) { + syslog(LOG_NOTICE, MODPREFIX "entry \"%s\" not found in map\n", name); + return 1; + } + + syslog(LOG_DEBUG, MODPREFIX "lookup for \"%s\" gave \"%s\"", + name, hes_result[0]); + rv = ctxt->parser->parse_mount(root,name,name_len,hes_result[0],ctxt->parser->context); + free(hes_result); + return rv; +} + +/* 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 -urN autofs-0.3.14/modules/lookup_nisplus.c autofs-0.3.15-pre5/modules/lookup_nisplus.c --- autofs-0.3.14/modules/lookup_nisplus.c Wed Dec 31 16:00:00 1969 +++ autofs-0.3.15-pre5/modules/lookup_nisplus.c Sat Mar 28 18:03:16 1998 @@ -0,0 +1,104 @@ +#ident "$Id: lookup_nisplus.c,v 1.2 1998/03/29 02:03:06 hpa Exp $" +/* + * lookup_nisplus.c + * + * Module for Linux automountd to access a NIS+ automount map + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MODULE_LOOKUP +#include "automount.h" + +#define MAPFMT_DEFAULT "sun" + +#define MODPREFIX "lookup(nisplus): " + +struct lookup_context { + const char *domainname; + const char *mapname; + struct parse_mod *parse; +}; + +int lookup_version = AUTOFS_LOOKUP_VERSION; /* Required by protocol */ + +int lookup_init(const char *mapfmt, int argc, const char * const *argv, + void **context) +{ + struct lookup_context *ctxt; + + 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]; + + /* nis_local_directory () returns a pointer to a static buffer. + We don't need to copy or free it. */ + ctxt->domainname = nis_local_directory (); + + if ( !mapfmt ) + mapfmt = MAPFMT_DEFAULT; + + return !(ctxt->parse = open_parse(mapfmt,MODPREFIX,argc-1,argv+1)); +} + +int lookup_mount(const char *root, const 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 -urN autofs-0.3.14/modules/lookup_program.c autofs-0.3.15-pre5/modules/lookup_program.c --- autofs-0.3.14/modules/lookup_program.c Sat Sep 20 18:38:50 1997 +++ autofs-0.3.15-pre5/modules/lookup_program.c Sat Mar 28 18:03:16 1998 @@ -1,7 +1,21 @@ -/* - * lookup_program.c +#ident "$Id: lookup_program.c,v 1.2 1997/10/06 21:52:02 hpa Exp $" +/* ----------------------------------------------------------------------- * + * + * lookup_program.c - module for Linux automount to access an + * automount map via a query program + * + * Copyright 1997 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 + * the Free Software Foundation, Inc., 675 Mass Ave, Cambridge MA 02139, + * USA; either version 2 of the License, or (at your option) any later + * version; incorporated herein by reference. * - * Module for Linux automountd to access a automount map via a query program + * ----------------------------------------------------------------------- */ + +/* + */ #include @@ -28,13 +42,14 @@ #define MAPENT_MAX_LEN 4095 struct lookup_context { - char *mapname; + const 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) +int lookup_init(const char *mapfmt, int argc, const char * const *argv, + void **context) { struct lookup_context *ctxt; @@ -65,7 +80,8 @@ return !(ctxt->parse = open_parse(mapfmt,MODPREFIX,argc-1,argv+1)); } -int lookup_mount(char *root, char *name, int name_len, void *context) +int lookup_mount(const char *root, const char *name, int name_len, + void *context) { struct lookup_context *ctxt = (struct lookup_context *) context; char mapent[MAPENT_MAX_LEN+1], *mapp; diff -urN autofs-0.3.14/modules/lookup_yp.c autofs-0.3.15-pre5/modules/lookup_yp.c --- autofs-0.3.14/modules/lookup_yp.c Sat Sep 20 18:38:50 1997 +++ autofs-0.3.15-pre5/modules/lookup_yp.c Sat Mar 28 18:03:16 1998 @@ -1,7 +1,20 @@ -/* - * lookup_yp.c +#ident "$Id: lookup_yp.c,v 1.2 1997/10/06 21:52:03 hpa Exp $" +/* ----------------------------------------------------------------------- * + * + * lookup_yp.c - module for Linux automountd to access a YP (NIS) + * automount map + * + * Copyright 1997 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 + * the Free Software Foundation, Inc., 675 Mass Ave, Cambridge MA 02139, + * USA; either version 2 of the License, or (at your option) any later + * version; incorporated herein by reference. * - * Module for Linux automountd to access a YP (NIS) automount map + * ----------------------------------------------------------------------- */ + +/* */ #include @@ -25,14 +38,15 @@ #define MODPREFIX "lookup(yp): " struct lookup_context { - char *domainname; - char *mapname; + const char *domainname; + const 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) +int lookup_init(const char *mapfmt, int argc, const char * const *argv, + void **context) { struct lookup_context *ctxt; int err; @@ -48,7 +62,8 @@ } ctxt->mapname = argv[0]; - err = yp_get_default_domain(&ctxt->domainname); + /* This should, but doesn't, take a const char ** */ + err = yp_get_default_domain((char **) &ctxt->domainname); if ( err ) { syslog(LOG_CRIT, MODPREFIX "map %s: %s\n", ctxt->mapname, yperr_string(err)); return 1; @@ -60,7 +75,8 @@ return !(ctxt->parse = open_parse(mapfmt,MODPREFIX,argc-1,argv+1)); } -int lookup_mount(char *root, char *name, int name_len, void *context) +int lookup_mount(const char *root, const char *name, + int name_len, void *context) { struct lookup_context *ctxt = (struct lookup_context *) context; char *mapent; @@ -69,11 +85,16 @@ syslog(LOG_DEBUG, MODPREFIX "looking up %s", name); - err = yp_match(ctxt->domainname,ctxt->mapname,name,name_len,&mapent,&mapent_len); + /* For reasons unknown, the standard YP definitions doesn't define input + strings as const char *. However, my understanding is that they will + not be modified by the library. */ + err = yp_match((char *) ctxt->domainname, (char *) ctxt->mapname, + (char *) name, name_len, &mapent, &mapent_len); if ( err == YPERR_KEY ) { /* Try to get the "*" entry if there is one - note that we *don't* modify "name" so & -> the name we used, not "*" */ - err = yp_match(ctxt->domainname,ctxt->mapname,"*",1,&mapent,&mapent_len); + err = yp_match((char *) ctxt->domainname, (char *) ctxt->mapname, + "*", 1, &mapent, &mapent_len); } if ( err ) { syslog(LOG_NOTICE, MODPREFIX "lookup for %s failed: %s", name, yperr_string(err)); diff -urN autofs-0.3.14/modules/mount_afs.c autofs-0.3.15-pre5/modules/mount_afs.c --- autofs-0.3.14/modules/mount_afs.c Wed Dec 31 16:00:00 1969 +++ autofs-0.3.15-pre5/modules/mount_afs.c Sat Mar 28 18:03:16 1998 @@ -0,0 +1,55 @@ +#ident "$Id: mount_afs.c,v 1.1 1998/03/27 04:15:49 hpa Exp $" +/* + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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 -urN autofs-0.3.14/modules/mount_autofs.c autofs-0.3.15-pre5/modules/mount_autofs.c --- autofs-0.3.14/modules/mount_autofs.c Wed Dec 31 16:00:00 1969 +++ autofs-0.3.15-pre5/modules/mount_autofs.c Sat Mar 28 18:03:17 1998 @@ -0,0 +1,136 @@ +#ident "$Id: mount_autofs.c,v 1.2 1998/03/27 06:14:15 hpa Exp $" +/* + * mount_autofs.c + * + * Module for recursive autofs mounts. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MODULE_MOUNT +#include "automount.h" + +#define MODPREFIX "mount(autofs): " +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 *c_options, + void *context) +{ + char *fullpath, **argv; + int argc, status; + char *options, *p; + pid_t slave, wp; + + fullpath = alloca(strlen(root)+name_len+2); + if ( !fullpath ) { + syslog(LOG_ERR, MODPREFIX "alloca: %m"); + return 1; + } + sprintf(fullpath, "%s/%s", root, name); + + options = alloca(strlen(c_options)+1); + if ( !options ) { + syslog(LOG_ERR, MODPREFIX "alloca: %m"); + return 1; + } + strcpy(options, c_options); + + syslog(LOG_DEBUG, MODPREFIX "calling mkdir %s", fullpath); + if ( mkdir(fullpath, 0555) && errno != EEXIST ) { + syslog(LOG_NOTICE, MODPREFIX "mkdir %s failed: %m", name); + return 1; + } + + syslog(LOG_DEBUG, MODPREFIX "fullpath=%s what=%s options=%s", + fullpath, what, options); + + /* Build our argument vector. */ + + argc = 5; + if ( options ) { + char *p = options; + do { + argc++; + } while ((p = strchr(p,',')) != NULL); + } + argv = (char **) alloca((argc+1) * sizeof(char *)); + + argc = 0; + argv[argc++] = _PATH_AUTOMOUNT; + argv[argc++] = "--submount"; + argv[argc++] = fullpath; + argv[argc++] = strcpy(alloca(strlen(what)+1), what); + + if ( (p = strchr(argv[argc-1], ':')) == NULL ) { + syslog(LOG_NOTICE, MODPREFIX "%s missing script type on %s", name, what); + goto error; + } + + argv[argc++] = p; + + if ( options ) { + argv[argc++] = strtok(options, ","); + while ((argv[argc++] = strtok(NULL, ",")) != NULL) + continue; + } + argv[argc] = NULL; + + /* Spawn a new daemon. If initialization is successful, the daemon will send + itself SIGSTOP, which we detect and let it go on its merry way. */ + + slave = fork(); + if ( slave < 0 ) { + syslog(LOG_ERR, MODPREFIX "fork: %m"); + goto error; + } else if ( slave == 0 ) { + /* Slave process */ + execv(_PATH_AUTOMOUNT, argv); + _exit(255); + } + + while ( (wp = waitpid(slave, &status, WUNTRACED)) == -1 && errno == EINTR ); + if ( wp != slave ) { + syslog(LOG_NOTICE, MODPREFIX "waitpid: %m"); + goto error; + } + + if ( !WIFSTOPPED(status) || WSTOPSIG(status) != SIGSTOP ) { + syslog(LOG_NOTICE, MODPREFIX "sub automount returned status 0x%x", status); + goto error; + } + + kill(slave, SIGCONT); /* Carry on, private */ + + syslog(LOG_DEBUG, MODPREFIX "mounted %s on %s", what, fullpath); + return 0; + +error: + rmdir(fullpath); + syslog(LOG_NOTICE, MODPREFIX "failed to mount %s on %s", what, fullpath); + return 1; +} + +int mount_done(void *context) +{ + return 0; +} diff -urN autofs-0.3.14/modules/mount_ext2.c autofs-0.3.15-pre5/modules/mount_ext2.c --- autofs-0.3.14/modules/mount_ext2.c Wed Dec 31 16:00:00 1969 +++ autofs-0.3.15-pre5/modules/mount_ext2.c Sat Mar 28 18:03:16 1998 @@ -0,0 +1,94 @@ +#ident "$Id: mount_ext2.c,v 1.1 1998/03/27 04:59:37 hpa Exp $" +/* ----------------------------------------------------------------------- * + * + * mount_ext2.c - module for Linux automountd to mount ext2 filesystems + * after running fsck on them. + * + * Copyright 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 + * the Free Software Foundation, Inc., 675 Mass Ave, Cambridge MA 02139, + * USA; either version 2 of the License, or (at your option) any later + * version; incorporated herein by reference. + * + * ----------------------------------------------------------------------- */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MODULE_MOUNT +#include "automount.h" + +#define MODPREFIX "mount(ext2): " +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 *fullpath; + int err; + + fullpath = alloca(strlen(root)+name_len+2); + if ( !fullpath ) { + syslog(LOG_ERR, MODPREFIX "alloca: %m"); + return 1; + } + sprintf(fullpath, "%s/%s", root, name); + + syslog(LOG_DEBUG, MODPREFIX "calling mkdir %s", fullpath); + if ( mkdir(fullpath, 0555) && errno != EEXIST ) { + syslog(LOG_NOTICE, MODPREFIX "mkdir %s failed: %m", name); + return 1; + } + + syslog(LOG_DEBUG, MODPREFIX "calling fsck.ext2 -p %s", what); + err = spawnl(LOG_DEBUG, _PATH_E2FSCK, _PATH_E2FSCK, "-p", what, NULL); + if ( err & ~7 ) { + syslog(LOG_ERR, MODPREFIX "%s: filesystem needs repair, won't mount", + what); + return 1; + } + + if ( options ) { + syslog(LOG_DEBUG, MODPREFIX "calling mount -t %s -o %s %s %s", + fstype, options, what, fullpath); + err = spawnl(LOG_NOTICE, _PATH_MOUNT, _PATH_MOUNT, "-t", fstype, + "-o", options, what, fullpath, NULL); + } else { + syslog(LOG_DEBUG, MODPREFIX "calling mount -t %s %s %s", + fstype, what, fullpath); + err = spawnl(LOG_NOTICE, _PATH_MOUNT, _PATH_MOUNT, "-t", fstype, + what, fullpath, NULL); + } + if ( err ) { + rmdir(fullpath); + syslog(LOG_NOTICE, MODPREFIX "failed to mount %s (type %s) on %s", + what, fstype, fullpath); + return 1; + } else { + syslog(LOG_DEBUG, MODPREFIX "mounted %s type %s on %s", + what, fstype, fullpath); + return 0; + } +} + +int mount_done(void *context) +{ + return 0; +} diff -urN autofs-0.3.14/modules/mount_generic.c autofs-0.3.15-pre5/modules/mount_generic.c --- autofs-0.3.14/modules/mount_generic.c Sat Sep 20 18:38:50 1997 +++ autofs-0.3.15-pre5/modules/mount_generic.c Sat Mar 28 18:03:16 1998 @@ -1,10 +1,18 @@ -/* - * mount_generic.c +#ident "$Id: mount_generic.c,v 1.2 1997/10/06 21:52:03 hpa Exp $" +/* ----------------------------------------------------------------------- * + * + * mount_generic.c - module for Linux automountd to mount filesystems + * for which no special magic is required * - * Module for Linux automountd to mount filesystems for which no special - * magic is required + * Copyright 1997 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 + * the Free Software Foundation, Inc., 675 Mass Ave, Cambridge MA 02139, + * USA; either version 2 of the License, or (at your option) any later + * version; incorporated herein by reference. + * + * ----------------------------------------------------------------------- */ #include #include @@ -29,8 +37,9 @@ return 0; } -int mount_mount(char *root, char *name, int name_len, char *what, - char *fstype, char *options, void *context) +int mount_mount(const char *root, const char *name, int name_len, + const char *what, const char *fstype, const char *options, + void *context) { char *fullpath; int err; diff -urN autofs-0.3.14/modules/mount_nfs.c autofs-0.3.15-pre5/modules/mount_nfs.c --- autofs-0.3.14/modules/mount_nfs.c Sat Sep 20 18:38:50 1997 +++ autofs-0.3.15-pre5/modules/mount_nfs.c Sat Mar 28 18:03:16 1998 @@ -1,10 +1,18 @@ -/* - * mount_nfs.c +#ident "$Id: mount_nfs.c,v 1.2 1997/10/06 21:52:03 hpa Exp $" +/* ----------------------------------------------------------------------- * + * + * mount_nfs.c - Module for Linux automountd to mount an NFS filesystem, + * with fallback to symlinking if the path is local * - * Module for Linux automountd to mount an NFS filesystem, with fallback to - * symlinking if the path is local + * Copyright 1997 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 + * the Free Software Foundation, Inc., 675 Mass Ave, Cambridge MA 02139, + * USA; either version 2 of the License, or (at your option) any later + * version; incorporated herein by reference. + * + * ----------------------------------------------------------------------- */ #include #include @@ -46,8 +54,9 @@ return 0; } -int mount_mount(char *root, char *name, int name_len, char *what, - char *fstype, char *options, void *context) +int mount_mount(const char *root, const char *name, int name_len, + const char *what, const char *fstype, + const char *options, void *context) { char *colon, **haddr, *fullpath; struct hostent *he; diff -urN autofs-0.3.14/modules/mount_smbfs.c autofs-0.3.15-pre5/modules/mount_smbfs.c --- autofs-0.3.14/modules/mount_smbfs.c Sat Sep 20 18:38:50 1997 +++ autofs-0.3.15-pre5/modules/mount_smbfs.c Sat Mar 28 18:03:16 1998 @@ -1,3 +1,4 @@ +#ident "$Id: mount_smbfs.c,v 1.2 1997/10/06 21:52:03 hpa Exp $" /* ----------------------------------------------------------------------- * * * mount_smbfs.c @@ -62,7 +63,8 @@ return 0; } -static int smb_parse_options(char *optstr,char **argv,char *qbuf,int *qbuflen) +static int smb_parse_options(char *optstr, const char **argv, + char *qbuf, int *qbuflen) { char *opt; int ln; @@ -123,14 +125,15 @@ return argc; } -int mount_mount(char *root, char *name, int name_len, char *what, - char *fstype, char *options, void *context) +int mount_mount(const char *root, const char *name, int name_len, + const char *what, const char *fstype, const char *options, + void *context) { char *fullpath, *optcopy; int err; char *qbuf; int argc, optsize, qbuflen; - char **argv; + const char **argv; fullpath = alloca(strlen(root)+name_len+2); optcopy = alloca(optsize = strlen(options)+1); diff -urN autofs-0.3.14/modules/parse_hesiod.c autofs-0.3.15-pre5/modules/parse_hesiod.c --- autofs-0.3.14/modules/parse_hesiod.c Wed Dec 31 16:00:00 1969 +++ autofs-0.3.15-pre5/modules/parse_hesiod.c Sat Mar 28 18:03:16 1998 @@ -0,0 +1,209 @@ +#ident "$Id: parse_hesiod.c,v 1.2 1998/03/28 03:22:38 hpa Exp $" +/* + * parse_hesiod.c + * + * Module for Linux automountd to parse a hesiod filesystem entry. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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(const char *filsysline, const char *name, int name_len, + char *source, int source_len, + char *options, int options_len) +{ + const 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(const char *filsysline, const char *name, int name_len, + char *source, int source_len, + char *options, int options_len) +{ + const 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(const char *filsysline, const char *name, int name_len, + char *source, int source_len, + char *options, int options_len) +{ + const 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, const char * const *argv, void **context) +{ + return 0; +} + +int parse_done(void *context) +{ + return 0; +} + +int parse_mount(const char *root, const char *name, + int name_len, const char *mapent, void *context) +{ + char source[HESIOD_LEN+1], + fstype[HESIOD_LEN+1], + options[HESIOD_LEN+1], + *q; + const char *p; + + 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); +} diff -urN autofs-0.3.14/modules/parse_sun.c autofs-0.3.15-pre5/modules/parse_sun.c --- autofs-0.3.14/modules/parse_sun.c Sat Sep 20 18:38:50 1997 +++ autofs-0.3.15-pre5/modules/parse_sun.c Sat Mar 28 18:03:16 1998 @@ -1,8 +1,18 @@ -/* - * parse_sun.c +#ident "$Id: parse_sun.c,v 1.2 1997/10/06 21:52:03 hpa Exp $" +/* ----------------------------------------------------------------------- * + * + * parse_sun.c - module for Linux automountd to parse a Sun-format + * automounter map + * + * Copyright 1997 Transmeta Corporation - All Rights Reserved * - * Module for Linux automountd to parse a Sun-format automounter map - */ + * 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 + * the Free Software Foundation, Inc., 675 Mass Ave, Cambridge MA 02139, + * USA; either version 2 of the License, or (at your option) any later + * version; incorporated herein by reference. + * + * ----------------------------------------------------------------------- */ #include #include @@ -80,7 +90,8 @@ } /* Find the $-variable matching a certain string fragment */ -static struct substvar *findvar(struct substvar *sv, char *str, int len) +static const struct substvar *findvar(const struct substvar *sv, + const char *str, int len) { while ( sv ) { if ( !strncmp(str,sv->def,len) && sv->def[len] == '\0' ) @@ -92,12 +103,13 @@ /* $- and &-expand a Sun-style map entry and return the length of the entry. If "dst" is NULL, just count the length. */ -static int expandsunent(char *src, char *dst, char *key, struct substvar *svc, - int slashify_colons) +static int expandsunent(const char *src, char *dst, const char *key, + const struct substvar *svc, int slashify_colons) { - struct substvar *sv; + const struct substvar *sv; int len, l, seen_colons; - char *p, ch; + const char *p; + char ch; len = 0; seen_colons = 0; @@ -224,7 +236,7 @@ /* Compare str with pat. Return 0 if compare equal or str is an abbreviation of pat of no less than mchr characters. */ -int strmcmp(char *str, char *pat, int mchr) +int strmcmp(const char *str, const char *pat, int mchr) { int nchr = 0; @@ -239,11 +251,12 @@ return *pat - *str; } -int parse_init(int argc, char **argv, void **context) +int parse_init(int argc, const char * const *argv, void **context) { struct parse_context *ctxt; struct substvar *sv; char *noptstr; + const char *xopt; int optlen, len; int i, bval; @@ -307,16 +320,15 @@ case '-': if ( !strncmp(argv[i]+2, "no-", 3) ) { - noptstr = argv[i]+5; + xopt = argv[i]+5; bval = 0; } else { - noptstr = argv[i]+2; + xopt = argv[i]+2; bval = 1; } - if ( strmcmp(noptstr, "slashify-colons", 1) ) { + if ( strmcmp(xopt, "slashify-colons", 1) ) ctxt->slashify_colons = bval; - } else syslog(LOG_ERR, MODPREFIX "unknown option: %s", argv[i]); @@ -366,7 +378,8 @@ } } -int parse_mount(char *root, char *name, int name_len, char *mapent, void *context) +int parse_mount(const char *root, const char *name, + int name_len, const char *mapent, void *context) { struct parse_context *ctxt = (struct parse_context *) context; char *pmapent, *options, *noptions, *ent, *p, *q, *fstype; diff -urN autofs-0.3.14/samples/auto.master autofs-0.3.15-pre5/samples/auto.master --- autofs-0.3.14/samples/auto.master Sat Sep 20 18:38:50 1997 +++ autofs-0.3.15-pre5/samples/auto.master Sat Mar 28 18:03:17 1998 @@ -1,3 +1,4 @@ +# $Id: auto.master,v 1.2 1997/10/06 21:52:03 hpa Exp $ # Sample auto.master file # Format of this file: # mountpoint map options diff -urN autofs-0.3.14/samples/auto.misc autofs-0.3.15-pre5/samples/auto.misc --- autofs-0.3.14/samples/auto.misc Sat Sep 20 18:38:50 1997 +++ autofs-0.3.15-pre5/samples/auto.misc Sat Mar 28 18:03:17 1998 @@ -1,3 +1,4 @@ +# $Id: auto.misc,v 1.2 1997/10/06 21:52:04 hpa Exp $ # This is an automounter map and it has the following format # key [ -mount-options-separated-by-comma ] location # Details may be found in the autofs(5) manpage diff -urN autofs-0.3.14/samples/rc.autofs autofs-0.3.15-pre5/samples/rc.autofs --- autofs-0.3.14/samples/rc.autofs Sat Sep 20 18:38:50 1997 +++ autofs-0.3.15-pre5/samples/rc.autofs Sat Mar 28 18:03:17 1998 @@ -1,5 +1,7 @@ #! /bin/bash # +# $Id: rc.autofs,v 1.3 1998/03/28 03:22:38 hpa Exp $ +# # rc file for automount using a Sun-style "master map". # We first look for a local /etc/auto.master, then a YP # map with that name @@ -49,8 +51,10 @@ options=`echo "$options" | sed -e 's/\(^\|[ \t]\)-/\1/g'` if [ -x $map ]; then echo "automount $dir program $map $options $localoptions" - else + elif [ -f $map ]; then echo "automount $dir file $map $options $localoptions" + else + echo "automount $dir `basename $map` $options $localoptions" fi fi done