rc.d: Improve dhclient script
[dragonfly.git] / sbin / iscontrol / config.c
bloba883866c071c4c7d355a3131cf6637f7e9ff57d9
1 /*-
2 * Copyright (c) 2005-2008 Daniel Braniss <danny@cs.huji.ac.il>
3 * All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
28 | $Id: config.c,v 2.1 2006/11/12 08:06:51 danny Exp danny $
31 #include <stdlib.h>
32 #include <unistd.h>
33 #include <stdio.h>
34 #include <string.h>
35 #include <errno.h>
36 #include <fcntl.h>
37 #include <time.h>
38 #include <ctype.h>
39 #include <camlib.h>
41 #include "iscsi.h"
42 #include "iscontrol.h"
45 | ints
47 #define OPT_port 1
48 #define OPT_tags 2
50 #define OPT_maxConnections 3
51 #define OPT_maxRecvDataSegmentLength 4
52 #define OPT_maxXmitDataSegmentLength 5
53 #define OPT_maxBurstLength 6
54 #define OPT_firstBurstLength 7
55 #define OPT_defaultTime2Wait 8
56 #define OPT_defaultTime2Retain 9
57 #define OPT_maxOutstandingR2T 10
58 #define OPT_errorRecoveryLevel 11
59 #define OPT_targetPortalGroupTag 12
60 #define OPT_headerDigest 13
61 #define OPT_dataDigest 14
63 | Booleans
65 #define OPT_initialR2T 16
66 #define OPT_immediateData 17
67 #define OPT_dataPDUInOrder 18
68 #define OPT_dataSequenceInOrder 19
70 | strings
72 #define OPT_sessionType 15
74 #define OPT_targetAddress 21
75 #define OPT_targetAlias 22
76 #define OPT_targetName 23
77 #define OPT_initiatorName 24
78 #define OPT_initiatorAlias 25
79 #define OPT_authMethod 26
81 #define OPT_chapSecret 27
82 #define OPT_chapIName 28
83 #define OPT_chapDigest 29
84 #define OPT_tgtChapName 30
85 #define OPT_tgtChapSecret 31
86 #define OPT_tgtChallengeLen 32
88 | private
90 #define OPT_maxluns 33
91 #define OPT_iqn 34
92 #define OPT_sockbufsize 35
94 #define _OFF(v) (offsetof(isc_opt_t *), (v))
95 #define _E(u, s, v) {.usage=u, .scope=s, .name=#v, .tokenID=OPT_##v}
97 static textkey_t keyMap[] = {
98 _E(U_PR, S_PR, port),
99 _E(U_PR, S_PR, tags),
100 _E(U_PR, S_PR, maxluns),
101 _E(U_PR, S_PR, sockbufsize),
103 _E(U_PR, S_PR, iqn),
104 _E(U_PR, S_PR, chapSecret),
105 _E(U_PR, S_PR, chapIName),
106 _E(U_PR, S_PR, chapDigest),
107 _E(U_PR, S_PR, tgtChapName),
108 _E(U_PR, S_PR, tgtChapSecret),
109 _E(U_PR, S_PR, tgtChallengeLen),
111 _E(U_IO, S_CO, headerDigest),
112 _E(U_IO, S_CO, dataDigest),
114 _E(U_IO, S_CO, authMethod),
116 _E(U_LO, S_SW, maxConnections),
117 _E(U_IO, S_SW, targetName),
119 _E(U_IO, S_SW, initiatorName),
120 _E(U_ALL,S_SW, targetAlias),
121 _E(U_ALL,S_SW, initiatorAlias),
122 _E(U_ALL,S_SW, targetAddress),
124 _E(U_ALL,S_SW, targetPortalGroupTag),
126 _E(U_LO, S_SW, initialR2T),
127 _E(U_LO, S_SW, immediateData),
129 _E(U_ALL,S_CO, maxRecvDataSegmentLength),
130 _E(U_ALL,S_CO, maxXmitDataSegmentLength),
132 _E(U_LO, S_SW, maxBurstLength),
133 _E(U_LO, S_SW, firstBurstLength),
134 _E(U_LO, S_SW, defaultTime2Wait),
135 _E(U_LO, S_SW, defaultTime2Retain),
137 _E(U_LO, S_SW, maxOutstandingR2T),
138 _E(U_LO, S_SW, dataPDUInOrder),
139 _E(U_LO, S_SW, dataSequenceInOrder),
141 _E(U_LO, S_SW, errorRecoveryLevel),
143 _E(U_LO, S_SW, sessionType),
145 {0, 0, 0, 0}
148 #define _OPT_INT(w) strtol((char *)w, NULL, 0)
149 #define _OPT_STR(w) (char *)(w)
151 static __inline int
152 _OPT_BOOL(char *w)
154 if(isalpha(*w))
155 return strcasecmp(w, "TRUE") == 0;
156 else
157 return _OPT_INT(w);
160 #define _CASE(k, v) case OPT_##k: op->k = v; break
161 static void
162 setOption(isc_opt_t *op, int which, void *rval)
164 switch(which) {
165 _CASE(port, _OPT_INT(rval));
166 _CASE(tags, _OPT_INT(rval));
167 _CASE(maxluns, _OPT_INT(rval));
168 _CASE(iqn, _OPT_STR(rval));
169 _CASE(sockbufsize, _OPT_INT(rval));
171 _CASE(maxConnections, _OPT_INT(rval));
172 _CASE(maxRecvDataSegmentLength, _OPT_INT(rval));
173 _CASE(maxXmitDataSegmentLength, _OPT_INT(rval));
174 _CASE(maxBurstLength, _OPT_INT(rval));
175 _CASE(firstBurstLength, _OPT_INT(rval));
176 _CASE(defaultTime2Wait, _OPT_INT(rval));
177 _CASE(defaultTime2Retain, _OPT_INT(rval));
178 _CASE(maxOutstandingR2T, _OPT_INT(rval));
179 _CASE(errorRecoveryLevel, _OPT_INT(rval));
180 _CASE(targetPortalGroupTag, _OPT_INT(rval));
181 _CASE(headerDigest, _OPT_STR(rval));
182 _CASE(dataDigest, _OPT_STR(rval));
184 _CASE(targetAddress, _OPT_STR(rval));
185 _CASE(targetAlias, _OPT_STR(rval));
186 _CASE(targetName, _OPT_STR(rval));
187 _CASE(initiatorName, _OPT_STR(rval));
188 _CASE(initiatorAlias, _OPT_STR(rval));
189 _CASE(authMethod, _OPT_STR(rval));
190 _CASE(chapSecret, _OPT_STR(rval));
191 _CASE(chapIName, _OPT_STR(rval));
192 _CASE(chapDigest, _OPT_STR(rval));
194 _CASE(tgtChapName, _OPT_STR(rval));
195 _CASE(tgtChapSecret, _OPT_STR(rval));
197 _CASE(initialR2T, _OPT_BOOL(rval));
198 _CASE(immediateData, _OPT_BOOL(rval));
199 _CASE(dataPDUInOrder, _OPT_BOOL(rval));
200 _CASE(dataSequenceInOrder, _OPT_BOOL(rval));
204 static char *
205 get_line(FILE *fd)
207 static char *sp, line[BUFSIZ];
208 char *lp, *p;
210 do {
211 if(sp == NULL)
212 sp = fgets(line, sizeof line, fd);
214 if((lp = sp) == NULL)
215 break;
216 if((p = strchr(lp, '\n')) != NULL)
217 *p = 0;
218 if((p = strchr(lp, '#')) != NULL)
219 *p = 0;
220 if((p = strchr(lp, ';')) != NULL) {
221 *p++ = 0;
222 sp = p;
223 } else
224 sp = NULL;
225 if(*lp)
226 return lp;
227 } while (feof(fd) == 0);
228 return NULL;
231 static int
232 getConfig(FILE *fd, char *key, char **Ar, int *nargs)
234 char *lp, *p, **ar;
235 int state, len, n;
237 ar = Ar;
238 if(key)
239 len = strlen(key);
240 else
241 len = 0;
242 state = 0;
243 while((lp = get_line(fd)) != NULL) {
244 for(; isspace(*lp); lp++)
246 switch(state) {
247 case 0:
248 if((p = strchr(lp, '{')) != NULL) {
249 n = 0;
250 while((--p > lp) && *p && isspace(*p));
251 n = p - lp;
252 if(len && strncmp(lp, key, MAX(n, len)) == 0)
253 state = 2;
254 else
255 state = 1;
256 continue;
258 break;
260 case 1:
261 if(*lp == '}')
262 state = 0;
263 continue;
265 case 2:
266 if(*lp == '}')
267 goto done;
269 break;
273 for(p = &lp[strlen(lp)-1]; isspace(*p); p--)
274 *p = 0;
275 if((*nargs)-- > 0)
276 *ar++ = strdup(lp);
279 done:
280 if(*nargs > 0)
281 *ar = NULL;
282 *nargs = ar - Ar;
283 return ar - Ar;
286 static textkey_t *
287 keyLookup(char *key)
289 textkey_t *tk;
291 for(tk = keyMap; tk->name; tk++) {
292 if(strcasecmp(key, tk->name) == 0)
293 return tk;
295 return NULL;
298 static void
299 puke(isc_opt_t *op)
301 printf("%24s = %d\n", "port", op->port);
302 printf("%24s = %d\n", "tags", op->tags);
303 printf("%24s = %d\n", "maxluns", op->maxluns);
304 printf("%24s = %s\n", "iqn", op->iqn);
306 printf("%24s = %d\n", "maxConnections", op->maxConnections);
307 printf("%24s = %d\n", "maxRecvDataSegmentLength", op->maxRecvDataSegmentLength);
308 printf("%24s = %d\n", "maxXmitDataSegmentLength", op->maxRecvDataSegmentLength);
309 printf("%24s = %d\n", "maxBurstLength", op->maxBurstLength);
310 printf("%24s = %d\n", "firstBurstLength", op->firstBurstLength);
311 printf("%24s = %d\n", "defaultTime2Wait", op->defaultTime2Wait);
312 printf("%24s = %d\n", "defaultTime2Retain", op->defaultTime2Retain);
313 printf("%24s = %d\n", "maxOutstandingR2T", op->maxOutstandingR2T);
314 printf("%24s = %d\n", "errorRecoveryLevel", op->errorRecoveryLevel);
315 printf("%24s = %d\n", "targetPortalGroupTag", op->targetPortalGroupTag);
317 printf("%24s = %s\n", "headerDigest", op->headerDigest);
318 printf("%24s = %s\n", "dataDigest", op->dataDigest);
320 printf("%24s = %d\n", "initialR2T", op->initialR2T);
321 printf("%24s = %d\n", "immediateData", op->immediateData);
322 printf("%24s = %d\n", "dataPDUInOrder", op->dataPDUInOrder);
323 printf("%24s = %d\n", "dataSequenceInOrder", op->dataSequenceInOrder);
325 printf("%24s = %s\n", "sessionType", op->sessionType);
326 printf("%24s = %s\n", "targetAddress", op->targetAddress);
327 printf("%24s = %s\n", "targetAlias", op->targetAlias);
328 printf("%24s = %s\n", "targetName", op->targetName);
329 printf("%24s = %s\n", "initiatorName", op->initiatorName);
330 printf("%24s = %s\n", "initiatorAlias", op->initiatorAlias);
331 printf("%24s = %s\n", "authMethod", op->authMethod);
332 printf("%24s = %s\n", "chapSecret", op->chapSecret);
333 printf("%24s = %s\n", "chapIName", op->chapIName);
334 printf("%24s = %s\n", "tgtChapName", op->tgtChapName);
335 printf("%24s = %s\n", "tgtChapSecret", op->tgtChapSecret);
336 printf("%24s = %d\n", "tgttgtChallengeLen", op->tgtChallengeLen);
339 void
340 parseArgs(int nargs, char **args, isc_opt_t *op)
342 char **ar;
343 char *p, *v;
344 textkey_t *tk;
346 for(ar = args; nargs > 0; nargs--, ar++) {
347 p = strchr(*ar, '=');
348 if(p == NULL)
349 continue;
350 *p = 0;
351 v = p + 1;
352 while(isspace(*--p))
353 *p = 0;
354 while(isspace(*v))
355 v++;
356 if((tk = keyLookup(*ar)) == NULL)
357 continue;
358 setOption(op, tk->tokenID, v);
362 void
363 parseConfig(FILE *fd, char *key, isc_opt_t *op)
365 char *Ar[256];
366 int cc;
368 cc = 256;
369 if(getConfig(fd, key, Ar, &cc))
370 parseArgs(cc, Ar, op);
371 if(vflag)
372 puke(op);