proc->thread stage 4: rework the VFS and DEVICE subsystems to take thread
[dragonfly.git] / sys / dev / raid / vinum / vinumparser.c
CommitLineData
984263bc
MD
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 * $Id: vinumparser.c,v 1.21 2000/12/20 03:44:13 grog Exp grog $
37 * $FreeBSD: src/sys/dev/vinum/vinumparser.c,v 1.20.2.5 2001/05/28 05:56:27 grog Exp $
dadab5e9 38 * $DragonFly: src/sys/dev/raid/vinum/vinumparser.c,v 1.3 2003/06/25 03:55:50 dillon Exp $
984263bc
MD
39 */
40
41/*
42 * This file contains the parser for the configuration routines. It's used
43 * both in the kernel and in the user interface program, thus the separate file.
44 */
45
46/*
47 * Go through a text and split up into text tokens. These are either non-blank
48 * sequences, or any sequence (except \0) enclosed in ' or ". Embedded ' or
49 * " characters may be escaped by \, which otherwise has no special meaning.
50 *
51 * Delimit by following with a \0, and return pointers to the starts at token [].
52 * Return the number of tokens found as the return value.
53 *
54 * This method has the restriction that a closing " or ' must be followed by
55 * grey space.
56 *
57 * Error conditions are end of line before end of quote, or no space after
58 * a closing quote. In this case, tokenize() returns -1.
59 */
60
61#include <sys/param.h>
62#include <dev/vinum/vinumkw.h>
63#ifdef _KERNEL
64#include <sys/systm.h>
65#include <sys/conf.h>
66#include <machine/setjmp.h>
67/* All this mess for a single struct definition */
68#include <sys/uio.h>
dadab5e9 69#include <sys/proc.h>
984263bc
MD
70#include <sys/namei.h>
71#include <sys/disklabel.h>
72#include <sys/mount.h>
73
74#include <dev/vinum/vinumvar.h>
75#include <dev/vinum/vinumio.h>
76#include <dev/vinum/vinumext.h>
77#define iswhite(c) ((c == ' ') || (c == '\t')) /* check for white space */
78#else /* userland */
79#include <ctype.h>
80#include <errno.h>
81#include <fcntl.h>
82#define iswhite isspace /* use the ctype macro */
83#endif
84
85/* enum keyword is defined in vinumvar.h */
86
87#define keypair(x) { #x, kw_##x } /* create pair "foo", kw_foo */
88#define flagkeypair(x) { "-"#x, kw_##x } /* create pair "-foo", kw_foo */
89#define KEYWORDSET(x) {sizeof (x) / sizeof (struct _keywords), x}
90
91/* Normal keywords. These are all the words that vinum knows. */
92struct _keywords keywords[] =
93{keypair(drive),
94 keypair(partition),
95 keypair(sd),
96 keypair(subdisk),
97 keypair(plex),
98 keypair(volume),
99 keypair(vol),
100 keypair(setupstate),
101 keypair(readpol),
102 keypair(org),
103 keypair(name),
104 keypair(writethrough),
105 keypair(writeback),
106 keypair(raw),
107 keypair(device),
108 keypair(concat),
109 keypair(raid4),
110 keypair(raid5),
111 keypair(striped),
112 keypair(plexoffset),
113 keypair(driveoffset),
114 keypair(length),
115 keypair(len),
116 keypair(size),
117 keypair(state),
118 keypair(round),
119 keypair(prefer),
120 keypair(rename),
121 keypair(detached),
122#ifndef _KERNEL /* for vinum(8) only */
123#ifdef VINUMDEBUG
124 keypair(debug),
125#endif
126 keypair(stripe),
127 keypair(mirror),
128#endif
129 keypair(attach),
130 keypair(detach),
131 keypair(printconfig),
132 keypair(saveconfig),
133 keypair(replace),
134 keypair(create),
135 keypair(read),
136 keypair(modify),
137 keypair(list),
138 keypair(l),
139 keypair(ld),
140 keypair(ls),
141 keypair(lp),
142 keypair(lv),
143 keypair(info),
144 keypair(set),
145 keypair(rm),
146 keypair(mv),
147 keypair(move),
148 keypair(init),
149 keypair(label),
150 keypair(resetconfig),
151 keypair(start),
152 keypair(stop),
153 keypair(makedev),
154 keypair(help),
155 keypair(quit),
156 keypair(setdaemon),
157 keypair(getdaemon),
158 keypair(max),
159 keypair(replace),
160 keypair(readpol),
161 keypair(resetstats),
162 keypair(setstate),
163 keypair(checkparity),
164 keypair(rebuildparity),
165 keypair(dumpconfig),
166 keypair(retryerrors)
167};
168struct keywordset keyword_set = KEYWORDSET(keywords);
169
170#ifndef _KERNEL
171struct _keywords flag_keywords[] =
172{flagkeypair(f),
173 flagkeypair(d),
174 flagkeypair(v),
175 flagkeypair(s),
176 flagkeypair(r),
177 flagkeypair(w)
178};
179struct keywordset flag_set = KEYWORDSET(flag_keywords);
180
181#endif
182
183/*
184 * Take a blank separated list of tokens and turn it into a list of
185 * individual nul-delimited strings. Build a list of pointers at
186 * token, which must have enough space for the tokens. Return the
187 * number of tokens, or -1 on error (typically a missing string
188 * delimiter).
189 */
190int
191tokenize(char *cptr, char *token[])
192{
193 char delim; /* delimiter for searching for the partner */
194 int tokennr; /* index of this token */
195 tokennr = 0; /* none found yet */
196
197 for (;;) {
198 while (iswhite(*cptr))
199 cptr++; /* skip initial white space */
200 if ((*cptr == '\0') || (*cptr == '\n') || (*cptr == '#')) /* end of line */
201 return tokennr; /* return number of tokens found */
202 delim = *cptr;
203 token[tokennr] = cptr; /* point to it */
204 tokennr++; /* one more */
205 /* XXX this is broken. It leaves superfluous \\ characters in the text */
206 if ((delim == '\'') || (delim == '"')) { /* delimitered */
207 for (;;) {
208 cptr++;
209 if ((*cptr == delim) && (cptr[-1] != '\\')) { /* found the partner */
210 cptr++; /* move on past */
211 if (!iswhite(*cptr)) /* error, no space after closing quote */
212 return -1;
213 *cptr++ = '\0'; /* delimit */
214 } else if ((*cptr == '\0') || (*cptr == '\n')) /* end of line */
215 return -1;
216 }
217 } else { /* not quoted */
218 while ((*cptr != '\0') && (!iswhite(*cptr)) && (*cptr != '\n'))
219 cptr++;
220 if (*cptr != '\0') /* not end of the line, */
221 *cptr++ = '\0'; /* delimit and move to the next */
222 }
223 }
224}
225
226/* Find a keyword and return an index */
227enum keyword
228get_keyword(char *name, struct keywordset *keywordset)
229{
230 int i;
231 struct _keywords *keywords = keywordset->k; /* point to the keywords */
232 if (name != NULL) { /* parameter exists */
233 for (i = 0; i < keywordset->size; i++)
234 if (!strcmp(name, keywords[i].name))
235 return (enum keyword) keywords[i].keyword;
236 }
237 return kw_invalid_keyword;
238}