Commit | Line | Data |
---|---|---|
b2441318 | 1 | // SPDX-License-Identifier: GPL-2.0 |
1da177e4 LT |
2 | /* |
3 | * getopt.c | |
4 | */ | |
5 | ||
b41f8b84 JP |
6 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
7 | ||
1da177e4 LT |
8 | #include <linux/kernel.h> |
9 | #include <linux/string.h> | |
10 | ||
11 | #include <asm/errno.h> | |
12 | ||
13 | #include "getopt.h" | |
14 | ||
15 | /** | |
16 | * ncp_getopt - option parser | |
17 | * @caller: name of the caller, for error messages | |
18 | * @options: the options string | |
19 | * @opts: an array of &struct option entries controlling parser operations | |
20 | * @optopt: output; will contain the current option | |
21 | * @optarg: output; will contain the value (if one exists) | |
1da177e4 LT |
22 | * @value: output; may be NULL; will be overwritten with the integer value |
23 | * of the current argument. | |
24 | * | |
25 | * Helper to parse options on the format used by mount ("a=b,c=d,e,f"). | |
26 | * Returns opts->val if a matching entry in the 'opts' array is found, | |
27 | * 0 when no more tokens are found, -1 if an error is encountered. | |
28 | */ | |
29 | int ncp_getopt(const char *caller, char **options, const struct ncp_option *opts, | |
30 | char **optopt, char **optarg, unsigned long *value) | |
31 | { | |
32 | char *token; | |
33 | char *val; | |
34 | ||
35 | do { | |
36 | if ((token = strsep(options, ",")) == NULL) | |
37 | return 0; | |
38 | } while (*token == '\0'); | |
39 | if (optopt) | |
40 | *optopt = token; | |
41 | ||
42 | if ((val = strchr (token, '=')) != NULL) { | |
43 | *val++ = 0; | |
44 | } | |
45 | *optarg = val; | |
46 | for (; opts->name; opts++) { | |
47 | if (!strcmp(opts->name, token)) { | |
48 | if (!val) { | |
49 | if (opts->has_arg & OPT_NOPARAM) { | |
50 | return opts->val; | |
51 | } | |
b41f8b84 JP |
52 | pr_info("%s: the %s option requires an argument\n", |
53 | caller, token); | |
1da177e4 LT |
54 | return -EINVAL; |
55 | } | |
56 | if (opts->has_arg & OPT_INT) { | |
8091b895 | 57 | int rc = kstrtoul(val, 0, value); |
1da177e4 | 58 | |
8091b895 FF |
59 | if (rc) { |
60 | pr_info("%s: invalid numeric value in %s=%s\n", | |
61 | caller, token, val); | |
62 | return rc; | |
1da177e4 | 63 | } |
8091b895 | 64 | return opts->val; |
1da177e4 LT |
65 | } |
66 | if (opts->has_arg & OPT_STRING) { | |
67 | return opts->val; | |
68 | } | |
b41f8b84 | 69 | pr_info("%s: unexpected argument %s to the %s option\n", |
1da177e4 LT |
70 | caller, val, token); |
71 | return -EINVAL; | |
72 | } | |
73 | } | |
b41f8b84 | 74 | pr_info("%s: Unrecognized mount option %s\n", caller, token); |
1da177e4 LT |
75 | return -EOPNOTSUPP; |
76 | } |