summaryrefslogtreecommitdiffstats
path: root/sbin/iscontrol/config.c
diff options
context:
space:
mode:
Diffstat (limited to 'sbin/iscontrol/config.c')
-rw-r--r--sbin/iscontrol/config.c376
1 files changed, 376 insertions, 0 deletions
diff --git a/sbin/iscontrol/config.c b/sbin/iscontrol/config.c
new file mode 100644
index 0000000..409ed2c
--- /dev/null
+++ b/sbin/iscontrol/config.c
@@ -0,0 +1,376 @@
+ /*-
+ * Copyright (c) 2005-2007 Daniel Braniss <danny@cs.huji.ac.il>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+/*
+ | $Id: config.c,v 2.1 2006/11/12 08:06:51 danny Exp danny $
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <time.h>
+#include <ctype.h>
+#include <camlib.h>
+
+#include "iscsi.h"
+#include "iscontrol.h"
+
+/*
+ | ints
+ */
+#define OPT_port 1
+#define OPT_tags 2
+
+#define OPT_maxConnections 3
+#define OPT_maxRecvDataSegmentLength 4
+#define OPT_maxXmitDataSegmentLength 5
+#define OPT_maxBurstLength 6
+#define OPT_firstBurstLength 7
+#define OPT_defaultTime2Wait 8
+#define OPT_defaultTime2Retain 9
+#define OPT_maxOutstandingR2T 10
+#define OPT_errorRecoveryLevel 11
+#define OPT_targetPortalGroupTag 12
+#define OPT_headerDigest 13
+#define OPT_dataDigest 14
+/*
+ | Booleans
+ */
+#define OPT_initialR2T 16
+#define OPT_immediateData 17
+#define OPT_dataPDUInOrder 18
+#define OPT_dataSequenceInOrder 19
+/*
+ | strings
+ */
+#define OPT_sessionType 15
+
+#define OPT_targetAddress 21
+#define OPT_targetAlias 22
+#define OPT_targetName 23
+#define OPT_initiatorName 24
+#define OPT_initiatorAlias 25
+#define OPT_authMethod 26
+
+#define OPT_chapSecret 27
+#define OPT_chapIName 28
+#define OPT_chapDigest 29
+#define OPT_tgtChapName 30
+#define OPT_tgtChapSecret 31
+#define OPT_tgtChallengeLen 32
+/*
+ | private
+ */
+#define OPT_maxluns 33
+#define OPT_iqn 34
+#define OPT_sockbufsize 35
+
+#define _OFF(v) ((int)&((isc_opt_t *)NULL)->v)
+#define _E(u, s, v) {.usage=u, .scope=s, .name=#v, .tokenID=OPT_##v}
+
+textkey_t keyMap[] = {
+ _E(U_PR, S_PR, port),
+ _E(U_PR, S_PR, tags),
+ _E(U_PR, S_PR, maxluns),
+ _E(U_PR, S_PR, sockbufsize),
+
+ _E(U_PR, S_PR, iqn),
+ _E(U_PR, S_PR, chapSecret),
+ _E(U_PR, S_PR, chapIName),
+ _E(U_PR, S_PR, chapDigest),
+ _E(U_PR, S_PR, tgtChapName),
+ _E(U_PR, S_PR, tgtChapSecret),
+ _E(U_PR, S_PR, tgtChallengeLen),
+
+ _E(U_IO, S_CO, headerDigest),
+ _E(U_IO, S_CO, dataDigest),
+
+ _E(U_IO, S_CO, authMethod),
+
+ _E(U_LO, S_SW, maxConnections),
+ _E(U_IO, S_SW, targetName),
+
+ _E(U_IO, S_SW, initiatorName),
+ _E(U_ALL,S_SW, targetAlias),
+ _E(U_ALL,S_SW, initiatorAlias),
+ _E(U_ALL,S_SW, targetAddress),
+
+ _E(U_ALL,S_SW, targetPortalGroupTag),
+
+ _E(U_LO, S_SW, initialR2T),
+ _E(U_LO, S_SW, immediateData),
+
+ _E(U_ALL,S_CO, maxRecvDataSegmentLength),
+ _E(U_ALL,S_CO, maxXmitDataSegmentLength),
+
+ _E(U_LO, S_SW, maxBurstLength),
+ _E(U_LO, S_SW, firstBurstLength),
+ _E(U_LO, S_SW, defaultTime2Wait),
+ _E(U_LO, S_SW, defaultTime2Retain),
+
+ _E(U_LO, S_SW, maxOutstandingR2T),
+ _E(U_LO, S_SW, dataPDUInOrder),
+ _E(U_LO, S_SW, dataSequenceInOrder),
+
+ _E(U_LO, S_SW, errorRecoveryLevel),
+
+ _E(U_LO, S_SW, sessionType),
+
+ {0}
+};
+
+#define _OPT_INT(w) strtol((char *)w, NULL, 0)
+#define _OPT_STR(w) (char *)(w)
+
+static __inline int
+_OPT_BOOL(char *w)
+{
+ if(isalpha(*w))
+ return strcasecmp(w, "TRUE") == 0;
+ else
+ return _OPT_INT(w);
+}
+
+#define _CASE(k, v) case OPT_##k: op->k = v; break
+static void
+setOption(isc_opt_t *op, int which, void *rval)
+{
+ switch(which) {
+ _CASE(port, _OPT_INT(rval));
+ _CASE(tags, _OPT_INT(rval));
+ _CASE(maxluns, _OPT_INT(rval));
+ _CASE(iqn, _OPT_STR(rval));
+ _CASE(sockbufsize, _OPT_INT(rval));
+
+ _CASE(maxConnections, _OPT_INT(rval));
+ _CASE(maxRecvDataSegmentLength, _OPT_INT(rval));
+ _CASE(maxXmitDataSegmentLength, _OPT_INT(rval));
+ _CASE(maxBurstLength, _OPT_INT(rval));
+ _CASE(firstBurstLength, _OPT_INT(rval));
+ _CASE(defaultTime2Wait, _OPT_INT(rval));
+ _CASE(defaultTime2Retain, _OPT_INT(rval));
+ _CASE(maxOutstandingR2T, _OPT_INT(rval));
+ _CASE(errorRecoveryLevel, _OPT_INT(rval));
+ _CASE(targetPortalGroupTag, _OPT_INT(rval));
+ _CASE(headerDigest, _OPT_STR(rval));
+ _CASE(dataDigest, _OPT_STR(rval));
+
+ _CASE(targetAddress, _OPT_STR(rval));
+ _CASE(targetAlias, _OPT_STR(rval));
+ _CASE(targetName, _OPT_STR(rval));
+ _CASE(initiatorName, _OPT_STR(rval));
+ _CASE(initiatorAlias, _OPT_STR(rval));
+ _CASE(authMethod, _OPT_STR(rval));
+ _CASE(chapSecret, _OPT_STR(rval));
+ _CASE(chapIName, _OPT_STR(rval));
+ _CASE(chapDigest, _OPT_STR(rval));
+
+ _CASE(tgtChapName, _OPT_STR(rval));
+ _CASE(tgtChapSecret, _OPT_STR(rval));
+
+ _CASE(initialR2T, _OPT_BOOL(rval));
+ _CASE(immediateData, _OPT_BOOL(rval));
+ _CASE(dataPDUInOrder, _OPT_BOOL(rval));
+ _CASE(dataSequenceInOrder, _OPT_BOOL(rval));
+ }
+}
+
+static char *
+getline(FILE *fd)
+{
+ static char *sp, line[BUFSIZ];
+ char *lp, *p;
+
+ do {
+ if(sp == NULL)
+ sp = fgets(line, sizeof line, fd);
+
+ if((lp = sp) == NULL)
+ break;
+ if((p = strchr(lp, '\n')) != NULL)
+ *p = 0;
+ if((p = strchr(lp, '#')) != NULL)
+ *p = 0;
+ if((p = strchr(lp, ';')) != NULL) {
+ *p++ = 0;
+ sp = p;
+ } else
+ sp = NULL;
+ if(*lp)
+ return lp;
+ } while (feof(fd) == 0);
+ return NULL;
+}
+
+static int
+getConfig(FILE *fd, char *key, char **Ar, int *nargs)
+{
+ char *lp, *p, **ar;
+ int state, len, n;
+
+ ar = Ar;
+ if(key)
+ len = strlen(key);
+ else
+ len = 0;
+ state = 0;
+ while((lp = getline(fd)) != NULL) {
+ for(; isspace(*lp); lp++)
+ ;
+ switch(state) {
+ case 0:
+ if((p = strchr(lp, '{')) != NULL) {
+ n = 0;
+ while((--p > lp) && *p && isspace(*p));
+ n = p - lp;
+ if(len && strncmp(lp, key, MAX(n, len)) == 0)
+ state = 2;
+ else
+ state = 1;
+ continue;
+ }
+ break;
+
+ case 1:
+ if(*lp == '}')
+ state = 0;
+ continue;
+
+ case 2:
+ if(*lp == '}')
+ goto done;
+
+ break;
+ }
+
+
+ for(p = &lp[strlen(lp)-1]; isspace(*p); p--)
+ *p = 0;
+ if((*nargs)-- > 0)
+ *ar++ = strdup(lp);
+ }
+
+ done:
+ if(*nargs > 0)
+ *ar = 0;
+ *nargs = ar - Ar;
+ return ar - Ar;
+}
+
+static textkey_t *
+keyLookup(char *key)
+{
+ textkey_t *tk;
+
+ for(tk = keyMap; tk->name; tk++) {
+ if(strcasecmp(key, tk->name) == 0)
+ return tk;
+ }
+ return NULL;
+}
+
+static void
+puke(isc_opt_t *op)
+{
+ printf("%24s = %d\n", "port", op->port);
+ printf("%24s = %d\n", "tags", op->tags);
+ printf("%24s = %d\n", "maxluns", op->maxluns);
+ printf("%24s = %s\n", "iqn", op->iqn);
+
+ printf("%24s = %d\n", "maxConnections", op->maxConnections);
+ printf("%24s = %d\n", "maxRecvDataSegmentLength", op->maxRecvDataSegmentLength);
+ printf("%24s = %d\n", "maxXmitDataSegmentLength", op->maxRecvDataSegmentLength);
+ printf("%24s = %d\n", "maxBurstLength", op->maxBurstLength);
+ printf("%24s = %d\n", "firstBurstLength", op->firstBurstLength);
+ printf("%24s = %d\n", "defaultTime2Wait", op->defaultTime2Wait);
+ printf("%24s = %d\n", "defaultTime2Retain", op->defaultTime2Retain);
+ printf("%24s = %d\n", "maxOutstandingR2T", op->maxOutstandingR2T);
+ printf("%24s = %d\n", "errorRecoveryLevel", op->errorRecoveryLevel);
+ printf("%24s = %d\n", "targetPortalGroupTag", op->targetPortalGroupTag);
+
+ printf("%24s = %s\n", "headerDigest", op->headerDigest);
+ printf("%24s = %s\n", "dataDigest", op->dataDigest);
+
+ printf("%24s = %d\n", "initialR2T", op->initialR2T);
+ printf("%24s = %d\n", "immediateData", op->immediateData);
+ printf("%24s = %d\n", "dataPDUInOrder", op->dataPDUInOrder);
+ printf("%24s = %d\n", "dataSequenceInOrder", op->dataSequenceInOrder);
+
+ printf("%24s = %s\n", "sessionType", op->sessionType);
+ printf("%24s = %s\n", "targetAddress", op->targetAddress);
+ printf("%24s = %s\n", "targetAlias", op->targetAlias);
+ printf("%24s = %s\n", "targetName", op->targetName);
+ printf("%24s = %s\n", "initiatorName", op->initiatorName);
+ printf("%24s = %s\n", "initiatorAlias", op->initiatorAlias);
+ printf("%24s = %s\n", "authMethod", op->authMethod);
+ printf("%24s = %s\n", "chapSecret", op->chapSecret);
+ printf("%24s = %s\n", "chapIName", op->chapIName);
+ printf("%24s = %s\n", "tgtChapName", op->tgtChapName);
+ printf("%24s = %s\n", "tgtChapSecret", op->tgtChapSecret);
+ printf("%24s = %d\n", "tgttgtChallengeLen", op->tgtChallengeLen);
+}
+
+void
+parseArgs(int nargs, char **args, isc_opt_t *op)
+{
+ char **ar;
+ char *p, *v;
+ textkey_t *tk;
+
+ for(ar = args; nargs > 0; nargs--, ar++) {
+ p = strchr(*ar, '=');
+ if(p == NULL)
+ continue;
+ *p = 0;
+ v = p + 1;
+ while(isspace(*--p))
+ *p = 0;
+ while(isspace(*v))
+ v++;
+ if((tk = keyLookup(*ar)) == NULL)
+ continue;
+ setOption(op, tk->tokenID, v);
+ }
+}
+
+void
+parseConfig(FILE *fd, char *key, isc_opt_t *op)
+{
+ char *Ar[256];
+ int cc;
+
+ cc = 256;
+ if(getConfig(fd, key, Ar, &cc))
+ parseArgs(cc, Ar, op);
+ if(vflag)
+ puke(op);
+}
OpenPOWER on IntegriCloud