2 * Amanda, The Advanced Maryland Automatic Network Disk Archiver
3 * Copyright (c) 1991-1998 University of Maryland at College Park
6 * Permission to use, copy, modify, distribute, and sell this software and its
7 * documentation for any purpose is hereby granted without fee, provided that
8 * the above copyright notice appear in all copies and that both that
9 * copyright notice and this permission notice appear in supporting
10 * documentation, and that the name of U.M. not be used in advertising or
11 * publicity pertaining to distribution of the software without specific,
12 * written prior permission. U.M. makes no representations about the
13 * suitability of this software for any purpose. It is provided "as is"
14 * without express or implied warranty.
16 * U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M.
18 * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
20 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
21 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
23 * Author: James da Silva, Systems Design and Analysis Group
24 * Computer Science Department
25 * University of Maryland at College Park
28 * $Id: diskfile.c,v 1.95 2006/07/26 15:17:37 martinea Exp $
40 static am_host_t *hostlist;
41 static netif_t *all_netifs;
44 static char *upcase(char *st);
45 static int parse_diskline(disklist_t *, const char *, FILE *, int *, char **);
46 static void disk_parserror(const char *, int, const char *, ...)
61 lst->head = lst->tail = NULL;
64 /* if we already have config errors, then don't bother */
65 if (config_errors(NULL) >= CFGERR_ERRORS) {
66 return config_errors(NULL);
69 if ((diskf = fopen(filename, "r")) == NULL) {
70 config_add_error(CFGERR_ERRORS,
71 vstrallocf(_("Could not open '%s': %s"), filename, strerror(errno)));
76 while ((line = agets(diskf)) != NULL) {
78 if (line[0] != '\0') {
79 if (parse_diskline(lst, filename, diskf, &line_num, &line) < 0) {
89 return config_errors(NULL);
98 for (p = hostlist; p != NULL; p = p->next) {
99 if(strcasecmp(p->hostname, hostname) == 0) return p;
106 const char *hostname,
107 const char *diskname)
112 host = lookup_host(hostname);
116 for (disk = host->disks; disk != NULL; disk = disk->hostnext) {
117 if (strcmp(disk->name, diskname) == 0)
125 * put disk on end of queue
133 if(list->tail == NULL) list->head = disk;
134 else list->tail->next = disk;
135 disk->prev = list->tail;
143 * put disk on head of queue
151 if(list->head == NULL) list->tail = disk;
152 else list->head->prev = disk;
153 disk->next = list->head;
161 * insert in sorted order
168 int (*cmp)(disk_t *a, disk_t *b))
176 if(cmp(disk, ptr) < 0) break;
183 if(prev == NULL) list->head = disk;
184 else prev->next = disk;
185 if(ptr == NULL) list->tail = disk;
186 else ptr->prev = disk;
198 disk = alloc(SIZEOF(disk_t));
199 bzero(disk, SIZEOF(disk_t));
201 disk->allow_split = 0;
202 disk->splitsize = (off_t)0;
203 disk->tape_splitsize = (off_t)0;
204 disk->split_diskbuffer = NULL;
205 disk->fallback_splitsize = (off_t)0;
206 disk->hostname = stralloc(hostname);
207 disk->name = stralloc(diskname);
208 disk->device = stralloc(diskname);
211 disk->compress = COMP_NONE;
212 disk->encrypt = ENCRYPT_NONE;
216 disk->exclude_list = NULL;
217 disk->exclude_file = NULL;
218 disk->include_list = NULL;
219 disk->include_file = NULL;
220 disk->application = NULL;
221 disk->pp_scriptlist = NULL;
223 host = lookup_host(hostname);
225 host = alloc(SIZEOF(am_host_t));
226 host->next = hostlist;
229 host->hostname = stralloc(hostname);
231 host->inprogress = 0;
236 host->features = NULL;
237 host->pre_script = 0;
238 host->post_script = 0;
240 enqueue_disk(list, disk);
243 disk->hostnext = host->disks;
251 * check if disk is present in list. Return true if so, false otherwise.
262 while ((t != NULL) && (t != disk)) {
277 int (*cmp)(disk_t *a, disk_t *b))
282 tmp = in; /* just in case in == out */
284 out->head = (disk_t *)0;
285 out->tail = (disk_t *)0;
287 while((disk = dequeue_disk(tmp)))
288 insert_disk(out, disk, cmp);
293 * remove disk from front of queue
302 if(list->head == NULL) return NULL;
305 list->head = disk->next;
307 if(list->head == NULL) list->tail = NULL;
308 else list->head->prev = NULL;
310 disk->prev = disk->next = NULL; /* for debugging */
319 if(disk->prev == NULL) list->head = disk->next;
320 else disk->prev->next = disk->next;
322 if(disk->next == NULL) list->tail = disk->prev;
323 else disk->next->prev = disk->prev;
325 disk->prev = disk->next = NULL;
333 am_host_t *host, *hostnext;
334 netif_t *netif, *next_if;
336 while (dl->head != NULL) {
337 dp = dequeue_disk(dl);
339 amfree(dp->hostname);
341 free_sl(dp->exclude_file);
342 free_sl(dp->exclude_list);
343 free_sl(dp->include_file);
344 free_sl(dp->include_list);
348 for(host=hostlist; host != NULL; host = hostnext) {
349 amfree(host->hostname);
350 am_release_feature_set(host->features);
351 host->features = NULL;
352 hostnext = host->next;
357 for (netif = all_netifs; netif != NULL; netif = next_if) {
358 next_if = netif->next;
371 if(islower((int)*s)) *s = (char)toupper((int)*s);
378 /* return 0 on success */
379 /* return -1 on error */
383 const char *filename,
386 /*@keep@*/ char ** line_p)
391 netif_t *netif = NULL;
392 interface_t *cfg_if = NULL;
393 char *hostname = NULL;
394 char *diskname, *diskdevice;
398 char *line = *line_p;
399 int line_num = *line_num_p;
407 assert(filename != NULL);
408 assert(line_num > 0);
409 assert(line != NULL);
413 skip_whitespace(s, ch);
414 if(ch == '\0' || ch == '#')
418 skip_non_whitespace(s, ch);
420 host = lookup_host(fp);
422 hostname = stralloc(fp);
424 hostname = stralloc(host->hostname);
425 if (strcmp(host->hostname, fp) != 0) {
426 disk_parserror(filename, line_num, _("Same host with different case: \"%s\" and \"%s\"."), host->hostname, fp);
431 shost = sanitise_filename(hostname);
432 for (p = hostlist; p != NULL; p = p->next) {
433 char *shostp = sanitise_filename(p->hostname);
434 if (strcmp(hostname, p->hostname) &&
435 !strcmp(shost, shostp)) {
436 disk_parserror(filename, line_num, _("Two hosts are mapping to the same name: \"%s\" and \"%s\""), p->hostname, hostname);
439 else if (strcasecmp(hostname, p->hostname) &&
440 match_host(hostname, p->hostname) &&
441 match_host(p->hostname, hostname)) {
442 disk_parserror(filename, line_num, _("Duplicate host name: \"%s\" and \"%s\""), p->hostname, hostname);
449 skip_whitespace(s, ch);
450 if(ch == '\0' || ch == '#') {
451 disk_parserror(filename, line_num, _("disk device name expected"));
457 skip_quoted_string(s, ch);
459 diskname = unquote_string(fp);
460 if (strlen(diskname) == 0) {
461 disk_parserror(filename, line_num, _("invalid empty diskname"));
465 skip_whitespace(s, ch);
466 if(ch == '\0' || ch == '#') {
467 disk_parserror(filename, line_num, _("disk dumptype expected"));
473 skip_quoted_string(s, ch);
480 dumptype = unquote_string(fp);
481 if (strlen(dumptype) == 0) {
482 disk_parserror(filename, line_num, _("invalid empty diskdevice"));
486 if ((dtype = lookup_dumptype(dumptype)) == NULL) {
487 diskdevice = dumptype;
488 skip_whitespace(s, ch);
489 if(ch == '\0' || ch == '#') {
490 disk_parserror(filename, line_num,
491 _("disk dumptype '%s' not found"), dumptype);
499 skip_quoted_string(s, ch);
502 dumptype = unquote_string(fp);
507 /* check for duplicate disk */
510 if ((disk = lookup_disk(hostname, diskname)) != NULL) {
516 a1 = clean_regex(diskname, 1);
517 a2 = clean_regex(disk->name, 1);
519 if (match_disk(a1, disk->name) && match_disk(a2, diskname)) {
522 disk = disk->hostnext;
527 while (dup == 0 && disk != NULL);
530 disk_parserror(filename, line_num,
531 _("duplicate disk record, previous on line %d"),
536 disk = alloc(SIZEOF(disk_t));
537 disk->line = line_num;
538 disk->hostname = hostname;
539 disk->name = diskname;
540 disk->device = diskdevice;
543 disk->inprogress = 0;
544 disk->application = NULL;
545 disk->pp_scriptlist = NULL;
546 disk->dataport_list = NULL;
550 sdisk = sanitise_filename(diskname);
551 for (dp = host->disks; dp != NULL; dp = dp->hostnext) {
552 char *sdiskp = sanitise_filename(dp->name);
553 if (strcmp(diskname, dp->name) != 0 &&
554 strcmp(sdisk, sdiskp) == 0) {
555 disk_parserror(filename, line_num,
556 _("Two disks are mapping to the same name: \"%s\" and \"%s\"; you must use different diskname"),
568 skip_whitespace(s, ch);
569 if (ch != '\0' && ch != '#') {
570 disk_parserror(filename, line_num,
571 _("expected line break after `{\', ignoring rest of line"));
574 if (strchr(s-1, '}') &&
575 (strchr(s-1, '#') == NULL ||
576 strchr(s-1, '}') < strchr(s-1, '#'))) {
577 disk_parserror(filename, line_num,_("'}' on same line than '{'"));
580 amfree(disk->device);
589 dtype = read_dumptype(vstralloc("custom(", hostname,
590 ":", disk->name, ")",
591 ".", anonymous_value(), NULL),
592 diskf, (char*)filename, line_num_p);
593 if (dtype == NULL || dup) {
594 disk_parserror(filename, line_num,
595 _("read of custom dumptype failed"));
598 amfree(disk->device);
609 *line_p = line = agets(diskf);
610 line_num = *line_num_p; /* no incr, read_dumptype did it already */
613 *line_p = line = stralloc("");
617 if((dtype = lookup_dumptype(dumptype)) == NULL) {
618 char *qdt = quote_string(dumptype);
620 disk_parserror(filename, line_num, _("undefined dumptype `%s'"), qdt);
624 amfree(disk->device);
637 /* disk_parserror already called, above */
638 g_assert(config_errors(NULL) != CFGERR_OK);
645 disk->dtype_name = dumptype_name(dtype);
646 disk->config = dtype;
647 disk->program = dumptype_get_program(dtype);
648 disk->exclude_list = duplicate_sl(dumptype_get_exclude(dtype).sl_list);
649 disk->exclude_file = duplicate_sl(dumptype_get_exclude(dtype).sl_file);
650 disk->exclude_optional = dumptype_get_exclude(dtype).optional;
651 disk->include_list = duplicate_sl(dumptype_get_include(dtype).sl_list);
652 disk->include_file = duplicate_sl(dumptype_get_include(dtype).sl_file);
653 disk->include_optional = dumptype_get_include(dtype).optional;
654 disk->priority = dumptype_get_priority(dtype);
655 disk->dumpcycle = dumptype_get_dumpcycle(dtype);
656 /* disk->frequency = dumptype_get_frequency(dtype);*/
657 disk->auth = dumptype_get_auth(dtype);
658 disk->maxdumps = dumptype_get_maxdumps(dtype);
659 disk->allow_split = dumptype_get_allow_split(dtype);
660 disk->tape_splitsize = dumptype_get_tape_splitsize(dtype);
661 disk->split_diskbuffer = dumptype_get_split_diskbuffer(dtype);
662 disk->fallback_splitsize = dumptype_get_fallback_splitsize(dtype);
663 if (disk->allow_split) {
664 tapetype_t *tapetype = lookup_tapetype(getconf_str(CNF_TAPETYPE));
665 disk->splitsize = tapetype_get_part_size(tapetype);
667 disk->splitsize = disk->tape_splitsize;
669 disk->maxpromoteday = dumptype_get_maxpromoteday(dtype);
670 disk->bumppercent = dumptype_get_bumppercent(dtype);
671 disk->bumpsize = dumptype_get_bumpsize(dtype);
672 disk->bumpdays = dumptype_get_bumpdays(dtype);
673 disk->bumpmult = dumptype_get_bumpmult(dtype);
674 disk->starttime = dumptype_get_starttime(dtype);
675 disk->application = dumptype_get_application(dtype);
676 disk->pp_scriptlist = dumptype_get_scriptlist(dtype);
678 if (disk->starttime > 0) {
681 stm = localtime(&st);
682 disk->start_t -= stm->tm_sec + 60 * stm->tm_min + 3600 * stm->tm_hour;
683 disk->start_t += disk->starttime / 100 * 3600 +
684 disk->starttime % 100 * 60;
685 if ((disk->start_t - st) < -43200)
686 disk->start_t += 86400;
688 disk->strategy = dumptype_get_strategy(dtype);
689 disk->ignore = dumptype_get_ignore(dtype);
690 disk->estimatelist = dumptype_get_estimatelist(dtype);
691 disk->compress = dumptype_get_compress(dtype);
692 disk->srvcompprog = dumptype_get_srvcompprog(dtype);
693 disk->clntcompprog = dumptype_get_clntcompprog(dtype);
694 disk->encrypt = dumptype_get_encrypt(dtype);
695 disk->srv_decrypt_opt = dumptype_get_srv_decrypt_opt(dtype);
696 disk->clnt_decrypt_opt = dumptype_get_clnt_decrypt_opt(dtype);
697 disk->srv_encrypt = dumptype_get_srv_encrypt(dtype);
698 disk->clnt_encrypt = dumptype_get_clnt_encrypt(dtype);
699 disk->amandad_path = dumptype_get_amandad_path(dtype);
700 disk->client_username = dumptype_get_client_username(dtype);
701 disk->client_port = dumptype_get_client_port(dtype);
702 disk->ssh_keys = dumptype_get_ssh_keys(dtype);
703 disk->comprate[0] = dumptype_get_comprate(dtype)[0];
704 disk->comprate[1] = dumptype_get_comprate(dtype)[1];
705 disk->data_path = dumptype_get_data_path(dtype);
708 * Boolean parameters with no value (Appears here as value 2) defaults
709 * to TRUE for backward compatibility and for logical consistency.
711 disk->record = dumptype_get_record(dtype) != 0;
712 disk->skip_incr = dumptype_get_skip_incr(dtype) != 0;
713 disk->skip_full = dumptype_get_skip_full(dtype) != 0;
714 disk->to_holdingdisk = dumptype_get_to_holdingdisk(dtype);
715 disk->kencrypt = dumptype_get_kencrypt(dtype) != 0;
716 disk->index = dumptype_get_index(dtype) != 0;
720 skip_whitespace(s, ch);
722 if(ch && ch != '#') { /* get optional spindle number */
726 skip_non_whitespace(s, ch);
729 if (*fp1 == '-') fp1++;
730 for(;*fp1!='\0';fp1++) {
731 if(!isdigit((int)*fp1)) {
736 disk_parserror(filename, line_num, _("non-integer spindle `%s'"), fp);
742 disk->spindle = atoi(fp);
746 skip_whitespace(s, ch);
748 if(ch && ch != '#') { /* get optional network interface */
749 skip_non_whitespace(s, ch);
751 if((cfg_if = lookup_interface(upcase(fp))) == NULL) {
752 disk_parserror(filename, line_num,
753 _("undefined network interface `%s'"), fp);
760 cfg_if = lookup_interface("default");
763 /* see if we already have a netif_t for this interface */
764 for (netif = all_netifs; netif != NULL; netif = netif->next) {
765 if (netif->config == cfg_if)
769 /* nope; make up a new one */
771 netif = alloc(sizeof(*netif));
772 netif->next = all_netifs;
774 netif->config = cfg_if;
778 skip_whitespace(s, ch);
779 if(ch && ch != '#') { /* now we have garbage, ignore it */
780 disk_parserror(filename, line_num, _("end of line expected"));
783 if (disk->program && disk->application &&
784 strcmp(disk->program,"APPLICATION")) {
785 disk_parserror(filename, line_num,
786 _("Both program and application set"));
789 if (disk->program && strcmp(disk->program,"APPLICATION")==0 &&
790 !disk->application) {
791 disk_parserror(filename, line_num,
792 _("program set to APPLICATION but no application set"));
795 if (disk->application) {
796 application_t *application;
799 application = lookup_application(disk->application);
800 g_assert(application != NULL);
801 plugin = application_get_plugin(application);
802 if (!plugin || strlen(plugin) == 0) {
803 disk_parserror(filename, line_num,
804 _("plugin not set for application"));
808 for (pp_iter = disk->pp_scriptlist; pp_iter != NULL;
809 pp_iter = pp_iter->next) {
810 pp_script_t *pp_script;
812 char *pp_script_name;
814 pp_script_name = (char*)pp_iter->data;
815 pp_script = lookup_pp_script(pp_script_name);
816 g_assert(pp_script != NULL);
817 plugin = pp_script_get_plugin(pp_script);
818 if (!plugin || strlen(plugin) == 0) {
819 disk_parserror(filename, line_num, _("plugin not set for script"));
823 /* success, add disk to lists */
825 if(host == NULL) { /* new host */
826 host = alloc(SIZEOF(am_host_t));
827 host->next = hostlist;
830 host->hostname = stralloc(hostname);
833 host->inprogress = 0;
834 host->maxdumps = 1; /* will be overwritten */
838 host->features = NULL;
839 host->pre_script = 0;
840 host->post_script = 0;
845 enqueue_disk(lst, disk);
848 disk->hostnext = host->disks;
850 host->maxdumps = disk->maxdumps;
856 printf_arglist_function2(void disk_parserror, const char *, filename,
857 int, line_num, const char *, format)
863 /* format the error message and hand it off to conffile */
865 arglist_start(argp, format);
866 msg = g_strdup_vprintf(format, argp);
867 errstr = g_strdup_printf("\"%s\", line %d: %s", filename, line_num, msg);
871 config_add_error(CFGERR_ERRORS, errstr);
879 int npr, /* we print first npr disks on queue, plus last two */
887 g_fprintf(f, _("%s QUEUE: empty\n"), st);
890 g_fprintf(f, _("%s QUEUE:\n"), st);
891 for(pos = 0, d = q.head, p = NULL; d != NULL; p = d, d = d->next, pos++) {
892 qname = quote_string(d->name);
893 if(pos < npr) g_fprintf(f, "%3d: %-10s %-4s\n",
894 pos, d->host->hostname, qname);
898 if(pos > npr+2) g_fprintf(f, " ...\n");
901 g_fprintf(f, "%3d: %-10s %-4s\n", pos-2, d->host->hostname, d->name);
904 g_fprintf(f, "%3d: %-10s %-4s\n", pos-1, d->host->hostname, d->name);
915 am_feature_t *their_features = dp->host->features;
918 assert(dp->host != NULL);
920 errarray = g_ptr_array_new();
922 if (!am_has_feature(their_features, fe_options_auth)) {
923 if (strcasecmp(dp->auth, "bsd") == 0)
924 if (!am_has_feature(their_features, fe_options_bsd_auth))
925 g_ptr_array_add(errarray, _("does not support auth"));
928 switch(dp->compress) {
930 if (!am_has_feature(their_features, fe_options_compress_fast)) {
931 g_ptr_array_add(errarray, _("does not support fast compression"));
935 if (!am_has_feature(their_features, fe_options_compress_best)) {
936 g_ptr_array_add(errarray, _("does not support best compression"));
940 if (am_has_feature(their_features, fe_options_compress_cust)) {
941 if (dp->clntcompprog == NULL || strlen(dp->clntcompprog) == 0) {
942 g_ptr_array_add(errarray, _("client custom compression with no compression program specified"));
945 g_ptr_array_add(errarray, _("does not support client custom compression"));
948 case COMP_SERVER_FAST:
950 case COMP_SERVER_BEST:
952 case COMP_SERVER_CUST:
953 if (dp->srvcompprog == NULL || strlen(dp->srvcompprog) == 0) {
954 g_ptr_array_add(errarray, _("server custom compression with no compression program specified"));
959 switch(dp->encrypt) {
961 if (am_has_feature(their_features, fe_options_encrypt_cust)) {
962 if (dp->clnt_decrypt_opt) {
963 if (!am_has_feature(their_features, fe_options_client_decrypt_option)) {
964 g_ptr_array_add(errarray, _("does not support client decrypt option"));
967 if (dp->clnt_encrypt == NULL || strlen(dp->clnt_encrypt) == 0) {
968 g_ptr_array_add(errarray, _("encrypt client with no encryption program specified"));
970 if (dp->compress == COMP_SERVER_FAST ||
971 dp->compress == COMP_SERVER_BEST ||
972 dp->compress == COMP_SERVER_CUST ) {
973 g_ptr_array_add(errarray, _("Client encryption with server compression is not supported. See amanda.conf(5) for detail"));
976 g_ptr_array_add(errarray, _("does not support client data encryption"));
979 case ENCRYPT_SERV_CUST:
980 if (dp->srv_encrypt == NULL || strlen(dp->srv_encrypt) == 0) {
981 g_ptr_array_add(errarray, _("No encryption program specified in dumptypes, Change the dumptype in the disklist or mention the encryption program to use in the dumptypes file"));
987 if (!am_has_feature(their_features, fe_options_no_record)) {
988 g_ptr_array_add(errarray, _("does not support no record"));
993 if (!am_has_feature(their_features, fe_options_index)) {
994 g_ptr_array_add(errarray, _("does not support index"));
999 if (!am_has_feature(their_features, fe_options_kencrypt)) {
1000 g_ptr_array_add(errarray, _("does not support kencrypt"));
1005 if (dp->exclude_file != NULL && dp->exclude_file->nb_element > 0) {
1006 nb_exclude = dp->exclude_file->nb_element;
1007 if (!am_has_feature(their_features, fe_options_exclude_file)) {
1008 g_ptr_array_add(errarray, _("does not support exclude file"));
1012 if (dp->exclude_list != NULL && dp->exclude_list->nb_element > 0) {
1013 nb_exclude += dp->exclude_list->nb_element;
1014 if (!am_has_feature(their_features, fe_options_exclude_list)) {
1015 g_ptr_array_add(errarray, _("does not support exclude list"));
1019 if (nb_exclude > 1 &&
1020 !am_has_feature(their_features, fe_options_multiple_exclude)) {
1021 g_ptr_array_add(errarray, _("does not support multiple exclude"));
1025 if (dp->include_file != NULL && dp->include_file->nb_element > 0) {
1026 nb_include = dp->include_file->nb_element;
1027 if (!am_has_feature(their_features, fe_options_include_file)) {
1028 g_ptr_array_add(errarray, ("does not support include file"));
1032 if (dp->include_list != NULL && dp->include_list->nb_element > 0) {
1033 nb_include += dp->include_list->nb_element;
1034 if (!am_has_feature(their_features, fe_options_include_list)) {
1035 g_ptr_array_add(errarray, _("does not support include list"));
1039 if (nb_include > 1 &&
1040 !am_has_feature(their_features, fe_options_multiple_exclude)) {
1041 g_ptr_array_add(errarray, _("does not support multiple include"));
1044 if (dp->exclude_optional) {
1045 if (!am_has_feature(their_features, fe_options_optional_exclude)) {
1046 g_ptr_array_add(errarray, _("does not support optional exclude"));
1049 if (dp->include_optional) {
1050 if (!am_has_feature(their_features, fe_options_optional_include)) {
1051 g_ptr_array_add(errarray, _("does not support optional include"));
1062 char *auth_opt = NULL;
1063 char *kencrypt_opt = "";
1064 char *compress_opt = "";
1065 char *encrypt_opt = stralloc("");
1066 char *decrypt_opt = stralloc("");
1067 char *record_opt = "";
1068 char *index_opt = "";
1069 char *exclude_file = NULL;
1070 char *exclude_list = NULL;
1071 char *include_file = NULL;
1072 char *include_list = NULL;
1073 char *excl_opt = "";
1074 char *incl_opt = "";
1076 char *result = NULL;
1080 am_feature_t *their_features = dp->host->features;
1083 assert(dp->host != NULL);
1085 qdpname = quote_string(dp->name);
1086 if (am_has_feature(their_features, fe_options_auth)) {
1087 auth_opt = vstralloc("auth=", dp->auth, ";", NULL);
1088 } else if(strcasecmp(dp->auth, "bsd") == 0) {
1089 if(am_has_feature(their_features, fe_options_bsd_auth))
1090 auth_opt = stralloc("bsd-auth;");
1093 switch(dp->compress) {
1095 compress_opt = "compress-fast;";
1098 compress_opt = "compress-best;";
1101 compress_opt = vstralloc("comp-cust=", dp->clntcompprog, ";", NULL);
1103 case COMP_SERVER_FAST:
1104 compress_opt = "srvcomp-fast;";
1106 case COMP_SERVER_BEST:
1107 compress_opt = "srvcomp-best;";
1109 case COMP_SERVER_CUST:
1110 compress_opt = vstralloc("srvcomp-cust=", dp->srvcompprog, ";", NULL);
1114 switch(dp->encrypt) {
1116 encrypt_opt = newvstralloc(encrypt_opt, "encrypt-cust=",
1117 dp->clnt_encrypt, ";", NULL);
1118 if (dp->clnt_decrypt_opt) {
1119 decrypt_opt = newvstralloc(decrypt_opt, "client-decrypt-option=",
1120 dp->clnt_decrypt_opt, ";", NULL);
1123 case ENCRYPT_SERV_CUST:
1124 encrypt_opt = newvstralloc(encrypt_opt, "encrypt-serv-cust=",
1125 dp->srv_encrypt, ";", NULL);
1126 if (dp->srv_decrypt_opt) {
1127 decrypt_opt = newvstralloc(decrypt_opt, "server-decrypt-option=",
1128 dp->srv_decrypt_opt, ";", NULL);
1134 record_opt = "no-record;";
1138 index_opt = "index;";
1142 kencrypt_opt = "kencrypt;";
1145 exclude_file = stralloc("");
1146 if (dp->exclude_file != NULL && dp->exclude_file->nb_element > 0) {
1147 for(excl = dp->exclude_file->first; excl != NULL;
1148 excl = excl->next) {
1149 qname = quote_string(excl->name);
1150 exc = newvstralloc( exc, "exclude-file=", qname, ";", NULL);
1151 strappend(exclude_file, exc);
1155 exclude_list = stralloc("");
1156 if (dp->exclude_list != NULL && dp->exclude_list->nb_element > 0) {
1157 for(excl = dp->exclude_list->first; excl != NULL;
1158 excl = excl->next) {
1159 qname = quote_string(excl->name);
1160 exc = newvstralloc( exc, "exclude-list=", qname, ";", NULL);
1161 strappend(exclude_list, exc);
1166 include_file = stralloc("");
1167 if (dp->include_file != NULL && dp->include_file->nb_element > 0) {
1168 for(excl = dp->include_file->first; excl != NULL;
1169 excl = excl->next) {
1170 qname = quote_string(excl->name);
1171 exc = newvstralloc(exc, "include-file=", qname, ";", NULL);
1172 strappend(include_file, exc);
1176 include_list = stralloc("");
1177 if (dp->include_list != NULL && dp->include_list->nb_element > 0) {
1178 for(excl = dp->include_list->first; excl != NULL;
1179 excl = excl->next) {
1180 qname = quote_string(excl->name);
1181 exc = newvstralloc(exc, "include-list=", qname, ";", NULL);
1182 strappend(include_list, exc);
1187 if (dp->exclude_optional) {
1188 excl_opt = "exclude-optional;";
1190 if (dp->include_optional) {
1191 incl_opt = "include-optional;";
1194 result = vstralloc(";",
1211 amfree(exclude_list);
1212 amfree(exclude_file);
1213 amfree(include_file);
1214 amfree(include_list);
1216 amfree(decrypt_opt);
1217 amfree(encrypt_opt);
1219 /* result contains at least 'auth=...' */
1232 char *encrypt_opt = stralloc("");
1233 char *decrypt_opt = stralloc("");
1236 char *data_path_opt = stralloc("");
1237 char *exclude = stralloc("");
1238 char *exclude_file = NULL;
1239 char *exclude_list = NULL;
1240 char *include = stralloc("");
1241 char *include_file = NULL;
1242 char *include_list = NULL;
1243 char *excl_opt = "";
1244 char *incl_opt = "";
1247 char *result = NULL;
1251 am_feature_t *their_features = dp->host->features;
1254 assert(dp->host != NULL);
1256 qdpname = quote_string(dp->name);
1257 if (am_has_feature(their_features, fe_options_auth)) {
1258 auth_opt = vstralloc(" <auth>", dp->auth, "</auth>\n", NULL);
1260 auth_opt = stralloc("");
1263 switch(dp->compress) {
1265 compress_opt = stralloc(" <compress>FAST</compress>\n");
1268 compress_opt = stralloc(" <compress>BEST</compress>\n");
1271 compress_opt = vstralloc(" <compress>CUSTOM"
1272 "<custom-compress-program>",
1274 "</custom-compress-program>\n"
1275 " </compress>\n", NULL);
1277 case COMP_SERVER_FAST:
1278 compress_opt = stralloc(" <compress>SERVER-FAST</compress>\n");
1280 case COMP_SERVER_BEST:
1281 compress_opt = stralloc(" <compress>SERVER-BEST</compress>\n");
1283 case COMP_SERVER_CUST:
1284 compress_opt = vstralloc(" <compress>SERVER-CUSTOM"
1285 "<custom-compress-program>",
1287 "</custom-compress-program>\n"
1288 " </compress>\n", NULL);
1291 compress_opt = stralloc("");
1294 switch(dp->encrypt) {
1296 if (dp->clnt_decrypt_opt) {
1297 decrypt_opt = newvstralloc(decrypt_opt,
1298 " <decrypt-option>",
1299 dp->clnt_decrypt_opt,
1300 "</decrypt-option>\n", NULL);
1303 encrypt_opt = newvstralloc(encrypt_opt,
1305 "<custom-encrypt-program>",
1307 "</custom-encrypt-program>\n",
1309 " </encrypt>\n", NULL);
1312 case ENCRYPT_SERV_CUST:
1314 decrypt_opt = newvstralloc(decrypt_opt,
1315 " <decrypt-option>",
1316 dp->srv_decrypt_opt,
1317 "</decrypt-option>\n", NULL);
1318 encrypt_opt = newvstralloc(encrypt_opt,
1319 " <encrypt>SERVER-CUSTOM"
1320 "<custom-encrypt-program>",
1322 "</custom-encrypt-program>\n",
1324 " </encrypt>\n", NULL);
1330 record_opt = " <record>NO</record>\n";
1332 record_opt = " <record>YES</record>\n";
1336 index_opt = " <index>YES</index>\n";
1342 kencrypt_opt = " <kencrypt>YES</kencrypt>\n";
1347 if (am_has_feature(their_features, fe_xml_data_path)) {
1348 switch(dp->data_path) {
1349 case DATA_PATH_AMANDA:
1350 amfree(data_path_opt);
1351 data_path_opt = stralloc(" <datapath>AMANDA</datapath>\n");
1353 case DATA_PATH_DIRECTTCP:
1354 { /* dp->dataport_list is not set for selfcheck/sendsize */
1355 if (am_has_feature(their_features, fe_xml_directtcp_list)) {
1357 char *value, *b64value;
1359 amfree(data_path_opt);
1360 data_path_opt = stralloc(" <datapath>DIRECTTCP");
1361 if (dp->dataport_list) {
1362 s = sc = stralloc(dp->dataport_list);
1370 b64value = amxml_format_tag("directtcp", value);
1371 vstrextend(&data_path_opt, "\n ", b64value, NULL);
1375 strappend(data_path_opt, "\n ");
1377 strappend(data_path_opt, "</datapath>\n");
1384 exclude_file = stralloc("");
1385 if (dp->exclude_file != NULL && dp->exclude_file->nb_element > 0) {
1386 for(excl = dp->exclude_file->first; excl != NULL;
1387 excl = excl->next) {
1388 q64name = amxml_format_tag("file", excl->name);
1389 exc = newvstralloc( exc, " ", q64name, "\n", NULL);
1390 strappend(exclude_file, exc);
1394 exclude_list = stralloc("");
1395 if (dp->exclude_list != NULL && dp->exclude_list->nb_element > 0) {
1396 for(excl = dp->exclude_list->first; excl != NULL;
1397 excl = excl->next) {
1398 q64name = amxml_format_tag("list", excl->name);
1399 exc = newvstralloc(exc, " ", q64name, "\n", NULL);
1400 strappend(exclude_list, exc);
1405 include_file = stralloc("");
1406 if (dp->include_file != NULL && dp->include_file->nb_element > 0) {
1407 for(excl = dp->include_file->first; excl != NULL;
1408 excl = excl->next) {
1409 q64name = amxml_format_tag("file", excl->name);
1410 exc = newvstralloc( exc, " ", q64name, "\n", NULL);
1411 strappend(include_file, exc);
1415 include_list = stralloc("");
1416 if (dp->include_list != NULL && dp->include_list->nb_element > 0) {
1417 for(excl = dp->include_list->first; excl != NULL;
1418 excl = excl->next) {
1419 q64name = amxml_format_tag("list", excl->name);
1420 exc = newvstralloc( exc, " ", q64name, "\n", NULL);
1421 strappend(include_list, exc);
1426 if (dp->exclude_optional) {
1427 excl_opt = " <optional>YES</optional>\n";
1429 if (dp->include_optional) {
1430 incl_opt = " <optional>YES</optional>\n";
1433 if (dp->exclude_file || dp->exclude_list)
1434 exclude = newvstralloc(exclude,
1439 " </exclude>\n", NULL);
1440 if (dp->include_file || dp->include_list)
1441 include = newvstralloc(include,
1446 " </include>\n", NULL);
1447 script_opt = xml_scripts(dp->pp_scriptlist, their_features);
1448 result = vstralloc(auth_opt,
1462 amfree(data_path_opt);
1463 amfree(compress_opt);
1465 amfree(exclude_list);
1466 amfree(exclude_file);
1468 amfree(include_file);
1469 amfree(include_list);
1471 amfree(decrypt_opt);
1472 amfree(encrypt_opt);
1475 /* result contains at least 'auth=...' */
1481 estimatelist_t estimatelist,
1482 am_feature_t *their_features)
1487 if (am_has_feature(their_features, fe_xml_estimatelist)) {
1488 vstrextend(&l, " <estimate>", NULL);
1489 for (el=estimatelist; el != NULL; el = el->next) {
1490 switch (GPOINTER_TO_INT(el->data)) {
1491 case ES_CLIENT : vstrextend(&l, "CLIENT ", NULL); break;
1492 case ES_SERVER : vstrextend(&l, "SERVER ", NULL); break;
1493 case ES_CALCSIZE: vstrextend(&l, "CALCSIZE ", NULL); break;
1496 vstrextend(&l, "</estimate>", NULL);
1497 } else { /* add the first estimate only */
1498 if (am_has_feature(their_features, fe_xml_estimate)) {
1499 vstrextend(&l, " <estimate>", NULL);
1500 switch (GPOINTER_TO_INT(estimatelist->data)) {
1501 case ES_CLIENT : vstrextend(&l, "CLIENT", NULL); break;
1502 case ES_SERVER : vstrextend(&l, "SERVER", NULL); break;
1503 case ES_CALCSIZE: vstrextend(&l, "CALCSIZE", NULL); break;
1506 vstrextend(&l, "</estimate>", NULL);
1507 if (GPOINTER_TO_INT(estimatelist->data) == ES_CALCSIZE) {
1508 vstrextend(&l, " <calcsize>YES</calcsize>", NULL);
1516 clean_dle_str_for_client(
1520 char *hack1, *hack2;
1525 rval_dle_str = stralloc(dle_str);
1527 /* Remove everything between " <encrypt>SERVER-CUSTOM" and "</encrypt>\n"
1529 #define SC "</encrypt>\n"
1530 #define SC_LEN strlen(SC)
1531 hack1 = strstr(rval_dle_str, " <encrypt>SERVER-CUSTOM");
1533 hack2 = strstr(hack1, SC);
1534 /* +1 is to also move the trailing '\0' */
1535 memmove(hack1, hack2 + SC_LEN, strlen(hack2 + SC_LEN) + 1);
1540 return rval_dle_str;
1544 am_feature_t *features;
1548 /* A GHFunc (callback for g_hash_table_foreach) */
1549 static void xml_property(
1552 gpointer user_data_p)
1554 char *property_s = key_p;
1556 property_t *property = value_p;
1557 char *b64value_data;
1558 xml_app_t *xml_app = user_data_p;
1561 b64property = amxml_format_tag("name", property_s);
1562 vstrextend(&xml_app->result, " <property>\n",
1563 " ", b64property, "\n", NULL);
1564 // TODO if client have fe_xml_property_priority
1565 if (property->priority &&
1566 am_has_feature(xml_app->features, fe_xml_property_priority)) {
1567 vstrextend(&xml_app->result, " <priority>yes</priority>\n", NULL);
1569 for(value = property->values; value != NULL; value = value->next) {
1570 b64value_data = amxml_format_tag("value", value->data);
1571 vstrextend(&xml_app->result, " ", b64value_data, "\n", NULL);
1572 amfree(b64value_data);
1574 vstrextend(&xml_app->result, " </property>\n", NULL);
1576 amfree(b64property);
1581 disk_t *dp G_GNUC_UNUSED,
1582 application_t *application,
1583 am_feature_t *their_features)
1588 proplist_t proplist;
1590 xml_app.features = their_features;
1591 xml_app.result = NULL;
1592 plugin = application_get_plugin(application);
1593 b64plugin = amxml_format_tag("plugin", plugin);
1594 xml_app.result = vstralloc(" <backup-program>\n",
1595 " ", b64plugin, "\n",
1597 proplist = application_get_property(application);
1598 g_hash_table_foreach(proplist, xml_property, &xml_app);
1600 vstrextend(&xml_app.result, " </backup-program>\n", NULL);
1604 return xml_app.result;
1610 identlist_t pp_scriptlist,
1611 am_feature_t *their_features)
1620 execute_on_t execute_on;
1622 proplist_t proplist;
1623 identlist_t pp_iter;
1624 pp_script_t *pp_script;
1627 xml_app.features = their_features;
1629 xml_scr = stralloc("");
1630 for (pp_iter = pp_scriptlist; pp_iter != NULL;
1631 pp_iter = pp_iter->next) {
1632 char *pp_script_name = pp_iter->data;
1633 pp_script = lookup_pp_script(pp_script_name);
1634 g_assert(pp_script != NULL);
1635 plugin = pp_script_get_plugin(pp_script);
1636 b64plugin = amxml_format_tag("plugin", plugin);
1637 xml_scr1 = vstralloc(" <script>\n",
1638 " ", b64plugin, "\n",
1641 execute_where = pp_script_get_execute_where(pp_script);
1642 switch (execute_where) {
1643 case ES_CLIENT: str = "CLIENT"; break;
1644 case ES_SERVER: str = "SERVER"; break;
1646 xml_scr1 = vstrextend(&xml_scr1, " <execute_where>",
1647 str, "</execute_where>\n", NULL);
1649 execute_on = pp_script_get_execute_on(pp_script);
1652 if (execute_on & EXECUTE_ON_PRE_DLE_AMCHECK) {
1653 eo_str = vstrextend(&eo_str, sep, "PRE-DLE-AMCHECK", NULL);
1656 if (execute_on & EXECUTE_ON_PRE_HOST_AMCHECK) {
1657 eo_str = vstrextend(&eo_str, sep, "PRE-HOST-AMCHECK", NULL);
1660 if (execute_on & EXECUTE_ON_POST_DLE_AMCHECK) {
1661 eo_str = vstrextend(&eo_str, sep, "POST-DLE-AMCHECK", NULL);
1664 if (execute_on & EXECUTE_ON_POST_HOST_AMCHECK) {
1665 eo_str = vstrextend(&eo_str, sep, "POST-HOST-AMCHECK", NULL);
1668 if (execute_on & EXECUTE_ON_PRE_DLE_ESTIMATE) {
1669 eo_str = vstrextend(&eo_str, sep, "PRE-DLE-ESTIMATE", NULL);
1672 if (execute_on & EXECUTE_ON_PRE_HOST_ESTIMATE) {
1673 eo_str = vstrextend(&eo_str, sep, "PRE-HOST-ESTIMATE", NULL);
1676 if (execute_on & EXECUTE_ON_POST_DLE_ESTIMATE) {
1677 eo_str = vstrextend(&eo_str, sep, "POST-DLE-ESTIMATE", NULL);
1680 if (execute_on & EXECUTE_ON_POST_HOST_ESTIMATE) {
1681 eo_str = vstrextend(&eo_str, sep, "POST-HOST-ESTIMATE", NULL);
1684 if (execute_on & EXECUTE_ON_PRE_DLE_BACKUP) {
1685 eo_str = vstrextend(&eo_str, sep, "PRE-DLE-BACKUP", NULL);
1688 if (execute_on & EXECUTE_ON_PRE_HOST_BACKUP) {
1689 eo_str = vstrextend(&eo_str, sep, "PRE-HOST-BACKUP", NULL);
1692 if (execute_on & EXECUTE_ON_POST_DLE_BACKUP) {
1693 eo_str = vstrextend(&eo_str, sep, "POST-DLE-BACKUP", NULL);
1696 if (execute_on & EXECUTE_ON_POST_HOST_BACKUP) {
1697 eo_str = vstrextend(&eo_str, sep, "POST-HOST-BACKUP", NULL);
1700 if (execute_on & EXECUTE_ON_PRE_RECOVER) {
1701 eo_str = vstrextend(&eo_str, sep, "PRE-RECOVER", NULL);
1704 if (execute_on & EXECUTE_ON_POST_RECOVER) {
1705 eo_str = vstrextend(&eo_str, sep, "POST-RECOVER", NULL);
1708 if (execute_on & EXECUTE_ON_PRE_LEVEL_RECOVER) {
1709 eo_str = vstrextend(&eo_str, sep, "PRE-LEVEL-RECOVER", NULL);
1712 if (execute_on & EXECUTE_ON_POST_LEVEL_RECOVER) {
1713 eo_str = vstrextend(&eo_str, sep, "POST-LEVEL-RECOVER", NULL);
1716 if (execute_on & EXECUTE_ON_INTER_LEVEL_RECOVER) {
1717 eo_str = vstrextend(&eo_str, sep, "INTER-LEVEL-RECOVER", NULL);
1720 if (execute_on != 0)
1721 xml_scr1 = vstrextend(&xml_scr1,
1722 " <execute_on>", eo_str,
1723 "</execute_on>\n", NULL);
1725 proplist = pp_script_get_property(pp_script);
1726 xml_app.result = stralloc("");
1727 g_hash_table_foreach(proplist, xml_property, &xml_app);
1728 xml_scr = vstrextend(&xml_scr, xml_scr1, xml_app.result, " </script>\n", NULL);
1730 amfree(xml_app.result);
1743 for (dp = origqp->head; dp != NULL; dp = dp->next) {
1744 if (dp->ignore || dp->strategy == DS_SKIP)
1756 char *prevhost = NULL;
1757 char *errstr = NULL;
1768 for(dp = origqp->head; dp != NULL; dp = dp->next) {
1774 for(i=0;i<sargc;i++) {
1776 for(dp = origqp->head; dp != NULL; dp = dp->next) {
1777 if(match_host(sargv[i], dp->host->hostname))
1782 for(dp = origqp->head; dp != NULL; dp = dp->next) {
1783 if(prevhost != NULL &&
1784 match_host(prevhost, dp->host->hostname) &&
1785 (match_disk(sargv[i], dp->name) ||
1786 (dp->device && match_disk(sargv[i], dp->device)))) {
1788 error(_("Argument %s cannot be both a host and a disk"),sargv[i]);
1792 if(dp->todo == -1) {
1796 } else { /* dp->todo == 0 */
1805 if(match_a_host == 1) {
1806 if(prev_match == 1) { /* all disk of the previous host */
1807 for(dp = origqp->head; dp != NULL; dp = dp->next) {
1808 if(match_host(prevhost,dp->host->hostname))
1809 if(dp->todo == -1) {
1814 if (!match_a_disk) {
1816 errstr1 = vstrallocf(_("All disks on host '%s' are ignored or have strategy \"skip\".\n"), prevhost);
1817 vstrextend(&errstr, errstr1, NULL);
1821 prevhost = sargv[i];
1826 if (strchr(sargv[i], (int)'\\')) {
1827 errstr1 = vstrallocf(_("Argument '%s' matches neither a host nor a disk; quoting may not be correct.\n"), sargv[i]);
1829 errstr1 = vstrallocf(_("Argument '%s' matches neither a host nor a disk.\n"), sargv[i]);
1831 vstrextend(&errstr, errstr1, NULL);
1835 } else if (dp_skip) {
1837 if (dp_skip->strategy == DS_SKIP) {
1838 errstr1 = vstrallocf(_("Argument '%s' matches a disk with strategy \"skip\".\n"), sargv[i]);
1840 errstr1 = vstrallocf(_("Argument '%s' matches a disk marked \"ignore\".\n"), sargv[i]);
1842 vstrextend(&errstr, errstr1, NULL);
1848 if(prev_match == 1) { /* all disk of the previous host */
1850 for(dp = origqp->head; dp != NULL; dp = dp->next) {
1851 if(match_host(prevhost,dp->host->hostname))
1852 if(dp->todo == -1) {
1857 if (!match_a_disk) {
1859 errstr1 = vstrallocf(_("All disks on host '%s' are ignored or have strategy \"skip\".\n"), prevhost);
1860 vstrextend(&errstr, errstr1, NULL);
1865 for(dp = origqp->head; dp != NULL; dp = dp->next) {
1883 /* rather than try to reproduce the adaptive matching logic in
1884 * match_disklist, this simply creates a new, fake disklist with one
1885 * element in it, and calls match_disklist directly */
1887 bzero(&h, sizeof(h));
1888 h.hostname = file->name;
1891 bzero(&d, sizeof(d));
1893 d.hostname = file->name;
1894 d.name = file->disk;
1895 d.device = file->disk;
1898 dl.head = dl.tail = &d;
1900 (void)match_disklist(&dl, sargc, sargv);
1905 disklist_netifs(void)
1912 static void dump_disk(const disk_t *);
1913 static void dump_disklist(const disklist_t *);
1914 int main(int, char *[]);
1920 g_printf(_(" DISK %s (HOST %s, LINE %d) TYPE %s NAME %s SPINDLE %d\n"),
1921 dp->name, dp->host->hostname, dp->line, dp->dtype_name,
1922 dp->name == NULL? "(null)": dp->name,
1928 const disklist_t * lst)
1930 const disk_t *dp, *prev;
1931 const am_host_t *hp;
1933 if(hostlist == NULL) {
1934 g_printf(_("DISKLIST not read in\n"));
1938 g_printf(_("DISKLIST BY HOSTNAME:\n"));
1940 for(hp = hostlist; hp != NULL; hp = hp->next) {
1941 char *if_name = NULL;
1942 if (hp->netif && hp->netif->config)
1943 if_name = interface_name(hp->netif->config);
1945 g_printf(_("HOST %s INTERFACE %s\n"),
1947 if_name ? _("(null)") : if_name);
1948 for(dp = hp->disks; dp != NULL; dp = dp->hostnext)
1954 g_printf(_("DISKLIST IN FILE ORDER:\n"));
1957 for(dp = lst->head; dp != NULL; prev = dp, dp = dp->next) {
1959 /* check pointers */
1960 if(dp->prev != prev) g_printf(_("*** prev pointer mismatch!\n"));
1961 if(dp->next == NULL && lst->tail != dp) g_printf(_("tail mismatch!\n"));
1971 char *conf_diskfile;
1976 * Configure program for internationalization:
1977 * 1) Only set the message locale for now.
1978 * 2) Set textdomain for all amanda related programs to "amanda"
1979 * We don't want to be forced to support dozens of message catalogs.
1981 setlocale(LC_MESSAGES, "C");
1982 textdomain("amanda");
1986 set_pname("diskfile");
1988 dbopen(DBG_SUBDIR_SERVER);
1990 /* Don't die when child closes pipe */
1991 signal(SIGPIPE, SIG_IGN);
1994 config_init(CONFIG_INIT_EXPLICIT_NAME, argv[1]);
1996 config_init(CONFIG_INIT_USE_CWD, NULL)
1999 if (config_errors(NULL) >= CFGERR_WARNINGS) {
2000 config_print_errors();
2001 if (config_errors(NULL) >= CFGERR_ERRORS) {
2002 g_critical(_("errors processing config file"));
2006 conf_diskfile = config_dir_relative(getconf_str(CNF_DISKFILE));
2007 result = read_diskfile(conf_diskfile, &lst);
2008 if(result == CFGERR_OK) {
2009 dump_disklist(&lst);
2011 config_print_errors();
2013 amfree(conf_diskfile);