]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/dev/vinum/vinumparser.c
This commit was generated by cvs2svn to compensate for changes in r54427,
[FreeBSD/FreeBSD.git] / sys / dev / vinum / vinumparser.c
1 /*-
2  * Copyright (c) 1997, 1998
3  *      Nan Yang Computer Services Limited.  All rights reserved.
4  *
5  *  This software is distributed under the so-called ``Berkeley
6  *  License'':
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  * 3. All advertising materials mentioning features or use of this software
17  *    must display the following acknowledgement:
18  *      This product includes software developed by Nan Yang Computer
19  *      Services Limited.
20  * 4. Neither the name of the Company nor the names of its contributors
21  *    may be used to endorse or promote products derived from this software
22  *    without specific prior written permission.
23  *
24  * This software is provided ``as is'', and any express or implied
25  * warranties, including, but not limited to, the implied warranties of
26  * merchantability and fitness for a particular purpose are disclaimed.
27  * In no event shall the company or contributors be liable for any
28  * direct, indirect, incidental, special, exemplary, or consequential
29  * damages (including, but not limited to, procurement of substitute
30  * goods or services; loss of use, data, or profits; or business
31  * interruption) however caused and on any theory of liability, whether
32  * in contract, strict liability, or tort (including negligence or
33  * otherwise) arising in any way out of the use of this software, even if
34  * advised of the possibility of such damage.
35  *
36  * $FreeBSD$
37  */
38
39 /*
40  * This file contains the parser for the configuration routines.  It's used
41  * both in the kernel and in the user interface program, thus the separate file.
42  */
43
44 /*
45  * Go through a text and split up into text tokens.  These are either non-blank
46  * sequences, or any sequence (except \0) enclosed in ' or ".  Embedded ' or
47  * " characters may be escaped by \, which otherwise has no special meaning.
48  *
49  * Delimit by following with a \0, and return pointers to the starts at token [].
50  * Return the number of tokens found as the return value.
51  *
52  * This method has the restriction that a closing " or ' must be followed by
53  * grey space.
54  *
55  * Error conditions are end of line before end of quote, or no space after
56  * a closing quote.  In this case, tokenize() returns -1.
57  */
58
59 #include <sys/param.h>
60 #ifdef KERNEL
61 #include <sys/systm.h>
62 #else
63 #include <ctype.h>
64 #include <errno.h>
65 #include <fcntl.h>
66 #endif
67 #include <machine/setjmp.h>
68 /* All this mess for a single struct definition */
69 #include <sys/uio.h>
70 #include <sys/namei.h>
71 #include <sys/disklabel.h>
72 #include <sys/mount.h>
73 #include <sys/conf.h>
74 #include <sys/buf.h>
75
76 #include <dev/vinum/vinumvar.h>
77 #include <dev/vinum/vinumkw.h>
78 #include <dev/vinum/vinumio.h>
79 #include <dev/vinum/vinumext.h>
80
81 #define SPACETAB(c) ((c == ' ') || (c == '\t'))             /* check for white space */
82
83 /* enum keyword is defined in vinumvar.h */
84
85 #define keypair(x) { #x, kw_##x }                           /* create pair "foo", kw_foo */
86 #define flagkeypair(x) { "-"#x, kw_##x }                    /* create pair "-foo", kw_foo */
87 #define KEYWORDSET(x) {sizeof (x) / sizeof (struct _keywords), x}
88
89 /* Normal keywords.  These are all the words that vinum knows. */
90 struct _keywords keywords[] =
91 {keypair(drive),
92     keypair(sd),
93     keypair(subdisk),
94     keypair(plex),
95     keypair(volume),
96     keypair(vol),
97     keypair(setupstate),
98     keypair(readpol),
99     keypair(org),
100     keypair(name),
101     keypair(writethrough),
102     keypair(writeback),
103     keypair(raw),
104     keypair(device),
105     keypair(concat),
106     keypair(raid5),
107     keypair(striped),
108     keypair(plexoffset),
109     keypair(driveoffset),
110     keypair(length),
111     keypair(len),
112     keypair(size),
113     keypair(state),
114     keypair(round),
115     keypair(prefer),
116     keypair(rename),
117     keypair(detached),
118 #ifndef KERNEL                                              /* for vinum(8) only */
119 #ifdef VINUMDEBUG
120     keypair(debug),
121     keypair(stripe),
122     keypair(mirror),
123 #endif
124 #endif
125     keypair(attach),
126     keypair(detach),
127     keypair(printconfig),
128     keypair(saveconfig),
129     keypair(replace),
130     keypair(create),
131     keypair(read),
132     keypair(modify),
133     keypair(list),
134     keypair(l),
135     keypair(ld),
136     keypair(ls),
137     keypair(lp),
138     keypair(lv),
139     keypair(info),
140     keypair(set),
141     keypair(rm),
142     keypair(init),
143     keypair(label),
144     keypair(resetconfig),
145     keypair(start),
146     keypair(stop),
147     keypair(makedev),
148     keypair(help),
149     keypair(quit),
150     keypair(setdaemon),
151     keypair(getdaemon),
152     keypair(max),
153     keypair(replace),
154     keypair(readpol),
155     keypair(resetstats),
156     keypair(setstate),
157     keypair(checkparity),
158     keypair(rebuildparity)
159 };
160 struct keywordset keyword_set = KEYWORDSET(keywords);
161
162 #ifndef KERNEL
163 struct _keywords flag_keywords[] =
164 {flagkeypair(f),
165     flagkeypair(d),
166     flagkeypair(v),
167     flagkeypair(s),
168     flagkeypair(r),
169     flagkeypair(w)
170 };
171 struct keywordset flag_set = KEYWORDSET(flag_keywords);
172
173 #endif
174
175 int
176 tokenize(char *cptr, char *token[])
177 {
178     char delim;                                             /* delimiter for searching for the partner */
179     int tokennr;                                            /* index of this token */
180     tokennr = 0;                                            /* none found yet */
181
182     for (;;) {
183         while (SPACETAB(*cptr))
184             cptr++;                                         /* skip initial white space */
185         if ((*cptr == '\0') || (*cptr == '\n') || (*cptr == '#')) /* end of line */
186             return tokennr;                                 /* return number of tokens found */
187         delim = *cptr;
188         token[tokennr] = cptr;                              /* point to it */
189         tokennr++;                                          /* one more */
190         /* XXX this is broken.  It leaves superfluous \\ characters in the text */
191         if ((delim == '\'') || (delim == '"')) {            /* delimitered */
192             for (;;) {
193                 cptr++;
194                 if ((*cptr == delim) && (cptr[-1] != '\\')) { /* found the partner */
195                     cptr++;                                 /* move on past */
196                     if (!SPACETAB(*cptr))                   /* error, no space after closing quote */
197                         return -1;
198                     *cptr++ = '\0';                         /* delimit */
199                 } else if ((*cptr == '\0') || (*cptr == '\n')) /* end of line */
200                     return -1;
201             }
202         } else {                                            /* not quoted */
203             while ((*cptr != '\0') && (!SPACETAB(*cptr)) && (*cptr != '\n'))
204                 cptr++;
205             if (*cptr != '\0')                              /* not end of the line, */
206                 *cptr++ = '\0';                             /* delimit and move to the next */
207         }
208     }
209 }
210
211 /* Find a keyword and return an index */
212 enum keyword
213 get_keyword(char *name, struct keywordset *keywordset)
214 {
215     int i;
216     struct _keywords *keywords = keywordset->k;             /* point to the keywords */
217     if (name != NULL) {                                     /* parameter exists */
218         for (i = 0; i < keywordset->size; i++)
219             if (!strcmp(name, keywords[i].name))
220                 return (enum keyword) keywords[i].keyword;
221     }
222     return kw_invalid_keyword;
223 }