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 * Authors: the Amanda Development Team. Its members are listed in a
24 * file named AUTHORS, in the root directory of this distribution.
27 * $Id: client_util.c,v 1.34 2006/05/25 01:47:11 johnfranks Exp $
33 #include "client_util.h"
36 #include "glib-util.h"
37 #include "timestamp.h"
38 #include "pipespawn.h"
42 #include "amandates.h"
44 #define MAXMAXDUMPS 16
46 static int add_exclude(FILE *file_exclude, char *aexc, int verbose);
47 static int add_include(char *disk, char *device, FILE *file_include, char *ainc, int verbose);
48 static char *build_name(char *disk, char *exin, int verbose);
49 static char *get_name(char *diskname, char *exin, time_t t, int n);
59 char *dirname = amname_to_dirname(device);
60 newname = vstralloc(dirname, "/", name , NULL);
64 newname = stralloc(name);
69 /* GDestroyFunc for a hash table whose values are GSLists contianing malloc'd
72 destroy_slist_free_full(gpointer list) {
73 slist_free_full((GSList *)list, g_free);
84 char number[NUM_STR_SIZE];
88 ts = get_timestamp_from_time(t);
92 g_snprintf(number, SIZEOF(number), "%03d", n - 1);
94 filename = vstralloc(get_pname(), ".", diskname, ".", ts, number, ".",
109 char *filename = NULL;
110 char *afilename = NULL;
116 struct dirent *entry;
118 size_t match_len, d_name_len;
122 diskname = sanitise_filename(disk);
124 dbgdir = stralloc2(AMANDA_TMPDIR, "/");
125 if((d = opendir(AMANDA_TMPDIR)) == NULL) {
126 error(_("open debug directory \"%s\": %s"),
127 AMANDA_TMPDIR, strerror(errno));
130 test_name = get_name(diskname, exin,
131 curtime - (getconf_int(CNF_DEBUG_DAYS) * 24 * 60 * 60), 0);
132 match_len = strlen(get_pname()) + strlen(diskname) + 2;
133 while((entry = readdir(d)) != NULL) {
134 if(is_dot_or_dotdot(entry->d_name)) {
137 d_name_len = strlen(entry->d_name);
138 if(strncmp(test_name, entry->d_name, match_len) != 0
139 || d_name_len < match_len + 14 + 8
140 || strcmp(entry->d_name+ d_name_len - 7, exin) != 0) {
141 continue; /* not one of our files */
143 if(strcmp(entry->d_name, test_name) < 0) {
144 e = newvstralloc(e, dbgdir, entry->d_name, NULL);
145 (void) unlink(e); /* get rid of old file */
154 filename = get_name(diskname, exin, curtime, n);
155 afilename = newvstralloc(afilename, dbgdir, filename, NULL);
156 if((fd=open(afilename, O_WRONLY|O_CREAT|O_APPEND, 0600)) < 0){
164 } while(!afilename && n < 1000);
166 if(afilename == NULL) {
167 filename = get_name(diskname, exin, curtime, 0);
168 afilename = newvstralloc(afilename, dbgdir, filename, NULL);
169 quoted = quote_string(afilename);
170 dbprintf(_("Cannot create %s (%s)\n"), quoted, strerror(errno));
172 g_printf(_("ERROR [cannot create %s (%s)]\n"),
173 quoted, strerror(errno));
196 (void)verbose; /* Quiet unused parameter warning */
199 if(aexc[l-1] == '\n') {
203 file = quoted = quote_string(aexc);
205 file[strlen(file) - 1] = '\0';
208 g_fprintf(file_exclude, "%s\n", file);
225 (void)disk; /* Quiet unused parameter warning */
226 (void)device; /* Quiet unused parameter warning */
229 if(ainc[l-1] == '\n') {
233 if (strncmp(ainc, "./", 2) != 0) {
234 quoted = quote_string(ainc);
235 dbprintf(_("include must start with './' (%s)\n"), quoted);
237 g_printf(_("ERROR [include must start with './' (%s)]\n"), quoted);
242 char *incname = ainc+2;
245 set_root = set_root_privs(1);
246 /* Take as is if not root && many '/' */
247 if(!set_root && strchr(incname, '/')) {
248 file = quoted = quote_string(ainc);
250 file[strlen(file) - 1] = '\0';
253 g_fprintf(file_include, "%s\n", file);
264 cwd = g_get_current_dir();
265 if (chdir(device) != 0) {
266 error(_("Failed to chdir(%s): %s\n"), device, strerror(errno));
268 glob(incname, 0, NULL, &globbuf);
269 if (chdir(cwd) != 0) {
270 error(_("Failed to chdir(%s): %s\n"), cwd, strerror(errno));
274 nb_exp = globbuf.gl_pathc;
275 for (nb=0; nb < nb_exp; nb++) {
276 file = stralloc2("./", globbuf.gl_pathv[nb]);
277 quoted = quote_string(file);
279 file[strlen(file) - 1] = '\0';
282 g_fprintf(file_include, "%s\n", file);
304 if (dle->exclude_file) nb_exclude += dle->exclude_file->nb_element;
305 if (dle->exclude_list) nb_exclude += dle->exclude_list->nb_element;
307 if (nb_exclude == 0) return NULL;
309 if ((filename = build_name(dle->disk, "exclude", verbose)) != NULL) {
310 if ((file_exclude = fopen(filename,"w")) != NULL) {
312 if (dle->exclude_file) {
313 for(excl = dle->exclude_file->first; excl != NULL;
315 add_exclude(file_exclude, excl->name,
316 verbose && dle->exclude_optional == 0);
320 if (dle->exclude_list) {
321 for(excl = dle->exclude_list->first; excl != NULL;
323 char *exclname = fixup_relative(excl->name, dle->device);
324 if((exclude = fopen(exclname, "r")) != NULL) {
325 while ((aexc = agets(exclude)) != NULL) {
326 if (aexc[0] == '\0') {
330 add_exclude(file_exclude, aexc,
331 verbose && dle->exclude_optional == 0);
337 quoted = quote_string(exclname);
338 dbprintf(_("Can't open exclude file %s (%s)\n"),
339 quoted, strerror(errno));
340 if(verbose && (dle->exclude_optional == 0 ||
342 g_printf(_("ERROR [Can't open exclude file %s (%s)]\n"),
343 quoted, strerror(errno));
350 fclose(file_exclude);
352 quoted = quote_string(filename);
353 dbprintf(_("Can't create exclude file %s (%s)\n"),
354 quoted, strerror(errno));
356 g_printf(_("ERROR [Can't create exclude file %s (%s)]\n"),
357 quoted, strerror(errno));
380 if (dle->include_file) nb_include += dle->include_file->nb_element;
381 if (dle->include_list) nb_include += dle->include_list->nb_element;
383 if (nb_include == 0) return NULL;
385 if ((filename = build_name(dle->disk, "include", verbose)) != NULL) {
386 if ((file_include = fopen(filename,"w")) != NULL) {
388 if (dle->include_file) {
389 for (incl = dle->include_file->first; incl != NULL;
391 nb_exp += add_include(dle->disk, dle->device, file_include,
393 verbose && dle->include_optional == 0);
397 if (dle->include_list) {
398 for (incl = dle->include_list->first; incl != NULL;
400 char *inclname = fixup_relative(incl->name, dle->device);
401 if ((include = fopen(inclname, "r")) != NULL) {
402 while ((ainc = agets(include)) != NULL) {
403 if (ainc[0] == '\0') {
407 nb_exp += add_include(dle->disk, dle->device,
409 verbose && dle->include_optional == 0);
415 quoted = quote_string(inclname);
416 dbprintf(_("Can't open include file %s (%s)\n"),
417 quoted, strerror(errno));
418 if (verbose && (dle->include_optional == 0 ||
420 g_printf(_("ERROR [Can't open include file %s (%s)]\n"),
421 quoted, strerror(errno));
428 fclose(file_include);
430 quoted = quote_string(filename);
431 dbprintf(_("Can't create include file %s (%s)\n"),
432 quoted, strerror(errno));
434 g_printf(_("ERROR [Can't create include file %s (%s)]\n"),
435 quoted, strerror(errno));
442 quoted = quote_string(dle->disk);
443 dbprintf(_("Nothing found to include for disk %s\n"), quoted);
444 if (verbose && dle->include_optional == 0) {
445 g_printf(_("ERROR [Nothing found to include for disk %s]\n"), quoted);
469 while (tok != NULL) {
470 if(am_has_feature(fs, fe_options_auth)
471 && BSTRNCMP(tok,"auth=") == 0) {
472 if (dle->auth != NULL) {
473 quoted = quote_string(tok + 5);
474 dbprintf(_("multiple auth option %s\n"), quoted);
476 g_printf(_("ERROR [multiple auth option %s]\n"), quoted);
480 dle->auth = stralloc(&tok[5]);
482 else if(am_has_feature(fs, fe_options_bsd_auth)
483 && BSTRNCMP(tok, "bsd-auth") == 0) {
484 if (dle->auth != NULL) {
485 dbprintf(_("multiple auth option\n"));
487 g_printf(_("ERROR [multiple auth option]\n"));
490 dle->auth = stralloc("bsd");
492 else if (BSTRNCMP(tok, "compress-fast") == 0) {
493 if (dle->compress != COMP_NONE) {
494 dbprintf(_("multiple compress option\n"));
496 g_printf(_("ERROR [multiple compress option]\n"));
499 dle->compress = COMP_FAST;
501 else if (BSTRNCMP(tok, "compress-best") == 0) {
502 if (dle->compress != COMP_NONE) {
503 dbprintf(_("multiple compress option\n"));
505 g_printf(_("ERROR [multiple compress option]\n"));
508 dle->compress = COMP_BEST;
510 else if (BSTRNCMP(tok, "srvcomp-fast") == 0) {
511 if (dle->compress != COMP_NONE) {
512 dbprintf(_("multiple compress option\n"));
514 g_printf(_("ERROR [multiple compress option]\n"));
517 dle->compress = COMP_SERVER_FAST;
519 else if (BSTRNCMP(tok, "srvcomp-best") == 0) {
520 if (dle->compress != COMP_NONE) {
521 dbprintf(_("multiple compress option\n"));
523 g_printf(_("ERROR [multiple compress option]\n"));
526 dle->compress = COMP_SERVER_BEST;
528 else if (BSTRNCMP(tok, "srvcomp-cust=") == 0) {
529 if (dle->compress != COMP_NONE) {
530 dbprintf(_("multiple compress option\n"));
532 g_printf(_("ERROR [multiple compress option]\n"));
535 dle->compprog = stralloc(tok + SIZEOF("srvcomp-cust=") -1);
536 dle->compress = COMP_SERVER_CUST;
538 else if (BSTRNCMP(tok, "comp-cust=") == 0) {
539 if (dle->compress != COMP_NONE) {
540 dbprintf(_("multiple compress option\n"));
542 g_printf(_("ERROR [multiple compress option]\n"));
545 dle->compprog = stralloc(tok + SIZEOF("comp-cust=") -1);
546 dle->compress = COMP_CUST;
547 /* parse encryption options */
549 else if (BSTRNCMP(tok, "encrypt-serv-cust=") == 0) {
550 if (dle->encrypt != ENCRYPT_NONE) {
551 dbprintf(_("multiple encrypt option\n"));
553 g_printf(_("ERROR [multiple encrypt option]\n"));
556 dle->srv_encrypt = stralloc(tok + SIZEOF("encrypt-serv-cust=") -1);
557 dle->encrypt = ENCRYPT_SERV_CUST;
559 else if (BSTRNCMP(tok, "encrypt-cust=") == 0) {
560 if (dle->encrypt != ENCRYPT_NONE) {
561 dbprintf(_("multiple encrypt option\n"));
563 g_printf(_("ERROR [multiple encrypt option]\n"));
566 dle->clnt_encrypt= stralloc(tok + SIZEOF("encrypt-cust=") -1);
567 dle->encrypt = ENCRYPT_CUST;
569 else if (BSTRNCMP(tok, "server-decrypt-option=") == 0) {
570 dle->srv_decrypt_opt = stralloc(tok + SIZEOF("server-decrypt-option=") -1);
572 else if (BSTRNCMP(tok, "client-decrypt-option=") == 0) {
573 dle->clnt_decrypt_opt = stralloc(tok + SIZEOF("client-decrypt-option=") -1);
575 else if (BSTRNCMP(tok, "no-record") == 0) {
576 if (dle->record != 1) {
577 dbprintf(_("multiple no-record option\n"));
579 g_printf(_("ERROR [multiple no-record option]\n"));
584 else if (BSTRNCMP(tok, "index") == 0) {
585 if (dle->create_index != 0) {
586 dbprintf(_("multiple index option\n"));
588 g_printf(_("ERROR [multiple index option]\n"));
591 dle->create_index = 1;
593 else if (BSTRNCMP(tok, "exclude-optional") == 0) {
594 if (dle->exclude_optional != 0) {
595 dbprintf(_("multiple exclude-optional option\n"));
597 g_printf(_("ERROR [multiple exclude-optional option]\n"));
600 dle->exclude_optional = 1;
602 else if (strcmp(tok, "include-optional") == 0) {
603 if (dle->include_optional != 0) {
604 dbprintf(_("multiple include-optional option\n"));
606 g_printf(_("ERROR [multiple include-optional option]\n"));
609 dle->include_optional = 1;
611 else if (BSTRNCMP(tok,"exclude-file=") == 0) {
612 exc = unquote_string(&tok[13]);
613 dle->exclude_file = append_sl(dle->exclude_file, exc);
616 else if (BSTRNCMP(tok,"exclude-list=") == 0) {
617 exc = unquote_string(&tok[13]);
618 dle->exclude_list = append_sl(dle->exclude_list, exc);
621 else if (BSTRNCMP(tok,"include-file=") == 0) {
622 inc = unquote_string(&tok[13]);
623 dle->include_file = append_sl(dle->include_file, inc);
626 else if (BSTRNCMP(tok,"include-list=") == 0) {
627 inc = unquote_string(&tok[13]);
628 dle->include_list = append_sl(dle->include_list, inc);
631 else if (BSTRNCMP(tok,"kencrypt") == 0) {
634 else if (strcmp(tok,"|") != 0) {
635 quoted = quote_string(tok);
636 dbprintf(_("unknown option %s\n"), quoted);
638 g_printf(_("ERROR [unknown option: %s]\n"), quoted);
642 tok = strtok(NULL, ";");
648 application_property_add_to_argv(
651 backup_support_option_t *bsu,
652 am_feature_t *amfeatures)
657 if (bsu->include_file && dle->include_file) {
658 for (incl = dle->include_file->first; incl != NULL;
660 g_ptr_array_add(argv_ptr, stralloc("--include-file"));
661 g_ptr_array_add(argv_ptr, stralloc(incl->name));
664 if (bsu->include_list && dle->include_list) {
665 for (incl = dle->include_list->first; incl != NULL;
667 g_ptr_array_add(argv_ptr, stralloc("--include-list"));
668 g_ptr_array_add(argv_ptr, stralloc(incl->name));
671 if (bsu->include_optional && dle->include_optional) {
672 g_ptr_array_add(argv_ptr, stralloc("--include-optional"));
673 g_ptr_array_add(argv_ptr, stralloc("yes"));
676 if (bsu->exclude_file && dle->exclude_file) {
677 for (excl = dle->exclude_file->first; excl != NULL;
679 g_ptr_array_add(argv_ptr, stralloc("--exclude-file"));
680 g_ptr_array_add(argv_ptr, stralloc(excl->name));
683 if (bsu->exclude_list && dle->exclude_list) {
684 for (excl = dle->exclude_list->first; excl != NULL;
686 g_ptr_array_add(argv_ptr, stralloc("--exclude-list"));
687 g_ptr_array_add(argv_ptr, stralloc(excl->name));
690 if (bsu->exclude_optional && dle->exclude_optional) {
691 g_ptr_array_add(argv_ptr, stralloc("--exclude-optional"));
692 g_ptr_array_add(argv_ptr, stralloc("yes"));
695 if (bsu->features && amfeatures) {
696 char *feature_string = am_feature_to_string(amfeatures);
697 g_ptr_array_add(argv_ptr, stralloc("--amfeatures"));
698 g_ptr_array_add(argv_ptr, feature_string);
701 if (dle->data_path == DATA_PATH_DIRECTTCP &&
702 bsu->data_path_set & DATA_PATH_DIRECTTCP) {
705 g_ptr_array_add(argv_ptr, stralloc("--data-path"));
706 g_ptr_array_add(argv_ptr, stralloc("directtcp"));
707 for (directtcp = dle->directtcp_list; directtcp != NULL;
708 directtcp = directtcp->next) {
709 g_ptr_array_add(argv_ptr, stralloc("--direct-tcp"));
710 g_ptr_array_add(argv_ptr, stralloc(directtcp->data));
711 break; /* XXX temporary; apps only support one ip:port pair */
716 property_add_to_argv(argv_ptr, dle->application_property);
723 proplist_t dle_proplist;
732 gpointer user_data_p)
734 char *property_s = key_p;
735 property_t *conf_property = value_p;
736 merge_property_t *merge_p = user_data_p;
737 property_t *dle_property = g_hash_table_lookup(merge_p->dle_proplist,
740 char *qdisk = quote_string(merge_p->dle->disk);
743 if (dle_property->priority && conf_property->priority) {
744 if (merge_p->verbose) {
746 _("ERROR %s (%s) Both server client have priority for property '%s'.\n"),
747 qdisk, merge_p->name, property_s);
749 g_debug("ERROR %s (%s) Both server client have priority for property '%s'.", qdisk, merge_p->name, property_s);
751 /* Use client property */
752 g_hash_table_remove(merge_p->dle_proplist, key_p);
753 g_hash_table_insert(merge_p->dle_proplist, key_p, conf_property);
754 } else if (dle_property->priority) {
755 if (merge_p->verbose) {
757 _("ERROR %s (%s) Server set priority for property '%s' but client set the property.\n"),
758 qdisk, merge_p->name, property_s);
760 g_debug("%s (%s) Server set priority for property '%s' but client set the property.", qdisk, merge_p->name, property_s);
761 /* use server property */
762 } else if (conf_property->priority) {
763 if (merge_p->verbose) {
765 _("ERROR %s (%s) Client set priority for property '%s' but server set the property.\n"),
766 qdisk, merge_p->name, property_s);
768 g_debug("%s (%s) Client set priority for property '%s' but server set the property.", qdisk, merge_p->name, property_s);
769 /* Use client property */
770 g_hash_table_remove(merge_p->dle_proplist, key_p);
771 g_hash_table_insert(merge_p->dle_proplist, key_p, conf_property);
772 } else if (!conf_property->append) {
773 if (merge_p->verbose) {
775 _("ERROR %s (%s) Both server and client set property '%s', using client value.\n"),
776 qdisk, merge_p->name, property_s);
778 g_debug("%s (%s) Both server and client set property '%s', using client value.", qdisk, merge_p->name, property_s);
779 /* Use client property */
780 g_hash_table_remove(merge_p->dle_proplist, key_p);
781 g_hash_table_insert(merge_p->dle_proplist, key_p, conf_property);
783 for (value = conf_property->values; value != NULL;
784 value = value->next) {
785 dle_property->values = g_slist_append(dle_property->values,
789 } else { /* take value from conf */
790 g_hash_table_insert(merge_p->dle_proplist, key_p, conf_property);
798 proplist_t dle_proplist,
799 proplist_t conf_proplist,
802 merge_property_t merge_p = {dle, name, dle_proplist, verbose, 1};
804 if (conf_proplist != NULL) {
805 g_hash_table_foreach(conf_proplist,
814 merge_dles_properties(
821 pp_script_t *pp_script;
824 for (dle=dles; dle != NULL; dle=dle->next) {
825 if (dle->program_is_application_api) {
827 if (dle->application_client_name &&
828 strlen(dle->application_client_name) > 0) {
829 app = lookup_application(dle->application_client_name);
831 char *qamname = quote_string(dle->disk);
832 char *errmsg = vstrallocf("Application '%s' not found on client",
833 dle->application_client_name);
834 char *qerrmsg = quote_string(errmsg);
837 g_fprintf(stdout, _("ERROR %s %s\n"), qamname, qerrmsg);
839 g_debug("%s: %s", qamname, qerrmsg);
845 app = lookup_application(dle->program);
848 merge_properties(dle, dle->program,
849 dle->application_property,
850 application_get_property(app),
854 for (scriptlist = dle->scriptlist; scriptlist != NULL;
855 scriptlist = scriptlist->next) {
856 script_t *script = scriptlist->data;
858 if (script->client_name && strlen(script->client_name) > 0) {
859 pp_script = lookup_pp_script(script->client_name);
861 char *qamname = quote_string(dle->disk);
862 char *errmsg = vstrallocf("Script '%s' not found on client",
863 script->client_name);
864 char *qerrmsg = quote_string(errmsg);
867 g_fprintf(stderr, _("ERROR %s %s\n"), qamname, qerrmsg);
869 g_debug("%s: %s", qamname, qerrmsg);
875 pp_script = lookup_pp_script(script->plugin);
878 merge_properties(dle, script->plugin,
880 pp_script_get_property(pp_script),
888 backup_support_option_t *
889 backup_support_option(
891 g_option_t *g_options,
894 GPtrArray **errarray)
897 int supportin, supportout, supporterr;
899 GPtrArray *argv_ptr = g_ptr_array_new();
905 backup_support_option_t *bsu;
907 *errarray = g_ptr_array_new();
908 cmd = vstralloc(APPLICATION_DIR, "/", program, NULL);
909 g_ptr_array_add(argv_ptr, stralloc(program));
910 g_ptr_array_add(argv_ptr, stralloc("support"));
911 if (g_options->config) {
912 g_ptr_array_add(argv_ptr, stralloc("--config"));
913 g_ptr_array_add(argv_ptr, stralloc(g_options->config));
915 if (g_options->hostname) {
916 g_ptr_array_add(argv_ptr, stralloc("--host"));
917 g_ptr_array_add(argv_ptr, stralloc(g_options->hostname));
920 g_ptr_array_add(argv_ptr, stralloc("--disk"));
921 g_ptr_array_add(argv_ptr, stralloc(disk));
924 g_ptr_array_add(argv_ptr, stralloc("--device"));
925 g_ptr_array_add(argv_ptr, stralloc(amdevice));
927 g_ptr_array_add(argv_ptr, NULL);
929 supporterr = fileno(stderr);
930 supportpid = pipespawnv(cmd, STDIN_PIPE|STDOUT_PIPE|STDERR_PIPE, 0,
931 &supportin, &supportout, &supporterr,
932 (char **)argv_ptr->pdata);
936 bsu = g_new0(backup_support_option_t, 1);
940 streamout = fdopen(supportout, "r");
942 error(_("Error opening pipe to child: %s"), strerror(errno));
945 while((line = agets(streamout)) != NULL) {
946 dbprintf(_("support line: %s\n"), line);
947 if (strncmp(line,"CONFIG ", 7) == 0) {
948 if (strcmp(line+7, "YES") == 0)
950 } else if (strncmp(line,"HOST ", 5) == 0) {
951 if (strcmp(line+5, "YES") == 0)
953 } else if (strncmp(line,"DISK ", 5) == 0) {
954 if (strcmp(line+5, "YES") == 0)
956 } else if (strncmp(line,"INDEX-LINE ", 11) == 0) {
957 if (strcmp(line+11, "YES") == 0)
959 } else if (strncmp(line,"INDEX-XML ", 10) == 0) {
960 if (strcmp(line+10, "YES") == 0)
962 } else if (strncmp(line,"MESSAGE-LINE ", 13) == 0) {
963 if (strcmp(line+13, "YES") == 0)
964 bsu->message_line = 1;
965 } else if (strncmp(line,"MESSAGE-XML ", 12) == 0) {
966 if (strcmp(line+12, "YES") == 0)
967 bsu->message_xml = 1;
968 } else if (strncmp(line,"RECORD ", 7) == 0) {
969 if (strcmp(line+7, "YES") == 0)
971 } else if (strncmp(line,"INCLUDE-FILE ", 13) == 0) {
972 if (strcmp(line+13, "YES") == 0)
973 bsu->include_file = 1;
974 } else if (strncmp(line,"INCLUDE-LIST ", 13) == 0) {
975 if (strcmp(line+13, "YES") == 0)
976 bsu->include_list = 1;
977 } else if (strncmp(line,"INCLUDE-LIST-GLOB ", 17) == 0) {
978 if (strcmp(line+17, "YES") == 0)
979 bsu->include_list_glob = 1;
980 } else if (strncmp(line,"INCLUDE-OPTIONAL ", 17) == 0) {
981 if (strcmp(line+17, "YES") == 0)
982 bsu->include_optional = 1;
983 } else if (strncmp(line,"EXCLUDE-FILE ", 13) == 0) {
984 if (strcmp(line+13, "YES") == 0)
985 bsu->exclude_file = 1;
986 } else if (strncmp(line,"EXCLUDE-LIST ", 13) == 0) {
987 if (strcmp(line+13, "YES") == 0)
988 bsu->exclude_list = 1;
989 } else if (strncmp(line,"EXCLUDE-LIST-GLOB ", 17) == 0) {
990 if (strcmp(line+17, "YES") == 0)
991 bsu->exclude_list_glob = 1;
992 } else if (strncmp(line,"EXCLUDE-OPTIONAL ", 17) == 0) {
993 if (strcmp(line+17, "YES") == 0)
994 bsu->exclude_optional = 1;
995 } else if (strncmp(line,"COLLECTION ", 11) == 0) {
996 if (strcmp(line+11, "YES") == 0)
998 } else if (strncmp(line,"CALCSIZE ", 9) == 0) {
999 if (strcmp(line+9, "YES") == 0)
1001 } else if (strncmp(line,"CLIENT-ESTIMATE ", 16) == 0) {
1002 if (strcmp(line+16, "YES") == 0)
1003 bsu->client_estimate = 1;
1004 } else if (strncmp(line,"MULTI-ESTIMATE ", 15) == 0) {
1005 if (strcmp(line+15, "YES") == 0)
1006 bsu->multi_estimate = 1;
1007 } else if (strncmp(line,"MAX-LEVEL ", 10) == 0) {
1008 bsu->max_level = atoi(line+10);
1009 } else if (strncmp(line,"RECOVER-MODE ", 13) == 0) {
1010 if (strcasecmp(line+13, "SMB") == 0)
1011 bsu->smb_recover_mode = 1;
1012 } else if (strncmp(line,"DATA-PATH ", 10) == 0) {
1013 if (strcasecmp(line+10, "AMANDA") == 0)
1014 bsu->data_path_set |= DATA_PATH_AMANDA;
1015 else if (strcasecmp(line+10, "DIRECTTCP") == 0)
1016 bsu->data_path_set |= DATA_PATH_DIRECTTCP;
1017 } else if (strncmp(line,"RECOVER-PATH ", 13) == 0) {
1018 if (strcasecmp(line+13, "CWD") == 0)
1019 bsu->recover_path = RECOVER_PATH_CWD;
1020 else if (strcasecmp(line+13, "REMOTE") == 0)
1021 bsu->recover_path = RECOVER_PATH_REMOTE;
1022 } else if (strncmp(line,"AMFEATURES ", 11) == 0) {
1023 if (strcmp(line+11, "YES") == 0)
1026 dbprintf(_("Invalid support line: %s\n"), line);
1032 if (bsu->data_path_set == 0)
1033 bsu->data_path_set = DATA_PATH_AMANDA;
1035 streamerr = fdopen(supporterr, "r");
1037 error(_("Error opening pipe to child: %s"), strerror(errno));
1040 while((line = agets(streamerr)) != NULL) {
1041 if (strlen(line) > 0) {
1042 g_ptr_array_add(*errarray, line);
1043 dbprintf("Application '%s': %s\n", program, line);
1049 if (waitpid(supportpid, &status, 0) < 0) {
1050 err = vstrallocf(_("waitpid failed: %s"), strerror(errno));
1051 } else if (!WIFEXITED(status)) {
1052 err = vstrallocf(_("exited with signal %d"), WTERMSIG(status));
1053 } else if (WEXITSTATUS(status) != 0) {
1054 err = vstrallocf(_("exited with status %d"), WEXITSTATUS(status));
1058 g_ptr_array_add(*errarray, err);
1059 dbprintf("Application '%s': %s\n", program, err);
1062 g_ptr_array_free_full(argv_ptr);
1070 execute_on_t execute_on,
1071 g_option_t *g_options,
1075 int scriptin, scriptout, scripterr;
1077 GPtrArray *argv_ptr = g_ptr_array_new();
1081 amwait_t wait_status;
1082 char *command = NULL;
1084 if ((script->execute_on & execute_on) == 0)
1086 if (script->execute_where != ES_CLIENT)
1089 cmd = vstralloc(APPLICATION_DIR, "/", script->plugin, NULL);
1090 g_ptr_array_add(argv_ptr, stralloc(script->plugin));
1092 switch (execute_on) {
1093 case EXECUTE_ON_PRE_DLE_AMCHECK:
1094 command = "PRE-DLE-AMCHECK";
1096 case EXECUTE_ON_PRE_HOST_AMCHECK:
1097 command = "PRE-HOST-AMCHECK";
1099 case EXECUTE_ON_POST_DLE_AMCHECK:
1100 command = "POST-DLE-AMCHECK";
1102 case EXECUTE_ON_POST_HOST_AMCHECK:
1103 command = "POST-HOST-AMCHECK";
1105 case EXECUTE_ON_PRE_DLE_ESTIMATE:
1106 command = "PRE-DLE-ESTIMATE";
1108 case EXECUTE_ON_PRE_HOST_ESTIMATE:
1109 command = "PRE-HOST-ESTIMATE";
1111 case EXECUTE_ON_POST_DLE_ESTIMATE:
1112 command = "POST-DLE-ESTIMATE";
1114 case EXECUTE_ON_POST_HOST_ESTIMATE:
1115 command = "POST-HOST-ESTIMATE";
1117 case EXECUTE_ON_PRE_DLE_BACKUP:
1118 command = "PRE-DLE-BACKUP";
1120 case EXECUTE_ON_PRE_HOST_BACKUP:
1121 command = "PRE-HOST-BACKUP";
1123 case EXECUTE_ON_POST_DLE_BACKUP:
1124 command = "POST-DLE-BACKUP";
1126 case EXECUTE_ON_POST_HOST_BACKUP:
1127 command = "POST-HOST-BACKUP";
1129 case EXECUTE_ON_PRE_RECOVER:
1130 command = "PRE-RECOVER";
1132 case EXECUTE_ON_POST_RECOVER:
1133 command = "POST-RECOVER";
1135 case EXECUTE_ON_PRE_LEVEL_RECOVER:
1136 command = "PRE-LEVEL-RECOVER";
1138 case EXECUTE_ON_POST_LEVEL_RECOVER:
1139 command = "POST-LEVEL-RECOVER";
1141 case EXECUTE_ON_INTER_LEVEL_RECOVER:
1142 command = "INTER-LEVEL-RECOVER";
1145 g_ptr_array_add(argv_ptr, stralloc(command));
1146 g_ptr_array_add(argv_ptr, stralloc("--execute-where"));
1147 g_ptr_array_add(argv_ptr, stralloc("client"));
1149 if (g_options->config) {
1150 g_ptr_array_add(argv_ptr, stralloc("--config"));
1151 g_ptr_array_add(argv_ptr, stralloc(g_options->config));
1153 if (g_options->hostname) {
1154 g_ptr_array_add(argv_ptr, stralloc("--host"));
1155 g_ptr_array_add(argv_ptr, stralloc(g_options->hostname));
1158 g_ptr_array_add(argv_ptr, stralloc("--disk"));
1159 g_ptr_array_add(argv_ptr, stralloc(dle->disk));
1162 g_ptr_array_add(argv_ptr, stralloc("--device"));
1163 g_ptr_array_add(argv_ptr, stralloc(dle->device));
1165 if (dle->levellist) {
1166 levellist_t levellist;
1167 char number[NUM_STR_SIZE];
1168 for (levellist=dle->levellist; levellist; levellist=levellist->next) {
1169 am_level_t *alevel = (am_level_t *)levellist->data;
1170 g_ptr_array_add(argv_ptr, stralloc("--level"));
1171 g_snprintf(number, SIZEOF(number), "%d", alevel->level);
1172 g_ptr_array_add(argv_ptr, stralloc(number));
1175 property_add_to_argv(argv_ptr, script->property);
1176 g_ptr_array_add(argv_ptr, NULL);
1178 scriptpid = pipespawnv(cmd, STDIN_PIPE|STDOUT_PIPE|STDERR_PIPE, 0,
1179 &scriptin, &scriptout, &scripterr,
1180 (char **)argv_ptr->pdata);
1184 script->result = g_new0(client_script_result_t, 1);
1185 script->result->proplist =
1186 g_hash_table_new_full(g_str_hash, g_str_equal,
1187 &g_free, &destroy_slist_free_full);
1188 script->result->output = g_ptr_array_new();
1189 script->result->err = g_ptr_array_new();
1191 streamout = fdopen(scriptout, "r");
1193 while((line = agets(streamout)) != NULL) {
1194 dbprintf("script: %s\n", line);
1195 if (BSTRNCMP(line, "PROPERTY ") == 0) {
1196 char *property_name, *property_value;
1197 property_name = line + 9;
1198 property_value = strchr(property_name,' ');
1199 if (property_value == NULL) {
1200 char *msg = g_strdup_printf(
1201 "ERROR %s: Bad output property: %s",
1202 script->plugin, line);
1203 g_ptr_array_add(script->result->output, msg);
1205 property_t *property;
1207 *property_value++ = '\0';
1208 property_name = stralloc(property_name);
1209 property_value = stralloc(property_value);
1210 property = g_hash_table_lookup(script->result->proplist,
1213 property = g_new0(property_t, 1);
1214 g_hash_table_insert(script->result->proplist,
1215 property_name, property);
1217 property->values = g_slist_append(property->values,
1222 g_ptr_array_add(script->result->output, line);
1228 streamerr = fdopen(scripterr, "r");
1230 while((line = agets(streamerr)) != NULL) {
1231 g_ptr_array_add(script->result->err,
1232 g_strdup_printf(_("Script '%s' command '%s': %s"),
1233 script->plugin, command, line));
1238 waitpid(scriptpid, &wait_status, 0);
1239 if (WIFSIGNALED(wait_status)) {
1240 g_ptr_array_add(script->result->err,
1241 g_strdup_printf(_("Script '%s' command '%s' terminated with signal %d: see %s"),
1242 script->plugin, command,
1243 WTERMSIG(wait_status),
1245 } else if (WIFEXITED(wait_status)) {
1246 if (WEXITSTATUS(wait_status) != 0) {
1247 g_ptr_array_add(script->result->err,
1248 g_strdup_printf(_("Script '%s' command '%s' exited with status %d: see %s"),
1249 script->plugin, command,
1250 WEXITSTATUS(wait_status),
1257 g_ptr_array_free_full(argv_ptr);
1260 void run_client_script_output(gpointer data, gpointer user_data);
1261 void run_client_script_err_amcheck(gpointer data, gpointer user_data);
1262 void run_client_script_err_estimate(gpointer data, gpointer user_data);
1263 void run_client_script_err_backup(gpointer data, gpointer user_data);
1264 void run_client_script_err_recover(gpointer data, gpointer user_data);
1266 typedef struct script_output_s {
1272 run_client_script_output(
1277 script_output_t *so = user_data;
1279 if (line && so->stream) {
1280 g_fprintf(so->stream, "%s\n", line);
1285 run_client_script_err_amcheck(
1290 script_output_t *so = user_data;
1292 if (line && so->stream) {
1293 g_fprintf(so->stream, "ERROR %s\n", line);
1298 run_client_script_err_estimate(
1303 script_output_t *so = user_data;
1305 if (line && so->stream) {
1306 char *qdisk = quote_string(so->dle->disk);
1307 g_fprintf(so->stream, "%s 0 WARNING \"%s\"\n", qdisk, line);
1313 run_client_script_err_backup(
1318 script_output_t *so = user_data;
1320 if (line && so->stream) {
1321 g_fprintf(so->stream, "? %s\n", line);
1326 run_client_script_err_recover(
1331 script_output_t *so = user_data;
1333 if (line && so->stream) {
1334 g_fprintf(so->stream, "%s\n", line);
1340 execute_on_t execute_on,
1341 g_option_t *g_options,
1347 GFunc client_script_err = NULL;
1348 script_output_t so = { streamout, dle };
1350 for (scriptlist = dle->scriptlist; scriptlist != NULL;
1351 scriptlist = scriptlist->next) {
1352 script = (script_t *)scriptlist->data;
1353 run_client_script(script, execute_on, g_options, dle);
1354 if (script->result && script->result->output) {
1355 g_ptr_array_foreach(script->result->output,
1356 run_client_script_output,
1358 g_ptr_array_free(script->result->output, TRUE);
1359 script->result->output = NULL;
1361 if (script->result && script->result->err) {
1362 switch (execute_on) {
1363 case EXECUTE_ON_PRE_DLE_AMCHECK:
1364 case EXECUTE_ON_PRE_HOST_AMCHECK:
1365 case EXECUTE_ON_POST_DLE_AMCHECK:
1366 case EXECUTE_ON_POST_HOST_AMCHECK:
1367 client_script_err = run_client_script_err_amcheck;
1369 case EXECUTE_ON_PRE_DLE_ESTIMATE:
1370 case EXECUTE_ON_PRE_HOST_ESTIMATE:
1371 case EXECUTE_ON_POST_DLE_ESTIMATE:
1372 case EXECUTE_ON_POST_HOST_ESTIMATE:
1373 if (am_has_feature(g_options->features,
1374 fe_sendsize_rep_warning)) {
1375 client_script_err = run_client_script_err_estimate;
1378 case EXECUTE_ON_PRE_DLE_BACKUP:
1379 case EXECUTE_ON_PRE_HOST_BACKUP:
1380 case EXECUTE_ON_POST_DLE_BACKUP:
1381 case EXECUTE_ON_POST_HOST_BACKUP:
1382 client_script_err = run_client_script_err_backup;
1384 case EXECUTE_ON_PRE_RECOVER:
1385 case EXECUTE_ON_POST_RECOVER:
1386 case EXECUTE_ON_PRE_LEVEL_RECOVER:
1387 case EXECUTE_ON_POST_LEVEL_RECOVER:
1388 case EXECUTE_ON_INTER_LEVEL_RECOVER:
1389 client_script_err = run_client_script_err_recover;
1391 if (client_script_err != NULL) {
1392 g_ptr_array_foreach(script->result->err,
1396 g_ptr_array_free(script->result->err, TRUE);
1397 script->result->err = NULL;
1413 char *cmd, *cmdline;
1415 GPtrArray *argv_ptr = g_ptr_array_new();
1416 char tmppath[PATH_MAX];
1417 char number[NUM_STR_SIZE];
1422 int pipefd = -1, nullfd = -1;
1425 FILE *dumpout = NULL;
1427 char *errmsg = NULL;
1429 amwait_t wait_status;
1433 char *amandates_file;
1435 qdisk = quote_string(disk);
1437 amandates_file = getconf_str(CNF_AMANDATES);
1438 if(!start_amandates(amandates_file, 0)) {
1439 char *errstr = strerror(errno);
1440 char *errmsg = vstrallocf(_("could not open %s: %s"), amandates_file, errstr);
1441 char *qerrmsg = quote_string(errmsg);
1442 g_printf(_("ERROR %s\n"), qerrmsg);
1450 cmd = vstralloc(amlibexecdir, "/", "calcsize", NULL);
1453 g_ptr_array_add(argv_ptr, stralloc("calcsize"));
1455 g_ptr_array_add(argv_ptr, stralloc(config));
1457 g_ptr_array_add(argv_ptr, stralloc("NOCONFIG"));
1459 g_ptr_array_add(argv_ptr, stralloc(program));
1461 canonicalize_pathname(disk, tmppath);
1462 g_ptr_array_add(argv_ptr, stralloc(tmppath));
1463 canonicalize_pathname(dirname, tmppath);
1464 g_ptr_array_add(argv_ptr, stralloc(tmppath));
1467 g_ptr_array_add(argv_ptr, stralloc("-X"));
1468 g_ptr_array_add(argv_ptr, stralloc(file_exclude));
1472 g_ptr_array_add(argv_ptr, stralloc("-I"));
1473 g_ptr_array_add(argv_ptr, stralloc(file_include));
1476 for (alevel = levels; alevel != NULL; alevel = alevel->next) {
1477 amdp = amandates_lookup(disk);
1478 level = GPOINTER_TO_INT(alevel->data);
1479 dbprintf("level: %d\n", level);
1481 for (i=0; i < level; i++) {
1482 if (dumpsince < amdp->dates[i])
1483 dumpsince = amdp->dates[i];
1485 g_snprintf(number, SIZEOF(number), "%d", level);
1486 g_ptr_array_add(argv_ptr, stralloc(number));
1487 g_snprintf(number, SIZEOF(number), "%d", dumpsince);
1488 g_ptr_array_add(argv_ptr, stralloc(number));
1491 g_ptr_array_add(argv_ptr, NULL);
1492 command = (char *)g_ptr_array_index(argv_ptr, 0);
1493 cmdline = stralloc(command);
1494 for(i = 1; i < argv_ptr->len - 1; i++)
1495 cmdline = vstrextend(&cmdline, " ",
1496 (char *)g_ptr_array_index(argv_ptr,i), NULL);
1497 dbprintf(_("running: \"%s\"\n"), cmdline);
1500 start_time = curclock();
1502 fflush(stderr); fflush(stdout);
1504 if ((nullfd = open("/dev/null", O_RDWR)) == -1) {
1505 errmsg = vstrallocf(_("Cannot access /dev/null : %s"),
1507 dbprintf("%s\n", errmsg);
1511 calcpid = pipespawnv(cmd, STDERR_PIPE, 0,
1512 &nullfd, &nullfd, &pipefd, (char **)argv_ptr->pdata);
1515 dumpout = fdopen(pipefd,"r");
1517 error(_("Can't fdopen: %s"), strerror(errno));
1521 match_expr = vstralloc(" %d SIZE %lld", NULL);
1522 len = strlen(qdisk);
1523 for(; (line = agets(dumpout)) != NULL; free(line)) {
1524 long long size_ = (long long)0;
1525 if (line[0] == '\0' || (int)strlen(line) <= len)
1527 /* Don't use sscanf for qdisk because it can have a '%'. */
1528 if (strncmp(line, qdisk, len) == 0 &&
1529 sscanf(line+len, match_expr, &level, &size_) == 2) {
1530 g_printf("%d %lld %d\n", level, size_, 1); /* write to sendsize */
1531 dbprintf(_("estimate size for %s level %d: %lld KB\n"),
1532 qdisk, level, size_);
1537 dbprintf(_("waiting for %s %s child (pid=%d)\n"),
1538 command, qdisk, (int)calcpid);
1539 waitpid(calcpid, &wait_status, 0);
1540 if (WIFSIGNALED(wait_status)) {
1541 errmsg = vstrallocf(_("%s terminated with signal %d: see %s"),
1542 "calcsize", WTERMSIG(wait_status),
1544 } else if (WIFEXITED(wait_status)) {
1545 if (WEXITSTATUS(wait_status) != 0) {
1546 errmsg = vstrallocf(_("%s exited with status %d: see %s"),
1547 "calcsize", WEXITSTATUS(wait_status),
1553 errmsg = vstrallocf(_("%s got bad exit: see %s"),
1554 "calcsize", dbfn());
1557 dbprintf(_("after %s %s wait: child pid=%d status=%d\n"),
1559 (int)calcpid, WEXITSTATUS(wait_status));
1561 dbprintf(_(".....\n"));
1562 dbprintf(_("estimate time for %s: %s\n"),
1564 walltime_str(timessub(curclock(), start_time)));
1567 if (errmsg && errmsg[0] != '\0') {
1568 char *qerrmsg = quote_string(errmsg);
1569 dbprintf(_("errmsg is %s\n"), errmsg);
1570 g_printf("ERROR %s\n", qerrmsg);
1575 g_ptr_array_free_full(argv_ptr);
1585 char *noun, *adjective;
1586 char *quoted = quote_string(filename);
1589 noun = "find", adjective = "exists";
1590 else if((mode & X_OK) == X_OK)
1591 noun = "execute", adjective = "executable";
1592 else if((mode & (W_OK|R_OK)) == (W_OK|R_OK))
1593 noun = "read/write", adjective = "read/writable";
1595 noun = "access", adjective = "accessible";
1597 if(access(filename, mode) == -1) {
1598 g_printf(_("ERROR [can not %s %s: %s]\n"), noun, quoted, strerror(errno));
1602 g_printf(_("OK %s %s\n"), quoted, adjective);
1613 struct stat stat_buf;
1616 if(!stat(filename, &stat_buf)) {
1617 if(!S_ISREG(stat_buf.st_mode)) {
1618 quoted = quote_string(filename);
1619 g_printf(_("ERROR [%s is not a file]\n"), quoted);
1624 int save_errno = errno;
1625 quoted = quote_string(filename);
1626 g_printf(_("ERROR [can not stat %s: %s]\n"), quoted,
1627 strerror(save_errno));
1631 if (getuid() == geteuid()) {
1632 return check_access(filename, mode);
1634 quoted = quote_string(filename);
1635 g_printf("OK %s\n", quoted);
1646 struct stat stat_buf;
1650 if(!stat(dirname, &stat_buf)) {
1651 if(!S_ISDIR(stat_buf.st_mode)) {
1652 quoted = quote_string(dirname);
1653 g_printf(_("ERROR [%s is not a directory]\n"), quoted);
1658 int save_errno = errno;
1659 quoted = quote_string(dirname);
1660 g_printf(_("ERROR [can not stat %s: %s]\n"), quoted,
1661 strerror(save_errno));
1665 if (getuid() == geteuid()) {
1667 dir = stralloc2(dirname, "/.");
1668 result = check_access(dir, mode);
1672 quoted = quote_string(dirname);
1673 g_printf("OK %s\n", quoted);
1683 #ifndef SINGLE_USERID
1684 struct stat stat_buf;
1685 char *quoted = quote_string(filename);
1687 if(!stat(filename, &stat_buf)) {
1688 if(stat_buf.st_uid != 0 ) {
1689 g_printf(_("ERROR [%s is not owned by root]\n"), quoted);
1693 if((stat_buf.st_mode & S_ISUID) != S_ISUID) {
1694 g_printf(_("ERROR [%s is not SUID root]\n"), quoted);
1700 g_printf(_("ERROR [can not stat %s: %s]\n"), quoted, strerror(errno));
1706 (void)filename; /* Quiet unused parameter warning */
1712 * Returns the value of the first integer in a string.
1726 while(ch && !isdigit(ch)) ch = *str++;
1727 if (pos == 1) break;
1729 while(ch && (isdigit(ch) || ch == '.')) ch = *str++;
1732 while(isdigit(ch) || ch == '.') ch = *str++;
1741 config_errors_to_error_string(
1745 gboolean multiple_errors = FALSE;
1748 errmsg = (char *)errlist->data;
1750 multiple_errors = TRUE;
1752 errmsg = _("(no error message)");
1755 return vstrallocf("ERROR %s%s", errmsg,
1756 multiple_errors? _(" (additional errors not displayed)"):"");
1763 amregex_t **re_table,
1764 amregex_t *orig_re_table,
1765 GSList *normal_message,
1766 GSList *ignore_message,
1767 GSList *strange_message)
1771 for(rp = orig_re_table; rp->regex != NULL; rp++) {
1772 if (rp->typ == typ) {
1776 for (mes = normal_message; mes != NULL; mes = mes->next) {
1777 if (strcmp(rp->regex, (char *)mes->data) == 0)
1780 for (mes = ignore_message; mes != NULL; mes = mes->next) {
1781 if (strcmp(rp->regex, (char *)mes->data) == 0)
1784 for (mes = strange_message; mes != NULL; mes = mes->next) {
1785 if (strcmp(rp->regex, (char *)mes->data) == 0)
1789 (*re_table)->regex = rp->regex;
1790 (*re_table)->srcline = rp->srcline;
1791 (*re_table)->scale = rp->scale;
1792 (*re_table)->field = rp->field;
1793 (*re_table)->typ = rp->typ;
1803 amregex_t **re_table,
1808 for (mes = message; mes != NULL; mes = mes->next) {
1809 (*re_table)->regex = (char *)mes->data;
1810 (*re_table)->srcline = 0;
1811 (*re_table)->scale = 0;
1812 (*re_table)->field = 0;
1813 (*re_table)->typ = typ;
1820 amregex_t *orig_re_table,
1821 GSList *normal_message,
1822 GSList *ignore_message,
1823 GSList *strange_message)
1827 amregex_t *re_table, *new_re_table;
1829 for(rp = orig_re_table; rp->regex != NULL; rp++) {
1832 nb += g_slist_length(normal_message);
1833 nb += g_slist_length(ignore_message);
1834 nb += g_slist_length(strange_message);
1837 re_table = new_re_table = malloc(nb * sizeof(amregex_t));
1839 /* add SIZE from orig_re_table */
1840 add_type_table(DMP_SIZE, &re_table, orig_re_table,
1841 normal_message, ignore_message, strange_message);
1843 /* add ignore_message */
1844 add_list_table(DMP_IGNORE, &re_table, ignore_message);
1846 /* add IGNORE from orig_re_table */
1847 add_type_table(DMP_IGNORE, &re_table, orig_re_table,
1848 normal_message, ignore_message, strange_message);
1850 /* add normal_message */
1851 add_list_table(DMP_NORMAL, &re_table, normal_message);
1853 /* add NORMAL from orig_re_table */
1854 add_type_table(DMP_NORMAL, &re_table, orig_re_table,
1855 normal_message, ignore_message, strange_message);
1857 /* add strange_message */
1858 add_list_table(DMP_STRANGE, &re_table, strange_message);
1860 /* add STRANGE from orig_re_table */
1861 add_type_table(DMP_STRANGE, &re_table, orig_re_table,
1862 normal_message, ignore_message, strange_message);
1864 /* Add DMP_STRANGE with NULL regex, */
1865 /* it is not copied by previous statement */
1866 re_table->regex = NULL;
1867 re_table->srcline = 0;
1868 re_table->scale = 0;
1869 re_table->field = 0;
1870 re_table->typ = DMP_STRANGE;
1872 return new_re_table;