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);
100 const char *hostname)
104 for (p = hostlist; p != NULL; p = p->next) {
105 if(strcasecmp(p->hostname, hostname) == 0) return p;
112 const char *hostname,
113 const char *diskname)
118 host = lookup_host(hostname);
122 for (disk = host->disks; disk != NULL; disk = disk->hostnext) {
123 if (strcmp(disk->name, diskname) == 0)
131 * put disk on end of queue
139 if(list->tail == NULL) list->head = disk;
140 else list->tail->next = disk;
141 disk->prev = list->tail;
149 * put disk on head of queue
157 if(list->head == NULL) list->tail = disk;
158 else list->head->prev = disk;
159 disk->next = list->head;
167 * insert in sorted order
174 int (*cmp)(disk_t *a, disk_t *b))
182 if(cmp(disk, ptr) < 0) break;
189 if(prev == NULL) list->head = disk;
190 else prev->next = disk;
191 if(ptr == NULL) list->tail = disk;
192 else ptr->prev = disk;
204 disk = alloc(SIZEOF(disk_t));
205 bzero(disk, SIZEOF(disk_t));
207 disk->allow_split = 0;
208 disk->max_warnings = 20;
209 disk->splitsize = (off_t)0;
210 disk->tape_splitsize = (off_t)0;
211 disk->split_diskbuffer = NULL;
212 disk->fallback_splitsize = (off_t)0;
213 disk->hostname = stralloc(hostname);
214 disk->name = stralloc(diskname);
215 disk->device = stralloc(diskname);
218 disk->compress = COMP_NONE;
219 disk->encrypt = ENCRYPT_NONE;
223 disk->exclude_list = NULL;
224 disk->exclude_file = NULL;
225 disk->include_list = NULL;
226 disk->include_file = NULL;
227 disk->application = NULL;
228 disk->pp_scriptlist = NULL;
230 host = lookup_host(hostname);
232 host = alloc(SIZEOF(am_host_t));
233 host->next = hostlist;
236 host->hostname = stralloc(hostname);
238 host->inprogress = 0;
243 host->features = NULL;
244 host->pre_script = 0;
245 host->post_script = 0;
247 enqueue_disk(list, disk);
250 disk->hostnext = host->disks;
258 * check if disk is present in list. Return true if so, false otherwise.
269 while ((t != NULL) && (t != disk)) {
284 int (*cmp)(disk_t *a, disk_t *b))
289 tmp = in; /* just in case in == out */
291 out->head = (disk_t *)0;
292 out->tail = (disk_t *)0;
294 while((disk = dequeue_disk(tmp)))
295 insert_disk(out, disk, cmp);
300 * remove disk from front of queue
309 if(list->head == NULL) return NULL;
312 list->head = disk->next;
314 if(list->head == NULL) list->tail = NULL;
315 else list->head->prev = NULL;
317 disk->prev = disk->next = NULL; /* for debugging */
326 if(disk->prev == NULL) list->head = disk->next;
327 else disk->prev->next = disk->next;
329 if(disk->next == NULL) list->tail = disk->prev;
330 else disk->next->prev = disk->prev;
332 disk->prev = disk->next = NULL;
340 am_host_t *host, *hostnext;
341 netif_t *netif, *next_if;
343 while (dl->head != NULL) {
344 dp = dequeue_disk(dl);
345 amfree(dp->filename);
347 amfree(dp->hostname);
349 free_sl(dp->exclude_file);
350 free_sl(dp->exclude_list);
351 free_sl(dp->include_file);
352 free_sl(dp->include_list);
356 for(host=hostlist; host != NULL; host = hostnext) {
357 amfree(host->hostname);
358 am_release_feature_set(host->features);
359 host->features = NULL;
360 hostnext = host->next;
365 for (netif = all_netifs; netif != NULL; netif = next_if) {
366 next_if = netif->next;
379 if(islower((int)*s)) *s = (char)toupper((int)*s);
386 /* return 0 on success */
387 /* return -1 on error */
391 const char *filename,
394 /*@keep@*/ char ** line_p)
399 netif_t *netif = NULL;
400 interface_t *cfg_if = NULL;
401 char *hostname = NULL;
402 char *diskname, *diskdevice;
406 char *line = *line_p;
407 int line_num = *line_num_p;
415 assert(filename != NULL);
416 assert(line_num > 0);
417 assert(line != NULL);
421 skip_whitespace(s, ch);
422 if(ch == '\0' || ch == '#')
426 skip_non_whitespace(s, ch);
428 if (g_str_equal(fp, "includefile")) {
430 char *include_filename;
431 skip_whitespace(s, ch);
432 if (ch == '\0' || ch == '#') {
433 disk_parserror(filename, line_num, _("include filename name expected"));
437 skip_quoted_string(s, ch);
439 include_name = unquote_string(fp);
440 include_filename = config_dir_relative(include_name);
441 read_diskfile(include_filename, lst);
442 g_free(include_filename);
443 g_free(include_name);
444 if (config_errors(NULL) >= CFGERR_WARNINGS) {
450 host = lookup_host(fp);
452 hostname = stralloc(fp);
454 hostname = stralloc(host->hostname);
455 if (strcmp(host->hostname, fp) != 0) {
456 disk_parserror(filename, line_num, _("Same host with different case: \"%s\" and \"%s\"."), host->hostname, fp);
461 shost = sanitise_filename(hostname);
462 for (p = hostlist; p != NULL; p = p->next) {
463 char *shostp = sanitise_filename(p->hostname);
464 if (strcmp(hostname, p->hostname) &&
465 !strcmp(shost, shostp)) {
466 disk_parserror(filename, line_num, _("Two hosts are mapping to the same name: \"%s\" and \"%s\""), p->hostname, hostname);
469 else if (strcasecmp(hostname, p->hostname) &&
470 match_host(hostname, p->hostname) &&
471 match_host(p->hostname, hostname)) {
472 disk_parserror(filename, line_num, _("Duplicate host name: \"%s\" and \"%s\""), p->hostname, hostname);
479 skip_whitespace(s, ch);
480 if(ch == '\0' || ch == '#') {
481 disk_parserror(filename, line_num, _("disk device name expected"));
487 skip_quoted_string(s, ch);
489 diskname = unquote_string(fp);
490 if (strlen(diskname) == 0) {
491 disk_parserror(filename, line_num, _("invalid empty diskname"));
495 skip_whitespace(s, ch);
496 if(ch == '\0' || ch == '#') {
497 disk_parserror(filename, line_num, _("disk dumptype expected"));
503 skip_quoted_string(s, ch);
510 dumptype = unquote_string(fp);
511 if (strlen(dumptype) == 0) {
512 disk_parserror(filename, line_num, _("invalid empty diskdevice"));
516 if ((dtype = lookup_dumptype(dumptype)) == NULL) {
517 diskdevice = dumptype;
518 skip_whitespace(s, ch);
519 if(ch == '\0' || ch == '#') {
520 disk_parserror(filename, line_num,
521 _("disk dumptype '%s' not found"), dumptype);
529 skip_quoted_string(s, ch);
532 dumptype = unquote_string(fp);
537 /* check for duplicate disk */
540 if ((disk = lookup_disk(hostname, diskname)) != NULL) {
546 a1 = clean_regex(diskname, 1);
547 a2 = clean_regex(disk->name, 1);
549 if (match_disk(a1, disk->name) && match_disk(a2, diskname)) {
552 disk = disk->hostnext;
557 while (dup == 0 && disk != NULL);
560 disk_parserror(filename, line_num,
561 _("duplicate disk record, previous on line %d"),
566 disk = alloc(SIZEOF(disk_t));
567 disk->filename = g_strdup(filename);
568 disk->line = line_num;
569 disk->hostname = hostname;
570 disk->name = diskname;
571 disk->device = diskdevice;
574 disk->inprogress = 0;
575 disk->application = NULL;
576 disk->pp_scriptlist = NULL;
577 disk->dataport_list = NULL;
581 sdisk = sanitise_filename(diskname);
582 for (dp = host->disks; dp != NULL; dp = dp->hostnext) {
583 char *sdiskp = sanitise_filename(dp->name);
584 if (strcmp(diskname, dp->name) != 0 &&
585 strcmp(sdisk, sdiskp) == 0) {
586 disk_parserror(filename, line_num,
587 _("Two disks are mapping to the same name: \"%s\" and \"%s\"; you must use different diskname"),
599 skip_whitespace(s, ch);
600 if (ch != '\0' && ch != '#') {
601 disk_parserror(filename, line_num,
602 _("expected line break after `{\', ignoring rest of line"));
605 if (strchr(s-1, '}') &&
606 (strchr(s-1, '#') == NULL ||
607 strchr(s-1, '}') < strchr(s-1, '#'))) {
608 disk_parserror(filename, line_num,_("'}' on same line than '{'"));
611 amfree(disk->device);
620 dtype = read_dumptype(vstralloc("custom(", hostname,
621 ":", disk->name, ")",
622 ".", anonymous_value(), NULL),
623 diskf, (char*)filename, line_num_p);
624 if (dtype == NULL || dup) {
625 disk_parserror(filename, line_num,
626 _("read of custom dumptype failed"));
629 amfree(disk->device);
640 *line_p = line = agets(diskf);
641 line_num = *line_num_p; /* no incr, read_dumptype did it already */
644 *line_p = line = stralloc("");
648 if((dtype = lookup_dumptype(dumptype)) == NULL) {
649 char *qdt = quote_string(dumptype);
651 disk_parserror(filename, line_num, _("undefined dumptype `%s'"), qdt);
655 amfree(disk->device);
668 /* disk_parserror already called, above */
669 g_assert(config_errors(NULL) != CFGERR_OK);
676 disk->dtype_name = dumptype_name(dtype);
677 disk->config = dtype;
678 disk->program = dumptype_get_program(dtype);
679 disk->exclude_list = duplicate_sl(dumptype_get_exclude(dtype).sl_list);
680 disk->exclude_file = duplicate_sl(dumptype_get_exclude(dtype).sl_file);
681 disk->exclude_optional = dumptype_get_exclude(dtype).optional;
682 disk->include_list = duplicate_sl(dumptype_get_include(dtype).sl_list);
683 disk->include_file = duplicate_sl(dumptype_get_include(dtype).sl_file);
684 disk->include_optional = dumptype_get_include(dtype).optional;
685 disk->priority = dumptype_get_priority(dtype);
686 disk->dumpcycle = dumptype_get_dumpcycle(dtype);
687 /* disk->frequency = dumptype_get_frequency(dtype);*/
688 disk->auth = dumptype_get_auth(dtype);
689 disk->maxdumps = dumptype_get_maxdumps(dtype);
690 disk->allow_split = dumptype_get_allow_split(dtype);
691 disk->max_warnings = dumptype_get_max_warnings(dtype);
692 disk->tape_splitsize = dumptype_get_tape_splitsize(dtype);
693 disk->split_diskbuffer = dumptype_get_split_diskbuffer(dtype);
694 disk->fallback_splitsize = dumptype_get_fallback_splitsize(dtype);
695 if (disk->allow_split) {
696 tapetype_t *tapetype = lookup_tapetype(getconf_str(CNF_TAPETYPE));
697 disk->splitsize = tapetype_get_part_size(tapetype);
699 disk->splitsize = disk->tape_splitsize;
701 disk->maxpromoteday = dumptype_get_maxpromoteday(dtype);
702 disk->bumppercent = dumptype_get_bumppercent(dtype);
703 disk->bumpsize = dumptype_get_bumpsize(dtype);
704 disk->bumpdays = dumptype_get_bumpdays(dtype);
705 disk->bumpmult = dumptype_get_bumpmult(dtype);
706 disk->starttime = dumptype_get_starttime(dtype);
707 disk->application = dumptype_get_application(dtype);
708 disk->pp_scriptlist = dumptype_get_scriptlist(dtype);
710 if (disk->starttime > 0) {
713 stm = localtime(&st);
714 disk->start_t -= stm->tm_sec + 60 * stm->tm_min + 3600 * stm->tm_hour;
715 disk->start_t += disk->starttime / 100 * 3600 +
716 disk->starttime % 100 * 60;
717 if ((disk->start_t - st) < -43200)
718 disk->start_t += 86400;
720 disk->strategy = dumptype_get_strategy(dtype);
721 disk->ignore = dumptype_get_ignore(dtype);
722 disk->estimatelist = dumptype_get_estimatelist(dtype);
723 disk->compress = dumptype_get_compress(dtype);
724 disk->srvcompprog = dumptype_get_srvcompprog(dtype);
725 disk->clntcompprog = dumptype_get_clntcompprog(dtype);
726 disk->encrypt = dumptype_get_encrypt(dtype);
727 disk->srv_decrypt_opt = dumptype_get_srv_decrypt_opt(dtype);
728 disk->clnt_decrypt_opt = dumptype_get_clnt_decrypt_opt(dtype);
729 disk->srv_encrypt = dumptype_get_srv_encrypt(dtype);
730 disk->clnt_encrypt = dumptype_get_clnt_encrypt(dtype);
731 disk->amandad_path = dumptype_get_amandad_path(dtype);
732 disk->client_username = dumptype_get_client_username(dtype);
733 disk->client_port = dumptype_get_client_port(dtype);
734 disk->ssh_keys = dumptype_get_ssh_keys(dtype);
735 disk->comprate[0] = dumptype_get_comprate(dtype)[0];
736 disk->comprate[1] = dumptype_get_comprate(dtype)[1];
737 disk->data_path = dumptype_get_data_path(dtype);
738 disk->dump_limit = dumptype_get_dump_limit(dtype);
741 * Boolean parameters with no value (Appears here as value 2) defaults
742 * to TRUE for backward compatibility and for logical consistency.
744 disk->record = dumptype_get_record(dtype) != 0;
745 disk->skip_incr = dumptype_get_skip_incr(dtype) != 0;
746 disk->skip_full = dumptype_get_skip_full(dtype) != 0;
747 disk->to_holdingdisk = dumptype_get_to_holdingdisk(dtype);
748 disk->kencrypt = dumptype_get_kencrypt(dtype) != 0;
749 disk->index = dumptype_get_index(dtype) != 0;
753 skip_whitespace(s, ch);
755 if(ch && ch != '#') { /* get optional spindle number */
759 skip_non_whitespace(s, ch);
762 if (*fp1 == '-') fp1++;
763 for(;*fp1!='\0';fp1++) {
764 if(!isdigit((int)*fp1)) {
769 disk_parserror(filename, line_num, _("non-integer spindle `%s'"), fp);
775 disk->spindle = atoi(fp);
779 skip_whitespace(s, ch);
781 if(ch && ch != '#') { /* get optional network interface */
782 skip_non_whitespace(s, ch);
784 if((cfg_if = lookup_interface(upcase(fp))) == NULL) {
785 disk_parserror(filename, line_num,
786 _("undefined network interface `%s'"), fp);
793 cfg_if = lookup_interface("default");
796 /* see if we already have a netif_t for this interface */
797 for (netif = all_netifs; netif != NULL; netif = netif->next) {
798 if (netif->config == cfg_if)
802 /* nope; make up a new one */
804 netif = alloc(sizeof(*netif));
805 netif->next = all_netifs;
807 netif->config = cfg_if;
811 skip_whitespace(s, ch);
812 if(ch && ch != '#') { /* now we have garbage, ignore it */
813 disk_parserror(filename, line_num, _("end of line expected"));
816 if (disk->program && disk->application &&
817 strcmp(disk->program,"APPLICATION")) {
818 disk_parserror(filename, line_num,
819 _("Both program and application set"));
822 if (disk->program && strcmp(disk->program,"APPLICATION")==0 &&
823 !disk->application) {
824 disk_parserror(filename, line_num,
825 _("program set to APPLICATION but no application set"));
828 if (disk->application) {
829 application_t *application;
832 application = lookup_application(disk->application);
833 g_assert(application != NULL);
834 plugin = application_get_plugin(application);
835 if (!plugin || strlen(plugin) == 0) {
836 disk_parserror(filename, line_num,
837 _("plugin not set for application"));
841 for (pp_iter = disk->pp_scriptlist; pp_iter != NULL;
842 pp_iter = pp_iter->next) {
843 pp_script_t *pp_script;
845 char *pp_script_name;
847 pp_script_name = (char*)pp_iter->data;
848 pp_script = lookup_pp_script(pp_script_name);
849 g_assert(pp_script != NULL);
850 plugin = pp_script_get_plugin(pp_script);
851 if (!plugin || strlen(plugin) == 0) {
852 disk_parserror(filename, line_num, _("plugin not set for script"));
856 /* success, add disk to lists */
858 if(host == NULL) { /* new host */
859 host = alloc(SIZEOF(am_host_t));
860 host->next = hostlist;
863 host->hostname = stralloc(hostname);
866 host->inprogress = 0;
867 host->maxdumps = 1; /* will be overwritten */
871 host->features = NULL;
872 host->pre_script = 0;
873 host->post_script = 0;
878 enqueue_disk(lst, disk);
881 disk->hostnext = host->disks;
883 host->maxdumps = disk->maxdumps;
889 printf_arglist_function2(void disk_parserror, const char *, filename,
890 int, line_num, const char *, format)
896 /* format the error message and hand it off to conffile */
898 arglist_start(argp, format);
899 msg = g_strdup_vprintf(format, argp);
900 errstr = g_strdup_printf("\"%s\", line %d: %s", filename, line_num, msg);
904 config_add_error(CFGERR_ERRORS, errstr);
912 int npr, /* we print first npr disks on queue, plus last two */
920 g_fprintf(f, _("%s QUEUE: empty\n"), st);
923 g_fprintf(f, _("%s QUEUE:\n"), st);
924 for(pos = 0, d = q.head, p = NULL; d != NULL; p = d, d = d->next, pos++) {
925 qname = quote_string(d->name);
926 if(pos < npr) g_fprintf(f, "%3d: %-10s %-4s\n",
927 pos, d->host->hostname, qname);
931 if(pos > npr+2) g_fprintf(f, " ...\n");
934 g_fprintf(f, "%3d: %-10s %-4s\n", pos-2, d->host->hostname, d->name);
937 g_fprintf(f, "%3d: %-10s %-4s\n", pos-1, d->host->hostname, d->name);
948 am_feature_t *their_features = dp->host->features;
951 assert(dp->host != NULL);
953 errarray = g_ptr_array_new();
955 if (!am_has_feature(their_features, fe_options_auth)) {
956 if (strcasecmp(dp->auth, "bsd") == 0)
957 if (!am_has_feature(their_features, fe_options_bsd_auth))
958 g_ptr_array_add(errarray, _("does not support auth"));
961 switch(dp->compress) {
963 if (!am_has_feature(their_features, fe_options_compress_fast)) {
964 g_ptr_array_add(errarray, _("does not support fast compression"));
968 if (!am_has_feature(their_features, fe_options_compress_best)) {
969 g_ptr_array_add(errarray, _("does not support best compression"));
973 if (am_has_feature(their_features, fe_options_compress_cust)) {
974 if (dp->clntcompprog == NULL || strlen(dp->clntcompprog) == 0) {
975 g_ptr_array_add(errarray, _("client custom compression with no compression program specified"));
978 g_ptr_array_add(errarray, _("does not support client custom compression"));
981 case COMP_SERVER_FAST:
983 case COMP_SERVER_BEST:
985 case COMP_SERVER_CUST:
986 if (dp->srvcompprog == NULL || strlen(dp->srvcompprog) == 0) {
987 g_ptr_array_add(errarray, _("server custom compression with no compression program specified"));
992 switch(dp->encrypt) {
994 if (am_has_feature(their_features, fe_options_encrypt_cust)) {
995 if (dp->clnt_decrypt_opt) {
996 if (!am_has_feature(their_features, fe_options_client_decrypt_option)) {
997 g_ptr_array_add(errarray, _("does not support client decrypt option"));
1000 if (dp->clnt_encrypt == NULL || strlen(dp->clnt_encrypt) == 0) {
1001 g_ptr_array_add(errarray, _("encrypt client with no encryption program specified"));
1003 if (dp->compress == COMP_SERVER_FAST ||
1004 dp->compress == COMP_SERVER_BEST ||
1005 dp->compress == COMP_SERVER_CUST ) {
1006 g_ptr_array_add(errarray, _("Client encryption with server compression is not supported. See amanda.conf(5) for detail"));
1009 g_ptr_array_add(errarray, _("does not support client data encryption"));
1012 case ENCRYPT_SERV_CUST:
1013 if (dp->srv_encrypt == NULL || strlen(dp->srv_encrypt) == 0) {
1014 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"));
1020 if (!am_has_feature(their_features, fe_options_no_record)) {
1021 g_ptr_array_add(errarray, _("does not support no record"));
1026 if (!am_has_feature(their_features, fe_options_index)) {
1027 g_ptr_array_add(errarray, _("does not support index"));
1032 if (!am_has_feature(their_features, fe_options_kencrypt)) {
1033 g_ptr_array_add(errarray, _("does not support kencrypt"));
1038 if (dp->exclude_file != NULL && dp->exclude_file->nb_element > 0) {
1039 nb_exclude = dp->exclude_file->nb_element;
1040 if (!am_has_feature(their_features, fe_options_exclude_file)) {
1041 g_ptr_array_add(errarray, _("does not support exclude file"));
1045 if (dp->exclude_list != NULL && dp->exclude_list->nb_element > 0) {
1046 nb_exclude += dp->exclude_list->nb_element;
1047 if (!am_has_feature(their_features, fe_options_exclude_list)) {
1048 g_ptr_array_add(errarray, _("does not support exclude list"));
1052 if (nb_exclude > 1 &&
1053 !am_has_feature(their_features, fe_options_multiple_exclude)) {
1054 g_ptr_array_add(errarray, _("does not support multiple exclude"));
1058 if (dp->include_file != NULL && dp->include_file->nb_element > 0) {
1059 nb_include = dp->include_file->nb_element;
1060 if (!am_has_feature(their_features, fe_options_include_file)) {
1061 g_ptr_array_add(errarray, ("does not support include file"));
1065 if (dp->include_list != NULL && dp->include_list->nb_element > 0) {
1066 nb_include += dp->include_list->nb_element;
1067 if (!am_has_feature(their_features, fe_options_include_list)) {
1068 g_ptr_array_add(errarray, _("does not support include list"));
1072 if (nb_include > 1 &&
1073 !am_has_feature(their_features, fe_options_multiple_exclude)) {
1074 g_ptr_array_add(errarray, _("does not support multiple include"));
1077 if (dp->exclude_optional) {
1078 if (!am_has_feature(their_features, fe_options_optional_exclude)) {
1079 g_ptr_array_add(errarray, _("does not support optional exclude"));
1082 if (dp->include_optional) {
1083 if (!am_has_feature(their_features, fe_options_optional_include)) {
1084 g_ptr_array_add(errarray, _("does not support optional include"));
1095 char *auth_opt = NULL;
1096 char *kencrypt_opt = "";
1097 char *compress_opt = "";
1098 char *encrypt_opt = stralloc("");
1099 char *decrypt_opt = stralloc("");
1100 char *record_opt = "";
1101 char *index_opt = "";
1102 char *exclude_file = NULL;
1103 char *exclude_list = NULL;
1104 char *include_file = NULL;
1105 char *include_list = NULL;
1106 char *excl_opt = "";
1107 char *incl_opt = "";
1109 char *result = NULL;
1113 am_feature_t *their_features = dp->host->features;
1116 assert(dp->host != NULL);
1118 qdpname = quote_string(dp->name);
1119 if (am_has_feature(their_features, fe_options_auth)) {
1120 auth_opt = vstralloc("auth=", dp->auth, ";", NULL);
1121 } else if(strcasecmp(dp->auth, "bsd") == 0) {
1122 if(am_has_feature(their_features, fe_options_bsd_auth))
1123 auth_opt = stralloc("bsd-auth;");
1126 switch(dp->compress) {
1128 compress_opt = "compress-fast;";
1131 compress_opt = "compress-best;";
1134 compress_opt = vstralloc("comp-cust=", dp->clntcompprog, ";", NULL);
1136 case COMP_SERVER_FAST:
1137 compress_opt = "srvcomp-fast;";
1139 case COMP_SERVER_BEST:
1140 compress_opt = "srvcomp-best;";
1142 case COMP_SERVER_CUST:
1143 compress_opt = vstralloc("srvcomp-cust=", dp->srvcompprog, ";", NULL);
1147 switch(dp->encrypt) {
1149 encrypt_opt = newvstralloc(encrypt_opt, "encrypt-cust=",
1150 dp->clnt_encrypt, ";", NULL);
1151 if (dp->clnt_decrypt_opt) {
1152 decrypt_opt = newvstralloc(decrypt_opt, "client-decrypt-option=",
1153 dp->clnt_decrypt_opt, ";", NULL);
1156 case ENCRYPT_SERV_CUST:
1157 encrypt_opt = newvstralloc(encrypt_opt, "encrypt-serv-cust=",
1158 dp->srv_encrypt, ";", NULL);
1159 if (dp->srv_decrypt_opt) {
1160 decrypt_opt = newvstralloc(decrypt_opt, "server-decrypt-option=",
1161 dp->srv_decrypt_opt, ";", NULL);
1167 record_opt = "no-record;";
1171 index_opt = "index;";
1175 kencrypt_opt = "kencrypt;";
1178 exclude_file = stralloc("");
1179 if (dp->exclude_file != NULL && dp->exclude_file->nb_element > 0) {
1180 for(excl = dp->exclude_file->first; excl != NULL;
1181 excl = excl->next) {
1182 qname = quote_string(excl->name);
1183 exc = newvstralloc( exc, "exclude-file=", qname, ";", NULL);
1184 strappend(exclude_file, exc);
1188 exclude_list = stralloc("");
1189 if (dp->exclude_list != NULL && dp->exclude_list->nb_element > 0) {
1190 for(excl = dp->exclude_list->first; excl != NULL;
1191 excl = excl->next) {
1192 qname = quote_string(excl->name);
1193 exc = newvstralloc( exc, "exclude-list=", qname, ";", NULL);
1194 strappend(exclude_list, exc);
1199 include_file = stralloc("");
1200 if (dp->include_file != NULL && dp->include_file->nb_element > 0) {
1201 for(excl = dp->include_file->first; excl != NULL;
1202 excl = excl->next) {
1203 qname = quote_string(excl->name);
1204 exc = newvstralloc(exc, "include-file=", qname, ";", NULL);
1205 strappend(include_file, exc);
1209 include_list = stralloc("");
1210 if (dp->include_list != NULL && dp->include_list->nb_element > 0) {
1211 for(excl = dp->include_list->first; excl != NULL;
1212 excl = excl->next) {
1213 qname = quote_string(excl->name);
1214 exc = newvstralloc(exc, "include-list=", qname, ";", NULL);
1215 strappend(include_list, exc);
1220 if (dp->exclude_optional) {
1221 excl_opt = "exclude-optional;";
1223 if (dp->include_optional) {
1224 incl_opt = "include-optional;";
1227 result = vstralloc(";",
1244 amfree(exclude_list);
1245 amfree(exclude_file);
1246 amfree(include_file);
1247 amfree(include_list);
1249 amfree(decrypt_opt);
1250 amfree(encrypt_opt);
1252 /* result contains at least 'auth=...' */
1257 am_feature_t *features;
1261 /* A GHFunc (callback for g_hash_table_foreach) */
1262 static void xml_property(
1265 gpointer user_data_p)
1268 property_t *property = value_p;
1269 xml_app_t *xml_app = user_data_p;
1273 strbuf = g_string_new(xml_app->result);
1275 tmp = amxml_format_tag("name", (char *)key_p);
1276 g_string_append_printf(strbuf, " <property>\n %s\n", tmp);
1279 // TODO if client have fe_xml_property_priority
1280 if (property->priority
1281 && am_has_feature(xml_app->features, fe_xml_property_priority))
1282 g_string_append(strbuf, " <priority>yes</priority>\n");
1284 for (value = property->values; value != NULL; value = value->next) {
1285 tmp = amxml_format_tag("value", value->data);
1286 g_string_append_printf(strbuf, " %s", tmp);
1289 g_string_append_printf(strbuf, "\n </property>\n");
1291 g_free(xml_app->result);
1292 xml_app->result = g_string_free(strbuf, FALSE);
1303 char *encrypt_opt = stralloc("");
1304 char *decrypt_opt = stralloc("");
1307 char *data_path_opt = stralloc("");
1308 char *exclude = stralloc("");
1309 char *exclude_file = NULL;
1310 char *exclude_list = NULL;
1311 char *include = stralloc("");
1312 char *include_file = NULL;
1313 char *include_list = NULL;
1314 char *excl_opt = "";
1315 char *incl_opt = "";
1318 char *result = NULL;
1322 am_feature_t *their_features = dp->host->features;
1325 assert(dp->host != NULL);
1327 qdpname = quote_string(dp->name);
1328 if (am_has_feature(their_features, fe_options_auth)) {
1329 auth_opt = vstralloc(" <auth>", dp->auth, "</auth>\n", NULL);
1331 auth_opt = stralloc("");
1334 switch(dp->compress) {
1336 compress_opt = stralloc(" <compress>FAST</compress>\n");
1339 compress_opt = stralloc(" <compress>BEST</compress>\n");
1342 compress_opt = vstralloc(" <compress>CUSTOM"
1343 "<custom-compress-program>",
1345 "</custom-compress-program>\n"
1346 " </compress>\n", NULL);
1348 case COMP_SERVER_FAST:
1349 compress_opt = stralloc(" <compress>SERVER-FAST</compress>\n");
1351 case COMP_SERVER_BEST:
1352 compress_opt = stralloc(" <compress>SERVER-BEST</compress>\n");
1354 case COMP_SERVER_CUST:
1355 compress_opt = vstralloc(" <compress>SERVER-CUSTOM"
1356 "<custom-compress-program>",
1358 "</custom-compress-program>\n"
1359 " </compress>\n", NULL);
1362 compress_opt = stralloc("");
1365 switch(dp->encrypt) {
1367 if (dp->clnt_decrypt_opt) {
1368 decrypt_opt = newvstralloc(decrypt_opt,
1369 " <decrypt-option>",
1370 dp->clnt_decrypt_opt,
1371 "</decrypt-option>\n", NULL);
1374 encrypt_opt = newvstralloc(encrypt_opt,
1376 "<custom-encrypt-program>",
1378 "</custom-encrypt-program>\n",
1380 " </encrypt>\n", NULL);
1383 case ENCRYPT_SERV_CUST:
1385 decrypt_opt = newvstralloc(decrypt_opt,
1386 " <decrypt-option>",
1387 dp->srv_decrypt_opt,
1388 "</decrypt-option>\n", NULL);
1389 encrypt_opt = newvstralloc(encrypt_opt,
1390 " <encrypt>SERVER-CUSTOM"
1391 "<custom-encrypt-program>",
1393 "</custom-encrypt-program>\n",
1395 " </encrypt>\n", NULL);
1401 record_opt = " <record>NO</record>\n";
1403 record_opt = " <record>YES</record>\n";
1407 index_opt = " <index>YES</index>\n";
1413 kencrypt_opt = " <kencrypt>YES</kencrypt>\n";
1418 if (am_has_feature(their_features, fe_xml_data_path)) {
1419 switch(dp->data_path) {
1420 case DATA_PATH_AMANDA:
1421 amfree(data_path_opt);
1422 data_path_opt = stralloc(" <datapath>AMANDA</datapath>\n");
1424 case DATA_PATH_DIRECTTCP:
1425 { /* dp->dataport_list is not set for selfcheck/sendsize */
1426 if (am_has_feature(their_features, fe_xml_directtcp_list)) {
1428 char *value, *b64value;
1430 amfree(data_path_opt);
1431 data_path_opt = stralloc(" <datapath>DIRECTTCP");
1432 if (dp->dataport_list) {
1433 s = sc = stralloc(dp->dataport_list);
1441 b64value = amxml_format_tag("directtcp", value);
1442 vstrextend(&data_path_opt, "\n ", b64value, NULL);
1446 strappend(data_path_opt, "\n ");
1448 strappend(data_path_opt, "</datapath>\n");
1455 exclude_file = stralloc("");
1456 if (dp->exclude_file != NULL && dp->exclude_file->nb_element > 0) {
1457 for(excl = dp->exclude_file->first; excl != NULL;
1458 excl = excl->next) {
1459 q64name = amxml_format_tag("file", excl->name);
1460 exc = newvstralloc( exc, " ", q64name, "\n", NULL);
1461 strappend(exclude_file, exc);
1465 exclude_list = stralloc("");
1466 if (dp->exclude_list != NULL && dp->exclude_list->nb_element > 0) {
1467 for(excl = dp->exclude_list->first; excl != NULL;
1468 excl = excl->next) {
1469 q64name = amxml_format_tag("list", excl->name);
1470 exc = newvstralloc(exc, " ", q64name, "\n", NULL);
1471 strappend(exclude_list, exc);
1476 include_file = stralloc("");
1477 if (dp->include_file != NULL && dp->include_file->nb_element > 0) {
1478 for(excl = dp->include_file->first; excl != NULL;
1479 excl = excl->next) {
1480 q64name = amxml_format_tag("file", excl->name);
1481 exc = newvstralloc( exc, " ", q64name, "\n", NULL);
1482 strappend(include_file, exc);
1486 include_list = stralloc("");
1487 if (dp->include_list != NULL && dp->include_list->nb_element > 0) {
1488 for(excl = dp->include_list->first; excl != NULL;
1489 excl = excl->next) {
1490 q64name = amxml_format_tag("list", excl->name);
1491 exc = newvstralloc( exc, " ", q64name, "\n", NULL);
1492 strappend(include_list, exc);
1497 if (dp->exclude_optional) {
1498 excl_opt = " <optional>YES</optional>\n";
1500 if (dp->include_optional) {
1501 incl_opt = " <optional>YES</optional>\n";
1504 if (dp->exclude_file || dp->exclude_list)
1505 exclude = newvstralloc(exclude,
1510 " </exclude>\n", NULL);
1511 if (dp->include_file || dp->include_list)
1512 include = newvstralloc(include,
1517 " </include>\n", NULL);
1518 script_opt = xml_scripts(dp->pp_scriptlist, their_features);
1519 result = vstralloc(auth_opt,
1533 amfree(data_path_opt);
1534 amfree(compress_opt);
1536 amfree(exclude_list);
1537 amfree(exclude_file);
1539 amfree(include_file);
1540 amfree(include_list);
1542 amfree(decrypt_opt);
1543 amfree(encrypt_opt);
1546 /* result contains at least 'auth=...' */
1551 xml_dumptype_properties(
1554 xml_app_t xml_dumptype;
1556 xml_dumptype.result = g_strdup("");
1557 xml_dumptype.features = NULL;
1558 if (dp && dp->config) {
1559 g_hash_table_foreach(dumptype_get_property(dp->config), xml_property,
1562 return xml_dumptype.result;
1567 estimatelist_t estimatelist,
1568 am_feature_t *their_features)
1573 if (am_has_feature(their_features, fe_xml_estimatelist)) {
1574 vstrextend(&l, " <estimate>", NULL);
1575 for (el=estimatelist; el != NULL; el = el->next) {
1576 switch (GPOINTER_TO_INT(el->data)) {
1577 case ES_CLIENT : vstrextend(&l, "CLIENT ", NULL); break;
1578 case ES_SERVER : vstrextend(&l, "SERVER ", NULL); break;
1579 case ES_CALCSIZE: vstrextend(&l, "CALCSIZE ", NULL); break;
1582 vstrextend(&l, "</estimate>", NULL);
1583 } else { /* add the first estimate only */
1584 if (am_has_feature(their_features, fe_xml_estimate)) {
1585 vstrextend(&l, " <estimate>", NULL);
1586 switch (GPOINTER_TO_INT(estimatelist->data)) {
1587 case ES_CLIENT : vstrextend(&l, "CLIENT", NULL); break;
1588 case ES_SERVER : vstrextend(&l, "SERVER", NULL); break;
1589 case ES_CALCSIZE: vstrextend(&l, "CALCSIZE", NULL); break;
1592 vstrextend(&l, "</estimate>", NULL);
1593 if (GPOINTER_TO_INT(estimatelist->data) == ES_CALCSIZE) {
1594 vstrextend(&l, " <calcsize>YES</calcsize>", NULL);
1602 clean_dle_str_for_client(
1604 am_feature_t *their_features)
1607 char *hack1, *hack2;
1608 char *pend, *pscript, *pproperty, *eproperty;
1614 rval_dle_str = stralloc(dle_str);
1616 /* Remove everything between " <encrypt>SERVER-CUSTOM" and "</encrypt>\n"
1618 #define SC "</encrypt>\n"
1619 #define SC_LEN strlen(SC)
1620 hack1 = strstr(rval_dle_str, " <encrypt>SERVER-CUSTOM");
1622 hack2 = strstr(hack1, SC);
1623 /* +1 is to also move the trailing '\0' */
1624 memmove(hack1, hack2 + SC_LEN, strlen(hack2 + SC_LEN) + 1);
1629 if (!am_has_feature(their_features, fe_dumptype_property)) {
1630 #define SC "</property>\n"
1631 #define SC_LEN strlen(SC)
1632 /* remove all dle properties, they are before backup-program or script
1634 hack1 = rval_dle_str;
1635 pend = strstr(rval_dle_str, "<backup-program>");
1636 pscript = strstr(rval_dle_str, "<script>");
1637 if (pscript && pscript < pend)
1639 if (!pend) /* the complete string */
1640 pend = rval_dle_str + strlen(rval_dle_str);
1642 pproperty = strstr(hack1, " <property>");
1643 if (pproperty && pproperty < pend) { /* remove it */
1644 eproperty = strstr(pproperty, SC);
1645 len = eproperty + SC_LEN - pproperty;
1646 memmove(pproperty, eproperty + SC_LEN, strlen(eproperty + SC_LEN) + 1);
1658 return rval_dle_str;
1664 disk_t *dp G_GNUC_UNUSED,
1665 application_t *application,
1666 am_feature_t *their_features)
1672 proplist_t proplist;
1674 xml_app.features = their_features;
1675 xml_app.result = NULL;
1676 plugin = application_get_plugin(application);
1677 b64plugin = amxml_format_tag("plugin", plugin);
1678 xml_app.result = vstralloc(" <backup-program>\n",
1679 " ", b64plugin, "\n",
1681 proplist = application_get_property(application);
1682 g_hash_table_foreach(proplist, xml_property, &xml_app);
1684 client_name = application_get_client_name(application);
1685 if (client_name && strlen(client_name) > 0 &&
1686 am_has_feature(their_features, fe_application_client_name)) {
1687 char *b64client_name = amxml_format_tag("client_name", client_name);
1688 vstrextend(&xml_app.result, " ", b64client_name, "\n", NULL);
1691 vstrextend(&xml_app.result, " </backup-program>\n", NULL);
1695 return xml_app.result;
1701 identlist_t pp_scriptlist,
1702 am_feature_t *their_features)
1712 execute_on_t execute_on;
1714 proplist_t proplist;
1715 identlist_t pp_iter;
1716 pp_script_t *pp_script;
1719 xml_app.features = their_features;
1721 xml_scr = stralloc("");
1722 for (pp_iter = pp_scriptlist; pp_iter != NULL;
1723 pp_iter = pp_iter->next) {
1724 char *pp_script_name = pp_iter->data;
1725 pp_script = lookup_pp_script(pp_script_name);
1726 g_assert(pp_script != NULL);
1727 plugin = pp_script_get_plugin(pp_script);
1728 b64plugin = amxml_format_tag("plugin", plugin);
1729 xml_scr1 = vstralloc(" <script>\n",
1730 " ", b64plugin, "\n",
1733 execute_where = pp_script_get_execute_where(pp_script);
1734 switch (execute_where) {
1735 case ES_CLIENT: str = "CLIENT"; break;
1736 case ES_SERVER: str = "SERVER"; break;
1738 xml_scr1 = vstrextend(&xml_scr1, " <execute_where>",
1739 str, "</execute_where>\n", NULL);
1741 execute_on = pp_script_get_execute_on(pp_script);
1743 eo_str = stralloc("");
1744 if (execute_on & EXECUTE_ON_PRE_DLE_AMCHECK) {
1745 eo_str = vstrextend(&eo_str, sep, "PRE-DLE-AMCHECK", NULL);
1748 if (execute_on & EXECUTE_ON_PRE_HOST_AMCHECK) {
1749 eo_str = vstrextend(&eo_str, sep, "PRE-HOST-AMCHECK", NULL);
1752 if (execute_on & EXECUTE_ON_POST_DLE_AMCHECK) {
1753 eo_str = vstrextend(&eo_str, sep, "POST-DLE-AMCHECK", NULL);
1756 if (execute_on & EXECUTE_ON_POST_HOST_AMCHECK) {
1757 eo_str = vstrextend(&eo_str, sep, "POST-HOST-AMCHECK", NULL);
1760 if (execute_on & EXECUTE_ON_PRE_DLE_ESTIMATE) {
1761 eo_str = vstrextend(&eo_str, sep, "PRE-DLE-ESTIMATE", NULL);
1764 if (execute_on & EXECUTE_ON_PRE_HOST_ESTIMATE) {
1765 eo_str = vstrextend(&eo_str, sep, "PRE-HOST-ESTIMATE", NULL);
1768 if (execute_on & EXECUTE_ON_POST_DLE_ESTIMATE) {
1769 eo_str = vstrextend(&eo_str, sep, "POST-DLE-ESTIMATE", NULL);
1772 if (execute_on & EXECUTE_ON_POST_HOST_ESTIMATE) {
1773 eo_str = vstrextend(&eo_str, sep, "POST-HOST-ESTIMATE", NULL);
1776 if (execute_on & EXECUTE_ON_PRE_DLE_BACKUP) {
1777 eo_str = vstrextend(&eo_str, sep, "PRE-DLE-BACKUP", NULL);
1780 if (execute_on & EXECUTE_ON_PRE_HOST_BACKUP) {
1781 eo_str = vstrextend(&eo_str, sep, "PRE-HOST-BACKUP", NULL);
1784 if (execute_on & EXECUTE_ON_POST_DLE_BACKUP) {
1785 eo_str = vstrextend(&eo_str, sep, "POST-DLE-BACKUP", NULL);
1788 if (execute_on & EXECUTE_ON_POST_HOST_BACKUP) {
1789 eo_str = vstrextend(&eo_str, sep, "POST-HOST-BACKUP", NULL);
1792 if (execute_on & EXECUTE_ON_PRE_RECOVER) {
1793 eo_str = vstrextend(&eo_str, sep, "PRE-RECOVER", NULL);
1796 if (execute_on & EXECUTE_ON_POST_RECOVER) {
1797 eo_str = vstrextend(&eo_str, sep, "POST-RECOVER", NULL);
1800 if (execute_on & EXECUTE_ON_PRE_LEVEL_RECOVER) {
1801 eo_str = vstrextend(&eo_str, sep, "PRE-LEVEL-RECOVER", NULL);
1804 if (execute_on & EXECUTE_ON_POST_LEVEL_RECOVER) {
1805 eo_str = vstrextend(&eo_str, sep, "POST-LEVEL-RECOVER", NULL);
1808 if (execute_on & EXECUTE_ON_INTER_LEVEL_RECOVER) {
1809 eo_str = vstrextend(&eo_str, sep, "INTER-LEVEL-RECOVER", NULL);
1812 if (execute_on != 0)
1813 xml_scr1 = vstrextend(&xml_scr1,
1814 " <execute_on>", eo_str,
1815 "</execute_on>\n", NULL);
1817 proplist = pp_script_get_property(pp_script);
1818 xml_app.result = stralloc("");
1819 g_hash_table_foreach(proplist, xml_property, &xml_app);
1821 client_name = pp_script_get_client_name(pp_script);
1822 if (client_name && strlen(client_name) > 0 &&
1823 am_has_feature(their_features, fe_script_client_name)) {
1824 char *b64client_name = amxml_format_tag("client_name",
1826 vstrextend(&xml_app.result, " ", b64client_name, "\n", NULL);
1829 xml_scr = vstrextend(&xml_scr, xml_scr1, xml_app.result, " </script>\n", NULL);
1831 amfree(xml_app.result);
1844 for (dp = origqp->head; dp != NULL; dp = dp->next) {
1845 if (dp->ignore || dp->strategy == DS_SKIP)
1857 char *prevhost = NULL;
1858 char *errstr = NULL;
1869 for(dp = origqp->head; dp != NULL; dp = dp->next) {
1875 for(i=0;i<sargc;i++) {
1877 for(dp = origqp->head; dp != NULL; dp = dp->next) {
1878 if(match_host(sargv[i], dp->host->hostname))
1883 for(dp = origqp->head; dp != NULL; dp = dp->next) {
1884 if(prevhost != NULL &&
1885 match_host(prevhost, dp->host->hostname) &&
1886 (match_disk(sargv[i], dp->name) ||
1887 (dp->device && match_disk(sargv[i], dp->device)))) {
1889 error(_("Argument %s cannot be both a host and a disk"),sargv[i]);
1893 if(dp->todo == -1) {
1897 } else if (dp->todo == 0) {
1901 } else { /* dp->todo == 1 */
1909 if(match_a_host == 1) {
1910 if(prev_match == 1) { /* all disk of the previous host */
1911 for(dp = origqp->head; dp != NULL; dp = dp->next) {
1912 if(match_host(prevhost,dp->host->hostname))
1913 if(dp->todo == -1) {
1918 if (!match_a_disk) {
1920 errstr1 = vstrallocf(_("All disks on host '%s' are ignored or have strategy \"skip\".\n"), prevhost);
1921 vstrextend(&errstr, errstr1, NULL);
1925 prevhost = sargv[i];
1930 if (strchr(sargv[i], (int)'\\')) {
1931 errstr1 = vstrallocf(_("Argument '%s' matches neither a host nor a disk; quoting may not be correct.\n"), sargv[i]);
1933 errstr1 = vstrallocf(_("Argument '%s' matches neither a host nor a disk.\n"), sargv[i]);
1935 vstrextend(&errstr, errstr1, NULL);
1939 } else if (dp_skip) {
1941 if (dp_skip->strategy == DS_SKIP) {
1942 errstr1 = vstrallocf(_("Argument '%s' matches a disk with strategy \"skip\".\n"), sargv[i]);
1944 errstr1 = vstrallocf(_("Argument '%s' matches a disk marked \"ignore\".\n"), sargv[i]);
1946 vstrextend(&errstr, errstr1, NULL);
1952 if(prev_match == 1) { /* all disk of the previous host */
1954 for(dp = origqp->head; dp != NULL; dp = dp->next) {
1955 if(match_host(prevhost,dp->host->hostname))
1956 if(dp->todo == -1) {
1961 if (!match_a_disk) {
1963 errstr1 = vstrallocf(_("All disks on host '%s' are ignored or have strategy \"skip\".\n"), prevhost);
1964 vstrextend(&errstr, errstr1, NULL);
1969 for(dp = origqp->head; dp != NULL; dp = dp->next) {
1987 /* rather than try to reproduce the adaptive matching logic in
1988 * match_disklist, this simply creates a new, fake disklist with one
1989 * element in it, and calls match_disklist directly */
1991 bzero(&h, sizeof(h));
1992 h.hostname = file->name;
1995 bzero(&d, sizeof(d));
1997 d.hostname = file->name;
1998 d.name = file->disk;
1999 d.device = file->disk;
2002 dl.head = dl.tail = &d;
2004 (void)match_disklist(&dl, sargc, sargv);
2009 disklist_netifs(void)
2016 static void dump_disk(const disk_t *);
2017 static void dump_disklist(const disklist_t *);
2018 int main(int, char *[]);
2024 g_printf(_(" DISK %s (HOST %s, LINE %d) TYPE %s NAME %s SPINDLE %d\n"),
2025 dp->name, dp->host->hostname, dp->line, dp->dtype_name,
2026 dp->name == NULL? "(null)": dp->name,
2032 const disklist_t * lst)
2034 const disk_t *dp, *prev;
2035 const am_host_t *hp;
2037 if(hostlist == NULL) {
2038 g_printf(_("DISKLIST not read in\n"));
2042 g_printf(_("DISKLIST BY HOSTNAME:\n"));
2044 for(hp = hostlist; hp != NULL; hp = hp->next) {
2045 char *if_name = NULL;
2046 if (hp->netif && hp->netif->config)
2047 if_name = interface_name(hp->netif->config);
2049 g_printf(_("HOST %s INTERFACE %s\n"),
2051 if_name ? _("(null)") : if_name);
2052 for(dp = hp->disks; dp != NULL; dp = dp->hostnext)
2058 g_printf(_("DISKLIST IN FILE ORDER:\n"));
2061 for(dp = lst->head; dp != NULL; prev = dp, dp = dp->next) {
2063 /* check pointers */
2064 if(dp->prev != prev) g_printf(_("*** prev pointer mismatch!\n"));
2065 if(dp->next == NULL && lst->tail != dp) g_printf(_("tail mismatch!\n"));
2075 char *conf_diskfile;
2080 * Configure program for internationalization:
2081 * 1) Only set the message locale for now.
2082 * 2) Set textdomain for all amanda related programs to "amanda"
2083 * We don't want to be forced to support dozens of message catalogs.
2085 setlocale(LC_MESSAGES, "C");
2086 textdomain("amanda");
2090 set_pname("diskfile");
2092 dbopen(DBG_SUBDIR_SERVER);
2094 /* Don't die when child closes pipe */
2095 signal(SIGPIPE, SIG_IGN);
2098 config_init(CONFIG_INIT_EXPLICIT_NAME, argv[1]);
2100 config_init(CONFIG_INIT_USE_CWD, NULL)
2103 if (config_errors(NULL) >= CFGERR_WARNINGS) {
2104 config_print_errors();
2105 if (config_errors(NULL) >= CFGERR_ERRORS) {
2106 g_critical(_("errors processing config file"));
2110 conf_diskfile = config_dir_relative(getconf_str(CNF_DISKFILE));
2111 result = read_diskfile(conf_diskfile, &lst);
2112 if(result == CFGERR_OK) {
2113 dump_disklist(&lst);
2115 config_print_errors();
2117 amfree(conf_diskfile);