]>
Commit | Line | Data |
---|---|---|
cdd964e9 MT |
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 | + ¶meter, &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, ¶meter)) | |
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 */ |