~james-w/+junk/fuse-debian-upstream

« back to all changes in this revision

Viewing changes to kernel/compat/parser.c

  • Committer: James Westby
  • Date: 2008-05-16 12:57:40 UTC
  • Revision ID: jw+debian@jameswestby.net-20080516125740-fn2iqsxtfd3olmib
Tags: upstream-debian-2.2.1
Import upstream from fuse_2.2.1.orig.tar.gz

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * lib/parser.c - simple parser for mount, etc. options.
 
3
 *
 
4
 * This source code is licensed under the GNU General Public License,
 
5
 * Version 2.  See the file COPYING for more details.
 
6
 */
 
7
 
 
8
#include <linux/config.h>
 
9
#ifdef CONFIG_MODVERSIONS
 
10
#define MODVERSIONS
 
11
#include <linux/modversions.h>
 
12
#endif
 
13
 
 
14
#include "parser.h"
 
15
 
 
16
#include <linux/ctype.h>
 
17
#include <linux/module.h>
 
18
#include <linux/slab.h>
 
19
#include <linux/string.h>
 
20
 
 
21
/**
 
22
 * match_one: - Determines if a string matches a simple pattern
 
23
 * @s: the string to examine for presense of the pattern
 
24
 * @p: the string containing the pattern
 
25
 * @args: array of %MAX_OPT_ARGS &substring_t elements. Used to return match
 
26
 * locations.
 
27
 *
 
28
 * Description: Determines if the pattern @p is present in string @s. Can only
 
29
 * match extremely simple token=arg style patterns. If the pattern is found,
 
30
 * the location(s) of the arguments will be returned in the @args array.
 
31
 */
 
32
static int match_one(char *s, char *p, substring_t args[])
 
33
{
 
34
        char *meta;
 
35
        int argc = 0;
 
36
 
 
37
        if (!p)
 
38
                return 1;
 
39
 
 
40
        while(1) {
 
41
                int len = -1;
 
42
                meta = strchr(p, '%');
 
43
                if (!meta)
 
44
                        return strcmp(p, s) == 0;
 
45
 
 
46
                if (strncmp(p, s, meta-p))
 
47
                        return 0;
 
48
 
 
49
                s += meta - p;
 
50
                p = meta + 1;
 
51
 
 
52
                if (isdigit(*p))
 
53
                        len = simple_strtoul(p, &p, 10);
 
54
                else if (*p == '%') {
 
55
                        if (*s++ != '%')
 
56
                                return 0;
 
57
                        continue;
 
58
                }
 
59
 
 
60
                if (argc >= MAX_OPT_ARGS)
 
61
                        return 0;
 
62
 
 
63
                args[argc].from = s;
 
64
                switch (*p++) {
 
65
                case 's':
 
66
                        if (strlen(s) == 0)
 
67
                                return 0;
 
68
                        else if (len == -1 || len > strlen(s))
 
69
                                len = strlen(s);
 
70
                        args[argc].to = s + len;
 
71
                        break;
 
72
                case 'd':
 
73
                        simple_strtol(s, &args[argc].to, 0);
 
74
                        goto num;
 
75
                case 'u':
 
76
                        simple_strtoul(s, &args[argc].to, 0);
 
77
                        goto num;
 
78
                case 'o':
 
79
                        simple_strtoul(s, &args[argc].to, 8);
 
80
                        goto num;
 
81
                case 'x':
 
82
                        simple_strtoul(s, &args[argc].to, 16);
 
83
                num:
 
84
                        if (args[argc].to == args[argc].from)
 
85
                                return 0;
 
86
                        break;
 
87
                default:
 
88
                        return 0;
 
89
                }
 
90
                s = args[argc].to;
 
91
                argc++;
 
92
        }
 
93
}
 
94
 
 
95
/**
 
96
 * match_token: - Find a token (and optional args) in a string
 
97
 * @s: the string to examine for token/argument pairs
 
98
 * @table: match_table_t describing the set of allowed option tokens and the
 
99
 * arguments that may be associated with them. Must be terminated with a
 
100
 * &struct match_token whose pattern is set to the NULL pointer.
 
101
 * @args: array of %MAX_OPT_ARGS &substring_t elements. Used to return match
 
102
 * locations.
 
103
 *
 
104
 * Description: Detects which if any of a set of token strings has been passed
 
105
 * to it. Tokens can include up to MAX_OPT_ARGS instances of basic c-style
 
106
 * format identifiers which will be taken into account when matching the
 
107
 * tokens, and whose locations will be returned in the @args array.
 
108
 */
 
109
int match_token(char *s, match_table_t table, substring_t args[])
 
110
{
 
111
        struct match_token *p;
 
112
 
 
113
        for (p = table; !match_one(s, p->pattern, args) ; p++)
 
114
                ;
 
115
 
 
116
        return p->token;
 
117
}
 
118
 
 
119
/**
 
120
 * match_number: scan a number in the given base from a substring_t
 
121
 * @s: substring to be scanned
 
122
 * @result: resulting integer on success
 
123
 * @base: base to use when converting string
 
124
 *
 
125
 * Description: Given a &substring_t and a base, attempts to parse the substring
 
126
 * as a number in that base. On success, sets @result to the integer represented
 
127
 * by the string and returns 0. Returns either -ENOMEM or -EINVAL on failure.
 
128
 */
 
129
static int match_number(substring_t *s, int *result, int base)
 
130
{
 
131
        char *endp;
 
132
        char *buf;
 
133
        int ret;
 
134
 
 
135
        buf = kmalloc(s->to - s->from + 1, GFP_KERNEL);
 
136
        if (!buf)
 
137
                return -ENOMEM;
 
138
        memcpy(buf, s->from, s->to - s->from);
 
139
        buf[s->to - s->from] = '\0';
 
140
        *result = simple_strtol(buf, &endp, base);
 
141
        ret = 0;
 
142
        if (endp == buf)
 
143
                ret = -EINVAL;
 
144
        kfree(buf);
 
145
        return ret;
 
146
}
 
147
 
 
148
/**
 
149
 * match_int: - scan a decimal representation of an integer from a substring_t
 
150
 * @s: substring_t to be scanned
 
151
 * @result: resulting integer on success
 
152
 *
 
153
 * Description: Attempts to parse the &substring_t @s as a decimal integer. On
 
154
 * success, sets @result to the integer represented by the string and returns 0.
 
155
 * Returns either -ENOMEM or -EINVAL on failure.
 
156
 */
 
157
int match_int(substring_t *s, int *result)
 
158
{
 
159
        return match_number(s, result, 0);
 
160
}
 
161
 
 
162
/**
 
163
 * match_octal: - scan an octal representation of an integer from a substring_t
 
164
 * @s: substring_t to be scanned
 
165
 * @result: resulting integer on success
 
166
 *
 
167
 * Description: Attempts to parse the &substring_t @s as an octal integer. On
 
168
 * success, sets @result to the integer represented by the string and returns
 
169
 * 0. Returns either -ENOMEM or -EINVAL on failure.
 
170
 */
 
171
int match_octal(substring_t *s, int *result)
 
172
{
 
173
        return match_number(s, result, 8);
 
174
}
 
175
 
 
176
/**
 
177
 * match_hex: - scan a hex representation of an integer from a substring_t
 
178
 * @s: substring_t to be scanned
 
179
 * @result: resulting integer on success
 
180
 *
 
181
 * Description: Attempts to parse the &substring_t @s as a hexadecimal integer.
 
182
 * On success, sets @result to the integer represented by the string and
 
183
 * returns 0. Returns either -ENOMEM or -EINVAL on failure.
 
184
 */
 
185
int match_hex(substring_t *s, int *result)
 
186
{
 
187
        return match_number(s, result, 16);
 
188
}
 
189
 
 
190
/**
 
191
 * match_strcpy: - copies the characters from a substring_t to a string
 
192
 * @to: string to copy characters to.
 
193
 * @s: &substring_t to copy
 
194
 *
 
195
 * Description: Copies the set of characters represented by the given
 
196
 * &substring_t @s to the c-style string @to. Caller guarantees that @to is
 
197
 * large enough to hold the characters of @s.
 
198
 */
 
199
void match_strcpy(char *to, substring_t *s)
 
200
{
 
201
        memcpy(to, s->from, s->to - s->from);
 
202
        to[s->to - s->from] = '\0';
 
203
}
 
204
 
 
205
/**
 
206
 * match_strdup: - allocate a new string with the contents of a substring_t
 
207
 * @s: &substring_t to copy
 
208
 *
 
209
 * Description: Allocates and returns a string filled with the contents of
 
210
 * the &substring_t @s. The caller is responsible for freeing the returned
 
211
 * string with kfree().
 
212
 */
 
213
char *match_strdup(substring_t *s)
 
214
{
 
215
        char *p = kmalloc(s->to - s->from + 1, GFP_KERNEL);
 
216
        if (p)
 
217
                match_strcpy(p, s);
 
218
        return p;
 
219
}
 
220