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 $
38 static am_host_t *hostlist;
39 static netif_t *all_netifs;
42 static char *upcase(char *st);
43 static int parse_diskline(disklist_t *, const char *, FILE *, int *, char **);
44 static void disk_parserror(const char *, int, const char *, ...)
59 lst->head = lst->tail = NULL;
62 if ((diskf = fopen(filename, "r")) == NULL) {
67 while ((line = agets(diskf)) != NULL) {
69 if (line[0] != '\0') {
70 if (parse_diskline(lst, filename, diskf, &line_num, &line) < 0) {
89 for (p = hostlist; p != NULL; p = p->next) {
90 if(strcasecmp(p->hostname, hostname) == 0) return p;
103 host = lookup_host(hostname);
107 for (disk = host->disks; disk != NULL; disk = disk->hostnext) {
108 if (strcmp(disk->name, diskname) == 0)
116 * put disk on end of queue
124 if(list->tail == NULL) list->head = disk;
125 else list->tail->next = disk;
126 disk->prev = list->tail;
134 * put disk on head of queue
142 if(list->head == NULL) list->tail = disk;
143 else list->head->prev = disk;
144 disk->next = list->head;
152 * insert in sorted order
159 int (*cmp)(disk_t *a, disk_t *b))
167 if(cmp(disk, ptr) < 0) break;
174 if(prev == NULL) list->head = disk;
175 else prev->next = disk;
176 if(ptr == NULL) list->tail = disk;
177 else ptr->prev = disk;
189 disk = alloc(SIZEOF(disk_t));
191 disk->tape_splitsize = (off_t)0;
192 disk->split_diskbuffer = NULL;
193 disk->fallback_splitsize = (off_t)0;
194 disk->hostname = stralloc(hostname);
195 disk->name = stralloc(diskname);
196 disk->device = stralloc(diskname);
199 disk->compress = COMP_NONE;
200 disk->encrypt = ENCRYPT_NONE;
204 disk->exclude_list = NULL;
205 disk->exclude_file = NULL;
206 disk->include_list = NULL;
207 disk->include_file = NULL;
209 host = lookup_host(hostname);
211 host = alloc(SIZEOF(am_host_t));
212 host->next = hostlist;
215 host->hostname = stralloc(hostname);
217 host->inprogress = 0;
222 host->features = NULL;
224 enqueue_disk(list, disk);
227 disk->hostnext = host->disks;
235 * check if disk is present in list. Return true if so, false otherwise.
246 while ((t != NULL) && (t != disk)) {
261 int (*cmp)(disk_t *a, disk_t *b))
266 tmp = in; /* just in case in == out */
268 out->head = (disk_t *)0;
269 out->tail = (disk_t *)0;
271 while((disk = dequeue_disk(tmp)))
272 insert_disk(out, disk, cmp);
277 * remove disk from front of queue
286 if(list->head == NULL) return NULL;
289 list->head = disk->next;
291 if(list->head == NULL) list->tail = NULL;
292 else list->head->prev = NULL;
294 disk->prev = disk->next = NULL; /* for debugging */
303 if(disk->prev == NULL) list->head = disk->next;
304 else disk->prev->next = disk->next;
306 if(disk->next == NULL) list->tail = disk->prev;
307 else disk->next->prev = disk->prev;
309 disk->prev = disk->next = NULL;
317 am_host_t *host, *hostnext;
319 while (dl->head != NULL) {
320 dp = dequeue_disk(dl);
322 amfree(dp->hostname);
324 free_sl(dp->exclude_file);
325 free_sl(dp->exclude_list);
326 free_sl(dp->include_file);
327 free_sl(dp->include_list);
331 for(host=hostlist; host != NULL; host = hostnext) {
332 amfree(host->hostname);
333 am_release_feature_set(host->features);
334 host->features = NULL;
335 hostnext = host->next;
348 if(islower((int)*s)) *s = (char)toupper((int)*s);
355 /* return 0 on success */
356 /* return -1 on error */
360 const char *filename,
363 /*@keep@*/ char ** line_p)
368 netif_t *netif = NULL;
369 interface_t *cfg_if = NULL;
370 char *hostname = NULL;
371 char *diskname, *diskdevice;
375 char *line = *line_p;
376 int line_num = *line_num_p;
383 assert(filename != NULL);
384 assert(line_num > 0);
385 assert(line != NULL);
389 skip_whitespace(s, ch);
390 if(ch == '\0' || ch == '#')
394 skip_non_whitespace(s, ch);
396 host = lookup_host(fp);
398 hostname = stralloc(fp);
400 hostname = stralloc(host->hostname);
401 if (strcmp(host->hostname, fp) != 0) {
402 disk_parserror(filename, line_num, "Same host with different case: \"%s\" and \"%s\".", host->hostname, fp);
407 shost = sanitise_filename(hostname);
408 for (p = hostlist; p != NULL; p = p->next) {
409 char *shostp = sanitise_filename(p->hostname);
410 if (strcmp(hostname, p->hostname) &&
411 !strcmp(shost, shostp)) {
412 disk_parserror(filename, line_num, "Two hosts are mapping to the same name: \"%s\" and \"%s\"", p->hostname, hostname);
415 else if (strcasecmp(hostname, p->hostname) &&
416 match_host(hostname, p->hostname) &&
417 match_host(p->hostname, hostname)) {
418 disk_parserror(filename, line_num, _("Duplicate host name: \"%s\" and \"%s\""), p->hostname, hostname);
425 skip_whitespace(s, ch);
426 if(ch == '\0' || ch == '#') {
427 disk_parserror(filename, line_num, _("disk device name expected"));
433 skip_quoted_string(s, ch);
435 diskname = unquote_string(fp);
437 skip_whitespace(s, ch);
438 if(ch == '\0' || ch == '#') {
439 disk_parserror(filename, line_num, _("disk dumptype expected"));
445 skip_quoted_string(s, ch);
452 dumptype = unquote_string(fp);
453 if ((dtype = lookup_dumptype(dumptype)) == NULL) {
454 diskdevice = dumptype;
455 skip_whitespace(s, ch);
456 if(ch == '\0' || ch == '#') {
457 disk_parserror(filename, line_num,
458 _("disk dumptype '%s' not found"), dumptype);
466 skip_quoted_string(s, ch);
469 dumptype = unquote_string(fp);
474 /* check for duplicate disk */
477 if ((disk = lookup_disk(hostname, diskname)) != NULL) {
482 if (match_disk(diskname, disk->name) &&
483 match_disk(disk->name, diskname)) {
486 disk = disk->hostnext;
489 while (dup == 0 && disk != NULL);
492 disk_parserror(filename, line_num,
493 _("duplicate disk record, previous on line %d"),
498 disk = alloc(SIZEOF(disk_t));
499 disk->line = line_num;
500 disk->hostname = stralloc(hostname);
501 disk->name = diskname;
502 disk->device = diskdevice;
505 disk->inprogress = 0;
509 sdisk = sanitise_filename(diskname);
510 for (dp = host->disks; dp != NULL; dp = dp->next) {
511 char *sdiskp = sanitise_filename(dp->name);
512 if (strcmp(diskname, dp->name) != 0 &&
513 strcmp(sdisk, sdiskp) == 0) {
514 disk_parserror(filename, line_num,
515 _("Two disks are mapping to the same name: \"%s\" and \"%s\"; you must use different diskname"),
527 skip_whitespace(s, ch);
528 if (ch != '\0' && ch != '#') {
529 disk_parserror(filename, line_num,
530 _("expected line break after `{\', ignoring rest of line"));
533 if (strchr(s-1, '}') &&
534 (strchr(s-1, '#') == NULL ||
535 strchr(s-1, '}') < strchr(s-1, '#'))) {
536 disk_parserror(filename, line_num,_("'}' on same line than '{'"));
539 amfree(disk->device);
548 dtype = read_dumptype(vstralloc("custom(", hostname,
549 ":", disk->name, ")", NULL),
550 diskf, (char*)filename, line_num_p);
551 if (dtype == NULL || dup) {
552 disk_parserror(filename, line_num,
553 _("read of custom dumptype failed"));
556 amfree(disk->device);
567 *line_p = line = agets(diskf);
568 line_num = *line_num_p; /* no incr, read_dumptype did it already */
571 *line_p = line = stralloc("");
575 if((dtype = lookup_dumptype(dumptype)) == NULL) {
576 char *qdt = quote_string(dumptype);
578 disk_parserror(filename, line_num, _("undefined dumptype `%s'"), qdt);
583 amfree(disk->device);
601 disk->dtype_name = dumptype_name(dtype);
602 disk->program = dumptype_get_program(dtype);
603 disk->exclude_list = duplicate_sl(dumptype_get_exclude(dtype).sl_list);
604 disk->exclude_file = duplicate_sl(dumptype_get_exclude(dtype).sl_file);
605 disk->exclude_optional = dumptype_get_exclude(dtype).optional;
606 disk->include_list = duplicate_sl(dumptype_get_include(dtype).sl_list);
607 disk->include_file = duplicate_sl(dumptype_get_include(dtype).sl_file);
608 disk->include_optional = dumptype_get_include(dtype).optional;
609 disk->priority = dumptype_get_priority(dtype);
610 disk->dumpcycle = dumptype_get_dumpcycle(dtype);
611 /* disk->frequency = dumptype_get_frequency(dtype);*/
612 disk->security_driver = dumptype_get_security_driver(dtype);
613 disk->maxdumps = dumptype_get_maxdumps(dtype);
614 disk->tape_splitsize = dumptype_get_tape_splitsize(dtype);
615 disk->split_diskbuffer = dumptype_get_split_diskbuffer(dtype);
616 disk->fallback_splitsize = dumptype_get_fallback_splitsize(dtype);
617 disk->maxpromoteday = dumptype_get_maxpromoteday(dtype);
618 disk->bumppercent = dumptype_get_bumppercent(dtype);
619 disk->bumpsize = dumptype_get_bumpsize(dtype);
620 disk->bumpdays = dumptype_get_bumpdays(dtype);
621 disk->bumpmult = dumptype_get_bumpmult(dtype);
622 disk->starttime = dumptype_get_starttime(dtype);
624 if (disk->starttime > 0) {
627 stm = localtime(&st);
628 disk->start_t -= stm->tm_sec + 60 * stm->tm_min + 3600 * stm->tm_hour;
629 disk->start_t += disk->starttime / 100 * 3600 +
630 disk->starttime % 100 * 60;
631 if ((disk->start_t - st) < -43200)
632 disk->start_t += 86400;
634 disk->strategy = dumptype_get_strategy(dtype);
635 disk->ignore = dumptype_get_ignore(dtype);
636 disk->estimate = dumptype_get_estimate(dtype);
637 disk->compress = dumptype_get_compress(dtype);
638 disk->srvcompprog = dumptype_get_srvcompprog(dtype);
639 disk->clntcompprog = dumptype_get_clntcompprog(dtype);
640 disk->encrypt = dumptype_get_encrypt(dtype);
641 disk->srv_decrypt_opt = dumptype_get_srv_decrypt_opt(dtype);
642 disk->clnt_decrypt_opt = dumptype_get_clnt_decrypt_opt(dtype);
643 disk->srv_encrypt = dumptype_get_srv_encrypt(dtype);
644 disk->clnt_encrypt = dumptype_get_clnt_encrypt(dtype);
645 disk->amandad_path = dumptype_get_amandad_path(dtype);
646 disk->client_username = dumptype_get_client_username(dtype);
647 disk->ssh_keys = dumptype_get_ssh_keys(dtype);
648 disk->comprate[0] = dumptype_get_comprate(dtype)[0];
649 disk->comprate[1] = dumptype_get_comprate(dtype)[1];
652 * Boolean parameters with no value (Appears here as value 2) defaults
653 * to TRUE for backward compatibility and for logical consistency.
655 disk->record = dumptype_get_record(dtype) != 0;
656 disk->skip_incr = dumptype_get_skip_incr(dtype) != 0;
657 disk->skip_full = dumptype_get_skip_full(dtype) != 0;
658 disk->to_holdingdisk = dumptype_get_to_holdingdisk(dtype);
659 disk->kencrypt = dumptype_get_kencrypt(dtype) != 0;
660 disk->index = dumptype_get_index(dtype) != 0;
664 skip_whitespace(s, ch);
666 if(ch && ch != '#') { /* get optional spindle number */
670 skip_non_whitespace(s, ch);
673 if (*fp1 == '-') fp1++;
674 for(;*fp1!='\0';fp1++) {
675 if(!isdigit((int)*fp1)) {
680 disk_parserror(filename, line_num, _("non-integer spindle `%s'"), fp);
686 disk->spindle = atoi(fp);
690 skip_whitespace(s, ch);
692 if(ch && ch != '#') { /* get optional network interface */
693 skip_non_whitespace(s, ch);
695 if((cfg_if = lookup_interface(upcase(fp))) == NULL) {
696 disk_parserror(filename, line_num,
697 _("undefined network interface `%s'"), fp);
704 cfg_if = lookup_interface("default");
707 /* see if we already have a netif_t for this interface */
708 for (netif = all_netifs; netif != NULL; netif = netif->next) {
709 if (netif->config == cfg_if)
713 /* nope; make up a new one */
715 netif = alloc(sizeof(*netif));
716 netif->next = all_netifs;
718 netif->config = cfg_if;
722 skip_whitespace(s, ch);
723 if(ch && ch != '#') { /* now we have garbage, ignore it */
724 disk_parserror(filename, line_num, _("end of line expected"));
727 if(dumptype_get_ignore(dtype) || dumptype_get_strategy(dtype) == DS_SKIP) {
731 /* success, add disk to lists */
733 if(host == NULL) { /* new host */
734 host = alloc(SIZEOF(am_host_t));
735 host->next = hostlist;
738 host->hostname = hostname;
741 host->inprogress = 0;
742 host->maxdumps = 1; /* will be overwritten */
746 host->features = NULL;
753 enqueue_disk(lst, disk);
756 disk->hostnext = host->disks;
758 host->maxdumps = disk->maxdumps;
764 printf_arglist_function2(void disk_parserror, const char *, filename,
765 int, line_num, const char *, format)
768 const char *xlated_fmt = gettext(format);
770 /* print error message */
772 g_fprintf(stderr, "\"%s\", line %d: ", filename, line_num);
773 arglist_start(argp, format);
774 g_vfprintf(stderr, xlated_fmt, argp);
784 int npr, /* we print first npr disks on queue, plus last two */
792 g_fprintf(f, _("%s QUEUE: empty\n"), st);
795 g_fprintf(f, _("%s QUEUE:\n"), st);
796 for(pos = 0, d = q.head, p = NULL; d != NULL; p = d, d = d->next, pos++) {
797 qname = quote_string(d->name);
798 if(pos < npr) g_fprintf(f, "%3d: %-10s %-4s\n",
799 pos, d->host->hostname, qname);
803 if(pos > npr+2) g_fprintf(f, " ...\n");
806 g_fprintf(f, "%3d: %-10s %-4s\n", pos-2, d->host->hostname, d->name);
809 g_fprintf(f, "%3d: %-10s %-4s\n", pos-1, d->host->hostname, d->name);
816 am_feature_t * their_features,
819 char *auth_opt = NULL;
820 char *kencrypt_opt = "";
821 char *compress_opt = "";
822 char *encrypt_opt = stralloc("");
823 char *decrypt_opt = stralloc("");
824 char *record_opt = "";
825 char *index_opt = "";
826 char *exclude_file = NULL;
827 char *exclude_list = NULL;
828 char *include_file = NULL;
829 char *include_list = NULL;
842 assert(dp->host != NULL);
844 qdpname = quote_string(dp->name);
845 if(am_has_feature(dp->host->features, fe_options_auth)) {
846 auth_opt = vstralloc("auth=", dp->security_driver, ";", NULL);
847 } else if(strcasecmp(dp->security_driver, "bsd") == 0) {
848 if(am_has_feature(dp->host->features, fe_options_bsd_auth))
849 auth_opt = stralloc("bsd-auth;");
852 _("WARNING: %s:%s does not support auth or bsd-auth\n"),
853 dp->host->hostname, qdpname);
855 } else if(strcasecmp(dp->security_driver, "krb4") == 0) {
856 if(am_has_feature(dp->host->features, fe_options_krb4_auth))
857 auth_opt = stralloc("krb4-auth;");
860 _("WARNING: %s:%s does not support auth or krb4-auth\n"),
861 dp->host->hostname, qdpname);
864 if(am_has_feature(dp->host->features, fe_options_kencrypt)) {
865 kencrypt_opt = "kencrypt;";
869 _("WARNING: %s:%s does not support kencrypt\n"),
870 dp->host->hostname, qdpname);
875 switch(dp->compress) {
877 if(am_has_feature(their_features, fe_options_compress_fast)) {
878 compress_opt = "compress-fast;";
882 _("WARNING: %s:%s does not support fast compression\n"),
883 dp->host->hostname, qdpname);
887 if(am_has_feature(their_features, fe_options_compress_best)) {
888 compress_opt = "compress-best;";
892 _("WARNING: %s:%s does not support best compression\n"),
893 dp->host->hostname, qdpname);
897 if(am_has_feature(their_features, fe_options_compress_cust)) {
898 compress_opt = vstralloc("comp-cust=", dp->clntcompprog, ";", NULL);
899 if (BSTRNCMP(compress_opt, "comp-cust=;") == 0){
902 _("ERROR: %s:%s client custom compression with no compression program specified\n"),
903 dp->host->hostname, qdpname);
910 _("WARNING: %s:%s does not support client custom compression\n"),
911 dp->host->hostname, qdpname);
914 case COMP_SERVER_FAST:
915 if(am_has_feature(their_features, fe_options_srvcomp_fast)) {
916 compress_opt = "srvcomp-fast;";
919 case COMP_SERVER_BEST:
920 if(am_has_feature(their_features, fe_options_srvcomp_best)) {
921 compress_opt = "srvcomp-best;";
924 case COMP_SERVER_CUST:
925 if(am_has_feature(their_features, fe_options_srvcomp_cust)) {
926 compress_opt = vstralloc("srvcomp-cust=", dp->srvcompprog, ";", NULL);
927 if (BSTRNCMP(compress_opt, "srvcomp-cust=;") == 0){
930 _("ERROR: %s:%s server custom compression with no compression program specified\n"),
931 dp->host->hostname, qdpname);
938 _("WARNING: %s:%s does not support server custom compression\n"),
939 dp->host->hostname, qdpname);
944 switch(dp->encrypt) {
946 if(am_has_feature(their_features, fe_options_encrypt_cust)) {
947 encrypt_opt = newvstralloc(encrypt_opt, "encrypt-cust=",
948 dp->clnt_encrypt, ";", NULL);
949 if (BSTRNCMP(encrypt_opt, "encrypt-cust=;") == 0) {
952 _("ERROR: %s:%s encrypt client with no encryption program specified\n"),
953 dp->host->hostname, qdpname);
957 if ( dp->compress == COMP_SERVER_FAST ||
958 dp->compress == COMP_SERVER_BEST ||
959 dp->compress == COMP_SERVER_CUST ) {
962 _("ERROR: %s:Client encryption with server compression is "
963 "not supported. See amanda.conf(5) for detail.\n"),
968 if(dp->clnt_decrypt_opt) {
969 if(am_has_feature(their_features, fe_options_client_decrypt_option)) {
970 decrypt_opt = newvstralloc(decrypt_opt, "client-decrypt-option=",
971 dp->clnt_decrypt_opt, ";", NULL);
975 _("WARNING: %s:%s does not support client decrypt option\n"),
976 dp->host->hostname, qdpname);
982 _("WARNING: %s:%s does not support client data encryption\n"),
983 dp->host->hostname, qdpname);
986 case ENCRYPT_SERV_CUST:
987 if(am_has_feature(their_features, fe_options_encrypt_serv_cust)) {
988 encrypt_opt = newvstralloc(encrypt_opt, "encrypt-serv-cust=",
989 dp->srv_encrypt, ";", NULL);
990 if (BSTRNCMP(encrypt_opt, "encrypt-serv-cust=;") == 0){
993 _("ERROR: %s:%s No encryption program specified in dumptypes\n"),
994 dp->host->hostname, qdpname);
995 g_fprintf(fdout, _("Change the dumptype in the disklist or mention "
996 "the ecnryption program to use in the dumptypes file"));
1001 if(dp->srv_decrypt_opt) {
1002 if(am_has_feature(their_features, fe_options_server_decrypt_option)) {
1003 decrypt_opt = newvstralloc(decrypt_opt, "server-decrypt-option=",
1004 dp->srv_decrypt_opt, ";", NULL);
1008 _("WARNING: %s:%s does not support server decrypt option\n"),
1009 dp->host->hostname, qdpname);
1015 _("WARNING: %s:%s does not support server data encryption\n"),
1016 dp->host->hostname, qdpname);
1022 if(am_has_feature(their_features, fe_options_no_record)) {
1023 record_opt = "no-record;";
1026 g_fprintf(fdout, _("WARNING: %s:%s does not support no record\n"),
1027 dp->host->hostname, qdpname);
1032 if(am_has_feature(their_features, fe_options_index)) {
1033 index_opt = "index;";
1036 g_fprintf(fdout, _("WARNING: %s:%s does not support index\n"),
1037 dp->host->hostname, qdpname);
1041 if(dp->kencrypt) kencrypt_opt = "kencrypt;";
1044 exclude_file = stralloc("");
1045 nb_exclude_file = 0;
1046 if(dp->exclude_file != NULL && dp->exclude_file->nb_element > 0) {
1047 nb_exclude_file = dp->exclude_file->nb_element;
1048 if(am_has_feature(their_features, fe_options_exclude_file)) {
1049 if(am_has_feature(their_features, fe_options_multiple_exclude) ||
1050 dp->exclude_file->nb_element == 1) {
1051 for(excl = dp->exclude_file->first; excl != NULL;
1052 excl = excl->next) {
1053 qname = quote_string(excl->name);
1054 exc = newvstralloc( exc, "exclude-file=", qname, ";", NULL);
1055 strappend(exclude_file, exc);
1059 qname = quote_string(dp->exclude_file->last->name);
1060 exc = newvstralloc(exc, "exclude-file=", qname, ";", NULL);
1061 strappend(exclude_file, exc);
1064 _("WARNING: %s:%s does not support multiple exclude\n"),
1065 dp->host->hostname, qdpname);
1070 g_fprintf(fdout, _("WARNING: %s:%s does not support exclude file\n"),
1071 dp->host->hostname, qdpname);
1074 exclude_list = stralloc("");
1075 if(dp->exclude_list != NULL && dp->exclude_list->nb_element > 0) {
1076 if(am_has_feature(their_features, fe_options_exclude_list)) {
1077 if(am_has_feature(their_features, fe_options_multiple_exclude) ||
1078 (dp->exclude_list->nb_element == 1 && nb_exclude_file == 0)) {
1079 for(excl = dp->exclude_list->first; excl != NULL;
1080 excl = excl->next) {
1081 qname = quote_string(excl->name);
1082 exc = newvstralloc( exc, "exclude-list=", qname, ";", NULL);
1083 strappend(exclude_list, exc);
1087 qname = quote_string(dp->exclude_list->last->name);
1088 exc = newvstralloc(exc, "exclude-list=", qname, ";", NULL);
1089 strappend(exclude_list, exc);
1092 _("WARNING: %s:%s does not support multiple exclude\n"),
1093 dp->host->hostname, qdpname);
1098 g_fprintf(fdout, _("WARNING: %s:%s does not support exclude list\n"),
1099 dp->host->hostname, qdpname);
1103 include_file = stralloc("");
1104 nb_include_file = 0;
1105 if(dp->include_file != NULL && dp->include_file->nb_element > 0) {
1106 nb_include_file = dp->include_file->nb_element;
1107 if(am_has_feature(their_features, fe_options_include_file)) {
1108 if(am_has_feature(their_features, fe_options_multiple_include) ||
1109 dp->include_file->nb_element == 1) {
1110 for(excl = dp->include_file->first; excl != NULL;
1111 excl = excl->next) {
1112 qname = quote_string(excl->name);
1113 exc = newvstralloc(exc, "include-file=", qname, ";", NULL);
1114 strappend(include_file, exc);
1118 qname = quote_string(dp->include_file->last->name);
1119 exc = newvstralloc(exc, "include-file=", qname, ";", NULL);
1120 strappend(include_file, exc);
1123 _("WARNING: %s:%s does not support multiple include\n"),
1124 dp->host->hostname, qdpname);
1129 g_fprintf(fdout, _("WARNING: %s:%s does not support include file\n"),
1130 dp->host->hostname, qdpname);
1133 include_list = stralloc("");
1134 if(dp->include_list != NULL && dp->include_list->nb_element > 0) {
1135 if(am_has_feature(their_features, fe_options_include_list)) {
1136 if(am_has_feature(their_features, fe_options_multiple_include) ||
1137 (dp->include_list->nb_element == 1 && nb_include_file == 0)) {
1138 for(excl = dp->include_list->first; excl != NULL;
1139 excl = excl->next) {
1140 qname = quote_string(excl->name);
1141 exc = newvstralloc(exc, "include-list=", qname, ";", NULL);
1142 strappend(include_list, exc);
1146 qname = quote_string(dp->include_list->last->name);
1147 exc = newvstralloc(exc, "include-list=", qname, ";", NULL);
1148 strappend(include_list, exc);
1151 _("WARNING: %s:%s does not support multiple include\n"),
1152 dp->host->hostname, qdpname);
1157 g_fprintf(fdout, _("WARNING: %s:%s does not support include list\n"),
1158 dp->host->hostname, qdpname);
1162 if(dp->exclude_optional) {
1163 if(am_has_feature(their_features, fe_options_optional_exclude)) {
1164 excl_opt = "exclude-optional;";
1168 _("WARNING: %s:%s does not support optional exclude\n"),
1169 dp->host->hostname, qdpname);
1172 if(dp->include_optional) {
1173 if(am_has_feature(their_features, fe_options_optional_include)) {
1174 incl_opt = "include-optional;";
1178 _("WARNING: %s:%s does not support optional include\n"),
1179 dp->host->hostname, qdpname);
1183 result = vstralloc(";",
1200 amfree(exclude_list);
1201 amfree(exclude_file);
1202 amfree(include_file);
1203 amfree(include_list);
1205 amfree(decrypt_opt);
1206 amfree(encrypt_opt);
1208 /* result contains at least 'auth=...' */
1224 char *prevhost = NULL;
1225 char *errstr = NULL;
1235 for(dp = origqp->head; dp != NULL; dp = dp->next) {
1241 for(i=0;i<sargc;i++) {
1243 for(dp = origqp->head; dp != NULL; dp = dp->next) {
1244 if(match_host(sargv[i], dp->host->hostname))
1248 for(dp = origqp->head; dp != NULL; dp = dp->next) {
1249 if(prevhost != NULL &&
1250 match_host(prevhost, dp->host->hostname) &&
1251 (match_disk(sargv[i], dp->name) ||
1252 (dp->device && match_disk(sargv[i], dp->device)))) {
1254 error(_("Argument %s cannot be both a host and a disk"),sargv[i]);
1258 if(dp->todo == -1) {
1267 if(match_a_host == 1) {
1268 if(prev_match == 1) { /* all disk of the previous host */
1269 for(dp = origqp->head; dp != NULL; dp = dp->next) {
1270 if(match_host(prevhost,dp->host->hostname))
1275 prevhost = sargv[i];
1279 char *errstr1 = vstrallocf(_("Argument '%s' matches neither a host nor a disk.\n"), sargv[i]);
1280 vstrextend(&errstr, errstr1, NULL);
1286 if(prev_match == 1) { /* all disk of the previous host */
1287 for(dp = origqp->head; dp != NULL; dp = dp->next) {
1288 if(match_host(prevhost,dp->host->hostname))
1294 for(dp = origqp->head; dp != NULL; dp = dp->next) {
1303 disklist_netifs(void)
1310 static void dump_disk(const disk_t *);
1311 static void dump_disklist(const disklist_t *);
1312 int main(int, char *[]);
1318 g_printf(_(" DISK %s (HOST %s, LINE %d) TYPE %s NAME %s SPINDLE %d\n"),
1319 dp->name, dp->host->hostname, dp->line, dp->dtype_name,
1320 dp->name == NULL? "(null)": dp->name,
1326 const disklist_t * lst)
1328 const disk_t *dp, *prev;
1329 const am_host_t *hp;
1331 if(hostlist == NULL) {
1332 g_printf(_("DISKLIST not read in\n"));
1336 g_printf(_("DISKLIST BY HOSTNAME:\n"));
1338 for(hp = hostlist; hp != NULL; hp = hp->next) {
1339 char *if_name = NULL;
1340 if (hp->netif && hp->netif->config)
1341 if_name = interface_name(hp->netif->config);
1343 g_printf(_("HOST %s INTERFACE %s\n"),
1345 if_name ? _("(null)") : if_name);
1346 for(dp = hp->disks; dp != NULL; dp = dp->hostnext)
1352 g_printf(_("DISKLIST IN FILE ORDER:\n"));
1355 for(dp = lst->head; dp != NULL; prev = dp, dp = dp->next) {
1357 /* check pointers */
1358 if(dp->prev != prev) g_printf(_("*** prev pointer mismatch!\n"));
1359 if(dp->next == NULL && lst->tail != dp) g_printf(_("tail mismatch!\n"));
1369 char *conf_diskfile;
1374 * Configure program for internationalization:
1375 * 1) Only set the message locale for now.
1376 * 2) Set textdomain for all amanda related programs to "amanda"
1377 * We don't want to be forced to support dozens of message catalogs.
1379 setlocale(LC_MESSAGES, "C");
1380 textdomain("amanda");
1384 set_pname("diskfile");
1386 dbopen(DBG_SUBDIR_SERVER);
1388 /* Don't die when child closes pipe */
1389 signal(SIGPIPE, SIG_IGN);
1391 malloc_size_1 = malloc_inuse(&malloc_hist_1);
1394 config_name = argv[1];
1395 if (strchr(config_name, '/') != NULL) {
1396 config_dir = stralloc2(argv[1], "/");
1397 config_name = strrchr(config_name, '/') + 1;
1399 config_dir = vstralloc(CONFIG_DIR, "/", config_name, "/", NULL);
1402 config_dir = stralloc("");
1404 conffile = stralloc2(config_dir, CONFFILE_NAME);
1405 if((result = read_conffile(conffile)) == 0) {
1406 conf_diskfile = config_dir_relative(getconf_str(CNF_DISKFILE));
1407 result = read_diskfile(conf_diskfile, &lst);
1409 dump_disklist(&lst);
1411 amfree(conf_diskfile);