1 /*
2  * FUSE: Filesystem in Userspace
3  * Copyright (C) 2001-2007  Miklos Szeredi <miklos@szeredi.hu>
4  *
5  * This program can be distributed under the terms of the GNU LGPLv2.
6  * See the file COPYING.LIB.
7  */
8 
9 #ifndef FUSE_OPT_H_
10 #define FUSE_OPT_H_
11 
12 /** @file
13  *
14  * This file defines the option parsing interface of FUSE
15  */
16 
17 /**
18  * Option description
19  *
20  * This structure describes a single option, and action associated
21  * with it, in case it matches.
22  *
23  * More than one such match may occur, in which case the action for
24  * each match is executed.
25  *
26  * There are three possible actions in case of a match:
27  *
28  * i) An integer (int or unsigned) variable determined by 'offset' is
29  *    set to 'value'
30  *
31  * ii) The processing function is called, with 'value' as the key
32  *
33  * iii) An integer (any) or string (char *) variable determined by
34  *    'offset' is set to the value of an option parameter
35  *
36  * 'offset' should normally be either set to
37  *
38  *  - 'offsetof(struct foo, member)'  actions i) and iii)
39  *
40  *  - -1                              action ii)
41  *
42  * The 'offsetof()' macro is defined in the <stddef.h> header.
43  *
44  * The template determines which options match, and also have an
45  * effect on the action.  Normally the action is either i) or ii), but
46  * if a format is present in the template, then action iii) is
47  * performed.
48  *
49  * The types of templates are:
50  *
51  * 1) "-x", "-foo", "--foo", "--foo-bar", etc. These match only
52  *   themselves.  Invalid values are "--" and anything beginning
53  *   with "-o"
54  *
55  * 2) "foo", "foo-bar", etc.  These match "-ofoo", "-ofoo-bar" or
56  *    the relevant option in a comma separated option list
57  *
58  * 3) "bar=", "--foo=", etc.  These are variations of 1) and 2)
59  *    which have a parameter
60  *
61  * 4) "bar=%s", "--foo=%lu", etc.  Same matching as above but perform
62  *    action iii).
63  *
64  * 5) "-x ", etc.  Matches either "-xparam" or "-x param" as
65  *    two separate arguments
66  *
67  * 6) "-x %s", etc.  Combination of 4) and 5)
68  *
69  * If the format is "%s", memory is allocated for the string unlike with
70  * scanf().  The previous value (if non-NULL) stored at the this location is
71  * freed.
72  */
73 struct fuse_opt {
74     /** Matching template and optional parameter formatting */
75     const char *templ;
76 
77     /**
78      * Offset of variable within 'data' parameter of fuse_opt_parse()
79      * or -1
80      */
81     unsigned long offset;
82 
83     /**
84      * Value to set the variable to, or to be passed as 'key' to the
85      * processing function. Ignored if template has a format
86      */
87     int value;
88 };
89 
90 /**
91  * Key option. In case of a match, the processing function will be
92  * called with the specified key.
93  */
94 #define FUSE_OPT_KEY(templ, key) \
95     {                            \
96         templ, -1U, key          \
97     }
98 
99 /**
100  * Last option. An array of 'struct fuse_opt' must end with a NULL
101  * template value
102  */
103 #define FUSE_OPT_END \
104     {                \
105         NULL, 0, 0   \
106     }
107 
108 /**
109  * Argument list
110  */
111 struct fuse_args {
112     /** Argument count */
113     int argc;
114 
115     /** Argument vector.  NULL terminated */
116     char **argv;
117 
118     /** Is 'argv' allocated? */
119     int allocated;
120 };
121 
122 /**
123  * Initializer for 'struct fuse_args'
124  */
125 #define FUSE_ARGS_INIT(argc, argv) \
126     {                              \
127         argc, argv, 0              \
128     }
129 
130 /**
131  * Key value passed to the processing function if an option did not
132  * match any template
133  */
134 #define FUSE_OPT_KEY_OPT -1
135 
136 /**
137  * Key value passed to the processing function for all non-options
138  *
139  * Non-options are the arguments beginning with a character other than
140  * '-' or all arguments after the special '--' option
141  */
142 #define FUSE_OPT_KEY_NONOPT -2
143 
144 /**
145  * Special key value for options to keep
146  *
147  * Argument is not passed to processing function, but behave as if the
148  * processing function returned 1
149  */
150 #define FUSE_OPT_KEY_KEEP -3
151 
152 /**
153  * Special key value for options to discard
154  *
155  * Argument is not passed to processing function, but behave as if the
156  * processing function returned zero
157  */
158 #define FUSE_OPT_KEY_DISCARD -4
159 
160 /**
161  * Processing function
162  *
163  * This function is called if
164  *    - option did not match any 'struct fuse_opt'
165  *    - argument is a non-option
166  *    - option did match and offset was set to -1
167  *
168  * The 'arg' parameter will always contain the whole argument or
169  * option including the parameter if exists.  A two-argument option
170  * ("-x foo") is always converted to single argument option of the
171  * form "-xfoo" before this function is called.
172  *
173  * Options of the form '-ofoo' are passed to this function without the
174  * '-o' prefix.
175  *
176  * The return value of this function determines whether this argument
177  * is to be inserted into the output argument vector, or discarded.
178  *
179  * @param data is the user data passed to the fuse_opt_parse() function
180  * @param arg is the whole argument or option
181  * @param key determines why the processing function was called
182  * @param outargs the current output argument list
183  * @return -1 on error, 0 if arg is to be discarded, 1 if arg should be kept
184  */
185 typedef int (*fuse_opt_proc_t)(void *data, const char *arg, int key,
186                                struct fuse_args *outargs);
187 
188 /**
189  * Option parsing function
190  *
191  * If 'args' was returned from a previous call to fuse_opt_parse() or
192  * it was constructed from
193  *
194  * A NULL 'args' is equivalent to an empty argument vector
195  *
196  * A NULL 'opts' is equivalent to an 'opts' array containing a single
197  * end marker
198  *
199  * A NULL 'proc' is equivalent to a processing function always
200  * returning '1'
201  *
202  * @param args is the input and output argument list
203  * @param data is the user data
204  * @param opts is the option description array
205  * @param proc is the processing function
206  * @return -1 on error, 0 on success
207  */
208 int fuse_opt_parse(struct fuse_args *args, void *data,
209                    const struct fuse_opt opts[], fuse_opt_proc_t proc);
210 
211 /**
212  * Add an option to a comma separated option list
213  *
214  * @param opts is a pointer to an option list, may point to a NULL value
215  * @param opt is the option to add
216  * @return -1 on allocation error, 0 on success
217  */
218 int fuse_opt_add_opt(char **opts, const char *opt);
219 
220 /**
221  * Add an option, escaping commas, to a comma separated option list
222  *
223  * @param opts is a pointer to an option list, may point to a NULL value
224  * @param opt is the option to add
225  * @return -1 on allocation error, 0 on success
226  */
227 int fuse_opt_add_opt_escaped(char **opts, const char *opt);
228 
229 /**
230  * Add an argument to a NULL terminated argument vector
231  *
232  * @param args is the structure containing the current argument list
233  * @param arg is the new argument to add
234  * @return -1 on allocation error, 0 on success
235  */
236 int fuse_opt_add_arg(struct fuse_args *args, const char *arg);
237 
238 /**
239  * Add an argument at the specified position in a NULL terminated
240  * argument vector
241  *
242  * Adds the argument to the N-th position.  This is useful for adding
243  * options at the beginning of the array which must not come after the
244  * special '--' option.
245  *
246  * @param args is the structure containing the current argument list
247  * @param pos is the position at which to add the argument
248  * @param arg is the new argument to add
249  * @return -1 on allocation error, 0 on success
250  */
251 int fuse_opt_insert_arg(struct fuse_args *args, int pos, const char *arg);
252 
253 /**
254  * Free the contents of argument list
255  *
256  * The structure itself is not freed
257  *
258  * @param args is the structure containing the argument list
259  */
260 void fuse_opt_free_args(struct fuse_args *args);
261 
262 
263 /**
264  * Check if an option matches
265  *
266  * @param opts is the option description array
267  * @param opt is the option to match
268  * @return 1 if a match is found, 0 if not
269  */
270 int fuse_opt_match(const struct fuse_opt opts[], const char *opt);
271 
272 #endif /* FUSE_OPT_H_ */
273