1 /*-
|
2 * Copyright (c) 2005-2008 Daniel Braniss <danny@cs.huji.ac.il>
|
2 * Copyright (c) 2005-2009 Daniel Braniss <danny@cs.huji.ac.il> |
3 * All rights reserved. 4 * 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. 13 * 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. 25 * 26 */ 27/* 28 | $Id: config.c,v 2.1 2006/11/12 08:06:51 danny Exp danny $ 29 */ 30 31#include <sys/cdefs.h>
|
32__FBSDID("$FreeBSD: head/sbin/iscontrol/config.c 209052 2010-06-11 17:03:04Z uqs $");
|
32__FBSDID("$FreeBSD: head/sbin/iscontrol/config.c 211095 2010-08-09 12:36:36Z des $"); |
33 34#include <stdlib.h> 35#include <unistd.h> 36#include <stdio.h> 37#include <string.h> 38#include <errno.h> 39#include <fcntl.h> 40#include <time.h> 41#include <ctype.h> 42#include <camlib.h> 43
|
44#include "iscsi.h"
|
44#include <dev/iscsi/initiator/iscsi.h> |
45#include "iscontrol.h" 46 47/* 48 | ints 49 */ 50#define OPT_port 1 51#define OPT_tags 2 52 53#define OPT_maxConnections 3 54#define OPT_maxRecvDataSegmentLength 4 55#define OPT_maxXmitDataSegmentLength 5 56#define OPT_maxBurstLength 6 57#define OPT_firstBurstLength 7 58#define OPT_defaultTime2Wait 8 59#define OPT_defaultTime2Retain 9 60#define OPT_maxOutstandingR2T 10 61#define OPT_errorRecoveryLevel 11 62#define OPT_targetPortalGroupTag 12 63#define OPT_headerDigest 13 64#define OPT_dataDigest 14 65/* 66 | Booleans 67 */ 68#define OPT_initialR2T 16 69#define OPT_immediateData 17 70#define OPT_dataPDUInOrder 18 71#define OPT_dataSequenceInOrder 19 72/* 73 | strings 74 */ 75#define OPT_sessionType 15 76 77#define OPT_targetAddress 21 78#define OPT_targetAlias 22 79#define OPT_targetName 23 80#define OPT_initiatorName 24 81#define OPT_initiatorAlias 25 82#define OPT_authMethod 26 83 84#define OPT_chapSecret 27 85#define OPT_chapIName 28 86#define OPT_chapDigest 29 87#define OPT_tgtChapName 30 88#define OPT_tgtChapSecret 31 89#define OPT_tgtChallengeLen 32 90/* 91 | private 92 */ 93#define OPT_maxluns 33 94#define OPT_iqn 34 95#define OPT_sockbufsize 35 96
|
97/* 98 | sentinel 99 */ 100#define OPT_end 0 101 |
102#define _OFF(v) ((int)&((isc_opt_t *)NULL)->v) 103#define _E(u, s, v) {.usage=u, .scope=s, .name=#v, .tokenID=OPT_##v} 104 105textkey_t keyMap[] = { 106 _E(U_PR, S_PR, port), 107 _E(U_PR, S_PR, tags), 108 _E(U_PR, S_PR, maxluns), 109 _E(U_PR, S_PR, sockbufsize), 110 111 _E(U_PR, S_PR, iqn), 112 _E(U_PR, S_PR, chapSecret), 113 _E(U_PR, S_PR, chapIName), 114 _E(U_PR, S_PR, chapDigest), 115 _E(U_PR, S_PR, tgtChapName), 116 _E(U_PR, S_PR, tgtChapSecret), 117 _E(U_PR, S_PR, tgtChallengeLen), 118 119 _E(U_IO, S_CO, headerDigest), 120 _E(U_IO, S_CO, dataDigest), 121 122 _E(U_IO, S_CO, authMethod), 123 124 _E(U_LO, S_SW, maxConnections), 125 _E(U_IO, S_SW, targetName), 126 127 _E(U_IO, S_SW, initiatorName), 128 _E(U_ALL,S_SW, targetAlias), 129 _E(U_ALL,S_SW, initiatorAlias), 130 _E(U_ALL,S_SW, targetAddress), 131 132 _E(U_ALL,S_SW, targetPortalGroupTag), 133 134 _E(U_LO, S_SW, initialR2T), 135 _E(U_LO, S_SW, immediateData), 136 137 _E(U_ALL,S_CO, maxRecvDataSegmentLength), 138 _E(U_ALL,S_CO, maxXmitDataSegmentLength), 139 140 _E(U_LO, S_SW, maxBurstLength), 141 _E(U_LO, S_SW, firstBurstLength), 142 _E(U_LO, S_SW, defaultTime2Wait), 143 _E(U_LO, S_SW, defaultTime2Retain), 144 145 _E(U_LO, S_SW, maxOutstandingR2T), 146 _E(U_LO, S_SW, dataPDUInOrder), 147 _E(U_LO, S_SW, dataSequenceInOrder), 148 149 _E(U_LO, S_SW, errorRecoveryLevel), 150 151 _E(U_LO, S_SW, sessionType), 152
|
148 {0}
|
153 _E(0, 0, end) |
154}; 155 156#define _OPT_INT(w) strtol((char *)w, NULL, 0) 157#define _OPT_STR(w) (char *)(w) 158 159static __inline int 160_OPT_BOOL(char *w) 161{
|
157 if(isalpha(*w))
|
162 if(isalpha((unsigned char)*w)) |
163 return strcasecmp(w, "TRUE") == 0; 164 else 165 return _OPT_INT(w); 166} 167 168#define _CASE(k, v) case OPT_##k: op->k = v; break 169static void 170setOption(isc_opt_t *op, int which, void *rval) 171{ 172 switch(which) { 173 _CASE(port, _OPT_INT(rval)); 174 _CASE(tags, _OPT_INT(rval)); 175 _CASE(maxluns, _OPT_INT(rval)); 176 _CASE(iqn, _OPT_STR(rval)); 177 _CASE(sockbufsize, _OPT_INT(rval)); 178 179 _CASE(maxConnections, _OPT_INT(rval)); 180 _CASE(maxRecvDataSegmentLength, _OPT_INT(rval)); 181 _CASE(maxXmitDataSegmentLength, _OPT_INT(rval)); 182 _CASE(maxBurstLength, _OPT_INT(rval)); 183 _CASE(firstBurstLength, _OPT_INT(rval)); 184 _CASE(defaultTime2Wait, _OPT_INT(rval)); 185 _CASE(defaultTime2Retain, _OPT_INT(rval)); 186 _CASE(maxOutstandingR2T, _OPT_INT(rval)); 187 _CASE(errorRecoveryLevel, _OPT_INT(rval)); 188 _CASE(targetPortalGroupTag, _OPT_INT(rval)); 189 _CASE(headerDigest, _OPT_STR(rval)); 190 _CASE(dataDigest, _OPT_STR(rval)); 191 192 _CASE(targetAddress, _OPT_STR(rval)); 193 _CASE(targetAlias, _OPT_STR(rval)); 194 _CASE(targetName, _OPT_STR(rval)); 195 _CASE(initiatorName, _OPT_STR(rval)); 196 _CASE(initiatorAlias, _OPT_STR(rval)); 197 _CASE(authMethod, _OPT_STR(rval)); 198 _CASE(chapSecret, _OPT_STR(rval)); 199 _CASE(chapIName, _OPT_STR(rval)); 200 _CASE(chapDigest, _OPT_STR(rval)); 201 202 _CASE(tgtChapName, _OPT_STR(rval)); 203 _CASE(tgtChapSecret, _OPT_STR(rval)); 204 205 _CASE(initialR2T, _OPT_BOOL(rval)); 206 _CASE(immediateData, _OPT_BOOL(rval)); 207 _CASE(dataPDUInOrder, _OPT_BOOL(rval)); 208 _CASE(dataSequenceInOrder, _OPT_BOOL(rval)); 209 } 210} 211 212static char * 213getline(FILE *fd) 214{ 215 static char *sp, line[BUFSIZ]; 216 char *lp, *p; 217 218 do { 219 if(sp == NULL) 220 sp = fgets(line, sizeof line, fd); 221 222 if((lp = sp) == NULL) 223 break; 224 if((p = strchr(lp, '\n')) != NULL) 225 *p = 0; 226 if((p = strchr(lp, '#')) != NULL) 227 *p = 0; 228 if((p = strchr(lp, ';')) != NULL) { 229 *p++ = 0; 230 sp = p; 231 } else 232 sp = NULL; 233 if(*lp) 234 return lp; 235 } while (feof(fd) == 0); 236 return NULL; 237} 238 239static int 240getConfig(FILE *fd, char *key, char **Ar, int *nargs) 241{ 242 char *lp, *p, **ar; 243 int state, len, n; 244 245 ar = Ar; 246 if(key) 247 len = strlen(key); 248 else 249 len = 0; 250 state = 0; 251 while((lp = getline(fd)) != NULL) {
|
247 for(; isspace(*lp); lp++)
|
252 for(; isspace((unsigned char)*lp); lp++) |
253 ; 254 switch(state) { 255 case 0: 256 if((p = strchr(lp, '{')) != NULL) {
|
252 while((--p > lp) && *p && isspace(*p));
|
257 while((--p > lp) && *p && isspace((unsigned char)*p)); |
258 n = p - lp; 259 if(len && strncmp(lp, key, MAX(n, len)) == 0) 260 state = 2; 261 else 262 state = 1; 263 continue; 264 } 265 break; 266 267 case 1: 268 if(*lp == '}') 269 state = 0; 270 continue; 271 272 case 2: 273 if(*lp == '}') 274 goto done; 275 276 break; 277 } 278 279
|
275 for(p = &lp[strlen(lp)-1]; isspace(*p); p--)
|
280 for(p = &lp[strlen(lp)-1]; isspace((unsigned char)*p); p--) |
281 *p = 0; 282 if((*nargs)-- > 0) 283 *ar++ = strdup(lp); 284 } 285 286 done: 287 if(*nargs > 0) 288 *ar = 0; 289 *nargs = ar - Ar; 290 return ar - Ar; 291} 292 293static textkey_t * 294keyLookup(char *key) 295{ 296 textkey_t *tk; 297 298 for(tk = keyMap; tk->name; tk++) { 299 if(strcasecmp(key, tk->name) == 0) 300 return tk; 301 } 302 return NULL; 303} 304 305static void 306puke(isc_opt_t *op) 307{ 308 printf("%24s = %d\n", "port", op->port); 309 printf("%24s = %d\n", "tags", op->tags); 310 printf("%24s = %d\n", "maxluns", op->maxluns); 311 printf("%24s = %s\n", "iqn", op->iqn); 312 313 printf("%24s = %d\n", "maxConnections", op->maxConnections); 314 printf("%24s = %d\n", "maxRecvDataSegmentLength", op->maxRecvDataSegmentLength); 315 printf("%24s = %d\n", "maxXmitDataSegmentLength", op->maxRecvDataSegmentLength); 316 printf("%24s = %d\n", "maxBurstLength", op->maxBurstLength); 317 printf("%24s = %d\n", "firstBurstLength", op->firstBurstLength); 318 printf("%24s = %d\n", "defaultTime2Wait", op->defaultTime2Wait); 319 printf("%24s = %d\n", "defaultTime2Retain", op->defaultTime2Retain); 320 printf("%24s = %d\n", "maxOutstandingR2T", op->maxOutstandingR2T); 321 printf("%24s = %d\n", "errorRecoveryLevel", op->errorRecoveryLevel); 322 printf("%24s = %d\n", "targetPortalGroupTag", op->targetPortalGroupTag); 323 324 printf("%24s = %s\n", "headerDigest", op->headerDigest); 325 printf("%24s = %s\n", "dataDigest", op->dataDigest); 326 327 printf("%24s = %d\n", "initialR2T", op->initialR2T); 328 printf("%24s = %d\n", "immediateData", op->immediateData); 329 printf("%24s = %d\n", "dataPDUInOrder", op->dataPDUInOrder); 330 printf("%24s = %d\n", "dataSequenceInOrder", op->dataSequenceInOrder); 331 332 printf("%24s = %s\n", "sessionType", op->sessionType); 333 printf("%24s = %s\n", "targetAddress", op->targetAddress); 334 printf("%24s = %s\n", "targetAlias", op->targetAlias); 335 printf("%24s = %s\n", "targetName", op->targetName); 336 printf("%24s = %s\n", "initiatorName", op->initiatorName); 337 printf("%24s = %s\n", "initiatorAlias", op->initiatorAlias); 338 printf("%24s = %s\n", "authMethod", op->authMethod); 339 printf("%24s = %s\n", "chapSecret", op->chapSecret); 340 printf("%24s = %s\n", "chapIName", op->chapIName); 341 printf("%24s = %s\n", "tgtChapName", op->tgtChapName); 342 printf("%24s = %s\n", "tgtChapSecret", op->tgtChapSecret); 343 printf("%24s = %d\n", "tgttgtChallengeLen", op->tgtChallengeLen); 344} 345 346void 347parseArgs(int nargs, char **args, isc_opt_t *op) 348{ 349 char **ar; 350 char *p, *v; 351 textkey_t *tk; 352 353 for(ar = args; nargs > 0; nargs--, ar++) { 354 p = strchr(*ar, '='); 355 if(p == NULL) 356 continue; 357 *p = 0; 358 v = p + 1;
|
354 while(isspace(*--p))
|
359 while(isspace((unsigned char)*--p)) |
360 *p = 0;
|
356 while(isspace(*v))
|
361 while(isspace((unsigned char)*v)) |
362 v++; 363 if((tk = keyLookup(*ar)) == NULL) 364 continue; 365 setOption(op, tk->tokenID, v); 366 } 367} 368 369void 370parseConfig(FILE *fd, char *key, isc_opt_t *op) 371{ 372 char *Ar[256]; 373 int cc; 374 375 cc = 256; 376 if(getConfig(fd, key, Ar, &cc)) 377 parseArgs(cc, Ar, op); 378 if(vflag) 379 puke(op); 380}
|