]> git.ipfire.org Git - ipfire-3.x.git/blob - iscsi-initiator-utils/patches/iscsi-initiator-utils-add-libiscsi.patch
Move all packages to root.
[ipfire-3.x.git] / iscsi-initiator-utils / patches / iscsi-initiator-utils-add-libiscsi.patch
1 diff --git a/Makefile b/Makefile
2 index db460eb..a4d4ce0 100644
3 --- a/Makefile
4 +++ b/Makefile
5 @@ -32,6 +32,7 @@ user: ;
6 $(MAKE) -C utils/fwparam_ibft
7 $(MAKE) -C usr
8 $(MAKE) -C utils
9 + $(MAKE) -C libiscsi
10 @echo
11 @echo "Compilation complete Output file"
12 @echo "----------------------------------- ----------------"
13 @@ -53,6 +54,7 @@ kernel: force
14 force: ;
15
16 clean:
17 + $(MAKE) -C libiscsi clean
18 $(MAKE) -C utils/sysdeps clean
19 $(MAKE) -C utils/fwparam_ibft clean
20 $(MAKE) -C utils clean
21 diff --git a/libiscsi/Makefile b/libiscsi/Makefile
22 new file mode 100644
23 index 0000000..4aeb44f
24 --- /dev/null
25 +++ b/libiscsi/Makefile
26 @@ -0,0 +1,62 @@
27 +# This Makefile will work only with GNU make.
28 +
29 +OSNAME=$(shell uname -s)
30 +OPTFLAGS ?= -O2 -g
31 +WARNFLAGS ?= -Wall -Wstrict-prototypes
32 +CFLAGS = $(OPTFLAGS) $(WARNFLAGS) -I../include -I../usr -I../utils/open-isns \
33 + -D$(OSNAME) -fPIC -D_GNU_SOURCE -fvisibility=hidden
34 +LIB = libiscsi.so.0
35 +TESTS = tests/test_discovery_sendtargets tests/test_discovery_firmware
36 +TESTS += tests/test_login tests/test_logout tests/test_params
37 +TESTS += tests/test_get_network_config tests/test_get_initiator_name
38 +TESTS += tests/test_set_auth tests/test_get_auth
39 +
40 +COMMON_SRCS = sysdeps.o
41 +# sources shared between iscsid, iscsiadm and iscsistart
42 +ISCSI_LIB_SRCS = session_info.o iscsi_util.o io.o auth.o discovery.o login.o log.o md5.o sha1.o iface.o idbm.o sysfs.o iscsi_sysfs.o iscsi_net_util.o iscsid_req.o
43 +FW_PARAM_SRCS = fw_entry.o prom_lex.o prom_parse.tab.o fwparam_ppc.o fwparam_sysfs.o
44 +
45 +# sources shared with the userspace utils, note we build these separately
46 +# to get PIC versions.
47 +COMMON_OBJS = $(patsubst %.o, common-objs/%.o, $(COMMON_SRCS))
48 +USR_OBJS = $(patsubst %.o, usr-objs/%.o, $(ISCSI_LIB_SRCS) strings.o)
49 +FW_OBJS = $(patsubst %.o, fw-objs/%.o, $(FW_PARAM_SRCS))
50 +
51 +# Flags for the tests
52 +tests/% : CFLAGS = $(OPTFLAGS) $(WARNFLAGS) -I.
53 +
54 +all: lib tests html
55 +
56 +lib: $(LIB)
57 +tests: $(TESTS)
58 +
59 +common-objs/%.o: ../utils/sysdeps/%.c
60 + mkdir -p common-objs
61 + $(CC) $(CFLAGS) -c $< -o $@
62 +
63 +usr-objs/%.o: ../usr/%.c
64 + mkdir -p usr-objs
65 + $(CC) $(CFLAGS) -c $< -o $@
66 +
67 +fw-objs/%.o: ../utils/fwparam_ibft/%.c
68 + mkdir -p fw-objs
69 + $(CC) $(CFLAGS) -c $< -o $@
70 +
71 +$(LIB): $(COMMON_OBJS) $(FW_OBJS) $(USR_OBJS) libiscsi.o
72 + $(CC) $(CFLAGS) -L../utils/open-isns -lisns -shared -Wl,-soname,$(LIB) $^ -o $@
73 + ln -s -f $(LIB) libiscsi.so
74 +
75 +$(TESTS): $(FW_OBJS) $(COMMON_OBJS) $(USR_OBJS) $(LIB)
76 + $(CC) $(CFLAGS) -L../utils/open-isns -lisns -c $< -o $@
77 +
78 +html: libiscsi.h libiscsi.doxy
79 + doxygen libiscsi.doxy
80 +
81 +clean:
82 + rm -rf *.o common-objs usr-objs fw-objs libuip-objs libiscsi.so* \
83 + .depend *~ html $(TESTS) tests/*~
84 +
85 +depend:
86 + gcc $(CFLAGS) -M `ls *.c` > .depend
87 +
88 +-include .depend ../usr/.depend
89 diff --git a/libiscsi/libiscsi.c b/libiscsi/libiscsi.c
90 new file mode 100644
91 index 0000000..a9eb0a6
92 --- /dev/null
93 +++ b/libiscsi/libiscsi.c
94 @@ -0,0 +1,563 @@
95 +/*
96 + * iSCSI Administration library
97 + *
98 + * Copyright (C) 2008-2009 Red Hat, Inc. All rights reserved.
99 + * Copyright (C) 2008-2009 Hans de Goede <hdegoede@redhat.com>
100 + * maintained by open-iscsi@googlegroups.com
101 + *
102 + * This program is free software; you can redistribute it and/or modify
103 + * it under the terms of the GNU General Public License as published
104 + * by the Free Software Foundation; either version 2 of the License, or
105 + * (at your option) any later version.
106 + *
107 + * This program is distributed in the hope that it will be useful, but
108 + * WITHOUT ANY WARRANTY; without even the implied warranty of
109 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
110 + * General Public License for more details.
111 + *
112 + * See the file COPYING included with this distribution for more details.
113 + */
114 +
115 +#include <stdio.h>
116 +#include <stdlib.h>
117 +#include <string.h>
118 +#include <errno.h>
119 +#include <unistd.h>
120 +#include <sys/syslog.h>
121 +#include "libiscsi.h"
122 +#include "idbm.h"
123 +#include "discovery.h"
124 +#include "log.h"
125 +#include "sysfs.h"
126 +#include "iscsi_sysfs.h"
127 +#include "session_info.h"
128 +#include "iscsi_util.h"
129 +#include "sysdeps.h"
130 +#include "iface.h"
131 +#include "iscsi_proto.h"
132 +#include "fw_context.h"
133 +#include "iscsid_req.h"
134 +
135 +#define CHECK(a) { context->error_str[0] = 0; rc = a; if (rc) goto leave; }
136 +
137 +struct libiscsi_context {
138 + char error_str[256];
139 + /* For get_parameter_helper() */
140 + const char *parameter;
141 + char *value;
142 +};
143 +
144 +static void libiscsi_log(int prio, void *priv, const char *fmt, va_list ap)
145 +{
146 + struct libiscsi_context *context = priv;
147 +
148 + if (prio > LOG_ERR) /* We are only interested in errors (or worse) */
149 + return;
150 +
151 + vsnprintf(context->error_str, sizeof(context->error_str), fmt, ap);
152 +}
153 +
154 +struct libiscsi_context *libiscsi_init(void)
155 +{
156 + struct libiscsi_context *context;
157 +
158 + context = calloc(1, sizeof *context);
159 + if (!context)
160 + return NULL;
161 +
162 + log_init("libiscsi", 1024, libiscsi_log, context);
163 + sysfs_init();
164 + increase_max_files();
165 + if (idbm_init(NULL)) {
166 + sysfs_cleanup();
167 + free(context);
168 + return NULL;
169 + }
170 +
171 + iface_setup_host_bindings();
172 +
173 + return context;
174 +}
175 +
176 +void libiscsi_cleanup(struct libiscsi_context *context)
177 +{
178 + idbm_terminate();
179 + free_transports();
180 + sysfs_cleanup();
181 + free(context);
182 +}
183 +
184 +static void free_rec_list(struct list_head *rec_list)
185 +{
186 + struct node_rec *rec, *tmp;
187 +
188 + list_for_each_entry_safe(rec, tmp, rec_list, list) {
189 + list_del(&rec->list);
190 + free(rec);
191 + }
192 +}
193 +
194 +int libiscsi_discover_sendtargets(struct libiscsi_context *context,
195 + const char *address, int port,
196 + const struct libiscsi_auth_info *auth_info,
197 + int *nr_found, struct libiscsi_node **found_nodes)
198 +{
199 + struct discovery_rec drec;
200 + LIST_HEAD(bound_rec_list);
201 + struct node_rec *rec;
202 + int rc = 0, found = 0;
203 +
204 + INIT_LIST_HEAD(&bound_rec_list);
205 +
206 + if (nr_found)
207 + *nr_found = 0;
208 + if (found_nodes)
209 + *found_nodes = NULL;
210 +
211 + CHECK(libiscsi_verify_auth_info(context, auth_info))
212 +
213 + /* Fill the drec struct with all needed info */
214 + memset(&drec, 0, sizeof drec);
215 + idbm_sendtargets_defaults(&drec.u.sendtargets);
216 + drec.type = DISCOVERY_TYPE_SENDTARGETS;
217 + strlcpy(drec.address, address, sizeof(drec.address));
218 + drec.port = port ? port : ISCSI_LISTEN_PORT;
219 + switch(auth_info ? auth_info->method : libiscsi_auth_none) {
220 + case libiscsi_auth_chap:
221 + drec.u.sendtargets.auth.authmethod = AUTH_METHOD_CHAP;
222 + strlcpy(drec.u.sendtargets.auth.username,
223 + auth_info->chap.username, AUTH_STR_MAX_LEN);
224 + strlcpy((char *)drec.u.sendtargets.auth.password,
225 + auth_info->chap.password, AUTH_STR_MAX_LEN);
226 + drec.u.sendtargets.auth.password_length =
227 + strlen((char *)drec.u.sendtargets.auth.password);
228 + strlcpy(drec.u.sendtargets.auth.username_in,
229 + auth_info->chap.reverse_username, AUTH_STR_MAX_LEN);
230 + strlcpy((char *)drec.u.sendtargets.auth.password_in,
231 + auth_info->chap.reverse_password, AUTH_STR_MAX_LEN);
232 + drec.u.sendtargets.auth.password_in_length =
233 + strlen((char *)drec.u.sendtargets.auth.password_in);
234 + break;
235 + }
236 +
237 + CHECK(idbm_add_discovery(&drec))
238 +
239 + CHECK(idbm_bind_ifaces_to_nodes(discovery_sendtargets,
240 + &drec, NULL, &bound_rec_list))
241 +
242 + /* now add/update records */
243 + list_for_each_entry(rec, &bound_rec_list, list) {
244 + CHECK(idbm_add_node(rec, &drec, 1 /* overwrite */))
245 + found++;
246 + }
247 +
248 + if (nr_found)
249 + *nr_found = found;
250 +
251 + if (found_nodes && found) {
252 + *found_nodes = calloc(found, sizeof **found_nodes);
253 + if (*found_nodes == NULL) {
254 + snprintf(context->error_str,
255 + sizeof(context->error_str), strerror(ENOMEM));
256 + rc = ENOMEM;
257 + goto leave;
258 + }
259 + found = 0;
260 + list_for_each_entry(rec, &bound_rec_list, list) {
261 + strlcpy((*found_nodes)[found].name, rec->name,
262 + LIBISCSI_VALUE_MAXLEN);
263 + (*found_nodes)[found].tpgt = rec->tpgt;
264 + strlcpy((*found_nodes)[found].address,
265 + rec->conn[0].address, NI_MAXHOST);
266 + (*found_nodes)[found].port = rec->conn[0].port;
267 + found++;
268 + }
269 + }
270 +
271 +leave:
272 + free_rec_list(&bound_rec_list);
273 + return rc;
274 +}
275 +
276 +int libiscsi_discover_firmware(struct libiscsi_context *context,
277 + int *nr_found, struct libiscsi_node **found_nodes)
278 +{
279 + struct boot_context fw_entry;
280 + struct node_rec rec;
281 + int rc = 0;
282 +
283 + if (nr_found)
284 + *nr_found = 0;
285 + if (found_nodes)
286 + *found_nodes = NULL;
287 +
288 + memset(&fw_entry, 0, sizeof fw_entry);
289 + rc = fw_get_entry(&fw_entry);
290 + if (rc) {
291 + strcpy(context->error_str, "Could not read fw values.");
292 + return rc;
293 + }
294 +
295 + memset(&rec, 0, sizeof rec);
296 + idbm_node_setup_defaults(&rec);
297 +
298 + strlcpy(rec.name, fw_entry.targetname, TARGET_NAME_MAXLEN);
299 + rec.tpgt = 1;
300 + strlcpy(rec.conn[0].address, fw_entry.target_ipaddr, NI_MAXHOST);
301 + rec.conn[0].port = fw_entry.target_port;
302 +
303 + iface_setup_defaults(&rec.iface);
304 + strncpy(rec.iface.iname, fw_entry.initiatorname,
305 + sizeof(fw_entry.initiatorname));
306 + strncpy(rec.session.auth.username, fw_entry.chap_name,
307 + sizeof(fw_entry.chap_name));
308 + strncpy((char *)rec.session.auth.password, fw_entry.chap_password,
309 + sizeof(fw_entry.chap_password));
310 + strncpy(rec.session.auth.username_in, fw_entry.chap_name_in,
311 + sizeof(fw_entry.chap_name_in));
312 + strncpy((char *)rec.session.auth.password_in,
313 + fw_entry.chap_password_in,
314 + sizeof(fw_entry.chap_password_in));
315 + rec.session.auth.password_length =
316 + strlen((char *)fw_entry.chap_password);
317 + rec.session.auth.password_in_length =
318 + strlen((char *)fw_entry.chap_password_in);
319 +
320 + CHECK(idbm_add_node(&rec, NULL, 1 /* overwrite */))
321 +
322 + if (nr_found)
323 + *nr_found = 1;
324 +
325 + if (found_nodes) {
326 + *found_nodes = calloc(1, sizeof **found_nodes);
327 + if (*found_nodes == NULL) {
328 + snprintf(context->error_str,
329 + sizeof(context->error_str), strerror(ENOMEM));
330 + rc = ENOMEM;
331 + goto leave;
332 + }
333 + strlcpy((*found_nodes)[0].name, rec.name,
334 + LIBISCSI_VALUE_MAXLEN);
335 + (*found_nodes)[0].tpgt = rec.tpgt;
336 + strlcpy((*found_nodes)[0].address,
337 + rec.conn[0].address, NI_MAXHOST);
338 + (*found_nodes)[0].port = rec.conn[0].port;
339 + }
340 +
341 +leave:
342 + return rc;
343 +}
344 +
345 +int libiscsi_verify_auth_info(struct libiscsi_context *context,
346 + const struct libiscsi_auth_info *auth_info)
347 +{
348 + switch(auth_info ? auth_info->method : libiscsi_auth_none) {
349 + case libiscsi_auth_none:
350 + break;
351 + case libiscsi_auth_chap:
352 + if (!auth_info->chap.username[0]) {
353 + strcpy(context->error_str, "Empty username");
354 + return EINVAL;
355 + }
356 + if (!auth_info->chap.password[0]) {
357 + strcpy(context->error_str, "Empty password");
358 + return EINVAL;
359 + }
360 + if (auth_info->chap.reverse_username[0] &&
361 + !auth_info->chap.reverse_password[0]) {
362 + strcpy(context->error_str, "Empty reverse password");
363 + return EINVAL;
364 + }
365 + break;
366 + default:
367 + sprintf(context->error_str,
368 + "Invalid authentication method: %d",
369 + (int)auth_info->method);
370 + return EINVAL;
371 + }
372 + return 0;
373 +}
374 +
375 +int libiscsi_node_set_auth(struct libiscsi_context *context,
376 + const struct libiscsi_node *node,
377 + const struct libiscsi_auth_info *auth_info)
378 +{
379 + int rc = 0;
380 +
381 + CHECK(libiscsi_verify_auth_info(context, auth_info))
382 +
383 + switch(auth_info ? auth_info->method : libiscsi_auth_none) {
384 + case libiscsi_auth_none:
385 + CHECK(libiscsi_node_set_parameter(context, node,
386 + "node.session.auth.authmethod", "None"))
387 + CHECK(libiscsi_node_set_parameter(context, node,
388 + "node.session.auth.username", ""))
389 + CHECK(libiscsi_node_set_parameter(context, node,
390 + "node.session.auth.password", ""))
391 + CHECK(libiscsi_node_set_parameter(context, node,
392 + "node.session.auth.username_in", ""))
393 + CHECK(libiscsi_node_set_parameter(context, node,
394 + "node.session.auth.password_in", ""))
395 + break;
396 +
397 + case libiscsi_auth_chap:
398 + CHECK(libiscsi_node_set_parameter(context, node,
399 + "node.session.auth.authmethod", "CHAP"))
400 + CHECK(libiscsi_node_set_parameter(context, node,
401 + "node.session.auth.username",
402 + auth_info->chap.username))
403 + CHECK(libiscsi_node_set_parameter(context, node,
404 + "node.session.auth.password",
405 + auth_info->chap.password))
406 + CHECK(libiscsi_node_set_parameter(context, node,
407 + "node.session.auth.username_in",
408 + auth_info->chap.reverse_username))
409 + CHECK(libiscsi_node_set_parameter(context, node,
410 + "node.session.auth.password_in",
411 + auth_info->chap.reverse_password))
412 + break;
413 + }
414 +leave:
415 + return rc;
416 +}
417 +
418 +int libiscsi_node_get_auth(struct libiscsi_context *context,
419 + const struct libiscsi_node *node,
420 + struct libiscsi_auth_info *auth_info)
421 +{
422 + int rc = 0;
423 + char value[LIBISCSI_VALUE_MAXLEN];
424 +
425 + memset(auth_info, 0, sizeof *auth_info);
426 +
427 + CHECK(libiscsi_node_get_parameter(context, node,
428 + "node.session.auth.authmethod", value))
429 +
430 + if (!strcmp(value, "None")) {
431 + auth_info->method = libiscsi_auth_none;
432 + } else if (!strcmp(value, "CHAP")) {
433 + auth_info->method = libiscsi_auth_chap;
434 + CHECK(libiscsi_node_get_parameter(context, node,
435 + "node.session.auth.username",
436 + auth_info->chap.username))
437 + CHECK(libiscsi_node_get_parameter(context, node,
438 + "node.session.auth.password",
439 + auth_info->chap.password))
440 + CHECK(libiscsi_node_get_parameter(context, node,
441 + "node.session.auth.username_in",
442 + auth_info->chap.reverse_username))
443 + CHECK(libiscsi_node_get_parameter(context, node,
444 + "node.session.auth.password_in",
445 + auth_info->chap.reverse_password))
446 + } else {
447 + snprintf(context->error_str, sizeof(context->error_str),
448 + "unknown authentication method: %s", value);
449 + rc = EINVAL;
450 + }
451 +leave:
452 + return rc;
453 +}
454 +
455 +static void node_to_rec(const struct libiscsi_node *node,
456 + struct node_rec *rec)
457 +{
458 + memset(rec, 0, sizeof *rec);
459 + idbm_node_setup_defaults(rec);
460 + strlcpy(rec->name, node->name, TARGET_NAME_MAXLEN);
461 + rec->tpgt = node->tpgt;
462 + strlcpy(rec->conn[0].address, node->address, NI_MAXHOST);
463 + rec->conn[0].port = node->port;
464 +}
465 +
466 +int login_helper(void *data, node_rec_t *rec)
467 +{
468 + int rc = iscsid_req_by_rec(MGMT_IPC_SESSION_LOGIN, rec);
469 + if (rc) {
470 + iscsid_handle_error(rc);
471 + rc = ENOTCONN;
472 + }
473 + return rc;
474 +}
475 +
476 +int libiscsi_node_login(struct libiscsi_context *context,
477 + const struct libiscsi_node *node)
478 +{
479 + int nr_found = 0, rc;
480 +
481 + CHECK(idbm_for_each_iface(&nr_found, NULL, login_helper,
482 + (char *)node->name, node->tpgt,
483 + (char *)node->address, node->port))
484 + if (nr_found == 0) {
485 + strcpy(context->error_str, "No such node");
486 + rc = ENODEV;
487 + }
488 +leave:
489 + return rc;
490 +}
491 +
492 +static int logout_helper(void *data, struct session_info *info)
493 +{
494 + int rc;
495 + struct node_rec *rec = data;
496 +
497 + if (!iscsi_match_session(rec, info))
498 + /* Tell iscsi_sysfs_for_each_session this session was not a
499 + match so that it will not increase nr_found. */
500 + return -1;
501 +
502 + rc = iscsid_req_by_sid(MGMT_IPC_SESSION_LOGOUT, info->sid);
503 + if (rc) {
504 + iscsid_handle_error(rc);
505 + rc = EIO;
506 + }
507 +
508 + return rc;
509 +}
510 +
511 +int libiscsi_node_logout(struct libiscsi_context *context,
512 + const struct libiscsi_node *node)
513 +{
514 + int nr_found = 0, rc;
515 + struct node_rec rec;
516 +
517 + node_to_rec(node, &rec);
518 + CHECK(iscsi_sysfs_for_each_session(&rec, &nr_found, logout_helper))
519 + if (nr_found == 0) {
520 + strcpy(context->error_str, "No matching session");
521 + rc = ENODEV;
522 + }
523 +leave:
524 + return rc;
525 +}
526 +
527 +int libiscsi_node_set_parameter(struct libiscsi_context *context,
528 + const struct libiscsi_node *node,
529 + const char *parameter, const char *value)
530 +{
531 + int nr_found = 0, rc;
532 + struct db_set_param set_param = {
533 + .name = (char *)parameter,
534 + .value = (char *)value,
535 + };
536 +
537 + CHECK(idbm_for_each_iface(&nr_found, &set_param, idbm_node_set_param,
538 + (char *)node->name, node->tpgt,
539 + (char *)node->address, node->port))
540 + if (nr_found == 0) {
541 + strcpy(context->error_str, "No such node");
542 + rc = ENODEV;
543 + }
544 +leave:
545 + return rc;
546 +}
547 +
548 +static int get_parameter_helper(void *data, node_rec_t *rec)
549 +{
550 + struct libiscsi_context *context = data;
551 + recinfo_t *info;
552 + int i;
553 +
554 + info = idbm_recinfo_alloc(MAX_KEYS);
555 + if (!info) {
556 + snprintf(context->error_str, sizeof(context->error_str),
557 + strerror(ENOMEM));
558 + return ENOMEM;
559 + }
560 +
561 + idbm_recinfo_node(rec, info);
562 +
563 + for (i = 0; i < MAX_KEYS; i++) {
564 + if (!info[i].visible)
565 + continue;
566 +
567 + if (strcmp(context->parameter, info[i].name))
568 + continue;
569 +
570 + strlcpy(context->value, info[i].value, LIBISCSI_VALUE_MAXLEN);
571 + break;
572 + }
573 +
574 + free(info);
575 +
576 + if (i == MAX_KEYS) {
577 + strcpy(context->error_str, "No such parameter");
578 + return EINVAL;
579 + }
580 +
581 + return 0;
582 +}
583 +
584 +int libiscsi_node_get_parameter(struct libiscsi_context *context,
585 + const struct libiscsi_node *node, const char *parameter, char *value)
586 +{
587 + int nr_found = 0, rc = 0;
588 +
589 + context->parameter = parameter;
590 + context->value = value;
591 +
592 + /* Note we assume there is only one interface, if not we will get
593 + the value from the last interface iterated over!
594 + This (multiple interfaces) can only happen if someone explicitly
595 + created ones using iscsiadm. Even then this should not be a problem
596 + as most settings should be the same independent of the iface. */
597 + CHECK(idbm_for_each_iface(&nr_found, context, get_parameter_helper,
598 + (char *)node->name, node->tpgt,
599 + (char *)node->address, node->port))
600 + if (nr_found == 0) {
601 + strcpy(context->error_str, "No such node");
602 + rc = ENODEV;
603 + }
604 +leave:
605 + return rc;
606 +}
607 +
608 +const char *libiscsi_get_error_string(struct libiscsi_context *context)
609 +{
610 + /* Sometimes the core open-iscsi code does not give us an error
611 + message */
612 + if (!context->error_str[0])
613 + return "Unknown error";
614 +
615 + return context->error_str;
616 +}
617 +
618 +
619 +/************************** Utility functions *******************************/
620 +
621 +int libiscsi_get_firmware_network_config(
622 + struct libiscsi_network_config *config)
623 +{
624 + struct boot_context fw_entry;
625 +
626 + memset(config, 0, sizeof *config);
627 + memset(&fw_entry, 0, sizeof fw_entry);
628 + if (fw_get_entry(&fw_entry))
629 + return ENODEV;
630 +
631 + config->dhcp = strlen(fw_entry.dhcp) ? 1 : 0;
632 + strncpy(config->iface_name, fw_entry.iface, sizeof fw_entry.iface);
633 + strncpy(config->mac_address, fw_entry.mac, sizeof fw_entry.mac);
634 + strncpy(config->ip_address, fw_entry.ipaddr, sizeof fw_entry.ipaddr);
635 + strncpy(config->netmask, fw_entry.mask, sizeof fw_entry.mask);
636 + strncpy(config->gateway, fw_entry.gateway, sizeof fw_entry.gateway);
637 + strncpy(config->primary_dns, fw_entry.primary_dns,
638 + sizeof fw_entry.primary_dns);
639 + strncpy(config->secondary_dns, fw_entry.secondary_dns,
640 + sizeof fw_entry.secondary_dns);
641 + return 0;
642 +}
643 +
644 +int libiscsi_get_firmware_initiator_name(char *initiatorname)
645 +{
646 + struct boot_context fw_entry;
647 +
648 + memset(initiatorname, 0, LIBISCSI_VALUE_MAXLEN);
649 + memset(&fw_entry, 0, sizeof fw_entry);
650 + if (fw_get_entry(&fw_entry))
651 + return ENODEV;
652 +
653 + strncpy(initiatorname, fw_entry.initiatorname,
654 + sizeof fw_entry.initiatorname);
655 +
656 + return 0;
657 +}
658 diff --git a/libiscsi/libiscsi.doxy b/libiscsi/libiscsi.doxy
659 new file mode 100644
660 index 0000000..663770f
661 --- /dev/null
662 +++ b/libiscsi/libiscsi.doxy
663 @@ -0,0 +1,1473 @@
664 +# Doxyfile 1.5.7.1
665 +
666 +# This file describes the settings to be used by the documentation system
667 +# doxygen (www.doxygen.org) for a project
668 +#
669 +# All text after a hash (#) is considered a comment and will be ignored
670 +# The format is:
671 +# TAG = value [value, ...]
672 +# For lists items can also be appended using:
673 +# TAG += value [value, ...]
674 +# Values that contain spaces should be placed between quotes (" ")
675 +
676 +#---------------------------------------------------------------------------
677 +# Project related configuration options
678 +#---------------------------------------------------------------------------
679 +
680 +# This tag specifies the encoding used for all characters in the config file
681 +# that follow. The default is UTF-8 which is also the encoding used for all
682 +# text before the first occurrence of this tag. Doxygen uses libiconv (or the
683 +# iconv built into libc) for the transcoding. See
684 +# http://www.gnu.org/software/libiconv for the list of possible encodings.
685 +
686 +DOXYFILE_ENCODING = UTF-8
687 +
688 +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded
689 +# by quotes) that should identify the project.
690 +
691 +PROJECT_NAME = libiscsi
692 +
693 +# The PROJECT_NUMBER tag can be used to enter a project or revision number.
694 +# This could be handy for archiving the generated documentation or
695 +# if some version control system is used.
696 +
697 +PROJECT_NUMBER =
698 +
699 +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
700 +# base path where the generated documentation will be put.
701 +# If a relative path is entered, it will be relative to the location
702 +# where doxygen was started. If left blank the current directory will be used.
703 +
704 +OUTPUT_DIRECTORY =
705 +
706 +# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create
707 +# 4096 sub-directories (in 2 levels) under the output directory of each output
708 +# format and will distribute the generated files over these directories.
709 +# Enabling this option can be useful when feeding doxygen a huge amount of
710 +# source files, where putting all generated files in the same directory would
711 +# otherwise cause performance problems for the file system.
712 +
713 +CREATE_SUBDIRS = NO
714 +
715 +# The OUTPUT_LANGUAGE tag is used to specify the language in which all
716 +# documentation generated by doxygen is written. Doxygen will use this
717 +# information to generate all constant output in the proper language.
718 +# The default language is English, other supported languages are:
719 +# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional,
720 +# Croatian, Czech, Danish, Dutch, Farsi, Finnish, French, German, Greek,
721 +# Hungarian, Italian, Japanese, Japanese-en (Japanese with English messages),
722 +# Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, Polish,
723 +# Portuguese, Romanian, Russian, Serbian, Serbian-Cyrilic, Slovak, Slovene,
724 +# Spanish, Swedish, and Ukrainian.
725 +
726 +OUTPUT_LANGUAGE = English
727 +
728 +# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will
729 +# include brief member descriptions after the members that are listed in
730 +# the file and class documentation (similar to JavaDoc).
731 +# Set to NO to disable this.
732 +
733 +BRIEF_MEMBER_DESC = YES
734 +
735 +# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend
736 +# the brief description of a member or function before the detailed description.
737 +# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
738 +# brief descriptions will be completely suppressed.
739 +
740 +REPEAT_BRIEF = NO
741 +
742 +# This tag implements a quasi-intelligent brief description abbreviator
743 +# that is used to form the text in various listings. Each string
744 +# in this list, if found as the leading text of the brief description, will be
745 +# stripped from the text and the result after processing the whole list, is
746 +# used as the annotated text. Otherwise, the brief description is used as-is.
747 +# If left blank, the following values are used ("$name" is automatically
748 +# replaced with the name of the entity): "The $name class" "The $name widget"
749 +# "The $name file" "is" "provides" "specifies" "contains"
750 +# "represents" "a" "an" "the"
751 +
752 +ABBREVIATE_BRIEF =
753 +
754 +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
755 +# Doxygen will generate a detailed section even if there is only a brief
756 +# description.
757 +
758 +ALWAYS_DETAILED_SEC = YES
759 +
760 +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all
761 +# inherited members of a class in the documentation of that class as if those
762 +# members were ordinary class members. Constructors, destructors and assignment
763 +# operators of the base classes will not be shown.
764 +
765 +INLINE_INHERITED_MEMB = NO
766 +
767 +# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full
768 +# path before files name in the file list and in the header files. If set
769 +# to NO the shortest path that makes the file name unique will be used.
770 +
771 +FULL_PATH_NAMES = YES
772 +
773 +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag
774 +# can be used to strip a user-defined part of the path. Stripping is
775 +# only done if one of the specified strings matches the left-hand part of
776 +# the path. The tag can be used to show relative paths in the file list.
777 +# If left blank the directory from which doxygen is run is used as the
778 +# path to strip.
779 +
780 +STRIP_FROM_PATH =
781 +
782 +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of
783 +# the path mentioned in the documentation of a class, which tells
784 +# the reader which header file to include in order to use a class.
785 +# If left blank only the name of the header file containing the class
786 +# definition is used. Otherwise one should specify the include paths that
787 +# are normally passed to the compiler using the -I flag.
788 +
789 +STRIP_FROM_INC_PATH =
790 +
791 +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter
792 +# (but less readable) file names. This can be useful is your file systems
793 +# doesn't support long names like on DOS, Mac, or CD-ROM.
794 +
795 +SHORT_NAMES = NO
796 +
797 +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen
798 +# will interpret the first line (until the first dot) of a JavaDoc-style
799 +# comment as the brief description. If set to NO, the JavaDoc
800 +# comments will behave just like regular Qt-style comments
801 +# (thus requiring an explicit @brief command for a brief description.)
802 +
803 +JAVADOC_AUTOBRIEF = NO
804 +
805 +# If the QT_AUTOBRIEF tag is set to YES then Doxygen will
806 +# interpret the first line (until the first dot) of a Qt-style
807 +# comment as the brief description. If set to NO, the comments
808 +# will behave just like regular Qt-style comments (thus requiring
809 +# an explicit \brief command for a brief description.)
810 +
811 +QT_AUTOBRIEF = NO
812 +
813 +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen
814 +# treat a multi-line C++ special comment block (i.e. a block of //! or ///
815 +# comments) as a brief description. This used to be the default behaviour.
816 +# The new default is to treat a multi-line C++ comment block as a detailed
817 +# description. Set this tag to YES if you prefer the old behaviour instead.
818 +
819 +MULTILINE_CPP_IS_BRIEF = NO
820 +
821 +# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented
822 +# member inherits the documentation from any documented member that it
823 +# re-implements.
824 +
825 +INHERIT_DOCS = YES
826 +
827 +# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce
828 +# a new page for each member. If set to NO, the documentation of a member will
829 +# be part of the file/class/namespace that contains it.
830 +
831 +SEPARATE_MEMBER_PAGES = NO
832 +
833 +# The TAB_SIZE tag can be used to set the number of spaces in a tab.
834 +# Doxygen uses this value to replace tabs by spaces in code fragments.
835 +
836 +TAB_SIZE = 8
837 +
838 +# This tag can be used to specify a number of aliases that acts
839 +# as commands in the documentation. An alias has the form "name=value".
840 +# For example adding "sideeffect=\par Side Effects:\n" will allow you to
841 +# put the command \sideeffect (or @sideeffect) in the documentation, which
842 +# will result in a user-defined paragraph with heading "Side Effects:".
843 +# You can put \n's in the value part of an alias to insert newlines.
844 +
845 +ALIASES =
846 +
847 +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C
848 +# sources only. Doxygen will then generate output that is more tailored for C.
849 +# For instance, some of the names that are used will be different. The list
850 +# of all members will be omitted, etc.
851 +
852 +OPTIMIZE_OUTPUT_FOR_C = YES
853 +
854 +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java
855 +# sources only. Doxygen will then generate output that is more tailored for
856 +# Java. For instance, namespaces will be presented as packages, qualified
857 +# scopes will look different, etc.
858 +
859 +OPTIMIZE_OUTPUT_JAVA = NO
860 +
861 +# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran
862 +# sources only. Doxygen will then generate output that is more tailored for
863 +# Fortran.
864 +
865 +OPTIMIZE_FOR_FORTRAN = NO
866 +
867 +# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL
868 +# sources. Doxygen will then generate output that is tailored for
869 +# VHDL.
870 +
871 +OPTIMIZE_OUTPUT_VHDL = NO
872 +
873 +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want
874 +# to include (a tag file for) the STL sources as input, then you should
875 +# set this tag to YES in order to let doxygen match functions declarations and
876 +# definitions whose arguments contain STL classes (e.g. func(std::string); v.s.
877 +# func(std::string) {}). This also make the inheritance and collaboration
878 +# diagrams that involve STL classes more complete and accurate.
879 +
880 +BUILTIN_STL_SUPPORT = NO
881 +
882 +# If you use Microsoft's C++/CLI language, you should set this option to YES to
883 +# enable parsing support.
884 +
885 +CPP_CLI_SUPPORT = NO
886 +
887 +# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only.
888 +# Doxygen will parse them like normal C++ but will assume all classes use public
889 +# instead of private inheritance when no explicit protection keyword is present.
890 +
891 +SIP_SUPPORT = NO
892 +
893 +# For Microsoft's IDL there are propget and propput attributes to indicate getter
894 +# and setter methods for a property. Setting this option to YES (the default)
895 +# will make doxygen to replace the get and set methods by a property in the
896 +# documentation. This will only work if the methods are indeed getting or
897 +# setting a simple type. If this is not the case, or you want to show the
898 +# methods anyway, you should set this option to NO.
899 +
900 +IDL_PROPERTY_SUPPORT = YES
901 +
902 +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
903 +# tag is set to YES, then doxygen will reuse the documentation of the first
904 +# member in the group (if any) for the other members of the group. By default
905 +# all members of a group must be documented explicitly.
906 +
907 +DISTRIBUTE_GROUP_DOC = NO
908 +
909 +# Set the SUBGROUPING tag to YES (the default) to allow class member groups of
910 +# the same type (for instance a group of public functions) to be put as a
911 +# subgroup of that type (e.g. under the Public Functions section). Set it to
912 +# NO to prevent subgrouping. Alternatively, this can be done per class using
913 +# the \nosubgrouping command.
914 +
915 +SUBGROUPING = YES
916 +
917 +# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum
918 +# is documented as struct, union, or enum with the name of the typedef. So
919 +# typedef struct TypeS {} TypeT, will appear in the documentation as a struct
920 +# with name TypeT. When disabled the typedef will appear as a member of a file,
921 +# namespace, or class. And the struct will be named TypeS. This can typically
922 +# be useful for C code in case the coding convention dictates that all compound
923 +# types are typedef'ed and only the typedef is referenced, never the tag name.
924 +
925 +TYPEDEF_HIDES_STRUCT = NO
926 +
927 +# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to
928 +# determine which symbols to keep in memory and which to flush to disk.
929 +# When the cache is full, less often used symbols will be written to disk.
930 +# For small to medium size projects (<1000 input files) the default value is
931 +# probably good enough. For larger projects a too small cache size can cause
932 +# doxygen to be busy swapping symbols to and from disk most of the time
933 +# causing a significant performance penality.
934 +# If the system has enough physical memory increasing the cache will improve the
935 +# performance by keeping more symbols in memory. Note that the value works on
936 +# a logarithmic scale so increasing the size by one will rougly double the
937 +# memory usage. The cache size is given by this formula:
938 +# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0,
939 +# corresponding to a cache size of 2^16 = 65536 symbols
940 +
941 +SYMBOL_CACHE_SIZE = 0
942 +
943 +#---------------------------------------------------------------------------
944 +# Build related configuration options
945 +#---------------------------------------------------------------------------
946 +
947 +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in
948 +# documentation are documented, even if no documentation was available.
949 +# Private class members and static file members will be hidden unless
950 +# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
951 +
952 +EXTRACT_ALL = YES
953 +
954 +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class
955 +# will be included in the documentation.
956 +
957 +EXTRACT_PRIVATE = NO
958 +
959 +# If the EXTRACT_STATIC tag is set to YES all static members of a file
960 +# will be included in the documentation.
961 +
962 +EXTRACT_STATIC = NO
963 +
964 +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs)
965 +# defined locally in source files will be included in the documentation.
966 +# If set to NO only classes defined in header files are included.
967 +
968 +EXTRACT_LOCAL_CLASSES = YES
969 +
970 +# This flag is only useful for Objective-C code. When set to YES local
971 +# methods, which are defined in the implementation section but not in
972 +# the interface are included in the documentation.
973 +# If set to NO (the default) only methods in the interface are included.
974 +
975 +EXTRACT_LOCAL_METHODS = NO
976 +
977 +# If this flag is set to YES, the members of anonymous namespaces will be
978 +# extracted and appear in the documentation as a namespace called
979 +# 'anonymous_namespace{file}', where file will be replaced with the base
980 +# name of the file that contains the anonymous namespace. By default
981 +# anonymous namespace are hidden.
982 +
983 +EXTRACT_ANON_NSPACES = NO
984 +
985 +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all
986 +# undocumented members of documented classes, files or namespaces.
987 +# If set to NO (the default) these members will be included in the
988 +# various overviews, but no documentation section is generated.
989 +# This option has no effect if EXTRACT_ALL is enabled.
990 +
991 +HIDE_UNDOC_MEMBERS = NO
992 +
993 +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all
994 +# undocumented classes that are normally visible in the class hierarchy.
995 +# If set to NO (the default) these classes will be included in the various
996 +# overviews. This option has no effect if EXTRACT_ALL is enabled.
997 +
998 +HIDE_UNDOC_CLASSES = NO
999 +
1000 +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all
1001 +# friend (class|struct|union) declarations.
1002 +# If set to NO (the default) these declarations will be included in the
1003 +# documentation.
1004 +
1005 +HIDE_FRIEND_COMPOUNDS = NO
1006 +
1007 +# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any
1008 +# documentation blocks found inside the body of a function.
1009 +# If set to NO (the default) these blocks will be appended to the
1010 +# function's detailed documentation block.
1011 +
1012 +HIDE_IN_BODY_DOCS = NO
1013 +
1014 +# The INTERNAL_DOCS tag determines if documentation
1015 +# that is typed after a \internal command is included. If the tag is set
1016 +# to NO (the default) then the documentation will be excluded.
1017 +# Set it to YES to include the internal documentation.
1018 +
1019 +INTERNAL_DOCS = NO
1020 +
1021 +# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate
1022 +# file names in lower-case letters. If set to YES upper-case letters are also
1023 +# allowed. This is useful if you have classes or files whose names only differ
1024 +# in case and if your file system supports case sensitive file names. Windows
1025 +# and Mac users are advised to set this option to NO.
1026 +
1027 +CASE_SENSE_NAMES = YES
1028 +
1029 +# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen
1030 +# will show members with their full class and namespace scopes in the
1031 +# documentation. If set to YES the scope will be hidden.
1032 +
1033 +HIDE_SCOPE_NAMES = NO
1034 +
1035 +# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen
1036 +# will put a list of the files that are included by a file in the documentation
1037 +# of that file.
1038 +
1039 +SHOW_INCLUDE_FILES = YES
1040 +
1041 +# If the INLINE_INFO tag is set to YES (the default) then a tag [inline]
1042 +# is inserted in the documentation for inline members.
1043 +
1044 +INLINE_INFO = YES
1045 +
1046 +# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen
1047 +# will sort the (detailed) documentation of file and class members
1048 +# alphabetically by member name. If set to NO the members will appear in
1049 +# declaration order.
1050 +
1051 +SORT_MEMBER_DOCS = YES
1052 +
1053 +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the
1054 +# brief documentation of file, namespace and class members alphabetically
1055 +# by member name. If set to NO (the default) the members will appear in
1056 +# declaration order.
1057 +
1058 +SORT_BRIEF_DOCS = NO
1059 +
1060 +# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the
1061 +# hierarchy of group names into alphabetical order. If set to NO (the default)
1062 +# the group names will appear in their defined order.
1063 +
1064 +SORT_GROUP_NAMES = NO
1065 +
1066 +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be
1067 +# sorted by fully-qualified names, including namespaces. If set to
1068 +# NO (the default), the class list will be sorted only by class name,
1069 +# not including the namespace part.
1070 +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
1071 +# Note: This option applies only to the class list, not to the
1072 +# alphabetical list.
1073 +
1074 +SORT_BY_SCOPE_NAME = NO
1075 +
1076 +# The GENERATE_TODOLIST tag can be used to enable (YES) or
1077 +# disable (NO) the todo list. This list is created by putting \todo
1078 +# commands in the documentation.
1079 +
1080 +GENERATE_TODOLIST = YES
1081 +
1082 +# The GENERATE_TESTLIST tag can be used to enable (YES) or
1083 +# disable (NO) the test list. This list is created by putting \test
1084 +# commands in the documentation.
1085 +
1086 +GENERATE_TESTLIST = YES
1087 +
1088 +# The GENERATE_BUGLIST tag can be used to enable (YES) or
1089 +# disable (NO) the bug list. This list is created by putting \bug
1090 +# commands in the documentation.
1091 +
1092 +GENERATE_BUGLIST = YES
1093 +
1094 +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or
1095 +# disable (NO) the deprecated list. This list is created by putting
1096 +# \deprecated commands in the documentation.
1097 +
1098 +GENERATE_DEPRECATEDLIST= YES
1099 +
1100 +# The ENABLED_SECTIONS tag can be used to enable conditional
1101 +# documentation sections, marked by \if sectionname ... \endif.
1102 +
1103 +ENABLED_SECTIONS =
1104 +
1105 +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines
1106 +# the initial value of a variable or define consists of for it to appear in
1107 +# the documentation. If the initializer consists of more lines than specified
1108 +# here it will be hidden. Use a value of 0 to hide initializers completely.
1109 +# The appearance of the initializer of individual variables and defines in the
1110 +# documentation can be controlled using \showinitializer or \hideinitializer
1111 +# command in the documentation regardless of this setting.
1112 +
1113 +MAX_INITIALIZER_LINES = 30
1114 +
1115 +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated
1116 +# at the bottom of the documentation of classes and structs. If set to YES the
1117 +# list will mention the files that were used to generate the documentation.
1118 +
1119 +SHOW_USED_FILES = YES
1120 +
1121 +# If the sources in your project are distributed over multiple directories
1122 +# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy
1123 +# in the documentation. The default is NO.
1124 +
1125 +SHOW_DIRECTORIES = NO
1126 +
1127 +# Set the SHOW_FILES tag to NO to disable the generation of the Files page.
1128 +# This will remove the Files entry from the Quick Index and from the
1129 +# Folder Tree View (if specified). The default is YES.
1130 +
1131 +SHOW_FILES = YES
1132 +
1133 +# Set the SHOW_NAMESPACES tag to NO to disable the generation of the
1134 +# Namespaces page. This will remove the Namespaces entry from the Quick Index
1135 +# and from the Folder Tree View (if specified). The default is YES.
1136 +
1137 +SHOW_NAMESPACES = YES
1138 +
1139 +# The FILE_VERSION_FILTER tag can be used to specify a program or script that
1140 +# doxygen should invoke to get the current version for each file (typically from
1141 +# the version control system). Doxygen will invoke the program by executing (via
1142 +# popen()) the command <command> <input-file>, where <command> is the value of
1143 +# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file
1144 +# provided by doxygen. Whatever the program writes to standard output
1145 +# is used as the file version. See the manual for examples.
1146 +
1147 +FILE_VERSION_FILTER =
1148 +
1149 +# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed by
1150 +# doxygen. The layout file controls the global structure of the generated output files
1151 +# in an output format independent way. The create the layout file that represents
1152 +# doxygen's defaults, run doxygen with the -l option. You can optionally specify a
1153 +# file name after the option, if omitted DoxygenLayout.xml will be used as the name
1154 +# of the layout file.
1155 +
1156 +LAYOUT_FILE =
1157 +
1158 +#---------------------------------------------------------------------------
1159 +# configuration options related to warning and progress messages
1160 +#---------------------------------------------------------------------------
1161 +
1162 +# The QUIET tag can be used to turn on/off the messages that are generated
1163 +# by doxygen. Possible values are YES and NO. If left blank NO is used.
1164 +
1165 +QUIET = YES
1166 +
1167 +# The WARNINGS tag can be used to turn on/off the warning messages that are
1168 +# generated by doxygen. Possible values are YES and NO. If left blank
1169 +# NO is used.
1170 +
1171 +WARNINGS = YES
1172 +
1173 +# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings
1174 +# for undocumented members. If EXTRACT_ALL is set to YES then this flag will
1175 +# automatically be disabled.
1176 +
1177 +WARN_IF_UNDOCUMENTED = YES
1178 +
1179 +# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for
1180 +# potential errors in the documentation, such as not documenting some
1181 +# parameters in a documented function, or documenting parameters that
1182 +# don't exist or using markup commands wrongly.
1183 +
1184 +WARN_IF_DOC_ERROR = YES
1185 +
1186 +# This WARN_NO_PARAMDOC option can be abled to get warnings for
1187 +# functions that are documented, but have no documentation for their parameters
1188 +# or return value. If set to NO (the default) doxygen will only warn about
1189 +# wrong or incomplete parameter documentation, but not about the absence of
1190 +# documentation.
1191 +
1192 +WARN_NO_PARAMDOC = NO
1193 +
1194 +# The WARN_FORMAT tag determines the format of the warning messages that
1195 +# doxygen can produce. The string should contain the $file, $line, and $text
1196 +# tags, which will be replaced by the file and line number from which the
1197 +# warning originated and the warning text. Optionally the format may contain
1198 +# $version, which will be replaced by the version of the file (if it could
1199 +# be obtained via FILE_VERSION_FILTER)
1200 +
1201 +WARN_FORMAT = "$file:$line: $text"
1202 +
1203 +# The WARN_LOGFILE tag can be used to specify a file to which warning
1204 +# and error messages should be written. If left blank the output is written
1205 +# to stderr.
1206 +
1207 +WARN_LOGFILE =
1208 +
1209 +#---------------------------------------------------------------------------
1210 +# configuration options related to the input files
1211 +#---------------------------------------------------------------------------
1212 +
1213 +# The INPUT tag can be used to specify the files and/or directories that contain
1214 +# documented source files. You may enter file names like "myfile.cpp" or
1215 +# directories like "/usr/src/myproject". Separate the files or directories
1216 +# with spaces.
1217 +
1218 +INPUT =
1219 +
1220 +# This tag can be used to specify the character encoding of the source files
1221 +# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is
1222 +# also the default input encoding. Doxygen uses libiconv (or the iconv built
1223 +# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for
1224 +# the list of possible encodings.
1225 +
1226 +INPUT_ENCODING = UTF-8
1227 +
1228 +# If the value of the INPUT tag contains directories, you can use the
1229 +# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
1230 +# and *.h) to filter out the source-files in the directories. If left
1231 +# blank the following patterns are tested:
1232 +# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx
1233 +# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.f90
1234 +
1235 +FILE_PATTERNS =
1236 +
1237 +# The RECURSIVE tag can be used to turn specify whether or not subdirectories
1238 +# should be searched for input files as well. Possible values are YES and NO.
1239 +# If left blank NO is used.
1240 +
1241 +RECURSIVE = NO
1242 +
1243 +# The EXCLUDE tag can be used to specify files and/or directories that should
1244 +# excluded from the INPUT source files. This way you can easily exclude a
1245 +# subdirectory from a directory tree whose root is specified with the INPUT tag.
1246 +
1247 +EXCLUDE =
1248 +
1249 +# The EXCLUDE_SYMLINKS tag can be used select whether or not files or
1250 +# directories that are symbolic links (a Unix filesystem feature) are excluded
1251 +# from the input.
1252 +
1253 +EXCLUDE_SYMLINKS = NO
1254 +
1255 +# If the value of the INPUT tag contains directories, you can use the
1256 +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
1257 +# certain files from those directories. Note that the wildcards are matched
1258 +# against the file with absolute path, so to exclude all test directories
1259 +# for example use the pattern */test/*
1260 +
1261 +EXCLUDE_PATTERNS =
1262 +
1263 +# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
1264 +# (namespaces, classes, functions, etc.) that should be excluded from the
1265 +# output. The symbol name can be a fully qualified name, a word, or if the
1266 +# wildcard * is used, a substring. Examples: ANamespace, AClass,
1267 +# AClass::ANamespace, ANamespace::*Test
1268 +
1269 +EXCLUDE_SYMBOLS =
1270 +
1271 +# The EXAMPLE_PATH tag can be used to specify one or more files or
1272 +# directories that contain example code fragments that are included (see
1273 +# the \include command).
1274 +
1275 +EXAMPLE_PATH =
1276 +
1277 +# If the value of the EXAMPLE_PATH tag contains directories, you can use the
1278 +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
1279 +# and *.h) to filter out the source-files in the directories. If left
1280 +# blank all files are included.
1281 +
1282 +EXAMPLE_PATTERNS =
1283 +
1284 +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
1285 +# searched for input files to be used with the \include or \dontinclude
1286 +# commands irrespective of the value of the RECURSIVE tag.
1287 +# Possible values are YES and NO. If left blank NO is used.
1288 +
1289 +EXAMPLE_RECURSIVE = NO
1290 +
1291 +# The IMAGE_PATH tag can be used to specify one or more files or
1292 +# directories that contain image that are included in the documentation (see
1293 +# the \image command).
1294 +
1295 +IMAGE_PATH =
1296 +
1297 +# The INPUT_FILTER tag can be used to specify a program that doxygen should
1298 +# invoke to filter for each input file. Doxygen will invoke the filter program
1299 +# by executing (via popen()) the command <filter> <input-file>, where <filter>
1300 +# is the value of the INPUT_FILTER tag, and <input-file> is the name of an
1301 +# input file. Doxygen will then use the output that the filter program writes
1302 +# to standard output. If FILTER_PATTERNS is specified, this tag will be
1303 +# ignored.
1304 +
1305 +INPUT_FILTER =
1306 +
1307 +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
1308 +# basis. Doxygen will compare the file name with each pattern and apply the
1309 +# filter if there is a match. The filters are a list of the form:
1310 +# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further
1311 +# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER
1312 +# is applied to all files.
1313 +
1314 +FILTER_PATTERNS =
1315 +
1316 +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
1317 +# INPUT_FILTER) will be used to filter the input files when producing source
1318 +# files to browse (i.e. when SOURCE_BROWSER is set to YES).
1319 +
1320 +FILTER_SOURCE_FILES = NO
1321 +
1322 +#---------------------------------------------------------------------------
1323 +# configuration options related to source browsing
1324 +#---------------------------------------------------------------------------
1325 +
1326 +# If the SOURCE_BROWSER tag is set to YES then a list of source files will
1327 +# be generated. Documented entities will be cross-referenced with these sources.
1328 +# Note: To get rid of all source code in the generated output, make sure also
1329 +# VERBATIM_HEADERS is set to NO.
1330 +
1331 +SOURCE_BROWSER = NO
1332 +
1333 +# Setting the INLINE_SOURCES tag to YES will include the body
1334 +# of functions and classes directly in the documentation.
1335 +
1336 +INLINE_SOURCES = NO
1337 +
1338 +# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct
1339 +# doxygen to hide any special comment blocks from generated source code
1340 +# fragments. Normal C and C++ comments will always remain visible.
1341 +
1342 +STRIP_CODE_COMMENTS = YES
1343 +
1344 +# If the REFERENCED_BY_RELATION tag is set to YES
1345 +# then for each documented function all documented
1346 +# functions referencing it will be listed.
1347 +
1348 +REFERENCED_BY_RELATION = NO
1349 +
1350 +# If the REFERENCES_RELATION tag is set to YES
1351 +# then for each documented function all documented entities
1352 +# called/used by that function will be listed.
1353 +
1354 +REFERENCES_RELATION = NO
1355 +
1356 +# If the REFERENCES_LINK_SOURCE tag is set to YES (the default)
1357 +# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from
1358 +# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will
1359 +# link to the source code. Otherwise they will link to the documentstion.
1360 +
1361 +REFERENCES_LINK_SOURCE = YES
1362 +
1363 +# If the USE_HTAGS tag is set to YES then the references to source code
1364 +# will point to the HTML generated by the htags(1) tool instead of doxygen
1365 +# built-in source browser. The htags tool is part of GNU's global source
1366 +# tagging system (see http://www.gnu.org/software/global/global.html). You
1367 +# will need version 4.8.6 or higher.
1368 +
1369 +USE_HTAGS = NO
1370 +
1371 +# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen
1372 +# will generate a verbatim copy of the header file for each class for
1373 +# which an include is specified. Set to NO to disable this.
1374 +
1375 +VERBATIM_HEADERS = YES
1376 +
1377 +#---------------------------------------------------------------------------
1378 +# configuration options related to the alphabetical class index
1379 +#---------------------------------------------------------------------------
1380 +
1381 +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index
1382 +# of all compounds will be generated. Enable this if the project
1383 +# contains a lot of classes, structs, unions or interfaces.
1384 +
1385 +ALPHABETICAL_INDEX = NO
1386 +
1387 +# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then
1388 +# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns
1389 +# in which this list will be split (can be a number in the range [1..20])
1390 +
1391 +COLS_IN_ALPHA_INDEX = 5
1392 +
1393 +# In case all classes in a project start with a common prefix, all
1394 +# classes will be put under the same header in the alphabetical index.
1395 +# The IGNORE_PREFIX tag can be used to specify one or more prefixes that
1396 +# should be ignored while generating the index headers.
1397 +
1398 +IGNORE_PREFIX =
1399 +
1400 +#---------------------------------------------------------------------------
1401 +# configuration options related to the HTML output
1402 +#---------------------------------------------------------------------------
1403 +
1404 +# If the GENERATE_HTML tag is set to YES (the default) Doxygen will
1405 +# generate HTML output.
1406 +
1407 +GENERATE_HTML = YES
1408 +
1409 +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put.
1410 +# If a relative path is entered the value of OUTPUT_DIRECTORY will be
1411 +# put in front of it. If left blank `html' will be used as the default path.
1412 +
1413 +HTML_OUTPUT = html
1414 +
1415 +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for
1416 +# each generated HTML page (for example: .htm,.php,.asp). If it is left blank
1417 +# doxygen will generate files with .html extension.
1418 +
1419 +HTML_FILE_EXTENSION = .html
1420 +
1421 +# The HTML_HEADER tag can be used to specify a personal HTML header for
1422 +# each generated HTML page. If it is left blank doxygen will generate a
1423 +# standard header.
1424 +
1425 +HTML_HEADER =
1426 +
1427 +# The HTML_FOOTER tag can be used to specify a personal HTML footer for
1428 +# each generated HTML page. If it is left blank doxygen will generate a
1429 +# standard footer.
1430 +
1431 +HTML_FOOTER =
1432 +
1433 +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading
1434 +# style sheet that is used by each HTML page. It can be used to
1435 +# fine-tune the look of the HTML output. If the tag is left blank doxygen
1436 +# will generate a default style sheet. Note that doxygen will try to copy
1437 +# the style sheet file to the HTML output directory, so don't put your own
1438 +# stylesheet in the HTML output directory as well, or it will be erased!
1439 +
1440 +HTML_STYLESHEET =
1441 +
1442 +# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes,
1443 +# files or namespaces will be aligned in HTML using tables. If set to
1444 +# NO a bullet list will be used.
1445 +
1446 +HTML_ALIGN_MEMBERS = YES
1447 +
1448 +# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML
1449 +# documentation will contain sections that can be hidden and shown after the
1450 +# page has loaded. For this to work a browser that supports
1451 +# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox
1452 +# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari).
1453 +
1454 +HTML_DYNAMIC_SECTIONS = NO
1455 +
1456 +# If the GENERATE_DOCSET tag is set to YES, additional index files
1457 +# will be generated that can be used as input for Apple's Xcode 3
1458 +# integrated development environment, introduced with OSX 10.5 (Leopard).
1459 +# To create a documentation set, doxygen will generate a Makefile in the
1460 +# HTML output directory. Running make will produce the docset in that
1461 +# directory and running "make install" will install the docset in
1462 +# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find
1463 +# it at startup.
1464 +# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html for more information.
1465 +
1466 +GENERATE_DOCSET = NO
1467 +
1468 +# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the
1469 +# feed. A documentation feed provides an umbrella under which multiple
1470 +# documentation sets from a single provider (such as a company or product suite)
1471 +# can be grouped.
1472 +
1473 +DOCSET_FEEDNAME = "Doxygen generated docs"
1474 +
1475 +# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that
1476 +# should uniquely identify the documentation set bundle. This should be a
1477 +# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen
1478 +# will append .docset to the name.
1479 +
1480 +DOCSET_BUNDLE_ID = org.doxygen.Project
1481 +
1482 +# If the GENERATE_HTMLHELP tag is set to YES, additional index files
1483 +# will be generated that can be used as input for tools like the
1484 +# Microsoft HTML help workshop to generate a compiled HTML help file (.chm)
1485 +# of the generated HTML documentation.
1486 +
1487 +GENERATE_HTMLHELP = NO
1488 +
1489 +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can
1490 +# be used to specify the file name of the resulting .chm file. You
1491 +# can add a path in front of the file if the result should not be
1492 +# written to the html output directory.
1493 +
1494 +CHM_FILE =
1495 +
1496 +# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can
1497 +# be used to specify the location (absolute path including file name) of
1498 +# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run
1499 +# the HTML help compiler on the generated index.hhp.
1500 +
1501 +HHC_LOCATION =
1502 +
1503 +# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag
1504 +# controls if a separate .chi index file is generated (YES) or that
1505 +# it should be included in the master .chm file (NO).
1506 +
1507 +GENERATE_CHI = NO
1508 +
1509 +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING
1510 +# is used to encode HtmlHelp index (hhk), content (hhc) and project file
1511 +# content.
1512 +
1513 +CHM_INDEX_ENCODING =
1514 +
1515 +# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag
1516 +# controls whether a binary table of contents is generated (YES) or a
1517 +# normal table of contents (NO) in the .chm file.
1518 +
1519 +BINARY_TOC = NO
1520 +
1521 +# The TOC_EXPAND flag can be set to YES to add extra items for group members
1522 +# to the contents of the HTML help documentation and to the tree view.
1523 +
1524 +TOC_EXPAND = NO
1525 +
1526 +# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and QHP_VIRTUAL_FOLDER
1527 +# are set, an additional index file will be generated that can be used as input for
1528 +# Qt's qhelpgenerator to generate a Qt Compressed Help (.qch) of the generated
1529 +# HTML documentation.
1530 +
1531 +GENERATE_QHP = NO
1532 +
1533 +# If the QHG_LOCATION tag is specified, the QCH_FILE tag can
1534 +# be used to specify the file name of the resulting .qch file.
1535 +# The path specified is relative to the HTML output folder.
1536 +
1537 +QCH_FILE =
1538 +
1539 +# The QHP_NAMESPACE tag specifies the namespace to use when generating
1540 +# Qt Help Project output. For more information please see
1541 +# <a href="http://doc.trolltech.com/qthelpproject.html#namespace">Qt Help Project / Namespace</a>.
1542 +
1543 +QHP_NAMESPACE = org.doxygen.Project
1544 +
1545 +# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating
1546 +# Qt Help Project output. For more information please see
1547 +# <a href="http://doc.trolltech.com/qthelpproject.html#virtual-folders">Qt Help Project / Virtual Folders</a>.
1548 +
1549 +QHP_VIRTUAL_FOLDER = doc
1550 +
1551 +# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can
1552 +# be used to specify the location of Qt's qhelpgenerator.
1553 +# If non-empty doxygen will try to run qhelpgenerator on the generated
1554 +# .qhp file .
1555 +
1556 +QHG_LOCATION =
1557 +
1558 +# The DISABLE_INDEX tag can be used to turn on/off the condensed index at
1559 +# top of each HTML page. The value NO (the default) enables the index and
1560 +# the value YES disables it.
1561 +
1562 +DISABLE_INDEX = NO
1563 +
1564 +# This tag can be used to set the number of enum values (range [1..20])
1565 +# that doxygen will group on one line in the generated HTML documentation.
1566 +
1567 +ENUM_VALUES_PER_LINE = 4
1568 +
1569 +# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index
1570 +# structure should be generated to display hierarchical information.
1571 +# If the tag value is set to FRAME, a side panel will be generated
1572 +# containing a tree-like index structure (just like the one that
1573 +# is generated for HTML Help). For this to work a browser that supports
1574 +# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+,
1575 +# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are
1576 +# probably better off using the HTML help feature. Other possible values
1577 +# for this tag are: HIERARCHIES, which will generate the Groups, Directories,
1578 +# and Class Hierarchy pages using a tree view instead of an ordered list;
1579 +# ALL, which combines the behavior of FRAME and HIERARCHIES; and NONE, which
1580 +# disables this behavior completely. For backwards compatibility with previous
1581 +# releases of Doxygen, the values YES and NO are equivalent to FRAME and NONE
1582 +# respectively.
1583 +
1584 +GENERATE_TREEVIEW = NONE
1585 +
1586 +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be
1587 +# used to set the initial width (in pixels) of the frame in which the tree
1588 +# is shown.
1589 +
1590 +TREEVIEW_WIDTH = 250
1591 +
1592 +# Use this tag to change the font size of Latex formulas included
1593 +# as images in the HTML documentation. The default is 10. Note that
1594 +# when you change the font size after a successful doxygen run you need
1595 +# to manually remove any form_*.png images from the HTML output directory
1596 +# to force them to be regenerated.
1597 +
1598 +FORMULA_FONTSIZE = 10
1599 +
1600 +#---------------------------------------------------------------------------
1601 +# configuration options related to the LaTeX output
1602 +#---------------------------------------------------------------------------
1603 +
1604 +# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will
1605 +# generate Latex output.
1606 +
1607 +GENERATE_LATEX = NO
1608 +
1609 +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put.
1610 +# If a relative path is entered the value of OUTPUT_DIRECTORY will be
1611 +# put in front of it. If left blank `latex' will be used as the default path.
1612 +
1613 +LATEX_OUTPUT = latex
1614 +
1615 +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
1616 +# invoked. If left blank `latex' will be used as the default command name.
1617 +
1618 +LATEX_CMD_NAME = latex
1619 +
1620 +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to
1621 +# generate index for LaTeX. If left blank `makeindex' will be used as the
1622 +# default command name.
1623 +
1624 +MAKEINDEX_CMD_NAME = makeindex
1625 +
1626 +# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact
1627 +# LaTeX documents. This may be useful for small projects and may help to
1628 +# save some trees in general.
1629 +
1630 +COMPACT_LATEX = NO
1631 +
1632 +# The PAPER_TYPE tag can be used to set the paper type that is used
1633 +# by the printer. Possible values are: a4, a4wide, letter, legal and
1634 +# executive. If left blank a4wide will be used.
1635 +
1636 +PAPER_TYPE = a4wide
1637 +
1638 +# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX
1639 +# packages that should be included in the LaTeX output.
1640 +
1641 +EXTRA_PACKAGES =
1642 +
1643 +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for
1644 +# the generated latex document. The header should contain everything until
1645 +# the first chapter. If it is left blank doxygen will generate a
1646 +# standard header. Notice: only use this tag if you know what you are doing!
1647 +
1648 +LATEX_HEADER =
1649 +
1650 +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated
1651 +# is prepared for conversion to pdf (using ps2pdf). The pdf file will
1652 +# contain links (just like the HTML output) instead of page references
1653 +# This makes the output suitable for online browsing using a pdf viewer.
1654 +
1655 +PDF_HYPERLINKS = YES
1656 +
1657 +# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of
1658 +# plain latex in the generated Makefile. Set this option to YES to get a
1659 +# higher quality PDF documentation.
1660 +
1661 +USE_PDFLATEX = YES
1662 +
1663 +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode.
1664 +# command to the generated LaTeX files. This will instruct LaTeX to keep
1665 +# running if errors occur, instead of asking the user for help.
1666 +# This option is also used when generating formulas in HTML.
1667 +
1668 +LATEX_BATCHMODE = NO
1669 +
1670 +# If LATEX_HIDE_INDICES is set to YES then doxygen will not
1671 +# include the index chapters (such as File Index, Compound Index, etc.)
1672 +# in the output.
1673 +
1674 +LATEX_HIDE_INDICES = NO
1675 +
1676 +#---------------------------------------------------------------------------
1677 +# configuration options related to the RTF output
1678 +#---------------------------------------------------------------------------
1679 +
1680 +# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output
1681 +# The RTF output is optimized for Word 97 and may not look very pretty with
1682 +# other RTF readers or editors.
1683 +
1684 +GENERATE_RTF = NO
1685 +
1686 +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put.
1687 +# If a relative path is entered the value of OUTPUT_DIRECTORY will be
1688 +# put in front of it. If left blank `rtf' will be used as the default path.
1689 +
1690 +RTF_OUTPUT = rtf
1691 +
1692 +# If the COMPACT_RTF tag is set to YES Doxygen generates more compact
1693 +# RTF documents. This may be useful for small projects and may help to
1694 +# save some trees in general.
1695 +
1696 +COMPACT_RTF = NO
1697 +
1698 +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated
1699 +# will contain hyperlink fields. The RTF file will
1700 +# contain links (just like the HTML output) instead of page references.
1701 +# This makes the output suitable for online browsing using WORD or other
1702 +# programs which support those fields.
1703 +# Note: wordpad (write) and others do not support links.
1704 +
1705 +RTF_HYPERLINKS = NO
1706 +
1707 +# Load stylesheet definitions from file. Syntax is similar to doxygen's
1708 +# config file, i.e. a series of assignments. You only have to provide
1709 +# replacements, missing definitions are set to their default value.
1710 +
1711 +RTF_STYLESHEET_FILE =
1712 +
1713 +# Set optional variables used in the generation of an rtf document.
1714 +# Syntax is similar to doxygen's config file.
1715 +
1716 +RTF_EXTENSIONS_FILE =
1717 +
1718 +#---------------------------------------------------------------------------
1719 +# configuration options related to the man page output
1720 +#---------------------------------------------------------------------------
1721 +
1722 +# If the GENERATE_MAN tag is set to YES (the default) Doxygen will
1723 +# generate man pages
1724 +
1725 +GENERATE_MAN = NO
1726 +
1727 +# The MAN_OUTPUT tag is used to specify where the man pages will be put.
1728 +# If a relative path is entered the value of OUTPUT_DIRECTORY will be
1729 +# put in front of it. If left blank `man' will be used as the default path.
1730 +
1731 +MAN_OUTPUT = man
1732 +
1733 +# The MAN_EXTENSION tag determines the extension that is added to
1734 +# the generated man pages (default is the subroutine's section .3)
1735 +
1736 +MAN_EXTENSION = .3
1737 +
1738 +# If the MAN_LINKS tag is set to YES and Doxygen generates man output,
1739 +# then it will generate one additional man file for each entity
1740 +# documented in the real man page(s). These additional files
1741 +# only source the real man page, but without them the man command
1742 +# would be unable to find the correct page. The default is NO.
1743 +
1744 +MAN_LINKS = NO
1745 +
1746 +#---------------------------------------------------------------------------
1747 +# configuration options related to the XML output
1748 +#---------------------------------------------------------------------------
1749 +
1750 +# If the GENERATE_XML tag is set to YES Doxygen will
1751 +# generate an XML file that captures the structure of
1752 +# the code including all documentation.
1753 +
1754 +GENERATE_XML = NO
1755 +
1756 +# The XML_OUTPUT tag is used to specify where the XML pages will be put.
1757 +# If a relative path is entered the value of OUTPUT_DIRECTORY will be
1758 +# put in front of it. If left blank `xml' will be used as the default path.
1759 +
1760 +XML_OUTPUT = xml
1761 +
1762 +# The XML_SCHEMA tag can be used to specify an XML schema,
1763 +# which can be used by a validating XML parser to check the
1764 +# syntax of the XML files.
1765 +
1766 +XML_SCHEMA =
1767 +
1768 +# The XML_DTD tag can be used to specify an XML DTD,
1769 +# which can be used by a validating XML parser to check the
1770 +# syntax of the XML files.
1771 +
1772 +XML_DTD =
1773 +
1774 +# If the XML_PROGRAMLISTING tag is set to YES Doxygen will
1775 +# dump the program listings (including syntax highlighting
1776 +# and cross-referencing information) to the XML output. Note that
1777 +# enabling this will significantly increase the size of the XML output.
1778 +
1779 +XML_PROGRAMLISTING = YES
1780 +
1781 +#---------------------------------------------------------------------------
1782 +# configuration options for the AutoGen Definitions output
1783 +#---------------------------------------------------------------------------
1784 +
1785 +# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will
1786 +# generate an AutoGen Definitions (see autogen.sf.net) file
1787 +# that captures the structure of the code including all
1788 +# documentation. Note that this feature is still experimental
1789 +# and incomplete at the moment.
1790 +
1791 +GENERATE_AUTOGEN_DEF = NO
1792 +
1793 +#---------------------------------------------------------------------------
1794 +# configuration options related to the Perl module output
1795 +#---------------------------------------------------------------------------
1796 +
1797 +# If the GENERATE_PERLMOD tag is set to YES Doxygen will
1798 +# generate a Perl module file that captures the structure of
1799 +# the code including all documentation. Note that this
1800 +# feature is still experimental and incomplete at the
1801 +# moment.
1802 +
1803 +GENERATE_PERLMOD = NO
1804 +
1805 +# If the PERLMOD_LATEX tag is set to YES Doxygen will generate
1806 +# the necessary Makefile rules, Perl scripts and LaTeX code to be able
1807 +# to generate PDF and DVI output from the Perl module output.
1808 +
1809 +PERLMOD_LATEX = NO
1810 +
1811 +# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be
1812 +# nicely formatted so it can be parsed by a human reader. This is useful
1813 +# if you want to understand what is going on. On the other hand, if this
1814 +# tag is set to NO the size of the Perl module output will be much smaller
1815 +# and Perl will parse it just the same.
1816 +
1817 +PERLMOD_PRETTY = YES
1818 +
1819 +# The names of the make variables in the generated doxyrules.make file
1820 +# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX.
1821 +# This is useful so different doxyrules.make files included by the same
1822 +# Makefile don't overwrite each other's variables.
1823 +
1824 +PERLMOD_MAKEVAR_PREFIX =
1825 +
1826 +#---------------------------------------------------------------------------
1827 +# Configuration options related to the preprocessor
1828 +#---------------------------------------------------------------------------
1829 +
1830 +# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will
1831 +# evaluate all C-preprocessor directives found in the sources and include
1832 +# files.
1833 +
1834 +ENABLE_PREPROCESSING = YES
1835 +
1836 +# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro
1837 +# names in the source code. If set to NO (the default) only conditional
1838 +# compilation will be performed. Macro expansion can be done in a controlled
1839 +# way by setting EXPAND_ONLY_PREDEF to YES.
1840 +
1841 +MACRO_EXPANSION = NO
1842 +
1843 +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES
1844 +# then the macro expansion is limited to the macros specified with the
1845 +# PREDEFINED and EXPAND_AS_DEFINED tags.
1846 +
1847 +EXPAND_ONLY_PREDEF = NO
1848 +
1849 +# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files
1850 +# in the INCLUDE_PATH (see below) will be search if a #include is found.
1851 +
1852 +SEARCH_INCLUDES = YES
1853 +
1854 +# The INCLUDE_PATH tag can be used to specify one or more directories that
1855 +# contain include files that are not input files but should be processed by
1856 +# the preprocessor.
1857 +
1858 +INCLUDE_PATH =
1859 +
1860 +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
1861 +# patterns (like *.h and *.hpp) to filter out the header-files in the
1862 +# directories. If left blank, the patterns specified with FILE_PATTERNS will
1863 +# be used.
1864 +
1865 +INCLUDE_FILE_PATTERNS =
1866 +
1867 +# The PREDEFINED tag can be used to specify one or more macro names that
1868 +# are defined before the preprocessor is started (similar to the -D option of
1869 +# gcc). The argument of the tag is a list of macros of the form: name
1870 +# or name=definition (no spaces). If the definition and the = are
1871 +# omitted =1 is assumed. To prevent a macro definition from being
1872 +# undefined via #undef or recursively expanded use the := operator
1873 +# instead of the = operator.
1874 +
1875 +PREDEFINED =
1876 +
1877 +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then
1878 +# this tag can be used to specify a list of macro names that should be expanded.
1879 +# The macro definition that is found in the sources will be used.
1880 +# Use the PREDEFINED tag if you want to use a different macro definition.
1881 +
1882 +EXPAND_AS_DEFINED =
1883 +
1884 +# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then
1885 +# doxygen's preprocessor will remove all function-like macros that are alone
1886 +# on a line, have an all uppercase name, and do not end with a semicolon. Such
1887 +# function macros are typically used for boiler-plate code, and will confuse
1888 +# the parser if not removed.
1889 +
1890 +SKIP_FUNCTION_MACROS = YES
1891 +
1892 +#---------------------------------------------------------------------------
1893 +# Configuration::additions related to external references
1894 +#---------------------------------------------------------------------------
1895 +
1896 +# The TAGFILES option can be used to specify one or more tagfiles.
1897 +# Optionally an initial location of the external documentation
1898 +# can be added for each tagfile. The format of a tag file without
1899 +# this location is as follows:
1900 +# TAGFILES = file1 file2 ...
1901 +# Adding location for the tag files is done as follows:
1902 +# TAGFILES = file1=loc1 "file2 = loc2" ...
1903 +# where "loc1" and "loc2" can be relative or absolute paths or
1904 +# URLs. If a location is present for each tag, the installdox tool
1905 +# does not have to be run to correct the links.
1906 +# Note that each tag file must have a unique name
1907 +# (where the name does NOT include the path)
1908 +# If a tag file is not located in the directory in which doxygen
1909 +# is run, you must also specify the path to the tagfile here.
1910 +
1911 +TAGFILES =
1912 +
1913 +# When a file name is specified after GENERATE_TAGFILE, doxygen will create
1914 +# a tag file that is based on the input files it reads.
1915 +
1916 +GENERATE_TAGFILE =
1917 +
1918 +# If the ALLEXTERNALS tag is set to YES all external classes will be listed
1919 +# in the class index. If set to NO only the inherited external classes
1920 +# will be listed.
1921 +
1922 +ALLEXTERNALS = NO
1923 +
1924 +# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed
1925 +# in the modules index. If set to NO, only the current project's groups will
1926 +# be listed.
1927 +
1928 +EXTERNAL_GROUPS = YES
1929 +
1930 +# The PERL_PATH should be the absolute path and name of the perl script
1931 +# interpreter (i.e. the result of `which perl').
1932 +
1933 +PERL_PATH = /usr/bin/perl
1934 +
1935 +#---------------------------------------------------------------------------
1936 +# Configuration options related to the dot tool
1937 +#---------------------------------------------------------------------------
1938 +
1939 +# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will
1940 +# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base
1941 +# or super classes. Setting the tag to NO turns the diagrams off. Note that
1942 +# this option is superseded by the HAVE_DOT option below. This is only a
1943 +# fallback. It is recommended to install and use dot, since it yields more
1944 +# powerful graphs.
1945 +
1946 +CLASS_DIAGRAMS = YES
1947 +
1948 +# You can define message sequence charts within doxygen comments using the \msc
1949 +# command. Doxygen will then run the mscgen tool (see
1950 +# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the
1951 +# documentation. The MSCGEN_PATH tag allows you to specify the directory where
1952 +# the mscgen tool resides. If left empty the tool is assumed to be found in the
1953 +# default search path.
1954 +
1955 +MSCGEN_PATH =
1956 +
1957 +# If set to YES, the inheritance and collaboration graphs will hide
1958 +# inheritance and usage relations if the target is undocumented
1959 +# or is not a class.
1960 +
1961 +HIDE_UNDOC_RELATIONS = YES
1962 +
1963 +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
1964 +# available from the path. This tool is part of Graphviz, a graph visualization
1965 +# toolkit from AT&T and Lucent Bell Labs. The other options in this section
1966 +# have no effect if this option is set to NO (the default)
1967 +
1968 +HAVE_DOT = NO
1969 +
1970 +# By default doxygen will write a font called FreeSans.ttf to the output
1971 +# directory and reference it in all dot files that doxygen generates. This
1972 +# font does not include all possible unicode characters however, so when you need
1973 +# these (or just want a differently looking font) you can specify the font name
1974 +# using DOT_FONTNAME. You need need to make sure dot is able to find the font,
1975 +# which can be done by putting it in a standard location or by setting the
1976 +# DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory
1977 +# containing the font.
1978 +
1979 +DOT_FONTNAME = FreeSans
1980 +
1981 +# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs.
1982 +# The default size is 10pt.
1983 +
1984 +DOT_FONTSIZE = 10
1985 +
1986 +# By default doxygen will tell dot to use the output directory to look for the
1987 +# FreeSans.ttf font (which doxygen will put there itself). If you specify a
1988 +# different font using DOT_FONTNAME you can set the path where dot
1989 +# can find it using this tag.
1990 +
1991 +DOT_FONTPATH =
1992 +
1993 +# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen
1994 +# will generate a graph for each documented class showing the direct and
1995 +# indirect inheritance relations. Setting this tag to YES will force the
1996 +# the CLASS_DIAGRAMS tag to NO.
1997 +
1998 +CLASS_GRAPH = YES
1999 +
2000 +# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen
2001 +# will generate a graph for each documented class showing the direct and
2002 +# indirect implementation dependencies (inheritance, containment, and
2003 +# class references variables) of the class with other documented classes.
2004 +
2005 +COLLABORATION_GRAPH = YES
2006 +
2007 +# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen
2008 +# will generate a graph for groups, showing the direct groups dependencies
2009 +
2010 +GROUP_GRAPHS = YES
2011 +
2012 +# If the UML_LOOK tag is set to YES doxygen will generate inheritance and
2013 +# collaboration diagrams in a style similar to the OMG's Unified Modeling
2014 +# Language.
2015 +
2016 +UML_LOOK = NO
2017 +
2018 +# If set to YES, the inheritance and collaboration graphs will show the
2019 +# relations between templates and their instances.
2020 +
2021 +TEMPLATE_RELATIONS = NO
2022 +
2023 +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT
2024 +# tags are set to YES then doxygen will generate a graph for each documented
2025 +# file showing the direct and indirect include dependencies of the file with
2026 +# other documented files.
2027 +
2028 +INCLUDE_GRAPH = YES
2029 +
2030 +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and
2031 +# HAVE_DOT tags are set to YES then doxygen will generate a graph for each
2032 +# documented header file showing the documented files that directly or
2033 +# indirectly include this file.
2034 +
2035 +INCLUDED_BY_GRAPH = YES
2036 +
2037 +# If the CALL_GRAPH and HAVE_DOT options are set to YES then
2038 +# doxygen will generate a call dependency graph for every global function
2039 +# or class method. Note that enabling this option will significantly increase
2040 +# the time of a run. So in most cases it will be better to enable call graphs
2041 +# for selected functions only using the \callgraph command.
2042 +
2043 +CALL_GRAPH = NO
2044 +
2045 +# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then
2046 +# doxygen will generate a caller dependency graph for every global function
2047 +# or class method. Note that enabling this option will significantly increase
2048 +# the time of a run. So in most cases it will be better to enable caller
2049 +# graphs for selected functions only using the \callergraph command.
2050 +
2051 +CALLER_GRAPH = NO
2052 +
2053 +# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen
2054 +# will graphical hierarchy of all classes instead of a textual one.
2055 +
2056 +GRAPHICAL_HIERARCHY = YES
2057 +
2058 +# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES
2059 +# then doxygen will show the dependencies a directory has on other directories
2060 +# in a graphical way. The dependency relations are determined by the #include
2061 +# relations between the files in the directories.
2062 +
2063 +DIRECTORY_GRAPH = YES
2064 +
2065 +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
2066 +# generated by dot. Possible values are png, jpg, or gif
2067 +# If left blank png will be used.
2068 +
2069 +DOT_IMAGE_FORMAT = png
2070 +
2071 +# The tag DOT_PATH can be used to specify the path where the dot tool can be
2072 +# found. If left blank, it is assumed the dot tool can be found in the path.
2073 +
2074 +DOT_PATH =
2075 +
2076 +# The DOTFILE_DIRS tag can be used to specify one or more directories that
2077 +# contain dot files that are included in the documentation (see the
2078 +# \dotfile command).
2079 +
2080 +DOTFILE_DIRS =
2081 +
2082 +# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of
2083 +# nodes that will be shown in the graph. If the number of nodes in a graph
2084 +# becomes larger than this value, doxygen will truncate the graph, which is
2085 +# visualized by representing a node as a red box. Note that doxygen if the
2086 +# number of direct children of the root node in a graph is already larger than
2087 +# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note
2088 +# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.
2089 +
2090 +DOT_GRAPH_MAX_NODES = 50
2091 +
2092 +# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the
2093 +# graphs generated by dot. A depth value of 3 means that only nodes reachable
2094 +# from the root by following a path via at most 3 edges will be shown. Nodes
2095 +# that lay further from the root node will be omitted. Note that setting this
2096 +# option to 1 or 2 may greatly reduce the computation time needed for large
2097 +# code bases. Also note that the size of a graph can be further restricted by
2098 +# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.
2099 +
2100 +MAX_DOT_GRAPH_DEPTH = 0
2101 +
2102 +# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent
2103 +# background. This is disabled by default, because dot on Windows does not
2104 +# seem to support this out of the box. Warning: Depending on the platform used,
2105 +# enabling this option may lead to badly anti-aliased labels on the edges of
2106 +# a graph (i.e. they become hard to read).
2107 +
2108 +DOT_TRANSPARENT = NO
2109 +
2110 +# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output
2111 +# files in one run (i.e. multiple -o and -T options on the command line). This
2112 +# makes dot run faster, but since only newer versions of dot (>1.8.10)
2113 +# support this, this feature is disabled by default.
2114 +
2115 +DOT_MULTI_TARGETS = NO
2116 +
2117 +# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will
2118 +# generate a legend page explaining the meaning of the various boxes and
2119 +# arrows in the dot generated graphs.
2120 +
2121 +GENERATE_LEGEND = YES
2122 +
2123 +# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will
2124 +# remove the intermediate dot files that are used to generate
2125 +# the various graphs.
2126 +
2127 +DOT_CLEANUP = YES
2128 +
2129 +#---------------------------------------------------------------------------
2130 +# Configuration::additions related to the search engine
2131 +#---------------------------------------------------------------------------
2132 +
2133 +# The SEARCHENGINE tag specifies whether or not a search engine should be
2134 +# used. If set to NO the values of all tags below this one will be ignored.
2135 +
2136 +SEARCHENGINE = NO
2137 diff --git a/libiscsi/libiscsi.h b/libiscsi/libiscsi.h
2138 new file mode 100644
2139 index 0000000..a7d05a5
2140 --- /dev/null
2141 +++ b/libiscsi/libiscsi.h
2142 @@ -0,0 +1,343 @@
2143 +/*
2144 + * iSCSI Administration library
2145 + *
2146 + * Copyright (C) 2008-2009 Red Hat, Inc. All rights reserved.
2147 + * Copyright (C) 2008-2009 Hans de Goede <hdegoede@redhat.com>
2148 + * maintained by open-iscsi@googlegroups.com
2149 + *
2150 + * This program is free software; you can redistribute it and/or modify
2151 + * it under the terms of the GNU General Public License as published
2152 + * by the Free Software Foundation; either version 2 of the License, or
2153 + * (at your option) any later version.
2154 + *
2155 + * This program is distributed in the hope that it will be useful, but
2156 + * WITHOUT ANY WARRANTY; without even the implied warranty of
2157 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2158 + * General Public License for more details.
2159 + *
2160 + * See the file COPYING included with this distribution for more details.
2161 + */
2162 +
2163 +#ifndef __LIBISCSI_H
2164 +#define __LIBISCSI_H
2165 +
2166 +#include <netdb.h>
2167 +
2168 +#ifdef __cplusplus
2169 +extern "C" {
2170 +#endif /* __cplusplus */
2171 +
2172 +#if __GNUC__ >= 4
2173 +#define PUBLIC __attribute__ ((visibility("default")))
2174 +#else
2175 +#define PUBLIC
2176 +#endif
2177 +
2178 +/** \brief Maximum length for iSCSI values.
2179 + *
2180 + * Maximum length for iSCSI values such as hostnames and parameter values.
2181 + */
2182 +#define LIBISCSI_VALUE_MAXLEN 256
2183 +
2184 +/** \brief supported authentication methods
2185 + *
2186 + * This enum lists all supported authentication methods.
2187 + */
2188 +enum libiscsi_auth_t {
2189 + libiscsi_auth_none /** No authentication */,
2190 + libiscsi_auth_chap /** CHAP authentication */,
2191 +};
2192 +
2193 +/** \brief libiscsi context struct
2194 + *
2195 + * Note: even though libiscsi uses a context struct, the underlying open-iscsi
2196 + * code does not, so libiscsi is not thread safe, not even when using one
2197 + * context per thread!
2198 + */
2199 +struct libiscsi_context;
2200 +
2201 +/** \brief iSCSI node record
2202 + *
2203 + * Struct holding data uniquely identifying an iSCSI node.
2204 + */
2205 +struct libiscsi_node {
2206 + char name[LIBISCSI_VALUE_MAXLEN] /** iSCSI iqn for the node. */;
2207 + int tpgt /** Portal group number. */;
2208 + /* Note open-iscsi has some code in place for multiple connections in one
2209 + node record and thus multiple address / port combi's, but this does not
2210 + get used anywhere, so we keep things simple and assume one connection */
2211 + char address[NI_MAXHOST] /** Portal hostname or IP-address. */;
2212 + int port /** Portal port number. */;
2213 +};
2214 +
2215 +/** \brief libiscsi CHAP authentication information struct
2216 + *
2217 + * Struct holding all data needed for CHAP login / authentication. Note that
2218 + * \e reverse_username may be a 0 length string in which case only forward
2219 + * authentication will be done.
2220 + */
2221 +struct libiscsi_chap_auth_info {
2222 + char username[LIBISCSI_VALUE_MAXLEN] /** Username */;
2223 + char password[LIBISCSI_VALUE_MAXLEN] /** Password */;
2224 + char reverse_username[LIBISCSI_VALUE_MAXLEN] /** Reverse Username */;
2225 + char reverse_password[LIBISCSI_VALUE_MAXLEN] /** Reverse Password */;
2226 +};
2227 +
2228 +/** \brief generic libiscsi authentication information struct
2229 + *
2230 + * Struct holding authentication information for discovery and login.
2231 + */
2232 +struct libiscsi_auth_info {
2233 + enum libiscsi_auth_t method /** Authentication method to use */;
2234 + union {
2235 + struct libiscsi_chap_auth_info chap /** Chap specific info */;
2236 + } /** Union holding method depenend info */;
2237 +};
2238 +
2239 +/** \brief Initalize libiscsi
2240 + *
2241 + * This function creates a libiscsi context and initalizes it. This context
2242 + * is need to use other libiscsi funtions.
2243 + *
2244 + * \return A pointer to the created context, or NULL in case of an error.
2245 + */
2246 +PUBLIC struct libiscsi_context *libiscsi_init(void);
2247 +
2248 +/** \brief Cleanup libiscsi used resource
2249 + *
2250 + * This function cleanups any used resources and then destroys the passed
2251 + * context. After this the passed in context may no longer be used!
2252 + *
2253 + * \param context libiscsi context to operate on.
2254 + */
2255 +PUBLIC void libiscsi_cleanup(struct libiscsi_context *context);
2256 +
2257 +/** \brief Discover iSCSI nodes using sendtargets and add them to the node db.
2258 + *
2259 + * This function connects to the given address and port and then tries to
2260 + * discover iSCSI nodes using the sendtargets protocol. Any found nodes are
2261 + * added to the local iSCSI node database and are returned in a dynamically
2262 + * allocated array.
2263 + *
2264 + * Note that the (optional) authentication info is for authenticating the
2265 + * discovery, and is not for the found nodes! If the connection(s) to the
2266 + * node(s) need authentication too, you can set the username / password for
2267 + * those (which can be different!) using the libiscsi_node_set_auth() function.
2268 + *
2269 + * \param context libiscsi context to operate on.
2270 + * \param address Hostname or IP-address to connect to.
2271 + * \param port Port to connect to, or 0 for the default port.
2272 + * \param auth_info Authentication information, or NULL.
2273 + * \param nr_found The number of found nodes will be returned
2274 + * through this pointer if not NULL.
2275 + * \param found_nodes The address of the dynamically allocated array
2276 + * of found nodes will be returned through this
2277 + * pointer if not NULL. The caller must free this
2278 + * array using free().
2279 + * \return 0 on success, otherwise a standard error code
2280 + * (from errno.h).
2281 + */
2282 +PUBLIC int libiscsi_discover_sendtargets(struct libiscsi_context *context,
2283 + const char *address, int port, const struct libiscsi_auth_info *auth_info,
2284 + int *nr_found, struct libiscsi_node **found_nodes);
2285 +
2286 +/** \brief Read iSCSI node info from firmware and add them to the node db.
2287 + *
2288 + * This function discovers iSCSI nodes using firmware (ppc or ibft). Any found
2289 + * nodes are added to the local iSCSI node database and are returned in a
2290 + * dynamically allocated array.
2291 + *
2292 + * Note that unlike sendtargets discovery, this function will also read
2293 + * authentication info and store that in the database too.
2294 + *
2295 + * Note this function currently is a stub which will always return -EINVAL
2296 + * (IOW it is not yet implemented)
2297 + *
2298 + * \param context libiscsi context to operate on.
2299 + * \param nr_found The number of found nodes will be returned
2300 + * through this pointer if not NULL.
2301 + * \param found_nodes The address of the dynamically allocated array
2302 + * of found nodes will be returned through this
2303 + * pointer if not NULL. The caller must free this
2304 + * array using free().
2305 + * \return 0 on success, otherwise a standard error code
2306 + * (from errno.h).
2307 + */
2308 +PUBLIC int libiscsi_discover_firmware(struct libiscsi_context *context,
2309 + int *nr_found, struct libiscsi_node **found_nodes);
2310 +
2311 +/** \brief Check validity of the given authentication info.
2312 + *
2313 + * This function checks the validity of the given authentication info. For
2314 + * example in case of CHAP, if the username and password are not empty.
2315 + *
2316 + * This function is mainly intended for use by language bindings.
2317 + *
2318 + * \param context libiscsi context to operate on.
2319 + * \param auth_info Authentication information to check.
2320 + * \return 0 on success, otherwise EINVAL.
2321 + */
2322 +PUBLIC int libiscsi_verify_auth_info(struct libiscsi_context *context,
2323 + const struct libiscsi_auth_info *auth_info);
2324 +
2325 +/** \brief Set the authentication info for the given node.
2326 + *
2327 + * This function sets the authentication information for the node described by
2328 + * the given node record. This will overwrite any existing authentication
2329 + * information.
2330 + *
2331 + * This is the way to specify authentication information for nodes found
2332 + * through sendtargets discovery.
2333 + *
2334 + * Note:
2335 + * 1) This is a convience wrapper around libiscsi_node_set_parameter(),
2336 + * setting the node.session.auth.* parameters.
2337 + * 2) For nodes found through firmware discovery the authentication information
2338 + * has already been set from the firmware.
2339 + * 3) \e auth_info may be NULL in which case any existing authinfo will be
2340 + * cleared.
2341 + *
2342 + * \param context libiscsi context to operate on.
2343 + * \param node iSCSI node to set auth information of
2344 + * \param auth_info Authentication information, or NULL.
2345 + * \return 0 on success, otherwise a standard error code
2346 + * (from errno.h).
2347 + */
2348 +PUBLIC int libiscsi_node_set_auth(struct libiscsi_context *context,
2349 + const struct libiscsi_node *node,
2350 + const struct libiscsi_auth_info *auth_info);
2351 +
2352 +/** \brief Get the authentication info for the given node.
2353 + *
2354 + * This function gets the authentication information for the node described by
2355 + * the given node record.
2356 + *
2357 + * \param context libiscsi context to operate on.
2358 + * \param node iSCSI node to set auth information of
2359 + * \param auth_info Pointer to a libiscsi_auth_info struct where
2360 + * the retreived information will be stored.
2361 + * \return 0 on success, otherwise a standard error code
2362 + * (from errno.h).
2363 + */
2364 +PUBLIC int libiscsi_node_get_auth(struct libiscsi_context *context,
2365 + const struct libiscsi_node *node,
2366 + struct libiscsi_auth_info *auth_info);
2367 +
2368 +/** \brief Login to an iSCSI node.
2369 + *
2370 + * Login to the iSCSI node described by the given node record.
2371 + *
2372 + * \param context libiscsi context to operate on.
2373 + * \param node iSCSI node to login to.
2374 + * \return 0 on success, otherwise a standard error code
2375 + * (from errno.h).
2376 + */
2377 +PUBLIC int libiscsi_node_login(struct libiscsi_context *context,
2378 + const struct libiscsi_node *node);
2379 +
2380 +/** \brief Logout of an iSCSI node.
2381 + *
2382 + * Logout of the iSCSI node described by the given node record.
2383 + *
2384 + * \param context libiscsi context to operate on.
2385 + * \param node iSCSI node to logout from.
2386 + * \return 0 on success, otherwise a standard error code
2387 + * (from errno.h).
2388 + */
2389 +PUBLIC int libiscsi_node_logout(struct libiscsi_context *context,
2390 + const struct libiscsi_node *node);
2391 +
2392 +/** \brief Set an iSCSI parameter for the given node
2393 + *
2394 + * Set the given nodes iSCSI parameter named by \e parameter to value \e value.
2395 + *
2396 + * \param context libiscsi context to operate on.
2397 + * \param node iSCSI node to change a parameter from.
2398 + * \param parameter Name of the parameter to set.
2399 + * \param value Value to set the parameter too.
2400 + * \return 0 on success, otherwise a standard error code
2401 + * (from errno.h).
2402 + */
2403 +PUBLIC int libiscsi_node_set_parameter(struct libiscsi_context *context,
2404 + const struct libiscsi_node *node,
2405 + const char *parameter, const char *value);
2406 +
2407 +/** \brief Get the value of an iSCSI parameter for the given node
2408 + *
2409 + * Get the value of the given nodes iSCSI parameter named by \e parameter.
2410 + *
2411 + * \param context libiscsi context to operate on.
2412 + * \param node iSCSI node to change a parameter from.
2413 + * \param parameter Name of the parameter to get.
2414 + * \param value The retreived value is stored here, this buffer must be
2415 + * atleast LIBISCSI_VALUE_MAXLEN bytes large.
2416 + * \return 0 on success, otherwise a standard error code
2417 + * (from errno.h).
2418 + */
2419 +PUBLIC int libiscsi_node_get_parameter(struct libiscsi_context *context,
2420 + const struct libiscsi_node *node, const char *parameter, char *value);
2421 +
2422 +/** \brief Get human readable string describing the last libiscsi error.
2423 + *
2424 + * This function can be called to get a human readable error string when a
2425 + * libiscsi function has returned an error. This function uses a single buffer
2426 + * per context, thus the result is only valid as long as no other libiscsi
2427 + * calls are made on the same context after the failing function call.
2428 + *
2429 + * \param context libiscsi context to operate on.
2430 + *
2431 + * \return human readable string describing the last libiscsi error.
2432 + */
2433 +PUBLIC const char *libiscsi_get_error_string(struct libiscsi_context *context);
2434 +
2435 +
2436 +/************************** Utility functions *******************************/
2437 +
2438 +/** \brief libiscsi network config struct
2439 + *
2440 + * libiscsi network config struct.
2441 + */
2442 +struct libiscsi_network_config {
2443 + int dhcp /** Using DHCP? (boolean). */;
2444 + char iface_name[LIBISCSI_VALUE_MAXLEN] /** Interface name. */;
2445 + char mac_address[LIBISCSI_VALUE_MAXLEN] /** MAC address. */;
2446 + char ip_address[LIBISCSI_VALUE_MAXLEN] /** IP address. */;
2447 + char netmask[LIBISCSI_VALUE_MAXLEN] /** Netmask. */;
2448 + char gateway[LIBISCSI_VALUE_MAXLEN] /** IP of Default gateway. */;
2449 + char primary_dns[LIBISCSI_VALUE_MAXLEN] /** IP of the Primary DNS. */;
2450 + char secondary_dns[LIBISCSI_VALUE_MAXLEN] /** IP of the Secondary DNS. */;
2451 +};
2452 +
2453 +/** \brief Get network configuration information from iscsi firmware
2454 + *
2455 + * Function can be called to get the network configuration information
2456 + * (like dhcp, ip, netmask, default gateway, etc.) from the firmware of a
2457 + * network adapter with iscsi boot firmware.
2458 + *
2459 + * Note that not all fields of the returned struct are necessarilly filled,
2460 + * unset fields contain a 0 length string.
2461 + *
2462 + * \param config pointer to a libiscsi_network_config struct to fill.
2463 + *
2464 + * \return 0 on success, ENODEV when no iscsi firmware was found.
2465 + */
2466 +PUBLIC int libiscsi_get_firmware_network_config(
2467 + struct libiscsi_network_config *config);
2468 +
2469 +/** \brief Get the initiator name (iqn) from the iscsi firmware
2470 + *
2471 + * Get the initiator name (iqn) from the iscsi firmware.
2472 + *
2473 + * \param initiatorname The initiator name is stored here, this buffer must be
2474 + * atleast LIBISCSI_VALUE_MAXLEN bytes large.
2475 + * \return 0 on success, ENODEV when no iscsi firmware was found.
2476 + */
2477 +PUBLIC int libiscsi_get_firmware_initiator_name(char *initiatorname);
2478 +
2479 +#undef PUBLIC
2480 +
2481 +#ifdef __cplusplus
2482 +}
2483 +#endif /* __cplusplus */
2484 +
2485 +#endif
2486 diff --git a/libiscsi/pylibiscsi.c b/libiscsi/pylibiscsi.c
2487 new file mode 100644
2488 index 0000000..454a26a
2489 --- /dev/null
2490 +++ b/libiscsi/pylibiscsi.c
2491 @@ -0,0 +1,624 @@
2492 +/*
2493 + * iSCSI Administration library
2494 + *
2495 + * Copyright (C) 2008-2009 Red Hat, Inc. All rights reserved.
2496 + * Copyright (C) 2008-2009 Hans de Goede <hdegoede@redhat.com>
2497 + * maintained by open-iscsi@googlegroups.com
2498 + *
2499 + * This program is free software; you can redistribute it and/or modify
2500 + * it under the terms of the GNU General Public License as published
2501 + * by the Free Software Foundation; either version 2 of the License, or
2502 + * (at your option) any later version.
2503 + *
2504 + * This program is distributed in the hope that it will be useful, but
2505 + * WITHOUT ANY WARRANTY; without even the implied warranty of
2506 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2507 + * General Public License for more details.
2508 + *
2509 + * See the file COPYING included with this distribution for more details.
2510 + */
2511 +
2512 +#include <Python.h>
2513 +#include "libiscsi.h"
2514 +
2515 +static struct libiscsi_context *context = NULL;
2516 +
2517 +/****************************** helpers ***********************************/
2518 +static int check_string(const char *string)
2519 +{
2520 + if (strlen(string) >= LIBISCSI_VALUE_MAXLEN) {
2521 + PyErr_SetString(PyExc_ValueError, "string too long");
2522 + return -1;
2523 + }
2524 + return 0;
2525 +}
2526 +
2527 +/********************** PyIscsiChapAuthInfo ***************************/
2528 +
2529 +typedef struct {
2530 + PyObject_HEAD
2531 +
2532 + struct libiscsi_auth_info info;
2533 +} PyIscsiChapAuthInfo;
2534 +
2535 +static int PyIscsiChapAuthInfo_init(PyObject *self, PyObject *args,
2536 + PyObject *kwds)
2537 +{
2538 + int i;
2539 + PyIscsiChapAuthInfo *chap = (PyIscsiChapAuthInfo *)self;
2540 + char *kwlist[] = {"username", "password", "reverse_username",
2541 + "reverse_password", NULL};
2542 + const char *string[4] = { NULL, NULL, NULL, NULL };
2543 +
2544 + if (!PyArg_ParseTupleAndKeywords(args, kwds,
2545 + "zz|zz:chapAuthInfo.__init__",
2546 + kwlist, &string[0], &string[1],
2547 + &string[2], &string[3]))
2548 + return -1;
2549 +
2550 + for (i = 0; i < 4; i++)
2551 + if (string[i] && check_string(string[i]))
2552 + return -1;
2553 +
2554 + memset (&chap->info, 0, sizeof(chap->info));
2555 + chap->info.method = libiscsi_auth_chap;
2556 + if (string[0])
2557 + strcpy(chap->info.chap.username, string[0]);
2558 + if (string[1])
2559 + strcpy(chap->info.chap.password, string[1]);
2560 + if (string[2])
2561 + strcpy(chap->info.chap.reverse_username, string[2]);
2562 + if (string[3])
2563 + strcpy(chap->info.chap.reverse_password, string[3]);
2564 +
2565 + if (libiscsi_verify_auth_info(context, &chap->info)) {
2566 + PyErr_SetString(PyExc_ValueError,
2567 + libiscsi_get_error_string(context));
2568 + return -1;
2569 + }
2570 + return 0;
2571 +}
2572 +
2573 +static PyObject *PyIscsiChapAuthInfo_get(PyObject *self, void *data)
2574 +{
2575 + PyIscsiChapAuthInfo *chap = (PyIscsiChapAuthInfo *)self;
2576 + const char *attr = (const char *)data;
2577 +
2578 + if (!strcmp(attr, "username")) {
2579 + return PyString_FromString(chap->info.chap.username);
2580 + } else if (!strcmp(attr, "password")) {
2581 + return PyString_FromString(chap->info.chap.password);
2582 + } else if (!strcmp(attr, "reverse_username")) {
2583 + return PyString_FromString(chap->info.chap.reverse_username);
2584 + } else if (!strcmp(attr, "reverse_password")) {
2585 + return PyString_FromString(chap->info.chap.reverse_password);
2586 + }
2587 + return NULL;
2588 +}
2589 +
2590 +static int PyIscsiChapAuthInfo_set(PyObject *self, PyObject *value, void *data)
2591 +{
2592 + PyIscsiChapAuthInfo *chap = (PyIscsiChapAuthInfo *)self;
2593 + const char *attr = (const char *)data;
2594 + const char *str;
2595 +
2596 + if (!PyArg_Parse(value, "s", &str) || check_string(str))
2597 + return -1;
2598 +
2599 + if (!strcmp(attr, "username")) {
2600 + strcpy(chap->info.chap.username, str);
2601 + } else if (!strcmp(attr, "password")) {
2602 + strcpy(chap->info.chap.password, str);
2603 + } else if (!strcmp(attr, "reverse_username")) {
2604 + strcpy(chap->info.chap.reverse_username, str);
2605 + } else if (!strcmp(attr, "reverse_password")) {
2606 + strcpy(chap->info.chap.reverse_password, str);
2607 + }
2608 +
2609 + return 0;
2610 +}
2611 +
2612 +static int PyIscsiChapAuthInfo_compare(PyIscsiChapAuthInfo *self,
2613 + PyIscsiChapAuthInfo *other)
2614 +{
2615 + int r;
2616 +
2617 + r = strcmp(self->info.chap.username, other->info.chap.username);
2618 + if (r)
2619 + return r;
2620 +
2621 + r = strcmp(self->info.chap.password, other->info.chap.password);
2622 + if (r)
2623 + return r;
2624 +
2625 + r = strcmp(self->info.chap.reverse_username,
2626 + other->info.chap.reverse_username);
2627 + if (r)
2628 + return r;
2629 +
2630 + r = strcmp(self->info.chap.reverse_password,
2631 + other->info.chap.reverse_password);
2632 + return r;
2633 +}
2634 +
2635 +static PyObject *PyIscsiChapAuthInfo_str(PyObject *self)
2636 +{
2637 + PyIscsiChapAuthInfo *chap = (PyIscsiChapAuthInfo *)self;
2638 + char s[1024], reverse[512] = "";
2639 +
2640 + if (chap->info.chap.reverse_username[0])
2641 + snprintf(reverse, sizeof(reverse), ", %s:%s",
2642 + chap->info.chap.reverse_username,
2643 + chap->info.chap.reverse_password);
2644 +
2645 + snprintf(s, sizeof(s), "%s:%s%s", chap->info.chap.username,
2646 + chap->info.chap.password, reverse);
2647 +
2648 + return PyString_FromString(s);
2649 +}
2650 +
2651 +static struct PyGetSetDef PyIscsiChapAuthInfo_getseters[] = {
2652 + {"username", (getter)PyIscsiChapAuthInfo_get,
2653 + (setter)PyIscsiChapAuthInfo_set,
2654 + "username", "username"},
2655 + {"password", (getter)PyIscsiChapAuthInfo_get,
2656 + (setter)PyIscsiChapAuthInfo_set,
2657 + "password", "password"},
2658 + {"reverse_username", (getter)PyIscsiChapAuthInfo_get,
2659 + (setter)PyIscsiChapAuthInfo_set,
2660 + "reverse_username", "reverse_username"},
2661 + {"reverse_password", (getter)PyIscsiChapAuthInfo_get,
2662 + (setter)PyIscsiChapAuthInfo_set,
2663 + "reverse_password", "reverse_password"},
2664 + {NULL}
2665 +};
2666 +
2667 +PyTypeObject PyIscsiChapAuthInfo_Type = {
2668 + PyObject_HEAD_INIT(NULL)
2669 + .tp_name = "libiscsi.chapAuthInfo",
2670 + .tp_basicsize = sizeof (PyIscsiChapAuthInfo),
2671 + .tp_getset = PyIscsiChapAuthInfo_getseters,
2672 + .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
2673 + Py_TPFLAGS_BASETYPE,
2674 + .tp_compare = (cmpfunc)PyIscsiChapAuthInfo_compare,
2675 + .tp_init = PyIscsiChapAuthInfo_init,
2676 + .tp_str = PyIscsiChapAuthInfo_str,
2677 + .tp_new = PyType_GenericNew,
2678 + .tp_doc = "iscsi chap authentication information.",
2679 +};
2680 +
2681 +/***************************** PyIscsiNode ********************************/
2682 +
2683 +typedef struct {
2684 + PyObject_HEAD
2685 +
2686 + struct libiscsi_node node;
2687 +} PyIscsiNode;
2688 +
2689 +static int PyIscsiNode_init(PyObject *self, PyObject *args, PyObject *kwds)
2690 +{
2691 + PyIscsiNode *node = (PyIscsiNode *)self;
2692 + char *kwlist[] = {"name", "tpgt", "address", "port", NULL};
2693 + const char *name = NULL, *address = NULL;
2694 + int tpgt = -1, port = 3260;
2695 +
2696 + if (!PyArg_ParseTupleAndKeywords(args, kwds, "s|isi:node.__init__",
2697 + kwlist, &name, &tpgt, &address, &port))
2698 + return -1;
2699 + if (address == NULL) {
2700 + PyErr_SetString(PyExc_ValueError, "address not set");
2701 + return -1;
2702 + }
2703 + if (check_string(name) || check_string(address))
2704 + return -1;
2705 +
2706 + strcpy(node->node.name, name);
2707 + node->node.tpgt = tpgt;
2708 + strcpy(node->node.address, address);
2709 + node->node.port = port;
2710 +
2711 + return 0;
2712 +}
2713 +
2714 +static PyObject *PyIscsiNode_get(PyObject *self, void *data)
2715 +{
2716 + PyIscsiNode *node = (PyIscsiNode *)self;
2717 + const char *attr = (const char *)data;
2718 +
2719 + if (!strcmp(attr, "name")) {
2720 + return PyString_FromString(node->node.name);
2721 + } else if (!strcmp(attr, "tpgt")) {
2722 + return PyInt_FromLong(node->node.tpgt);
2723 + } else if (!strcmp(attr, "address")) {
2724 + return PyString_FromString(node->node.address);
2725 + } else if (!strcmp(attr, "port")) {
2726 + return PyInt_FromLong(node->node.port);
2727 + }
2728 + return NULL;
2729 +}
2730 +
2731 +static int PyIscsiNode_set(PyObject *self, PyObject *value, void *data)
2732 +{
2733 + PyIscsiNode *node = (PyIscsiNode *)self;
2734 + const char *attr = (const char *)data;
2735 + const char *str;
2736 + int i;
2737 +
2738 + if (!strcmp(attr, "name")) {
2739 + if (!PyArg_Parse(value, "s", &str) || check_string(str))
2740 + return -1;
2741 + strcpy(node->node.name, str);
2742 + } else if (!strcmp(attr, "tpgt")) {
2743 + if (!PyArg_Parse(value, "i", &i))
2744 + return -1;
2745 + node->node.tpgt = i;
2746 + } else if (!strcmp(attr, "address")) {
2747 + if (!PyArg_Parse(value, "s", &str) || check_string(str))
2748 + return -1;
2749 + strcpy(node->node.address, str);
2750 + } else if (!strcmp(attr, "port")) {
2751 + if (!PyArg_Parse(value, "i", &i))
2752 + return -1;
2753 + node->node.port = i;
2754 + }
2755 +
2756 + return 0;
2757 +}
2758 +
2759 +static int PyIscsiNode_compare(PyIscsiNode *self, PyIscsiNode *other)
2760 +{
2761 + int res;
2762 +
2763 + res = strcmp(self->node.name, other->node.name);
2764 + if (res)
2765 + return res;
2766 +
2767 + if (self->node.tpgt < other->node.tpgt)
2768 + return -1;
2769 + if (self->node.tpgt > other->node.tpgt)
2770 + return -1;
2771 +
2772 + res = strcmp(self->node.address, other->node.address);
2773 + if (res)
2774 + return res;
2775 +
2776 + if (self->node.port < other->node.port)
2777 + return -1;
2778 + if (self->node.port > other->node.port)
2779 + return -1;
2780 +
2781 + return 0;
2782 +}
2783 +
2784 +static PyObject *PyIscsiNode_str(PyObject *self)
2785 +{
2786 + PyIscsiNode *node = (PyIscsiNode *)self;
2787 + char s[1024], tpgt[16] = "";
2788 +
2789 + if (node->node.tpgt != -1)
2790 + sprintf(tpgt, ",%d", node->node.tpgt);
2791 +
2792 + snprintf(s, sizeof(s), "%s:%d%s %s", node->node.address,
2793 + node->node.port, tpgt, node->node.name);
2794 +
2795 + return PyString_FromString(s);
2796 +}
2797 +
2798 +static PyObject *PyIscsiNode_login(PyObject *self)
2799 +{
2800 + PyIscsiNode *node = (PyIscsiNode *)self;
2801 +
2802 + if (libiscsi_node_login(context, &node->node)) {
2803 + PyErr_SetString(PyExc_IOError,
2804 + libiscsi_get_error_string(context));
2805 + return NULL;
2806 + }
2807 + Py_RETURN_NONE;
2808 +}
2809 +
2810 +static PyObject *PyIscsiNode_logout(PyObject *self)
2811 +{
2812 + PyIscsiNode *node = (PyIscsiNode *)self;
2813 +
2814 + if (libiscsi_node_logout(context, &node->node)) {
2815 + PyErr_SetString(PyExc_IOError,
2816 + libiscsi_get_error_string(context));
2817 + return NULL;
2818 + }
2819 + Py_RETURN_NONE;
2820 +}
2821 +
2822 +static PyObject *PyIscsiNode_setAuth(PyObject *self, PyObject *args,
2823 + PyObject *kwds)
2824 +{
2825 + char *kwlist[] = {"authinfo", NULL};
2826 + PyIscsiNode *node = (PyIscsiNode *)self;
2827 + PyObject *arg;
2828 + const struct libiscsi_auth_info *authinfo = NULL;
2829 +
2830 + if (!PyArg_ParseTupleAndKeywords(args, kwds, "O", kwlist, &arg))
2831 + return NULL;
2832 +
2833 + if (arg == Py_None) {
2834 + authinfo = NULL;
2835 + } else if (PyObject_IsInstance(arg, (PyObject *)
2836 + &PyIscsiChapAuthInfo_Type)) {
2837 + PyIscsiChapAuthInfo *pyauthinfo = (PyIscsiChapAuthInfo *)arg;
2838 + authinfo = &pyauthinfo->info;
2839 + } else {
2840 + PyErr_SetString(PyExc_ValueError, "invalid authinfo type");
2841 + return NULL;
2842 + }
2843 +
2844 + if (libiscsi_node_set_auth(context, &node->node, authinfo)) {
2845 + PyErr_SetString(PyExc_IOError,
2846 + libiscsi_get_error_string(context));
2847 + return NULL;
2848 + }
2849 + Py_RETURN_NONE;
2850 +}
2851 +
2852 +static PyObject *PyIscsiNode_getAuth(PyObject *self)
2853 +{
2854 + PyIscsiNode *node = (PyIscsiNode *)self;
2855 + PyIscsiChapAuthInfo *pyauthinfo;
2856 + struct libiscsi_auth_info authinfo;
2857 +
2858 + if (libiscsi_node_get_auth(context, &node->node, &authinfo)) {
2859 + PyErr_SetString(PyExc_IOError,
2860 + libiscsi_get_error_string(context));
2861 + return NULL;
2862 + }
2863 +
2864 + switch (authinfo.method) {
2865 + case libiscsi_auth_chap:
2866 + pyauthinfo = PyObject_New(PyIscsiChapAuthInfo,
2867 + &PyIscsiChapAuthInfo_Type);
2868 + if (!pyauthinfo)
2869 + return NULL;
2870 +
2871 + pyauthinfo->info = authinfo;
2872 +
2873 + return (PyObject *)pyauthinfo;
2874 +
2875 + case libiscsi_auth_none:
2876 + default:
2877 + Py_RETURN_NONE;
2878 + }
2879 +}
2880 +
2881 +static PyObject *PyIscsiNode_setParameter(PyObject *self, PyObject *args,
2882 + PyObject *kwds)
2883 +{
2884 + char *kwlist[] = {"parameter", "value", NULL};
2885 + PyIscsiNode *node = (PyIscsiNode *)self;
2886 + const char *parameter, *value;
2887 +
2888 + if (!PyArg_ParseTupleAndKeywords(args, kwds, "ss", kwlist,
2889 + &parameter, &value))
2890 + return NULL;
2891 + if (check_string(parameter) || check_string(value))
2892 + return NULL;
2893 +
2894 + if (libiscsi_node_set_parameter(context, &node->node, parameter,
2895 + value)) {
2896 + PyErr_SetString(PyExc_IOError,
2897 + libiscsi_get_error_string(context));
2898 + return NULL;
2899 + }
2900 + Py_RETURN_NONE;
2901 +}
2902 +
2903 +static PyObject *PyIscsiNode_getParameter(PyObject *self, PyObject *args,
2904 + PyObject *kwds)
2905 +{
2906 + char *kwlist[] = {"parameter", NULL};
2907 + PyIscsiNode *node = (PyIscsiNode *)self;
2908 + const char *parameter;
2909 + char value[LIBISCSI_VALUE_MAXLEN];
2910 +
2911 + if (!PyArg_ParseTupleAndKeywords(args, kwds, "s", kwlist, &parameter))
2912 + return NULL;
2913 + if (check_string(parameter))
2914 + return NULL;
2915 +
2916 + if (libiscsi_node_get_parameter(context, &node->node, parameter,
2917 + value)) {
2918 + PyErr_SetString(PyExc_IOError,
2919 + libiscsi_get_error_string(context));
2920 + return NULL;
2921 + }
2922 + return Py_BuildValue("s", value);
2923 +}
2924 +
2925 +static struct PyGetSetDef PyIscsiNode_getseters[] = {
2926 + {"name", (getter)PyIscsiNode_get, (setter)PyIscsiNode_set,
2927 + "name", "name"},
2928 + {"tpgt", (getter)PyIscsiNode_get, (setter)PyIscsiNode_set,
2929 + "tpgt", "tpgt"},
2930 + {"address", (getter)PyIscsiNode_get, (setter)PyIscsiNode_set,
2931 + "address", "address"},
2932 + {"port", (getter)PyIscsiNode_get, (setter)PyIscsiNode_set,
2933 + "port", "port"},
2934 + {NULL}
2935 +};
2936 +
2937 +static struct PyMethodDef PyIscsiNode_methods[] = {
2938 + {"login", (PyCFunction) PyIscsiNode_login, METH_NOARGS,
2939 + "Log in to the node"},
2940 + {"logout", (PyCFunction) PyIscsiNode_logout, METH_NOARGS,
2941 + "Log out of the node"},
2942 + {"setAuth", (PyCFunction) PyIscsiNode_setAuth,
2943 + METH_VARARGS|METH_KEYWORDS,
2944 + "Set authentication information"},
2945 + {"getAuth", (PyCFunction) PyIscsiNode_getAuth, METH_NOARGS,
2946 + "Get authentication information"},
2947 + {"setParameter", (PyCFunction) PyIscsiNode_setParameter,
2948 + METH_VARARGS|METH_KEYWORDS,
2949 + "Set an iscsi node parameter"},
2950 + {"getParameter", (PyCFunction) PyIscsiNode_getParameter,
2951 + METH_VARARGS|METH_KEYWORDS,
2952 + "Get an iscsi node parameter"},
2953 + {NULL}
2954 +};
2955 +
2956 +PyTypeObject PyIscsiNode_Type = {
2957 + PyObject_HEAD_INIT(NULL)
2958 + .tp_name = "libiscsi.node",
2959 + .tp_basicsize = sizeof (PyIscsiNode),
2960 + .tp_getset = PyIscsiNode_getseters,
2961 + .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
2962 + Py_TPFLAGS_BASETYPE,
2963 + .tp_methods = PyIscsiNode_methods,
2964 + .tp_compare = (cmpfunc)PyIscsiNode_compare,
2965 + .tp_init = PyIscsiNode_init,
2966 + .tp_str = PyIscsiNode_str,
2967 + .tp_new = PyType_GenericNew,
2968 + .tp_doc = "The iscsi node contains iscsi node information.",
2969 +};
2970 +
2971 +/***************************************************************************/
2972 +
2973 +static PyObject *pylibiscsi_discover_sendtargets(PyObject *self,
2974 + PyObject *args, PyObject *kwds)
2975 +{
2976 + char *kwlist[] = {"address", "port", "authinfo", NULL};
2977 + const char *address = NULL;
2978 + int i, nr_found, port = 3260;
2979 + PyObject *authinfo_arg = NULL;
2980 + const struct libiscsi_auth_info *authinfo = NULL;
2981 + struct libiscsi_node *found_nodes;
2982 + PyObject* found_node_list;
2983 +
2984 + if (!PyArg_ParseTupleAndKeywords(args, kwds, "s|iO",
2985 + kwlist, &address, &port,
2986 + &authinfo_arg))
2987 + return NULL;
2988 +
2989 + if (authinfo_arg) {
2990 + if (PyObject_IsInstance(authinfo_arg, (PyObject *)
2991 + &PyIscsiChapAuthInfo_Type)) {
2992 + PyIscsiChapAuthInfo *pyauthinfo =
2993 + (PyIscsiChapAuthInfo *)authinfo_arg;
2994 + authinfo = &pyauthinfo->info;
2995 + } else if (authinfo_arg != Py_None) {
2996 + PyErr_SetString(PyExc_ValueError,
2997 + "invalid authinfo type");
2998 + return NULL;
2999 + }
3000 + }
3001 +
3002 + if (libiscsi_discover_sendtargets(context, address, port, authinfo,
3003 + &nr_found, &found_nodes)) {
3004 + PyErr_SetString(PyExc_IOError,
3005 + libiscsi_get_error_string(context));
3006 + return NULL;
3007 + }
3008 +
3009 + if (nr_found == 0)
3010 + Py_RETURN_NONE;
3011 +
3012 + found_node_list = PyList_New(nr_found);
3013 + if (!found_node_list)
3014 + return NULL;
3015 +
3016 + for(i = 0; i < nr_found; i++) {
3017 + PyIscsiNode *pynode;
3018 +
3019 + pynode = PyObject_New(PyIscsiNode, &PyIscsiNode_Type);
3020 + if (!pynode) {
3021 + /* This will deref already added nodes for us */
3022 + Py_DECREF(found_node_list);
3023 + return NULL;
3024 + }
3025 + pynode->node = found_nodes[i];
3026 + PyList_SET_ITEM(found_node_list, i, (PyObject *)pynode);
3027 + }
3028 +
3029 + return found_node_list;
3030 +}
3031 +
3032 +static PyObject *pylibiscsi_discover_firmware(PyObject *self)
3033 +{
3034 + int i, nr_found;
3035 + struct libiscsi_node *found_nodes;
3036 + PyObject* found_node_list;
3037 +
3038 + if (libiscsi_discover_firmware(context, &nr_found, &found_nodes)) {
3039 + PyErr_SetString(PyExc_IOError,
3040 + libiscsi_get_error_string(context));
3041 + return NULL;
3042 + }
3043 +
3044 + if (nr_found == 0)
3045 + Py_RETURN_NONE;
3046 +
3047 + found_node_list = PyList_New(nr_found);
3048 + if (!found_node_list)
3049 + return NULL;
3050 +
3051 + for(i = 0; i < nr_found; i++) {
3052 + PyIscsiNode *pynode;
3053 +
3054 + pynode = PyObject_New(PyIscsiNode, &PyIscsiNode_Type);
3055 + if (!pynode) {
3056 + /* This will deref already added nodes for us */
3057 + Py_DECREF(found_node_list);
3058 + return NULL;
3059 + }
3060 + pynode->node = found_nodes[i];
3061 + PyList_SET_ITEM(found_node_list, i, (PyObject *)pynode);
3062 + }
3063 +
3064 + return found_node_list;
3065 +}
3066 +
3067 +static PyObject *pylibiscsi_get_firmware_initiator_name(PyObject *self)
3068 +{
3069 + char initiatorname[LIBISCSI_VALUE_MAXLEN];
3070 +
3071 + if (libiscsi_get_firmware_initiator_name(initiatorname)) {
3072 + PyErr_SetString(PyExc_IOError,
3073 + libiscsi_get_error_string(context));
3074 + return NULL;
3075 + }
3076 +
3077 + return PyString_FromString(initiatorname);
3078 +}
3079 +
3080 +static PyMethodDef pylibiscsi_functions[] = {
3081 + { "discover_sendtargets",
3082 + (PyCFunction)pylibiscsi_discover_sendtargets,
3083 + METH_VARARGS|METH_KEYWORDS,
3084 + "Do sendtargets discovery and return a list of found nodes)"},
3085 + { "discover_firmware",
3086 + (PyCFunction)pylibiscsi_discover_firmware, METH_NOARGS,
3087 + "Do firmware discovery and return a list of found nodes)"},
3088 + { "get_firmware_initiator_name",
3089 + (PyCFunction)pylibiscsi_get_firmware_initiator_name,
3090 + METH_NOARGS,
3091 + "Get initator name (iqn) from firmware"},
3092 + {NULL, NULL}
3093 +};
3094 +
3095 +PyMODINIT_FUNC initlibiscsi(void)
3096 +{
3097 + PyObject *m;
3098 +
3099 + if (!context) /* We may be called more then once */
3100 + context = libiscsi_init();
3101 + if (!context)
3102 + return;
3103 +
3104 + if (PyType_Ready(&PyIscsiChapAuthInfo_Type) < 0)
3105 + return;
3106 +
3107 + if (PyType_Ready(&PyIscsiNode_Type) < 0)
3108 + return;
3109 +
3110 + m = Py_InitModule("libiscsi", pylibiscsi_functions);
3111 + Py_INCREF(&PyIscsiChapAuthInfo_Type);
3112 + PyModule_AddObject(m, "chapAuthInfo", (PyObject *) &PyIscsiChapAuthInfo_Type);
3113 + Py_INCREF(&PyIscsiNode_Type);
3114 + PyModule_AddObject(m, "node", (PyObject *) &PyIscsiNode_Type);
3115 +}
3116 diff --git a/libiscsi/setup.py b/libiscsi/setup.py
3117 new file mode 100644
3118 index 0000000..bb4329b
3119 --- /dev/null
3120 +++ b/libiscsi/setup.py
3121 @@ -0,0 +1,9 @@
3122 +from distutils.core import setup, Extension
3123 +
3124 +module1 = Extension('libiscsimodule',
3125 + sources = ['pylibiscsi.c'],
3126 + libraries = ['iscsi'],
3127 + library_dirs = ['.'])
3128 +
3129 +setup (name = 'PyIscsi',version = '1.0',
3130 + description = 'libiscsi python bindings', ext_modules = [module1])
3131 diff --git a/libiscsi/tests/test_discovery_firmware.c b/libiscsi/tests/test_discovery_firmware.c
3132 new file mode 100644
3133 index 0000000..76e852a
3134 --- /dev/null
3135 +++ b/libiscsi/tests/test_discovery_firmware.c
3136 @@ -0,0 +1,53 @@
3137 +/*
3138 + * iSCSI Administration library
3139 + *
3140 + * Copyright (C) 2008-2009 Red Hat, Inc. All rights reserved.
3141 + * Copyright (C) 2008-2009 Hans de Goede <hdegoede@redhat.com>
3142 + * maintained by open-iscsi@googlegroups.com
3143 + *
3144 + * This program is free software; you can redistribute it and/or modify
3145 + * it under the terms of the GNU General Public License as published
3146 + * by the Free Software Foundation; either version 2 of the License, or
3147 + * (at your option) any later version.
3148 + *
3149 + * This program is distributed in the hope that it will be useful, but
3150 + * WITHOUT ANY WARRANTY; without even the implied warranty of
3151 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
3152 + * General Public License for more details.
3153 + *
3154 + * See the file COPYING included with this distribution for more details.
3155 + */
3156 +
3157 +#include <stdio.h>
3158 +#include <stdlib.h>
3159 +#include <string.h>
3160 +#include "libiscsi.h"
3161 +
3162 +int main(void)
3163 +{
3164 + struct libiscsi_node *found_nodes;
3165 + struct libiscsi_context *context;
3166 + int i, found, rc = 0;
3167 +
3168 + context = libiscsi_init();
3169 + if (!context) {
3170 + fprintf(stderr, "Error initializing libiscsi\n");
3171 + return 1;
3172 + }
3173 +
3174 + rc = libiscsi_discover_firmware(context, &found, &found_nodes);
3175 + if (rc)
3176 + fprintf(stderr, "Error discovering: %s\n",
3177 + libiscsi_get_error_string(context));
3178 +
3179 + for (i = 0; i < found; i++) {
3180 + fprintf(stdout, "Found node: %s, tpgt: %d, portal: %s:%d\n",
3181 + found_nodes[i].name, found_nodes[i].tpgt,
3182 + found_nodes[i].address, found_nodes[i].port);
3183 + }
3184 +
3185 + libiscsi_cleanup(context);
3186 + free (found_nodes);
3187 +
3188 + return rc;
3189 +}
3190 diff --git a/libiscsi/tests/test_discovery_sendtargets.c b/libiscsi/tests/test_discovery_sendtargets.c
3191 new file mode 100644
3192 index 0000000..1a3c12e
3193 --- /dev/null
3194 +++ b/libiscsi/tests/test_discovery_sendtargets.c
3195 @@ -0,0 +1,60 @@
3196 +/*
3197 + * iSCSI Administration library
3198 + *
3199 + * Copyright (C) 2008-2009 Red Hat, Inc. All rights reserved.
3200 + * Copyright (C) 2008-2009 Hans de Goede <hdegoede@redhat.com>
3201 + * maintained by open-iscsi@googlegroups.com
3202 + *
3203 + * This program is free software; you can redistribute it and/or modify
3204 + * it under the terms of the GNU General Public License as published
3205 + * by the Free Software Foundation; either version 2 of the License, or
3206 + * (at your option) any later version.
3207 + *
3208 + * This program is distributed in the hope that it will be useful, but
3209 + * WITHOUT ANY WARRANTY; without even the implied warranty of
3210 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
3211 + * General Public License for more details.
3212 + *
3213 + * See the file COPYING included with this distribution for more details.
3214 + */
3215 +
3216 +#include <stdio.h>
3217 +#include <stdlib.h>
3218 +#include <string.h>
3219 +#include "libiscsi.h"
3220 +
3221 +int main(void)
3222 +{
3223 + struct libiscsi_node *found_nodes;
3224 + struct libiscsi_context *context;
3225 + struct libiscsi_auth_info auth_info;
3226 + int i, found, rc = 0;
3227 +
3228 + context = libiscsi_init();
3229 + if (!context) {
3230 + fprintf(stderr, "Error initializing libiscsi\n");
3231 + return 1;
3232 + }
3233 +
3234 + memset(&auth_info, 0, sizeof(auth_info));
3235 + auth_info.method = libiscsi_auth_chap;
3236 + strcpy(auth_info.chap.username, "joe");
3237 + strcpy(auth_info.chap.password, "secret");
3238 +
3239 + rc = libiscsi_discover_sendtargets(context, "127.0.0.1", 3260,
3240 + &auth_info, &found, &found_nodes);
3241 + if (rc)
3242 + fprintf(stderr, "Error discovering: %s\n",
3243 + libiscsi_get_error_string(context));
3244 +
3245 + for (i = 0; i < found; i++) {
3246 + fprintf(stdout, "Found node: %s, tpgt: %d, portal: %s:%d\n",
3247 + found_nodes[i].name, found_nodes[i].tpgt,
3248 + found_nodes[i].address, found_nodes[i].port);
3249 + }
3250 +
3251 + libiscsi_cleanup(context);
3252 + free (found_nodes);
3253 +
3254 + return rc;
3255 +}
3256 diff --git a/libiscsi/tests/test_get_auth.c b/libiscsi/tests/test_get_auth.c
3257 new file mode 100644
3258 index 0000000..5e234da
3259 --- /dev/null
3260 +++ b/libiscsi/tests/test_get_auth.c
3261 @@ -0,0 +1,70 @@
3262 +/*
3263 + * iSCSI Administration library
3264 + *
3265 + * Copyright (C) 2008-2009 Red Hat, Inc. All rights reserved.
3266 + * Copyright (C) 2008-2009 Hans de Goede <hdegoede@redhat.com>
3267 + * maintained by open-iscsi@googlegroups.com
3268 + *
3269 + * This program is free software; you can redistribute it and/or modify
3270 + * it under the terms of the GNU General Public License as published
3271 + * by the Free Software Foundation; either version 2 of the License, or
3272 + * (at your option) any later version.
3273 + *
3274 + * This program is distributed in the hope that it will be useful, but
3275 + * WITHOUT ANY WARRANTY; without even the implied warranty of
3276 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
3277 + * General Public License for more details.
3278 + *
3279 + * See the file COPYING included with this distribution for more details.
3280 + */
3281 +
3282 +#include <stdio.h>
3283 +#include <stdlib.h>
3284 +#include <string.h>
3285 +#include "libiscsi.h"
3286 +
3287 +int main(void)
3288 +{
3289 + struct libiscsi_node node;
3290 + struct libiscsi_context *context;
3291 + struct libiscsi_auth_info auth_info;
3292 + int rc = 0;
3293 +
3294 + snprintf(node.name, LIBISCSI_VALUE_MAXLEN, "%s",
3295 + "iqn.2009-01.com.example:testdisk");
3296 + node.tpgt = 1;
3297 + snprintf(node.address, NI_MAXHOST, "%s", "127.0.0.1");
3298 + node.port = 3260;
3299 +
3300 + context = libiscsi_init();
3301 + if (!context) {
3302 + fprintf(stderr, "Error initializing libiscsi\n");
3303 + return 1;
3304 + }
3305 +
3306 + rc = libiscsi_node_get_auth(context, &node, &auth_info);
3307 + if (rc) {
3308 + fprintf(stderr, "Error setting authinfo: %s\n",
3309 + libiscsi_get_error_string(context));
3310 + goto leave;
3311 + }
3312 +
3313 + switch (auth_info.method) {
3314 + case libiscsi_auth_none:
3315 + printf("Method: \"None\"\n");
3316 + break;
3317 + case libiscsi_auth_chap:
3318 + printf("Method: \"CHAP\"\n");
3319 + printf("User: \"%s\"\n", auth_info.chap.username);
3320 + printf("Pass: \"%s\"\n", auth_info.chap.password);
3321 + printf("RevUser: \"%s\"\n",
3322 + auth_info.chap.reverse_username);
3323 + printf("RevPass: \"%s\"\n",
3324 + auth_info.chap.reverse_password);
3325 + break;
3326 + }
3327 +leave:
3328 + libiscsi_cleanup(context);
3329 +
3330 + return rc;
3331 +}
3332 diff --git a/libiscsi/tests/test_get_initiator_name.c b/libiscsi/tests/test_get_initiator_name.c
3333 new file mode 100644
3334 index 0000000..997c053
3335 --- /dev/null
3336 +++ b/libiscsi/tests/test_get_initiator_name.c
3337 @@ -0,0 +1,38 @@
3338 +/*
3339 + * iSCSI Administration library
3340 + *
3341 + * Copyright (C) 2008-2009 Red Hat, Inc. All rights reserved.
3342 + * Copyright (C) 2008-2009 Hans de Goede <hdegoede@redhat.com>
3343 + * maintained by open-iscsi@googlegroups.com
3344 + *
3345 + * This program is free software; you can redistribute it and/or modify
3346 + * it under the terms of the GNU General Public License as published
3347 + * by the Free Software Foundation; either version 2 of the License, or
3348 + * (at your option) any later version.
3349 + *
3350 + * This program is distributed in the hope that it will be useful, but
3351 + * WITHOUT ANY WARRANTY; without even the implied warranty of
3352 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
3353 + * General Public License for more details.
3354 + *
3355 + * See the file COPYING included with this distribution for more details.
3356 + */
3357 +
3358 +#include <stdio.h>
3359 +#include <stdlib.h>
3360 +#include <string.h>
3361 +#include "libiscsi.h"
3362 +
3363 +int main(void)
3364 +{
3365 + char initiatorname[LIBISCSI_VALUE_MAXLEN];
3366 +
3367 + if (libiscsi_get_firmware_initiator_name(initiatorname)) {
3368 + fprintf(stderr, "No iscsi boot firmware found\n");
3369 + return 1;
3370 + }
3371 +
3372 + printf("iqn:\t%s\n", initiatorname);
3373 +
3374 + return 0;
3375 +}
3376 diff --git a/libiscsi/tests/test_get_network_config.c b/libiscsi/tests/test_get_network_config.c
3377 new file mode 100644
3378 index 0000000..2dedd61
3379 --- /dev/null
3380 +++ b/libiscsi/tests/test_get_network_config.c
3381 @@ -0,0 +1,45 @@
3382 +/*
3383 + * iSCSI Administration library
3384 + *
3385 + * Copyright (C) 2008-2009 Red Hat, Inc. All rights reserved.
3386 + * Copyright (C) 2008-2009 Hans de Goede <hdegoede@redhat.com>
3387 + * maintained by open-iscsi@googlegroups.com
3388 + *
3389 + * This program is free software; you can redistribute it and/or modify
3390 + * it under the terms of the GNU General Public License as published
3391 + * by the Free Software Foundation; either version 2 of the License, or
3392 + * (at your option) any later version.
3393 + *
3394 + * This program is distributed in the hope that it will be useful, but
3395 + * WITHOUT ANY WARRANTY; without even the implied warranty of
3396 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
3397 + * General Public License for more details.
3398 + *
3399 + * See the file COPYING included with this distribution for more details.
3400 + */
3401 +
3402 +#include <stdio.h>
3403 +#include <stdlib.h>
3404 +#include <string.h>
3405 +#include "libiscsi.h"
3406 +
3407 +int main(void)
3408 +{
3409 + struct libiscsi_network_config config;
3410 +
3411 + if (libiscsi_get_firmware_network_config(&config)) {
3412 + fprintf(stderr, "No iscsi boot firmware found\n");
3413 + return 1;
3414 + }
3415 +
3416 + printf("dhcp:\t%d\n", config.dhcp);
3417 + printf("iface:\t%s\n", config.iface_name);
3418 + printf("mac:\t%s\n", config.mac_address);
3419 + printf("ipaddr:\t%s\n", config.ip_address);
3420 + printf("mask:\t%s\n", config.netmask);
3421 + printf("gate:\t%s\n", config.gateway);
3422 + printf("dns1:\t%s\n", config.primary_dns);
3423 + printf("dns2:\t%s\n", config.secondary_dns);
3424 +
3425 + return 0;
3426 +}
3427 diff --git a/libiscsi/tests/test_login.c b/libiscsi/tests/test_login.c
3428 new file mode 100644
3429 index 0000000..3eb70d6
3430 --- /dev/null
3431 +++ b/libiscsi/tests/test_login.c
3432 @@ -0,0 +1,52 @@
3433 +/*
3434 + * iSCSI Administration library
3435 + *
3436 + * Copyright (C) 2008-2009 Red Hat, Inc. All rights reserved.
3437 + * Copyright (C) 2008-2009 Hans de Goede <hdegoede@redhat.com>
3438 + * maintained by open-iscsi@googlegroups.com
3439 + *
3440 + * This program is free software; you can redistribute it and/or modify
3441 + * it under the terms of the GNU General Public License as published
3442 + * by the Free Software Foundation; either version 2 of the License, or
3443 + * (at your option) any later version.
3444 + *
3445 + * This program is distributed in the hope that it will be useful, but
3446 + * WITHOUT ANY WARRANTY; without even the implied warranty of
3447 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
3448 + * General Public License for more details.
3449 + *
3450 + * See the file COPYING included with this distribution for more details.
3451 + */
3452 +
3453 +#include <stdio.h>
3454 +#include <stdlib.h>
3455 +#include <string.h>
3456 +#include "libiscsi.h"
3457 +
3458 +int main(void)
3459 +{
3460 + struct libiscsi_node node;
3461 + struct libiscsi_context *context;
3462 + int rc = 0;
3463 +
3464 + snprintf(node.name, LIBISCSI_VALUE_MAXLEN, "%s",
3465 + "iqn.2009-01.com.example:testdisk");
3466 + node.tpgt = 1;
3467 + snprintf(node.address, NI_MAXHOST, "%s", "127.0.0.1");
3468 + node.port = 3260;
3469 +
3470 + context = libiscsi_init();
3471 + if (!context) {
3472 + fprintf(stderr, "Error initializing libiscsi\n");
3473 + return 1;
3474 + }
3475 +
3476 + rc = libiscsi_node_login(context, &node);
3477 + if (rc)
3478 + fprintf(stderr, "Error logging in: %s\n",
3479 + libiscsi_get_error_string(context));
3480 +
3481 + libiscsi_cleanup(context);
3482 +
3483 + return rc;
3484 +}
3485 diff --git a/libiscsi/tests/test_logout.c b/libiscsi/tests/test_logout.c
3486 new file mode 100644
3487 index 0000000..b734dca
3488 --- /dev/null
3489 +++ b/libiscsi/tests/test_logout.c
3490 @@ -0,0 +1,51 @@
3491 +/*
3492 + * iSCSI Administration library
3493 + *
3494 + * Copyright (C) 2008-2009 Red Hat, Inc. All rights reserved.
3495 + * Copyright (C) 2008-2009 Hans de Goede <hdegoede@redhat.com>
3496 + * maintained by open-iscsi@googlegroups.com
3497 + *
3498 + * This program is free software; you can redistribute it and/or modify
3499 + * it under the terms of the GNU General Public License as published
3500 + * by the Free Software Foundation; either version 2 of the License, or
3501 + * (at your option) any later version.
3502 + *
3503 + * This program is distributed in the hope that it will be useful, but
3504 + * WITHOUT ANY WARRANTY; without even the implied warranty of
3505 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
3506 + * General Public License for more details.
3507 + *
3508 + * See the file COPYING included with this distribution for more details.
3509 + */
3510 +
3511 +#include <stdio.h>
3512 +#include <stdlib.h>
3513 +#include "libiscsi.h"
3514 +
3515 +int main(void)
3516 +{
3517 + struct libiscsi_node node;
3518 + struct libiscsi_context *context;
3519 + int rc = 0;
3520 +
3521 + snprintf(node.name, LIBISCSI_VALUE_MAXLEN, "%s",
3522 + "iqn.2009-01.com.example:testdisk");
3523 + node.tpgt = 1;
3524 + snprintf(node.address, NI_MAXHOST, "%s", "127.0.0.1");
3525 + node.port = 3260;
3526 +
3527 + context = libiscsi_init();
3528 + if (!context) {
3529 + fprintf(stderr, "Error initializing libiscsi\n");
3530 + return 1;
3531 + }
3532 +
3533 + rc = libiscsi_node_logout(context, &node);
3534 + if (rc)
3535 + fprintf(stderr, "Error logging out: %s\n",
3536 + libiscsi_get_error_string(context));
3537 +
3538 + libiscsi_cleanup(context);
3539 +
3540 + return rc;
3541 +}
3542 diff --git a/libiscsi/tests/test_params.c b/libiscsi/tests/test_params.c
3543 new file mode 100644
3544 index 0000000..d3223be
3545 --- /dev/null
3546 +++ b/libiscsi/tests/test_params.c
3547 @@ -0,0 +1,103 @@
3548 +/*
3549 + * iSCSI Administration library
3550 + *
3551 + * Copyright (C) 2008-2009 Red Hat, Inc. All rights reserved.
3552 + * Copyright (C) 2008-2009 Hans de Goede <hdegoede@redhat.com>
3553 + * maintained by open-iscsi@googlegroups.com
3554 + *
3555 + * This program is free software; you can redistribute it and/or modify
3556 + * it under the terms of the GNU General Public License as published
3557 + * by the Free Software Foundation; either version 2 of the License, or
3558 + * (at your option) any later version.
3559 + *
3560 + * This program is distributed in the hope that it will be useful, but
3561 + * WITHOUT ANY WARRANTY; without even the implied warranty of
3562 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
3563 + * General Public License for more details.
3564 + *
3565 + * See the file COPYING included with this distribution for more details.
3566 + */
3567 +
3568 +#include <stdio.h>
3569 +#include <stdlib.h>
3570 +#include <errno.h>
3571 +#include <string.h>
3572 +#include "libiscsi.h"
3573 +
3574 +int main(void)
3575 +{
3576 + struct libiscsi_node node;
3577 + struct libiscsi_context *context;
3578 + char orig_value[LIBISCSI_VALUE_MAXLEN], value[LIBISCSI_VALUE_MAXLEN];
3579 + int rc = 0;
3580 +
3581 + snprintf(node.name, LIBISCSI_VALUE_MAXLEN, "%s",
3582 + "iqn.2009-01.com.example:testdisk");
3583 + node.tpgt = 1;
3584 + snprintf(node.address, NI_MAXHOST, "%s", "127.0.0.1");
3585 + node.port = 3260;
3586 +
3587 + context = libiscsi_init();
3588 + if (!context) {
3589 + fprintf(stderr, "Error initializing libiscsi\n");
3590 + return 1;
3591 + }
3592 +
3593 + rc = libiscsi_node_get_parameter(context, &node, "node.startup",
3594 + orig_value);
3595 + if (rc) {
3596 + fprintf(stderr, "Error getting original value: %s\n",
3597 + libiscsi_get_error_string(context));
3598 + goto leave;
3599 + }
3600 +
3601 + rc = libiscsi_node_set_parameter(context, &node, "node.startup",
3602 + "automatic");
3603 + if (rc) {
3604 + fprintf(stderr, "Error setting node startup param: %s\n",
3605 + libiscsi_get_error_string(context));
3606 + goto leave;
3607 + }
3608 +
3609 + rc = libiscsi_node_get_parameter(context, &node, "node.startup",
3610 + value);
3611 + if (rc) {
3612 + fprintf(stderr, "Error getting node startup param: %s\n",
3613 + libiscsi_get_error_string(context));
3614 + goto leave;
3615 + }
3616 +
3617 + if (strcmp(value, "automatic")) {
3618 + fprintf(stderr, "Error set and get values do not match!\n");
3619 + rc = EIO;
3620 + goto leave;
3621 + }
3622 +
3623 + rc = libiscsi_node_set_parameter(context, &node, "node.startup",
3624 + orig_value);
3625 + if (rc) {
3626 + fprintf(stderr, "Error setting original value: %s\n",
3627 + libiscsi_get_error_string(context));
3628 + goto leave;
3629 + }
3630 +
3631 + rc = libiscsi_node_get_parameter(context, &node, "node.startup",
3632 + value);
3633 + if (rc) {
3634 + fprintf(stderr, "Error re-getting original value: %s\n",
3635 + libiscsi_get_error_string(context));
3636 + goto leave;
3637 + }
3638 +
3639 + if (strcmp(value, orig_value)) {
3640 + fprintf(stderr,
3641 + "Error set and get original values do not match!\n");
3642 + rc = EIO;
3643 + goto leave;
3644 + }
3645 +
3646 +leave:
3647 + libiscsi_cleanup(context);
3648 +
3649 + return rc;
3650 +}
3651 diff --git a/libiscsi/tests/test_set_auth.c b/libiscsi/tests/test_set_auth.c
3652 new file mode 100644
3653 index 0000000..a21f888
3654 --- /dev/null
3655 +++ b/libiscsi/tests/test_set_auth.c
3656 @@ -0,0 +1,58 @@
3657 +/*
3658 + * iSCSI Administration library
3659 + *
3660 + * Copyright (C) 2008-2009 Red Hat, Inc. All rights reserved.
3661 + * Copyright (C) 2008-2009 Hans de Goede <hdegoede@redhat.com>
3662 + * maintained by open-iscsi@googlegroups.com
3663 + *
3664 + * This program is free software; you can redistribute it and/or modify
3665 + * it under the terms of the GNU General Public License as published
3666 + * by the Free Software Foundation; either version 2 of the License, or
3667 + * (at your option) any later version.
3668 + *
3669 + * This program is distributed in the hope that it will be useful, but
3670 + * WITHOUT ANY WARRANTY; without even the implied warranty of
3671 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
3672 + * General Public License for more details.
3673 + *
3674 + * See the file COPYING included with this distribution for more details.
3675 + */
3676 +
3677 +#include <stdio.h>
3678 +#include <stdlib.h>
3679 +#include <string.h>
3680 +#include "libiscsi.h"
3681 +
3682 +int main(void)
3683 +{
3684 + struct libiscsi_node node;
3685 + struct libiscsi_context *context;
3686 + struct libiscsi_auth_info auth_info;
3687 + int rc = 0;
3688 +
3689 + snprintf(node.name, LIBISCSI_VALUE_MAXLEN, "%s",
3690 + "iqn.2009-01.com.example:testdisk");
3691 + node.tpgt = 1;
3692 + snprintf(node.address, NI_MAXHOST, "%s", "127.0.0.1");
3693 + node.port = 3260;
3694 +
3695 + memset(&auth_info, 0, sizeof(auth_info));
3696 + auth_info.method = libiscsi_auth_chap;
3697 + strcpy(auth_info.chap.username, "joe");
3698 + strcpy(auth_info.chap.password, "secret");
3699 +
3700 + context = libiscsi_init();
3701 + if (!context) {
3702 + fprintf(stderr, "Error initializing libiscsi\n");
3703 + return 1;
3704 + }
3705 +
3706 + rc = libiscsi_node_set_auth(context, &node, &auth_info);
3707 + if (rc)
3708 + fprintf(stderr, "Error setting authinfo: %s\n",
3709 + libiscsi_get_error_string(context));
3710 +
3711 + libiscsi_cleanup(context);
3712 +
3713 + return rc;
3714 +}
3715 diff --git a/usr/discovery.c b/usr/discovery.c
3716 index 381f825..2233de7 100644
3717 --- a/usr/discovery.c
3718 +++ b/usr/discovery.c
3719 @@ -36,6 +36,7 @@
3720 #include "types.h"
3721 #include "iscsi_proto.h"
3722 #include "initiator.h"
3723 +#include "config.h"
3724 #include "log.h"
3725 #include "idbm.h"
3726 #include "iscsi_settings.h"
3727 diff --git a/usr/iscsi_ipc.h b/usr/iscsi_ipc.h
3728 index 74ef948..713914f 100644
3729 --- a/usr/iscsi_ipc.h
3730 +++ b/usr/iscsi_ipc.h
3731 @@ -111,4 +111,6 @@ struct iscsi_ipc {
3732 int (*recv_pdu_end) (struct iscsi_conn *conn);
3733 };
3734
3735 +struct iscsi_ipc *ipc;
3736 +
3737 #endif /* ISCSI_IPC_H */