From patchwork Sun May 9 13:29:40 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Scott Lovenberg X-Patchwork-Id: 52000 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.samba.org (fn.samba.org [216.83.154.106]) by ozlabs.org (Postfix) with ESMTP id 52A18B7D61 for ; Sun, 9 May 2010 23:29:51 +1000 (EST) Received: from fn.samba.org (localhost [127.0.0.1]) by lists.samba.org (Postfix) with ESMTP id 06E4346577; Sun, 9 May 2010 07:29:51 -0600 (MDT) X-Spam-Checker-Version: SpamAssassin 3.2.5 (2008-06-10) on fn.samba.org X-Spam-Level: X-Spam-Status: No, score=-3.1 required=3.8 tests=AWL, BAYES_00, NO_MORE_FUNN, SPF_PASS autolearn=no version=3.2.5 X-Original-To: linux-cifs-client@lists.samba.org Delivered-To: linux-cifs-client@lists.samba.org Received: from mail-qy0-f184.google.com (mail-qy0-f184.google.com [209.85.221.184]) by lists.samba.org (Postfix) with ESMTP id 16CFD46577 for ; Sun, 9 May 2010 07:29:44 -0600 (MDT) Received: by qyk14 with SMTP id 14so353558qyk.17 for ; Sun, 09 May 2010 06:29:43 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:received:received:from:to:cc:subject:date :message-id:x-mailer:in-reply-to:references:content-type :content-transfer-encoding; bh=lauNOLaO/6BMBn0aGlaFdcoMO5Hsl/BxCSW5xaHtfwk=; b=VG690XuTwS+TN1uEnW/6RpjKPvukvNtuq2C8vxmK2hTPnH2Qm1yt344MGiqTuPvgD6 w09nxN1cLjVoGpS+uipl7E4gCMunqRCXdam/f5RB+W9J6MIw1foNwtqlhj9qnhW2dAdw 3a59+iO6mI4AGI/988Dc2D9UbiCE2LDGzYmGU= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references :content-type:content-transfer-encoding; b=AxgmHOGxXjz8Z0k1UNXh6MWOjpWHwn1bUOK+N7C94I9BgvQ8YbH6AlN9TCNV/H0CtI ZFSPofpd3Y64w2PznJgbyDOw7Z+r4BeJVaGO27kcV170UHtmhfjy2acF7rE49ryBPJ2m ekLdIYL1THF7Aa+2TSKciz6bT6U36a09PzFeE= Received: by 10.224.17.217 with SMTP id t25mr1667764qaa.86.1273411783199; Sun, 09 May 2010 06:29:43 -0700 (PDT) Received: from localhost.localdomain (24.115.161.116.res-cmts.flt.ptd.net [24.115.161.116]) by mx.google.com with ESMTPS id g19sm2840772qcq.23.2010.05.09.06.29.41 (version=TLSv1/SSLv3 cipher=RC4-MD5); Sun, 09 May 2010 06:29:42 -0700 (PDT) From: Scott Lovenberg To: linux-cifs-client@lists.samba.org Date: Sun, 9 May 2010 09:29:40 -0400 Message-Id: <1273411780-10746-1-git-send-email-scott.lovenberg@gmail.com> X-Mailer: git-send-email 1.6.2.5 In-Reply-To: <1272549497-6578-1-git-send-email-scott.lovenberg@gmail.com> References: <1272549497-6578-1-git-send-email-scott.lovenberg@gmail.com> Cc: jlayton@samba.org Subject: [linux-cifs-client] [PATCH] Clean up option parsing in mount.cifs X-BeenThere: linux-cifs-client@lists.samba.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: The Linux CIFS VFS client List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: linux-cifs-client-bounces@lists.samba.org Errors-To: linux-cifs-client-bounces@lists.samba.org Moved option string parsing to function parse_opt_token(char*). Main loop in parse_options(const char*, struct parsed_mount_info*) transplanted to a switch block. The parsing function folds common options to a single macro: 1.) 'unc','target', and 'path' -> 'OPT_UNC' 2.) 'dom*' and 'workg*' -> 'OPT_DOM' 3.) 'nobrl' and 'nolock' -> 'OPT_NO_LOCK' Kept 'fmask' and 'dmask' (OPT_FMASK, OPT_DMASK), which fall through to 'file_mode' and 'dir_mode' in the main loop. Signed-off-by: Scott Lovenberg --- mount.cifs.c | 263 +++++++++++++++++++++++++++++++++++++++++---------------- 1 files changed, 189 insertions(+), 74 deletions(-) diff --git a/mount.cifs.c b/mount.cifs.c index 127e6db..a46eeba 100644 --- a/mount.cifs.c +++ b/mount.cifs.c @@ -129,6 +129,38 @@ #define CRED_PASS 2 #define CRED_DOM 4 +/* + * Values for parsing command line options. + */ +#define OPT_ERROR -1 +#define OPT_USERS 1 +#define OPT_USER 2 +#define OPT_USER_XATTR 3 +#define OPT_PASS 4 +#define OPT_SEC 5 +#define OPT_IP 6 +#define OPT_UNC 7 +#define OPT_CRED 8 +#define OPT_UID 9 +#define OPT_GID 10 +#define OPT_FMASK 11 +#define OPT_FILE_MODE 12 +#define OPT_DMASK 13 +#define OPT_DIR_MODE 14 +#define OPT_DOM 15 +#define OPT_NO_SUID 16 +#define OPT_SUID 17 +#define OPT_NO_DEV 18 +#define OPT_DEV 19 +#define OPT_NO_LOCK 20 +#define OPT_NO_EXEC 21 +#define OPT_EXEC 22 +#define OPT_GUEST 23 +#define OPT_RO 24 +#define OPT_RW 25 +#define OPT_REMOUNT 26 + + /* struct for holding parsed mount info for use by privleged process */ struct parsed_mount_info { unsigned long flags; @@ -695,17 +727,83 @@ get_pw_exit: return rc; } +/* + * Returns OPT_ERROR on unparsable token. + */ +static int parse_opt_token(char *token) +{ + if (token == NULL) + return OPT_ERROR; + + if (strncmp(token, "users", 5) == 0) + return OPT_USERS; + if (strncmp(token, "user_xattr", 10) == 0) + return OPT_USER_XATTR; + if (strncmp(token, "user", 4) == 0) + return OPT_USER; + if (strncmp(token, "pass", 4) == 0) + return OPT_PASS; + if (strncmp(token, "sec", 3) == 0) + return OPT_SEC; + if (strncmp(token, "ip", 2) == 0) + return OPT_IP; + if (strncmp(token, "unc", 3) == 0 || + strncmp(token, "target", 6) == 0 || + strncmp(token, "path", 4) == 0) + return OPT_UNC; + if (strncmp(token, "dom", 3) == 0 || strncmp(token, "workg", 5) == 0) + return OPT_DOM; + if (strncmp(token, "uid", 3) == 0) + return OPT_UID; + if (strncmp(token, "gid", 3) == 0) + return OPT_GID; + if (strncmp(token, "fmask", 5) == 0) + return OPT_FMASK; + if (strncmp(token, "file_mode", 9) == 0) + return OPT_FILE_MODE; + if (strncmp(token, "dmask", 5) == 0) + return OPT_DMASK; + if (strncmp(token, "dir_mode", 8) == 0) + return OPT_DIR_MODE; + if (strncmp(token, "nosuid", 6) == 0) + return OPT_NO_SUID; + if (strncmp(token, "suid", 4) == 0) + return OPT_SUID; + if (strncmp(token, "nodev", 5) == 0) + return OPT_NO_DEV; + if (strncmp(token, "nobrl", 5) == 0 || strncmp(token, "nolock", 6) == 0) + return OPT_NO_LOCK; + if (strncmp(token, "dev", 3) == 0) + return OPT_DEV; + if (strncmp(token, "noexec", 6) == 0) + return OPT_NO_EXEC; + if (strncmp(token, "exec", 4) == 0) + return OPT_EXEC; + if (strncmp(token, "guest", 5) == 0) + return OPT_GUEST; + if (strncmp(token, "ro", 2) == 0) + return OPT_RO; + if (strncmp(token, "rw", 2) == 0) + return OPT_RW; + if (strncmp(token, "remount", 7) == 0) + return OPT_REMOUNT; + + return OPT_ERROR; +} + static int parse_options(const char *data, struct parsed_mount_info *parsed_info) { - char *value = NULL, *equals = NULL; + char *value = NULL; + char *equals = NULL; char *next_keyword = NULL; char *out = parsed_info->options; unsigned long *filesys_flags = &parsed_info->flags; int out_len = 0; int word_len; int rc = 0; - int got_uid = 0, got_gid = 0; + int got_uid = 0; + int got_gid = 0; char user[32]; char group[32]; @@ -742,15 +840,15 @@ parse_options(const char *data, struct parsed_mount_info *parsed_info) value = equals + 1; } - /* FIXME: turn into a token parser? */ - if (strncmp(data, "users", 5) == 0) { + switch(parse_opt_token(data)) { + case OPT_USERS: if (!value || !*value) { *filesys_flags |= MS_USERS; goto nocopy; } - } else if (strncmp(data, "user_xattr", 10) == 0) { - /* do nothing - need to skip so not parsed as user name */ - } else if (strncmp(data, "user", 4) == 0) { + break; + + case OPT_USER: if (!value || !*value) { if (data[4] == '\0') { *filesys_flags |= MS_USER; @@ -777,7 +875,8 @@ parse_options(const char *data, struct parsed_mount_info *parsed_info) } goto nocopy; } - } else if (strncmp(data, "pass", 4) == 0) { + + case OPT_PASS: if (parsed_info->got_password) { fprintf(stderr, "password specified twice, ignoring second\n"); @@ -791,18 +890,21 @@ parse_options(const char *data, struct parsed_mount_info *parsed_info) if (rc) return rc; goto nocopy; - } else if (strncmp(data, "sec", 3) == 0) { + + case OPT_SEC: if (value) { if (!strncmp(value, "none", 4) || !strncmp(value, "krb5", 4)) parsed_info->got_password = 1; } - } else if (strncmp(data, "ip", 2) == 0) { + break; + + case OPT_IP: if (!value || !*value) { fprintf(stderr, - "target ip address argument missing"); + "target ip address argument missing\n"); } else if (strnlen(value, MAX_ADDRESS_LEN) <= - MAX_ADDRESS_LEN) { + MAX_ADDRESS_LEN) { if (parsed_info->verboseflag) fprintf(stderr, "ip address %s override specified\n", @@ -810,23 +912,24 @@ parse_options(const char *data, struct parsed_mount_info *parsed_info) } else { fprintf(stderr, "ip address too long\n"); return EX_USAGE; + } - } else if ((strncmp(data, "unc", 3) == 0) - || (strncmp(data, "target", 6) == 0) - || (strncmp(data, "path", 4) == 0)) { + break; + + /* unc || target || path */ + case OPT_UNC: if (!value || !*value) { fprintf(stderr, "invalid path to network resource\n"); - return EX_USAGE; /* needs_arg; */ + return EX_USAGE; } rc = parse_unc(value, parsed_info); if (rc) return rc; - } else if ((strncmp(data, "dom" /* domain */ , 3) == 0) - || (strncmp(data, "workg", 5) == 0)) { - /* note this allows for synonyms of "domain" - such as "DOM" and "dom" and "workgroup" - and "WORKGRP" etc. */ + break; + + /* dom || workgroup */ + case OPT_DOM: if (!value || !*value) { fprintf(stderr, "CIFS: invalid domain name\n"); return EX_USAGE; @@ -839,21 +942,23 @@ parse_options(const char *data, struct parsed_mount_info *parsed_info) strlcpy(parsed_info->domain, value, sizeof(parsed_info->domain)); goto nocopy; - } else if (strncmp(data, "cred", 4) == 0) { - if (value && *value) { - rc = open_cred_file(value, parsed_info); - if (rc) { - fprintf(stderr, - "error %d (%s) opening credential file %s\n", - rc, strerror(rc), value); - return rc; - } - } else { + + case OPT_CRED: + if (!value || !*value) { fprintf(stderr, "invalid credential file name specified\n"); return EX_USAGE; } - } else if (strncmp(data, "uid", 3) == 0) { + rc = open_cred_file(value, parsed_info); + if (rc) { + fprintf(stderr, + "error %d (%s) opening credential file %s\n", + rc, strerror(rc), value); + return rc; + } + break; + + case OPT_UID: if (value && *value) { got_uid = 1; if (!isdigit(*value)) { @@ -867,12 +972,13 @@ parse_options(const char *data, struct parsed_mount_info *parsed_info) } snprintf(user, sizeof(user), "%u", pw->pw_uid); - } else { - strlcpy(user, value, sizeof(user)); } + else + strlcpy(user, value, sizeof(user)); } goto nocopy; - } else if (strncmp(data, "gid", 3) == 0) { + + case OPT_GID: if (value && *value) { got_gid = 1; if (!isdigit(*value)) { @@ -886,14 +992,19 @@ parse_options(const char *data, struct parsed_mount_info *parsed_info) } snprintf(group, sizeof(group), "%u", gr->gr_gid); - } else { - strlcpy(group, value, sizeof(group)); } + else + strlcpy(group, value, sizeof(group)); } goto nocopy; - /* fmask and dmask synonyms for people used to smbfs syntax */ - } else if (strcmp(data, "file_mode") == 0 - || strcmp(data, "fmask") == 0) { + + /* fmask fall through to file_mode */ + case OPT_FMASK: + fprintf(stderr, + "WARNING: CIFS mount option 'fmask' is\ + deprecated. Use 'file_mode' instead.\n"); + data = "file_mode"; /* BB fix this */ + case OPT_FILE_MODE: if (!value || !*value) { fprintf(stderr, "Option '%s' requires a numerical argument\n", @@ -901,19 +1012,19 @@ parse_options(const char *data, struct parsed_mount_info *parsed_info) return EX_USAGE; } - if (value[0] != '0') { + if (value[0] != '0') fprintf(stderr, "WARNING: '%s' not expressed in octal.\n", data); - } + break; - if (strcmp(data, "fmask") == 0) { - fprintf(stderr, - "WARNING: CIFS mount option 'fmask' is deprecated. Use 'file_mode' instead.\n"); - data = "file_mode"; /* BB fix this */ - } - } else if (strcmp(data, "dir_mode") == 0 - || strcmp(data, "dmask") == 0) { + /* dmask falls through to dir_mode */ + case OPT_DMASK: + fprintf(stderr, + "WARNING: CIFS mount option 'dmask' is\ + deprecated. Use 'dir_mode' instead.\n"); + data = "dir_mode"; + case OPT_DIR_MODE: if (!value || !*value) { fprintf(stderr, "Option '%s' requires a numerical argument\n", @@ -921,49 +1032,53 @@ parse_options(const char *data, struct parsed_mount_info *parsed_info) return EX_USAGE; } - if (value[0] != '0') { + if (value[0] != '0') fprintf(stderr, "WARNING: '%s' not expressed in octal.\n", data); - } + break; - if (strcmp(data, "dmask") == 0) { - fprintf(stderr, - "WARNING: CIFS mount option 'dmask' is deprecated. Use 'dir_mode' instead.\n"); - data = "dir_mode"; - } - /* the following eight mount options should be - stripped out from what is passed into the kernel - since these eight options are best passed as the - mount flags rather than redundantly to the kernel - and could generate spurious warnings depending on the - level of the corresponding cifs vfs kernel code */ - } else if (strncmp(data, "nosuid", 6) == 0) { + /* the following mount options should be + stripped out from what is passed into the kernel + since these options are best passed as the + mount flags rather than redundantly to the kernel + and could generate spurious warnings depending on the + level of the corresponding cifs vfs kernel code */ + case OPT_NO_SUID: *filesys_flags |= MS_NOSUID; - } else if (strncmp(data, "suid", 4) == 0) { + break; + case OPT_SUID: *filesys_flags &= ~MS_NOSUID; - } else if (strncmp(data, "nodev", 5) == 0) { + break; + case OPT_NO_DEV: *filesys_flags |= MS_NODEV; - } else if ((strncmp(data, "nobrl", 5) == 0) || - (strncmp(data, "nolock", 6) == 0)) { + break; + /* nolock || nobrl */ + case OPT_NO_LOCK: *filesys_flags &= ~MS_MANDLOCK; - } else if (strncmp(data, "dev", 3) == 0) { + break; + case OPT_DEV: *filesys_flags &= ~MS_NODEV; - } else if (strncmp(data, "noexec", 6) == 0) { + break; + case OPT_NO_EXEC: *filesys_flags |= MS_NOEXEC; - } else if (strncmp(data, "exec", 4) == 0) { + break; + case OPT_EXEC: *filesys_flags &= ~MS_NOEXEC; - } else if (strncmp(data, "guest", 5) == 0) { + break; + case OPT_GUEST: parsed_info->got_user = 1; parsed_info->got_password = 1; - } else if (strncmp(data, "ro", 2) == 0) { + break; + case OPT_RO: *filesys_flags |= MS_RDONLY; goto nocopy; - } else if (strncmp(data, "rw", 2) == 0) { + case OPT_RW: *filesys_flags &= ~MS_RDONLY; goto nocopy; - } else if (strncmp(data, "remount", 7) == 0) { + case OPT_REMOUNT: *filesys_flags |= MS_REMOUNT; + break; } /* check size before copying option to buffer */