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;
41 static char *upcase(char *st);
42 static int parse_diskline(disklist_t *, const char *, FILE *, int *, char **);
43 static void disk_parserror(const char *, int, const char *, ...)
44 __attribute__ ((format (printf, 3, 4)));
58 lst->head = lst->tail = NULL;
61 if ((diskf = fopen(filename, "r")) == NULL) {
66 while ((line = agets(diskf)) != NULL) {
68 if (line[0] != '\0') {
69 if (parse_diskline(lst, filename, diskf, &line_num, &line) < 0) {
88 for (p = hostlist; p != NULL; p = p->next) {
89 if(strcasecmp(p->hostname, hostname) == 0) return p;
102 host = lookup_host(hostname);
106 for (disk = host->disks; disk != NULL; disk = disk->hostnext) {
107 if (strcmp(disk->name, diskname) == 0)
115 * put disk on end of queue
123 if(list->tail == NULL) list->head = disk;
124 else list->tail->next = disk;
125 disk->prev = list->tail;
133 * put disk on head of queue
141 if(list->head == NULL) list->tail = disk;
142 else list->head->prev = disk;
143 disk->next = list->head;
151 * insert in sorted order
158 int (*cmp)(disk_t *a, disk_t *b))
166 if(cmp(disk, ptr) < 0) break;
173 if(prev == NULL) list->head = disk;
174 else prev->next = disk;
175 if(ptr == NULL) list->tail = disk;
176 else ptr->prev = disk;
188 disk = alloc(SIZEOF(disk_t));
190 disk->tape_splitsize = (off_t)0;
191 disk->split_diskbuffer = NULL;
192 disk->fallback_splitsize = (off_t)0;
193 disk->hostname = stralloc(hostname);
194 disk->name = stralloc(diskname);
195 disk->device = stralloc(diskname);
198 disk->compress = COMP_NONE;
199 disk->encrypt = ENCRYPT_NONE;
203 disk->exclude_list = NULL;
204 disk->exclude_file = NULL;
205 disk->include_list = NULL;
206 disk->include_file = NULL;
208 host = lookup_host(hostname);
210 host = alloc(SIZEOF(am_host_t));
211 host->next = hostlist;
214 host->hostname = stralloc(hostname);
216 host->inprogress = 0;
221 host->features = NULL;
223 enqueue_disk(list, disk);
226 disk->hostnext = host->disks;
234 * check if disk is present in list. Return true if so, false otherwise.
245 while ((t != NULL) && (t != disk)) {
260 int (*cmp)(disk_t *a, disk_t *b))
265 tmp = in; /* just in case in == out */
267 out->head = (disk_t *)0;
268 out->tail = (disk_t *)0;
270 while((disk = dequeue_disk(tmp)))
271 insert_disk(out, disk, cmp);
276 * remove disk from front of queue
285 if(list->head == NULL) return NULL;
288 list->head = disk->next;
290 if(list->head == NULL) list->tail = NULL;
291 else list->head->prev = NULL;
293 disk->prev = disk->next = NULL; /* for debugging */
302 if(disk->prev == NULL) list->head = disk->next;
303 else disk->prev->next = disk->next;
305 if(disk->next == NULL) list->tail = disk->prev;
306 else disk->next->prev = disk->prev;
308 disk->prev = disk->next = NULL;
316 am_host_t *host, *hostnext;
318 while (dl->head != NULL) {
319 dp = dequeue_disk(dl);
321 free_sl(dp->exclude_file);
322 free_sl(dp->exclude_list);
323 free_sl(dp->include_file);
324 free_sl(dp->include_list);
328 for(host=hostlist; host != NULL; host = hostnext) {
329 amfree(host->hostname);
330 am_release_feature_set(host->features);
331 host->features = NULL;
332 hostnext = host->next;
345 if(islower((int)*s)) *s = (char)toupper((int)*s);
352 /* return 0 on success */
353 /* return -1 on error */
357 const char *filename,
360 /*@keep@*/ char ** line_p)
365 interface_t *netif = 0;
366 char *hostname = NULL;
367 char *diskname, *diskdevice;
371 char *line = *line_p;
372 int line_num = *line_num_p;
379 assert(filename != NULL);
380 assert(line_num > 0);
381 assert(line != NULL);
385 skip_whitespace(s, ch);
386 if(ch == '\0' || ch == '#')
390 skip_non_whitespace(s, ch);
392 host = lookup_host(fp);
394 hostname = stralloc(fp);
395 malloc_mark(hostname);
397 hostname = stralloc(host->hostname);
398 if (strcmp(host->hostname, fp) != 0) {
399 disk_parserror(filename, line_num, "Same host with different case: \"%s\" and \"%s\".", host->hostname, fp);
404 shost = sanitise_filename(hostname);
405 for (p = hostlist; p != NULL; p = p->next) {
406 char *shostp = sanitise_filename(p->hostname);
407 if (!strcmp(hostname, p->hostname) &&
408 strcmp(shost, shostp)) {
409 disk_parserror(filename, line_num, "Two host are mapping to the same name: \"%s\" and \"%s\"", p->hostname, hostname);
412 else if (strcasecmp(hostname, p->hostname) &&
413 match_host(hostname, p->hostname) &&
414 match_host(p->hostname, hostname)) {
415 disk_parserror(filename, line_num, "Duplicate host name: \"%s\" and \"%s\"", p->hostname, hostname);
422 skip_whitespace(s, ch);
423 if(ch == '\0' || ch == '#') {
424 disk_parserror(filename, line_num, "disk device name expected");
430 skip_quoted_string(s, ch);
432 diskname = unquote_string(fp);
434 skip_whitespace(s, ch);
435 if(ch == '\0' || ch == '#') {
436 disk_parserror(filename, line_num, "disk dumptype expected");
442 skip_quoted_string(s, ch);
449 dumptype = unquote_string(fp);
450 if ((dtype = lookup_dumptype(dumptype)) == NULL) {
451 diskdevice = dumptype;
452 skip_whitespace(s, ch);
453 if(ch == '\0' || ch == '#') {
454 disk_parserror(filename, line_num,
455 "disk dumptype '%s' not found", dumptype);
463 skip_quoted_string(s, ch);
466 dumptype = unquote_string(fp);
471 /* check for duplicate disk */
474 if ((disk = lookup_disk(hostname, diskname)) != NULL) {
479 if (match_disk(diskname, disk->name) &&
480 match_disk(disk->name, diskname)) {
483 disk = disk->hostnext;
486 while (dup == 0 && disk != NULL);
489 disk_parserror(filename, line_num,
490 "duplicate disk record, previous on line %d",
495 disk = alloc(SIZEOF(disk_t));
497 disk->line = line_num;
498 disk->hostname = stralloc(hostname);
499 disk->name = diskname;
500 disk->device = diskdevice;
501 malloc_mark(disk->name);
504 disk->inprogress = 0;
508 sdisk = sanitise_filename(diskname);
509 for (dp = host->disks; dp != NULL; dp = dp->next) {
510 char *sdiskp = sanitise_filename(dp->name);
511 if (strcmp(diskname, dp->name) != 0 &&
512 strcmp(sdisk, sdiskp) == 0) {
513 disk_parserror(filename, line_num,
514 "Two disk are mapping to the same name: \"%s\" and \"%s\""
515 ", 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 = dtype->name;
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((netif = lookup_interface(upcase(fp))) == NULL) {
696 disk_parserror(filename, line_num,
697 "undefined network interface `%s'", fp);
704 netif = lookup_interface("default");
707 skip_whitespace(s, ch);
708 if(ch && ch != '#') { /* now we have garbage, ignore it */
709 disk_parserror(filename, line_num, "end of line expected");
712 if(dumptype_get_ignore(dtype) || dumptype_get_strategy(dtype) == DS_SKIP) {
716 /* success, add disk to lists */
718 if(host == NULL) { /* new host */
719 host = alloc(SIZEOF(am_host_t));
721 host->next = hostlist;
724 host->hostname = hostname;
727 host->inprogress = 0;
728 host->maxdumps = 1; /* will be overwritten */
732 host->features = NULL;
739 enqueue_disk(lst, disk);
742 disk->hostnext = host->disks;
744 host->maxdumps = disk->maxdumps;
750 printf_arglist_function2(void disk_parserror, const char *, filename,
751 int, line_num, const char *, format)
755 /* print error message */
757 fprintf(stderr, "\"%s\", line %d: ", filename, line_num);
758 arglist_start(argp, format);
759 vfprintf(stderr, format, argp);
769 int npr, /* we print first npr disks on queue, plus last two */
777 fprintf(f, "%s QUEUE: empty\n", st);
780 fprintf(f, "%s QUEUE:\n", st);
781 for(pos = 0, d = q.head, p = NULL; d != NULL; p = d, d = d->next, pos++) {
782 qname = quote_string(d->name);
783 if(pos < npr) fprintf(f, "%3d: %-10s %-4s\n",
784 pos, d->host->hostname, qname);
788 if(pos > npr+2) fprintf(f, " ...\n");
791 fprintf(f, "%3d: %-10s %-4s\n", pos-2, d->host->hostname, d->name);
794 fprintf(f, "%3d: %-10s %-4s\n", pos-1, d->host->hostname, d->name);
801 am_feature_t * their_features,
804 char *auth_opt = NULL;
805 char *kencrypt_opt = "";
806 char *compress_opt = "";
807 char *encrypt_opt = stralloc("");
808 char *decrypt_opt = stralloc("");
809 char *record_opt = "";
810 char *index_opt = "";
811 char *exclude_file = NULL;
812 char *exclude_list = NULL;
813 char *include_file = NULL;
814 char *include_list = NULL;
827 assert(dp->host != NULL);
829 qdpname = quote_string(dp->name);
830 if(am_has_feature(dp->host->features, fe_options_auth)) {
831 auth_opt = vstralloc("auth=", dp->security_driver, ";", NULL);
832 } else if(strcasecmp(dp->security_driver, "bsd") == 0) {
833 if(am_has_feature(dp->host->features, fe_options_bsd_auth))
834 auth_opt = stralloc("bsd-auth;");
837 "WARNING: %s:%s does not support auth or bsd-auth\n",
838 dp->host->hostname, qdpname);
840 } else if(strcasecmp(dp->security_driver, "krb4") == 0) {
841 if(am_has_feature(dp->host->features, fe_options_krb4_auth))
842 auth_opt = stralloc("krb4-auth;");
845 "WARNING: %s:%s does not support auth or krb4-auth\n",
846 dp->host->hostname, qdpname);
849 if(am_has_feature(dp->host->features, fe_options_kencrypt)) {
850 kencrypt_opt = "kencrypt;";
854 "WARNING: %s:%s does not support kencrypt\n",
855 dp->host->hostname, qdpname);
860 switch(dp->compress) {
862 if(am_has_feature(their_features, fe_options_compress_fast)) {
863 compress_opt = "compress-fast;";
867 "WARNING: %s:%s does not support fast compression\n",
868 dp->host->hostname, qdpname);
872 if(am_has_feature(their_features, fe_options_compress_best)) {
873 compress_opt = "compress-best;";
877 "WARNING: %s:%s does not support best compression\n",
878 dp->host->hostname, qdpname);
882 if(am_has_feature(their_features, fe_options_compress_cust)) {
883 compress_opt = vstralloc("comp-cust=", dp->clntcompprog, ";", NULL);
884 if (BSTRNCMP(compress_opt, "comp-cust=;") == 0){
887 "ERROR: %s:%s client custom compression with no compression program specified\n",
888 dp->host->hostname, qdpname);
895 "WARNING: %s:%s does not support client custom compression\n",
896 dp->host->hostname, qdpname);
899 case COMP_SERVER_FAST:
900 if(am_has_feature(their_features, fe_options_srvcomp_fast)) {
901 compress_opt = "srvcomp-fast;";
904 case COMP_SERVER_BEST:
905 if(am_has_feature(their_features, fe_options_srvcomp_best)) {
906 compress_opt = "srvcomp-best;";
909 case COMP_SERVER_CUST:
910 if(am_has_feature(their_features, fe_options_srvcomp_cust)) {
911 compress_opt = vstralloc("srvcomp-cust=", dp->srvcompprog, ";", NULL);
912 if (BSTRNCMP(compress_opt, "srvcomp-cust=;") == 0){
915 "ERROR: %s:%s server custom compression with no compression program specified\n",
916 dp->host->hostname, qdpname);
923 "WARNING: %s:%s does not support server custom compression\n",
924 dp->host->hostname, qdpname);
929 switch(dp->encrypt) {
931 if(am_has_feature(their_features, fe_options_encrypt_cust)) {
932 encrypt_opt = newvstralloc(encrypt_opt, "encrypt-cust=",
933 dp->clnt_encrypt, ";", NULL);
934 if (BSTRNCMP(encrypt_opt, "encrypt-cust=;") == 0) {
937 "ERROR: %s:%s encrypt client with no encryption program specified\n",
938 dp->host->hostname, qdpname);
942 if ( dp->compress == COMP_SERVER_FAST ||
943 dp->compress == COMP_SERVER_BEST ||
944 dp->compress == COMP_SERVER_CUST ) {
947 "ERROR: %s:Client encryption with server compression is not supported. See amanda.conf(5) for detail.\n", dp->host->hostname);
951 if(dp->clnt_decrypt_opt) {
952 if(am_has_feature(their_features, fe_options_client_decrypt_option)) {
953 decrypt_opt = newvstralloc(decrypt_opt, "client-decrypt-option=",
954 dp->clnt_decrypt_opt, ";", NULL);
958 "WARNING: %s:%s does not support client decrypt option\n",
959 dp->host->hostname, qdpname);
965 "WARNING: %s:%s does not support client data encryption\n",
966 dp->host->hostname, qdpname);
969 case ENCRYPT_SERV_CUST:
970 if(am_has_feature(their_features, fe_options_encrypt_serv_cust)) {
971 encrypt_opt = newvstralloc(encrypt_opt, "encrypt-serv-cust=",
972 dp->srv_encrypt, ";", NULL);
973 if (BSTRNCMP(encrypt_opt, "encrypt-serv-cust=;") == 0){
976 "ERROR: %s:%s encrypt server with no encryption program specified\n",
977 dp->host->hostname, qdpname);
981 if(dp->srv_decrypt_opt) {
982 if(am_has_feature(their_features, fe_options_server_decrypt_option)) {
983 decrypt_opt = newvstralloc(decrypt_opt, "server-decrypt-option=",
984 dp->srv_decrypt_opt, ";", NULL);
988 "WARNING: %s:%s does not support server decrypt option\n",
989 dp->host->hostname, qdpname);
995 "WARNING: %s:%s does not support server data encryption\n",
996 dp->host->hostname, qdpname);
1002 if(am_has_feature(their_features, fe_options_no_record)) {
1003 record_opt = "no-record;";
1006 fprintf(fdout, "WARNING: %s:%s does not support no record\n",
1007 dp->host->hostname, qdpname);
1012 if(am_has_feature(their_features, fe_options_index)) {
1013 index_opt = "index;";
1016 fprintf(fdout, "WARNING: %s:%s does not support index\n",
1017 dp->host->hostname, qdpname);
1021 if(dp->kencrypt) kencrypt_opt = "kencrypt;";
1024 exclude_file = stralloc("");
1025 nb_exclude_file = 0;
1026 if(dp->exclude_file != NULL && dp->exclude_file->nb_element > 0) {
1027 nb_exclude_file = dp->exclude_file->nb_element;
1028 if(am_has_feature(their_features, fe_options_exclude_file)) {
1029 if(am_has_feature(their_features, fe_options_multiple_exclude) ||
1030 dp->exclude_file->nb_element == 1) {
1031 for(excl = dp->exclude_file->first; excl != NULL;
1032 excl = excl->next) {
1033 qname = quote_string(excl->name);
1034 exc = newvstralloc( exc, "exclude-file=", qname, ";", NULL);
1035 strappend(exclude_file, exc);
1039 qname = quote_string(dp->exclude_file->last->name);
1040 exc = newvstralloc(exc, "exclude-file=", qname, ";", NULL);
1041 strappend(exclude_file, exc);
1044 "WARNING: %s:%s does not support multiple exclude\n",
1045 dp->host->hostname, qdpname);
1050 fprintf(fdout, "WARNING: %s:%s does not support exclude file\n",
1051 dp->host->hostname, qdpname);
1054 exclude_list = stralloc("");
1055 if(dp->exclude_list != NULL && dp->exclude_list->nb_element > 0) {
1056 if(am_has_feature(their_features, fe_options_exclude_list)) {
1057 if(am_has_feature(their_features, fe_options_multiple_exclude) ||
1058 (dp->exclude_list->nb_element == 1 && nb_exclude_file == 0)) {
1059 for(excl = dp->exclude_list->first; excl != NULL;
1060 excl = excl->next) {
1061 qname = quote_string(excl->name);
1062 exc = newvstralloc( exc, "exclude-list=", qname, ";", NULL);
1063 strappend(exclude_list, exc);
1067 qname = quote_string(dp->exclude_list->last->name);
1068 exc = newvstralloc(exc, "exclude-list=", qname, ";", NULL);
1069 strappend(exclude_list, exc);
1072 "WARNING: %s:%s does not support multiple exclude\n",
1073 dp->host->hostname, qdpname);
1078 fprintf(fdout, "WARNING: %s:%s does not support exclude list\n",
1079 dp->host->hostname, qdpname);
1083 include_file = stralloc("");
1084 nb_include_file = 0;
1085 if(dp->include_file != NULL && dp->include_file->nb_element > 0) {
1086 nb_include_file = dp->include_file->nb_element;
1087 if(am_has_feature(their_features, fe_options_include_file)) {
1088 if(am_has_feature(their_features, fe_options_multiple_include) ||
1089 dp->include_file->nb_element == 1) {
1090 for(excl = dp->include_file->first; excl != NULL;
1091 excl = excl->next) {
1092 qname = quote_string(excl->name);
1093 exc = newvstralloc(exc, "include-file=", qname, ";", NULL);
1094 strappend(include_file, exc);
1098 qname = quote_string(dp->include_file->last->name);
1099 exc = newvstralloc(exc, "include-file=", qname, ";", NULL);
1100 strappend(include_file, exc);
1103 "WARNING: %s:%s does not support multiple include\n",
1104 dp->host->hostname, qdpname);
1109 fprintf(fdout, "WARNING: %s:%s does not support include file\n",
1110 dp->host->hostname, qdpname);
1113 include_list = stralloc("");
1114 if(dp->include_list != NULL && dp->include_list->nb_element > 0) {
1115 if(am_has_feature(their_features, fe_options_include_list)) {
1116 if(am_has_feature(their_features, fe_options_multiple_include) ||
1117 (dp->include_list->nb_element == 1 && nb_include_file == 0)) {
1118 for(excl = dp->include_list->first; excl != NULL;
1119 excl = excl->next) {
1120 qname = quote_string(excl->name);
1121 exc = newvstralloc(exc, "include-list=", qname, ";", NULL);
1122 strappend(include_list, exc);
1126 qname = quote_string(dp->include_list->last->name);
1127 exc = newvstralloc(exc, "include-list=", qname, ";", NULL);
1128 strappend(include_list, exc);
1131 "WARNING: %s:%s does not support multiple include\n",
1132 dp->host->hostname, qdpname);
1137 fprintf(fdout, "WARNING: %s:%s does not support include list\n",
1138 dp->host->hostname, qdpname);
1142 if(dp->exclude_optional) {
1143 if(am_has_feature(their_features, fe_options_optional_exclude)) {
1144 excl_opt = "exclude-optional;";
1148 "WARNING: %s:%s does not support optional exclude\n",
1149 dp->host->hostname, qdpname);
1152 if(dp->include_optional) {
1153 if(am_has_feature(their_features, fe_options_optional_include)) {
1154 incl_opt = "include-optional;";
1158 "WARNING: %s:%s does not support optional include\n",
1159 dp->host->hostname, qdpname);
1163 result = vstralloc(";",
1180 amfree(exclude_list);
1181 amfree(exclude_file);
1182 amfree(include_file);
1183 amfree(include_list);
1185 amfree(decrypt_opt);
1186 amfree(encrypt_opt);
1188 /* result contains at least 'auth=...' */
1204 char *prevhost = NULL;
1205 char *errstr = NULL;
1215 for(dp = origqp->head; dp != NULL; dp = dp->next) {
1221 for(i=0;i<sargc;i++) {
1223 for(dp = origqp->head; dp != NULL; dp = dp->next) {
1224 if(match_host(sargv[i], dp->host->hostname))
1228 for(dp = origqp->head; dp != NULL; dp = dp->next) {
1229 if(prevhost != NULL &&
1230 match_host(prevhost, dp->host->hostname) &&
1231 (match_disk(sargv[i], dp->name) ||
1232 (dp->device && match_disk(sargv[i], dp->device)))) {
1234 error("Argument %s match a host and a disk",sargv[i]);
1238 if(dp->todo == -1) {
1247 if(match_a_host == 1) {
1248 if(prev_match == 1) { /* all disk of the previous host */
1249 for(dp = origqp->head; dp != NULL; dp = dp->next) {
1250 if(match_host(prevhost,dp->host->hostname))
1255 prevhost = sargv[i];
1259 vstrextend(&errstr, "Argument '", sargv[i], "' match neither a host nor a disk.\n", NULL);
1264 if(prev_match == 1) { /* all disk of the previous host */
1265 for(dp = origqp->head; dp != NULL; dp = dp->next) {
1266 if(match_host(prevhost,dp->host->hostname))
1272 for(dp = origqp->head; dp != NULL; dp = dp->next) {
1283 static void dump_disk(const disk_t *);
1284 static void dump_disklist(const disklist_t *);
1285 int main(int, char *[]);
1291 printf(" DISK %s (HOST %s, LINE %d) TYPE %s NAME %s SPINDLE %d\n",
1292 dp->name, dp->host->hostname, dp->line, dp->dtype_name,
1293 dp->name == NULL? "(null)": dp->name,
1299 const disklist_t * lst)
1301 const disk_t *dp, *prev;
1302 const am_host_t *hp;
1304 if(hostlist == NULL) {
1305 printf("DISKLIST not read in\n");
1309 printf("DISKLIST BY HOSTNAME:\n");
1311 for(hp = hostlist; hp != NULL; hp = hp->next) {
1312 printf("HOST %s INTERFACE %s\n",
1314 (hp->netif == NULL||hp->netif->name == NULL) ? "(null)"
1316 for(dp = hp->disks; dp != NULL; dp = dp->hostnext)
1322 printf("DISKLIST IN FILE ORDER:\n");
1325 for(dp = lst->head; dp != NULL; prev = dp, dp = dp->next) {
1327 /* check pointers */
1328 if(dp->prev != prev) printf("*** prev pointer mismatch!\n");
1329 if(dp->next == NULL && lst->tail != dp) printf("tail mismatch!\n");
1339 char *conf_diskfile;
1342 unsigned long malloc_hist_1, malloc_size_1;
1343 unsigned long malloc_hist_2, malloc_size_2;
1347 set_pname("diskfile");
1349 dbopen(DBG_SUBDIR_SERVER);
1351 /* Don't die when child closes pipe */
1352 signal(SIGPIPE, SIG_IGN);
1354 malloc_size_1 = malloc_inuse(&malloc_hist_1);
1357 config_name = argv[1];
1358 if (strchr(config_name, '/') != NULL) {
1359 config_dir = stralloc2(argv[1], "/");
1360 config_name = strrchr(config_name, '/') + 1;
1362 config_dir = vstralloc(CONFIG_DIR, "/", config_name, "/", NULL);
1365 config_dir = stralloc("");
1367 conffile = stralloc2(config_dir, CONFFILE_NAME);
1368 if((result = read_conffile(conffile)) == 0) {
1369 conf_diskfile = getconf_str(CNF_DISKFILE);
1370 if (*conf_diskfile == '/') {
1371 conf_diskfile = stralloc(conf_diskfile);
1373 conf_diskfile = stralloc2(config_dir, conf_diskfile);
1375 result = read_diskfile(conf_diskfile, &lst);
1377 dump_disklist(&lst);
1379 amfree(conf_diskfile);
1384 malloc_size_2 = malloc_inuse(&malloc_hist_2);
1386 if(malloc_size_1 != malloc_size_2) {
1387 malloc_list(fileno(stderr), malloc_hist_1, malloc_hist_2);