aboutsummaryrefslogtreecommitdiffstats
path: root/modules/mount_smbfs.c
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>1997-10-06 21:05:49 +0000
committerH. Peter Anvin <hpa@zytor.com>1997-10-06 21:05:49 +0000
commitbddd43e289c8b8b62d7cb3f1f7eb27ca67cae28e (patch)
treeaac5e4a4b924cb13a54cc0760e99f349ea36bd12 /modules/mount_smbfs.c
downloadautofs3-bddd43e289c8b8b62d7cb3f1f7eb27ca67cae28e.tar.gz
autofs3-bddd43e289c8b8b62d7cb3f1f7eb27ca67cae28e.tar.xz
autofs3-bddd43e289c8b8b62d7cb3f1f7eb27ca67cae28e.zip
Initial revision
Diffstat (limited to 'modules/mount_smbfs.c')
-rw-r--r--modules/mount_smbfs.c180
1 files changed, 180 insertions, 0 deletions
diff --git a/modules/mount_smbfs.c b/modules/mount_smbfs.c
new file mode 100644
index 0000000..200d1f2
--- /dev/null
+++ b/modules/mount_smbfs.c
@@ -0,0 +1,180 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * mount_smbfs.c
+ *
+ * Module for Linux automountd to mount an SMB/CIFS filesystem
+ *
+ * Mount point input format expected is: //server/service[/root_path...]
+ *
+ * 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 <stdio.h>
+#include <malloc.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <syslog.h>
+#include <string.h>
+#include <syslog.h>
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#define MODULE_MOUNT
+#include "automount.h"
+
+#define MODPREFIX "mount(smbfs): "
+int mount_version = AUTOFS_MOUNT_VERSION; /* Required by protocol */
+
+struct smb_mount_opt {
+ char *optname; /* mount-style option name */
+ char *optflag; /* command-line flag for smbmount */
+ int hasarg; /* takes argument? */
+ int satisfies_pwd; /* true if this means we don't need a -n */
+};
+
+static struct smb_mount_opt mount_opt_list[] = {
+ { "nocaps", "-C", 0, 0 },
+ { "guest", "-n", 0, 1 },
+ { "passwd", "-P", 1, 1 },
+ { "srvname", "-s", 1, 0 },
+ { "mysmbname", "-c", 1, 0 },
+ { "login", "-U", 1, 0 },
+ { "uid", "-u", 1, 0 },
+ { "gid", "-g", 1, 0 },
+ { "filemod", "-f", 1, 0 },
+ { "dirmod", "-d", 1, 0 },
+ { "port", "-p", 1, 0 },
+ { "maxxmit", "-m", 1, 0 },
+ { NULL, NULL, 0, 0 }
+};
+
+int mount_init(void **context)
+{
+ return 0;
+}
+
+static int smb_parse_options(char *optstr, const char **argv,
+ char *qbuf, int *qbuflen)
+{
+ char *opt;
+ int ln;
+ int argc;
+ int has_pwd;
+ int qbufchr, qln;
+ struct smb_mount_opt *mount_opt;
+
+ has_pwd = 0;
+ qbufchr = 0;
+ argc = 0;
+
+ if ( optstr ) {
+ for ( opt = strtok(optstr, ",") ; opt ; opt = strtok(NULL, ",") ) {
+ for ( mount_opt = mount_opt_list ; mount_opt->optname ; mount_opt++ ) {
+ if ( mount_opt->hasarg ) {
+ ln = strlen(mount_opt->optname);
+ if ( !strncmp(opt, mount_opt->optname, ln) && opt[ln] == '=' ) {
+ qln = strlen(opt)-ln;
+ if ( argv ) {
+ *(argv++) = mount_opt->optflag;
+ memcpy(qbuf, opt+ln+1, qln);
+ *(argv++) = qbuf;
+ qbuf += qln;
+ }
+ qbufchr += qln;
+ has_pwd = has_pwd || mount_opt->satisfies_pwd;
+ argc += 2;
+ break;
+ }
+ } else {
+ if ( !strcmp(opt, mount_opt->optname) ) {
+ if ( argv )
+ *(argv++) = mount_opt->optflag;
+ has_pwd = has_pwd || mount_opt->satisfies_pwd;
+ argc++;
+ break;
+ }
+ }
+ }
+ /* Ignore unknown options */
+ }
+ }
+
+ if ( !has_pwd ) {
+ syslog(LOG_DEBUG, MODPREFIX "no password option, adding -n");
+ if ( argv )
+ *(argv++) = "-n";
+ argc++;
+ }
+
+ if ( argv )
+ *argv = NULL;
+
+ if ( qbuflen )
+ *qbuflen = qbufchr;
+
+ return argc;
+}
+
+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;
+ const char **argv;
+
+ fullpath = alloca(strlen(root)+name_len+2);
+ optcopy = alloca(optsize = strlen(options)+1);
+ if ( !fullpath || !optcopy ) {
+ syslog(LOG_ERR, MODPREFIX "alloca: %m");
+ return 1;
+ }
+ sprintf(fullpath, "%s/%s", root, name);
+
+ memcpy(optcopy, options, optsize);
+ argc = smb_parse_options(optcopy, NULL, NULL, &qbuflen) + 4;
+ argv = alloca(sizeof(char *) * argc);
+ qbuf = alloca(qbuflen);
+ if ( !argv || (qbuflen && !qbuf) ) {
+ syslog(LOG_ERR, MODPREFIX "alloca: %m");
+ return 1;
+ }
+ argv[0] = _PATH_SMBMOUNT;
+ argv[1] = what;
+ argv[2] = fullpath;
+ memcpy(optcopy, options, optsize);
+ smb_parse_options(optcopy, argv+3, qbuf, NULL);
+
+ 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;
+ }
+
+ err = spawnv(LOG_NOTICE, _PATH_SMBMOUNT, argv);
+
+ if ( err ) {
+ rmdir(fullpath);
+ syslog(LOG_NOTICE, MODPREFIX "failed to mount %s on %s", what, fullpath);
+ return 1;
+ } else {
+ syslog(LOG_DEBUG, MODPREFIX "mounted %s on %s", what, fullpath);
+ return 0;
+ }
+}
+
+int mount_done(void *context)
+{
+ return 0;
+}