ronnie
2022-10-14 1504bb53e29d3d46222c0b3ea994fc494b48e153
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
/*
 * getopt.c
 */
 
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
#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)
 *    @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;
               }
               pr_info("%s: the %s option requires an argument\n",
                   caller, token);
               return -EINVAL;
           }
           if (opts->has_arg & OPT_INT) {
               int rc = kstrtoul(val, 0, value);
 
               if (rc) {
                   pr_info("%s: invalid numeric value in %s=%s\n",
                       caller, token, val);
                   return rc;
               }
               return opts->val;
           }
           if (opts->has_arg & OPT_STRING) {
               return opts->val;
           }
           pr_info("%s: unexpected argument %s to the %s option\n",
               caller, val, token);
           return -EINVAL;
       }
   }
   pr_info("%s: Unrecognized mount option %s\n", caller, token);
   return -EOPNOTSUPP;
}