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