]> git.neil.brown.name Git - history.git/commitdiff
Add support for text mount option string to ncpfs.
authorPetr Vandrovec <vandrove@vc.cvut.cz>
Fri, 20 Sep 2002 22:34:14 +0000 (00:34 +0200)
committerPetr Vandrovec <vandrove@vc.cvut.cz>
Fri, 20 Sep 2002 22:34:14 +0000 (00:34 +0200)
fs/ncpfs/Makefile
fs/ncpfs/getopt.c [new file with mode: 0644]
fs/ncpfs/getopt.h [new file with mode: 0644]
fs/ncpfs/inode.c
include/linux/ncp_mount.h

index f28ef2850982418ed158a51470aacc068435c380..60bcf9e2a5284f91638d73882763bff9e4a2b6dc 100644 (file)
@@ -5,7 +5,7 @@
 obj-$(CONFIG_NCP_FS) += ncpfs.o
 
 ncpfs-objs   := dir.o file.o inode.o ioctl.o mmap.o ncplib_kernel.o sock.o \
-               ncpsign_kernel.o
+               ncpsign_kernel.o getopt.o
 ifeq ($(CONFIG_NCPFS_EXTRAS),y)
 ncpfs-objs   += symlink.o
 endif
diff --git a/fs/ncpfs/getopt.c b/fs/ncpfs/getopt.c
new file mode 100644 (file)
index 0000000..335b003
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ * getopt.c
+ */
+
+#include <linux/kernel.h>
+#include <linux/string.h>
+
+#include <asm/errno.h>
+
+#include "getopt.h"
+
+/**
+ *     ncp_getopt - option parser
+ *     @caller: name of the caller, for error messages
+ *     @options: the options string
+ *     @opts: an array of &struct option entries controlling parser operations
+ *     @optopt: output; will contain the current option
+ *     @optarg: output; will contain the value (if one exists)
+ *     @flag: output; may be NULL; should point to a long for or'ing flags
+ *     @value: output; may be NULL; will be overwritten with the integer value
+ *             of the current argument.
+ *
+ *     Helper to parse options on the format used by mount ("a=b,c=d,e,f").
+ *     Returns opts->val if a matching entry in the 'opts' array is found,
+ *     0 when no more tokens are found, -1 if an error is encountered.
+ */
+int ncp_getopt(const char *caller, char **options, const struct ncp_option *opts,
+              char **optopt, char **optarg, unsigned long *value)
+{
+       char *token;
+       char *val;
+
+       do {
+               if ((token = strsep(options, ",")) == NULL)
+                       return 0;
+       } while (*token == '\0');
+       if (optopt)
+               *optopt = token;
+
+       if ((val = strchr (token, '=')) != NULL) {
+               *val++ = 0;
+       }
+       *optarg = val;
+       for (; opts->name; opts++) {
+               if (!strcmp(opts->name, token)) {
+                       if (!val) {
+                               if (opts->has_arg & OPT_NOPARAM) {
+                                       return opts->val;
+                               }
+                               printk(KERN_INFO "%s: the %s option requires an argument\n",
+                                      caller, token);
+                               return -EINVAL;
+                       }
+                       if (opts->has_arg & OPT_INT) {
+                               char* v;
+
+                               *value = simple_strtoul(val, &v, 0);
+                               if (!*v) {
+                                       return opts->val;
+                               }
+                               printk(KERN_INFO "%s: invalid numeric value in %s=%s\n",
+                                       caller, token, val);
+                               return -EDOM;
+                       }
+                       if (opts->has_arg & OPT_STRING) {
+                               return opts->val;
+                       }
+                       printk(KERN_INFO "%s: unexpected argument %s to the %s option\n",
+                               caller, val, token);
+                       return -EINVAL;
+               }
+       }
+       printk(KERN_INFO "%s: Unrecognized mount option %s\n", caller, token);
+       return -EOPNOTSUPP;
+}
diff --git a/fs/ncpfs/getopt.h b/fs/ncpfs/getopt.h
new file mode 100644 (file)
index 0000000..cccc007
--- /dev/null
@@ -0,0 +1,16 @@
+#ifndef _LINUX_GETOPT_H
+#define _LINUX_GETOPT_H
+
+#define OPT_NOPARAM    1
+#define OPT_INT                2
+#define OPT_STRING     4
+struct ncp_option {
+       const char *name;
+       unsigned int has_arg;
+       int val;
+};
+
+extern int ncp_getopt(const char *caller, char **options, const struct ncp_option *opts,
+                     char **optopt, char **optarg, unsigned long *value);
+
+#endif /* _LINUX_GETOPT_H */
index 0a49d6a48d5f3bba6046cc0665f4793cc018cc61..c42a026b1448d7133306ea2acc0ae1374485b6ed 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/ncp_fs.h>
 
 #include "ncplib_kernel.h"
+#include "getopt.h"
 
 static void ncp_delete_inode(struct inode *);
 static void ncp_put_super(struct super_block *);
@@ -283,6 +284,88 @@ ncp_delete_inode(struct inode *inode)
        clear_inode(inode);
 }
 
+static const struct ncp_option ncp_opts[] = {
+       { "uid",        OPT_INT,        'u' },
+       { "gid",        OPT_INT,        'g' },
+       { "owner",      OPT_INT,        'o' },
+       { "mode",       OPT_INT,        'm' },
+       { "dirmode",    OPT_INT,        'd' },
+       { "timeout",    OPT_INT,        't' },
+       { "retry",      OPT_INT,        'r' },
+       { "flags",      OPT_INT,        'f' },
+       { "wdogpid",    OPT_INT,        'w' },
+       { "ncpfd",      OPT_INT,        'n' },
+       { "version",    OPT_INT,        'v' },
+       { NULL,         0,              0 } };
+
+static int ncp_parse_options(struct ncp_mount_data_kernel *data, char *options) {
+       int optval;
+       char *optarg;
+       unsigned long optint;
+       int version = 0;
+
+       data->flags = 0;
+       data->int_flags = 0;
+       data->mounted_uid = 0;
+       data->wdog_pid = -1;
+       data->ncp_fd = ~0;
+       data->time_out = 10;
+       data->retry_count = 20;
+       data->uid = 0;
+       data->gid = 0;
+       data->file_mode = 0600;
+       data->dir_mode = 0700;
+       data->mounted_vol[0] = 0;
+       
+       while ((optval = ncp_getopt("ncpfs", &options, ncp_opts, NULL, &optarg, &optint)) != 0) {
+               if (optval < 0)
+                       return optval;
+               switch (optval) {
+                       case 'u':
+                               data->uid = optint;
+                               break;
+                       case 'g':
+                               data->gid = optint;
+                               break;
+                       case 'o':
+                               data->mounted_uid = optint;
+                               break;
+                       case 'm':
+                               data->file_mode = optint;
+                               break;
+                       case 'd':
+                               data->dir_mode = optint;
+                               break;
+                       case 't':
+                               data->time_out = optint;
+                               break;
+                       case 'r':
+                               data->retry_count = optint;
+                               break;
+                       case 'f':
+                               data->flags = optint;
+                               break;
+                       case 'w':
+                               data->wdog_pid = optint;
+                               break;
+                       case 'n':
+                               data->ncp_fd = optint;
+                               break;
+                       case 'v':
+                               if (optint < NCP_MOUNT_VERSION_V4) {
+                                       return -ECHRNG;
+                               }
+                               if (optint > NCP_MOUNT_VERSION_V4) {
+                                       return -ECHRNG;
+                               }
+                               version = optint;
+                               break;
+                       
+               }
+       }
+       return 0;
+}
+
 static int ncp_fill_super(struct super_block *sb, void *raw_data, int silent)
 {
        struct ncp_mount_data_kernel data;
@@ -347,7 +430,12 @@ static int ncp_fill_super(struct super_block *sb, void *raw_data, int silent)
                        break;
                default:
                        error = -ECHRNG;
-                       goto out;
+                       if (*(__u32*)raw_data == cpu_to_be32(0x76657273)) {
+                               error = ncp_parse_options(&data, raw_data);
+                       }
+                       if (error)
+                               goto out;
+                       break;
        }
        error = -EBADF;
        ncp_filp = fget(data.ncp_fd);
index 4bdcfff1f79e5f45b6f36121059f0a055baffc79..38880685f6f6a600b3c8ebfc48b38975e56131bc 100644 (file)
@@ -11,7 +11,7 @@
 #include <linux/types.h>
 #include <linux/ncp.h>
 
-#define NCP_MOUNT_VERSION 3
+#define NCP_MOUNT_VERSION 3    /* Binary */
 
 /* Values for flags */
 #define NCP_MOUNT_SOFT         0x0001
@@ -41,7 +41,7 @@ struct ncp_mount_data {
        __kernel_mode_t dir_mode;
 };
 
-#define NCP_MOUNT_VERSION_V4   (4)
+#define NCP_MOUNT_VERSION_V4   (4)     /* Binary or text */
 
 struct ncp_mount_data_v4 {
        int version;