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.
28 * $Id: amxml.c 5151 2007-02-06 15:41:53Z martineau $
30 * xml parsing of amanda protocol packet
41 typedef struct amgxml_s {
44 GSList *element_names;
56 int has_backup_program;
60 property_t *property_data;
74 dle = malloc(sizeof(dle_t));
85 dle->program_is_application_api = 0;
87 dle->estimatelist = NULL;
90 dle->compress = COMP_NONE;
91 dle->encrypt = ENCRYPT_NONE;
93 dle->levellist = NULL;
96 dle->srv_encrypt = NULL;
97 dle->clnt_encrypt = NULL;
98 dle->srv_decrypt_opt = NULL;
99 dle->clnt_decrypt_opt = NULL;
100 dle->create_index = 0;
102 dle->exclude_file = NULL;
103 dle->exclude_list = NULL;
104 dle->include_file = NULL;
105 dle->include_list = NULL;
106 dle->exclude_optional = 0;
107 dle->include_optional = 0;
108 dle->application_property = NULL;
109 dle->scriptlist = NULL;
110 dle->data_path = DATA_PATH_AMANDA;
111 dle->directtcp_list = NULL;
116 /* Called for open tags <foo bar="baz"> */
117 static void amstart_element(GMarkupParseContext *context,
118 const gchar *element_name,
119 const gchar **attribute_names,
120 const gchar **attribute_values,
124 /* Called for close tags </foo> */
125 static void amend_element(GMarkupParseContext *context,
126 const gchar *element_name,
130 /* Called for character data */
131 /* text is not nul-terminated */
132 static void amtext(GMarkupParseContext *context,
138 /* Called for open tags <foo bar="baz"> */
141 G_GNUC_UNUSED GMarkupParseContext *context,
142 const gchar *element_name,
143 G_GNUC_UNUSED const gchar **attribute_names,
144 G_GNUC_UNUSED const gchar **attribute_values,
148 amgxml_t *data_user = user_data;
150 GSList *last_element = data_user->element_names;
151 char *last_element_name = NULL;
152 dle_t *dle = data_user->dle;
153 const gchar **at_names, **at_values;
156 last_element_name = last_element->data;
158 data_user->raw = NULL;
159 data_user->encoding = NULL;
161 if (attribute_names) {
162 for(at_names = attribute_names, at_values = attribute_values;
163 *at_names != NULL && at_values != NULL;
164 at_names++, at_values++) {
165 if (strcmp(*at_names, "encoding") == 0) {
166 data_user->encoding = stralloc(*at_values);
167 } else if (strcmp(*at_names, "raw") == 0) {
168 data_user->raw = base64_decode_alloc_string((char *)*at_values);
170 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
171 "XML: Invalid attribute '%s' for %s element",
172 *at_names, element_name);
178 if (strcmp(element_name, "dle") == 0) {
179 if (last_element != NULL) {
180 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
181 "XML: Invalid dle element");
184 for(adle = data_user->dles; adle != NULL && adle->next != NULL;
186 data_user->dle = alloc_dle();
188 data_user->dles = data_user->dle;
190 adle->next = data_user->dle;
192 data_user->has_calcsize = 0;
193 data_user->has_estimate = 0;
194 data_user->has_record = 0;
195 data_user->has_spindle = 0;
196 data_user->has_compress = 0;
197 data_user->has_encrypt = 0;
198 data_user->has_kencrypt = 0;
199 data_user->has_datapath = 0;
200 data_user->has_exclude = 0;
201 data_user->has_include = 0;
202 data_user->has_index = 0;
203 data_user->has_backup_program = 0;
204 data_user->has_plugin = 0;
205 data_user->has_optional = 0;
206 data_user->property_name = NULL;
207 data_user->property_data = NULL;
208 data_user->property = NULL;
209 data_user->script = NULL;
210 data_user->alevel = NULL;
211 data_user->encoding = NULL;
212 data_user->raw = NULL;
213 } else if(strcmp(element_name, "disk" ) == 0 ||
214 strcmp(element_name, "diskdevice" ) == 0 ||
215 strcmp(element_name, "calcsize" ) == 0 ||
216 strcmp(element_name, "estimate" ) == 0 ||
217 strcmp(element_name, "program" ) == 0 ||
218 strcmp(element_name, "auth" ) == 0 ||
219 strcmp(element_name, "index" ) == 0 ||
220 strcmp(element_name, "dumpdate" ) == 0 ||
221 strcmp(element_name, "level" ) == 0 ||
222 strcmp(element_name, "record" ) == 0 ||
223 strcmp(element_name, "spindle" ) == 0 ||
224 strcmp(element_name, "compress" ) == 0 ||
225 strcmp(element_name, "encrypt" ) == 0 ||
226 strcmp(element_name, "kencrypt" ) == 0 ||
227 strcmp(element_name, "datapath" ) == 0 ||
228 strcmp(element_name, "exclude" ) == 0 ||
229 strcmp(element_name, "include" ) == 0) {
230 if (strcmp(last_element_name, "dle") != 0) {
231 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
232 "XML: Invalid %s element", element_name);
235 if ((strcmp(element_name, "disk" ) == 0 && dle->disk) ||
236 (strcmp(element_name, "diskdevice" ) == 0 && dle->device) ||
237 (strcmp(element_name, "calcsize" ) == 0 && data_user->has_calcsize) ||
238 (strcmp(element_name, "estimate" ) == 0 && data_user->has_estimate) ||
239 (strcmp(element_name, "record" ) == 0 && data_user->has_record) ||
240 (strcmp(element_name, "spindle" ) == 0 && data_user->has_spindle) ||
241 (strcmp(element_name, "program" ) == 0 && dle->program) ||
242 (strcmp(element_name, "auth" ) == 0 && dle->auth) ||
243 (strcmp(element_name, "index" ) == 0 && data_user->has_index) ||
244 (strcmp(element_name, "dumpdate" ) == 0 && dle->dumpdate) ||
245 (strcmp(element_name, "compress" ) == 0 && data_user->has_compress) ||
246 (strcmp(element_name, "encrypt" ) == 0 && data_user->has_encrypt) ||
247 (strcmp(element_name, "kencrypt" ) == 0 && data_user->has_kencrypt) ||
248 (strcmp(element_name, "datapath" ) == 0 && data_user->has_datapath) ||
249 (strcmp(element_name, "exclude" ) == 0 && data_user->has_exclude) ||
250 (strcmp(element_name, "include" ) == 0 && data_user->has_include)) {
251 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
252 "XML: Duplicate %s element", element_name);
255 if (strcmp(element_name, "calcsize" ) == 0) data_user->has_calcsize = 1;
256 if (strcmp(element_name, "estimate" ) == 0) data_user->has_estimate = 1;
257 if (strcmp(element_name, "record" ) == 0) data_user->has_record = 1;
258 if (strcmp(element_name, "spindle" ) == 0) data_user->has_spindle = 1;
259 if (strcmp(element_name, "index" ) == 0) data_user->has_index = 1;
260 if (strcmp(element_name, "compress" ) == 0) data_user->has_compress = 1;
261 if (strcmp(element_name, "encrypt" ) == 0) data_user->has_encrypt = 1;
262 if (strcmp(element_name, "kencrypt" ) == 0) data_user->has_kencrypt = 1;
263 if (strcmp(element_name, "datapath" ) == 0) data_user->has_datapath = 1;
264 if (strcmp(element_name, "exclude" ) == 0) data_user->has_exclude = 1;
265 if (strcmp(element_name, "include" ) == 0) data_user->has_include = 1;
266 if (strcmp(element_name, "exclude") == 0 || strcmp(element_name, "include") == 0)
267 data_user->has_optional = 0;
268 if (strcmp(element_name, "level") == 0) {
269 data_user->alevel = g_new0(level_t, 1);
271 } else if (strcmp(element_name, "server") == 0) {
272 if (strcmp(last_element_name, "level") != 0) {
273 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
274 "XML: Invalid %s element", element_name);
277 } else if(strcmp(element_name, "custom-compress-program") == 0) {
278 if (strcmp(last_element_name, "compress") != 0) {
279 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
280 "XML: Invalid %s element", element_name);
284 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
285 "XML: Duplicate %s element", element_name);
288 } else if (strcmp(element_name, "custom-encrypt-program") == 0 ||
289 strcmp(element_name, "decrypt-option") == 0) {
290 if (strcmp(last_element_name, "encrypt") != 0) {
291 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
292 "XML: Invalid %s element", element_name);
295 if (strcmp(element_name, "custom-encrypt-program") == 0 &&
297 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
298 "XML: Duplicate %s element", element_name);
301 if (strcmp(element_name, "decrypt-option") == 0 &&
302 dle->clnt_decrypt_opt) {
303 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
304 "XML: Duplicate %s element", element_name);
307 } else if(strcmp(element_name, "plugin") == 0) {
308 if (strcmp(last_element_name, "backup-program") != 0 &&
309 strcmp(last_element_name, "script") != 0) {
310 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
311 "XML: Invalid %s element", element_name);
314 if (data_user->has_plugin) {
315 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
316 "XML: Duplicate %s element in '%s'", element_name,
320 } else if(strcmp(element_name, "property") == 0) {
321 if (strcmp(last_element_name, "backup-program") != 0 &&
322 strcmp(last_element_name, "script") != 0) {
323 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
324 "XML: Invalid %s element", element_name);
327 data_user->property_data = malloc(sizeof(property_t));
328 data_user->property_data->append = 0;
329 data_user->property_data->priority = 0;
330 data_user->property_data->values = NULL;
331 } else if(strcmp(element_name, "name") == 0) {
332 if (strcmp(last_element_name, "property") != 0) {
333 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
334 "XML: Invalid %s element", element_name);
337 if (data_user->property_name) {
338 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
339 "XML: Duplicate %s element in '%s'", element_name,
343 } else if(strcmp(element_name, "priority") == 0) {
344 if (strcmp(last_element_name, "property") != 0) {
345 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
346 "XML: Invalid %s element", element_name);
349 } else if(strcmp(element_name, "value") == 0) {
350 if (strcmp(last_element_name, "property") != 0) {
351 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
352 "XML: Invalid %s element", element_name);
355 } else if(strcmp(element_name, "file") == 0 ||
356 strcmp(element_name, "list") == 0 ||
357 strcmp(element_name, "optional") == 0) {
358 if (strcmp(last_element_name, "exclude") != 0 &&
359 strcmp(last_element_name, "include") != 0) {
360 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
361 "XML: Invalid %s element", element_name);
364 if (strcmp(element_name, "optional") == 0 && data_user->has_optional) {
365 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
366 "XML: Duplicate %s element", element_name);
369 if (strcmp(element_name, "optional") == 0) data_user->has_optional = 1;
370 } else if (strcmp(element_name, "backup-program") == 0) {
371 if (data_user->has_backup_program) {
372 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
373 "XML: Duplicate %s element", element_name);
376 data_user->has_backup_program = 1;
377 data_user->property =
378 g_hash_table_new_full(g_str_hash, g_str_equal, NULL, NULL);
379 data_user->has_plugin = 0;
381 } else if (strcmp(element_name, "script") == 0) {
382 data_user->property =
383 g_hash_table_new_full(g_str_hash, g_str_equal, NULL, NULL);
384 data_user->script = malloc(sizeof(script_t));
385 data_user->script->plugin = NULL;
386 data_user->script->execute_on = 0;
387 data_user->script->execute_where = ES_CLIENT;
388 data_user->script->property = NULL;
389 data_user->script->result = NULL;
390 data_user->has_plugin = 0;
391 } else if (strcmp(element_name, "execute_on") == 0) {
392 } else if (strcmp(element_name, "execute_where") == 0) {
393 } else if (strcmp(element_name, "directtcp") == 0) {
394 if (strcmp(last_element_name, "datapath") != 0) {
395 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
396 "XML: Invalid %s element", element_name);
400 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
401 "XML: Invalid %s element", element_name);
404 data_user->element_names = g_slist_prepend(data_user->element_names,
405 stralloc(element_name));
408 /* Called for close tags </foo> */
411 G_GNUC_UNUSED GMarkupParseContext *context,
412 const gchar *element_name,
416 amgxml_t *data_user = user_data;
417 GSList *last_element = data_user->element_names;
418 char *last_element_name = NULL;
419 dle_t *dle = data_user->dle;
422 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
423 "XML: Invalid closing tag");
426 last_element_name = last_element->data;
427 if (strcmp(last_element_name, element_name) != 0) {
428 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
429 "XML: Invalid closing tag '%s'", element_name);
433 if (strcmp(element_name, "property") == 0) {
434 g_hash_table_insert(data_user->property,
435 data_user->property_name,
436 data_user->property_data);
437 data_user->property_name = NULL;
438 data_user->property_data = NULL;
439 } else if (strcmp(element_name, "dle") == 0) {
440 if (dle->program_is_application_api &&
442 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
443 "XML: program set to APPLICATION but no application set");
446 if (dle->device == NULL && dle->disk)
447 dle->device = stralloc(dle->disk);
448 if (dle->estimatelist == NULL)
449 dle->estimatelist = g_slist_append(dle->estimatelist, ES_CLIENT);
450 /* Add check of required field */
451 data_user->dle = NULL;
452 } else if (strcmp(element_name, "backup-program") == 0) {
453 if (dle->program == NULL) {
454 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
455 "XML: No plugin set for application");
458 dle->application_property = data_user->property;
459 data_user->property = NULL;
460 } else if (strcmp(element_name, "script") == 0) {
461 if (data_user->script->plugin == NULL) {
462 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
463 "XML: No plugin set for script");
466 data_user->script->property = data_user->property;
467 data_user->property = NULL;
468 dle->scriptlist = g_slist_append(dle->scriptlist, data_user->script);
469 data_user->script = NULL;
470 } else if (strcmp(element_name, "level") == 0) {
471 dle->levellist = g_slist_append(dle->levellist, data_user->alevel);
472 data_user->alevel = NULL;
474 g_free(data_user->element_names->data);
475 data_user->element_names = g_slist_delete_link(data_user->element_names,
476 data_user->element_names);
479 /* Called for character data */
480 /* text is not nul-terminated */
483 G_GNUC_UNUSED GMarkupParseContext *context,
490 amgxml_t *data_user = user_data;
491 GSList *last_element = data_user->element_names;
492 char *last_element_name;
493 GSList *last_element2;
494 char *last_element2_name;
495 dle_t *dle = data_user->dle;
499 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
500 "XML: Invalid text");
503 last_element_name = last_element->data;
505 tt = malloc(text_len + 1);
506 strncpy(tt,text,text_len);
509 //check if it is only space
510 if (match_no_newline("^[ \f\n\r\t\v]*$", tt)) {
515 if (data_user->raw) {
517 tt = stralloc(data_user->raw);
518 } else if (strlen(tt) > 0) {
519 /* remove trailing space */
520 char *ttt = tt + strlen(tt) - 1;
528 //check if it is only space
529 if (match_no_newline("^[ \f\n\r\t\v]*$", tt)) {
534 if (strcmp(last_element_name, "dle") == 0 ||
535 strcmp(last_element_name, "backup-program") == 0 ||
536 strcmp(last_element_name, "exclude") == 0 ||
537 strcmp(last_element_name, "include") == 0) {
538 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
539 "XML: %s doesn't have text '%s'", last_element_name, tt);
541 } else if(strcmp(last_element_name, "disk") == 0) {
542 if (dle->disk != NULL) {
543 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
544 "XML: multiple text in %s", last_element_name);
548 } else if(strcmp(last_element_name, "diskdevice") == 0) {
549 if (dle->device != NULL) {
550 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
551 "XML: multiple text in %s", last_element_name);
555 } else if(strcmp(last_element_name, "calcsize") == 0) {
556 if (strcasecmp(tt,"yes") == 0) {
557 dle->estimatelist = g_slist_append(dle->estimatelist,
558 GINT_TO_POINTER(ES_CALCSIZE));
561 } else if(strcmp(last_element_name, "estimate") == 0) {
563 while (strlen(ttt) > 0) {
564 if (BSTRNCMP(ttt,"CLIENT") == 0) {
565 dle->estimatelist = g_slist_append(dle->estimatelist,
566 GINT_TO_POINTER(ES_CLIENT));
567 ttt += strlen("client");
568 } else if (BSTRNCMP(ttt,"CALCSIZE") == 0) {
569 if (!data_user->has_calcsize)
570 dle->estimatelist = g_slist_append(dle->estimatelist,
571 GINT_TO_POINTER(ES_CALCSIZE));
572 ttt += strlen("calcsize");
573 } else if (BSTRNCMP(ttt,"SERVER") == 0) {
574 dle->estimatelist = g_slist_append(dle->estimatelist,
575 GINT_TO_POINTER(ES_SERVER));
576 ttt += strlen("server");
578 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
579 "XML: bad estimate: %s", tt);
586 } else if(strcmp(last_element_name, "program") == 0) {
587 if (dle->program != NULL) {
588 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
589 "XML: multiple text in %s", last_element_name);
593 if (strcmp(tt, "APPLICATION") == 0) {
594 dle->program_is_application_api = 1;
597 } else if(strcmp(last_element_name, "plugin") == 0) {
598 last_element2 = g_slist_nth(data_user->element_names, 1);
599 if (!last_element2) {
600 error("Invalid name text");
602 last_element2_name = last_element2->data;
603 if (strcmp(last_element2_name, "backup-program") == 0) {
605 } else if (strcmp(last_element2_name, "script") == 0) {
606 data_user->script->plugin = tt;
608 error("plugin outside of backup-program");
610 data_user->has_plugin = 1;
611 } else if(strcmp(last_element_name, "name") == 0) {
612 last_element2 = g_slist_nth(data_user->element_names, 1);
613 if (!last_element2) {
614 error("Invalid name text");
616 last_element2_name = last_element2->data;
617 if (strcmp(last_element2_name, "property") == 0) {
618 data_user->property_name = tt;
620 error("name outside of property");
622 } else if(strcmp(last_element_name, "priority") == 0) {
623 last_element2 = g_slist_nth(data_user->element_names, 1);
624 if (!last_element2) {
625 error("Invalid priority text");
627 last_element2_name = last_element2->data;
628 if (strcmp(last_element2_name, "property") == 0) {
629 if (strcasecmp(tt,"yes") == 0) {
630 data_user->property_data->priority = 1;
633 error("priority outside of property");
635 } else if(strcmp(last_element_name, "value") == 0) {
636 last_element2 = g_slist_nth(data_user->element_names, 1);
637 if (!last_element2) {
638 error("Invalid name text");
640 last_element2_name = last_element2->data;
641 if (strcmp(last_element2_name, "property") == 0) {
642 data_user->property_data->values =
643 g_slist_append(data_user->property_data->values, tt);
645 error("value outside of property");
647 } else if(strcmp(last_element_name, "auth") == 0) {
648 if (dle->auth != NULL) {
649 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
650 "XML: multiple text in %s", last_element_name);
654 } else if(strcmp(last_element_name, "level") == 0) {
655 data_user->alevel->level = atoi(tt);
657 } else if (strcmp(last_element_name, "server") == 0) {
658 if (strcasecmp(tt,"no") == 0) {
659 data_user->alevel->server = 0;
660 } else if (strcasecmp(tt,"yes") == 0) {
661 data_user->alevel->server = 1;
663 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
664 "XML: Invalid %s (%s)", last_element_name, tt);
669 } else if(strcmp(last_element_name, "index") == 0) {
670 if (strcasecmp(tt,"no") == 0) {
671 dle->create_index = 0;
672 } else if (strcasecmp(tt,"yes") == 0) {
673 dle->create_index = 1;
675 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
676 "XML: Invalid %s (%s)", last_element_name, tt);
681 } else if(strcmp(last_element_name, "dumpdate") == 0) {
682 if (dle->dumpdate != NULL) {
683 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
684 "XML: multiple text in %s", last_element_name);
689 } else if(strcmp(last_element_name, "record") == 0) {
690 if (strcasecmp(tt, "no") == 0) {
692 } else if (strcasecmp(tt, "yes") == 0) {
695 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
696 "XML: Invalid %s (%s)", last_element_name, tt);
699 } else if(strcmp(last_element_name, "spindle") == 0) {
700 dle->spindle = atoi(tt);
701 } else if(strcmp(last_element_name, "compress") == 0) {
702 if (strcmp(tt, "FAST") == 0) {
703 dle->compress = COMP_FAST;
704 } else if (strcmp(tt, "BEST") == 0) {
705 dle->compress = COMP_BEST;
706 } else if (BSTRNCMP(tt, "CUSTOM") == 0) {
707 dle->compress = COMP_CUST;
708 } else if (strcmp(tt, "SERVER-FAST") == 0) {
709 dle->compress = COMP_SERVER_FAST;
710 } else if (strcmp(tt, "SERVER-BEST") == 0) {
711 dle->compress = COMP_SERVER_BEST;
712 } else if (BSTRNCMP(tt, "SERVER-CUSTOM") == 0) {
713 dle->compress = COMP_SERVER_CUST;
715 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
716 "XML: Invalid %s (%s)", last_element_name, tt);
721 } else if(strcmp(last_element_name, "custom-compress-program") == 0) {
722 if (dle->compprog != NULL) {
723 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
724 "XML: multiple text in %s", last_element_name);
729 } else if(strcmp(last_element_name, "encrypt") == 0) {
730 if (BSTRNCMP(tt,"NO") == 0) {
731 dle->encrypt = ENCRYPT_NONE;
732 } else if (BSTRNCMP(tt, "CUSTOM") == 0) {
733 dle->encrypt = ENCRYPT_CUST;
734 } else if (BSTRNCMP(tt, "SERVER-CUSTOM") == 0) {
735 dle->encrypt = ENCRYPT_SERV_CUST;
737 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
738 "XML: Invalid %s (%s)", last_element_name, tt);
743 } else if(strcmp(last_element_name, "kencrypt") == 0) {
744 if (strcasecmp(tt,"no") == 0) {
746 } else if (strcasecmp(tt,"yes") == 0) {
749 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
750 "XML: Invalid %s (%s)", last_element_name, tt);
755 } else if(strcmp(last_element_name, "custom-encrypt-program") == 0) {
756 last_element2 = g_slist_nth(data_user->element_names, 1);
757 if (!last_element2) {
758 error("XML: optional");
760 last_element2_name = last_element2->data;
761 dle->clnt_encrypt = tt;
762 } else if(strcmp(last_element_name, "decrypt-option") == 0) {
763 last_element2 = g_slist_nth(data_user->element_names, 1);
764 if (!last_element2) {
765 error("XML: optional");
767 last_element2_name = last_element2->data;
768 dle->clnt_decrypt_opt = tt;
769 } else if(strcmp(last_element_name, "exclude") == 0 ||
770 strcmp(last_element_name, "include") == 0) {
771 data_user->has_optional = 0;
772 } else if(strcmp(last_element_name, "file") == 0) {
773 last_element2 = g_slist_nth(data_user->element_names, 1);
774 if (!last_element2) {
775 error("XML: optional");
777 last_element2_name = last_element2->data;
778 if (strcmp(last_element2_name, "exclude") == 0) {
779 dle->exclude_file = append_sl(dle->exclude_file, tt);
780 } else if (strcmp(last_element2_name, "include") == 0) {
781 dle->include_file = append_sl(dle->include_file, tt);
785 } else if(strcmp(last_element_name, "list") == 0) {
786 last_element2 = g_slist_nth(data_user->element_names, 1);
787 if (!last_element2) {
788 error("XML: optional");
790 last_element2_name = last_element2->data;
791 if (strcmp(last_element2_name, "exclude") == 0) {
792 dle->exclude_list = append_sl(dle->exclude_list, tt);
793 } else if (strcmp(last_element2_name, "include") == 0) {
794 dle->include_list = append_sl(dle->include_list, tt);
798 } else if(strcmp(last_element_name, "optional") == 0) {
800 last_element2 = g_slist_nth(data_user->element_names, 1);
801 if (!last_element2) {
802 error("XML: optional");
804 last_element2_name = last_element2->data;
805 if (strcmp(last_element2_name, "exclude") == 0) {
806 dle->exclude_optional = 1;
807 } else if (strcmp(last_element2_name, "include") == 0) {
808 dle->include_optional = 1;
810 error("bad optional");
812 data_user->has_optional = 1;
814 } else if(strcmp(last_element_name, "script") == 0) {
815 } else if(strcmp(last_element_name, "execute_on") == 0) {
819 sep = strchr(tt1,',');
822 if (strcmp(tt1,"PRE-DLE-AMCHECK") == 0)
823 data_user->script->execute_on |= EXECUTE_ON_PRE_DLE_AMCHECK;
824 else if (strcmp(tt1,"PRE-HOST-AMCHECK") == 0)
825 data_user->script->execute_on |= EXECUTE_ON_PRE_HOST_AMCHECK;
826 else if (strcmp(tt1,"POST-DLE-AMCHECK") == 0)
827 data_user->script->execute_on |= EXECUTE_ON_POST_DLE_AMCHECK;
828 else if (strcmp(tt1,"POST-HOST-AMCHECK") == 0)
829 data_user->script->execute_on |= EXECUTE_ON_POST_HOST_AMCHECK;
830 else if (strcmp(tt1,"PRE-DLE-ESTIMATE") == 0)
831 data_user->script->execute_on |= EXECUTE_ON_PRE_DLE_ESTIMATE;
832 else if (strcmp(tt1,"PRE-HOST-ESTIMATE") == 0)
833 data_user->script->execute_on |= EXECUTE_ON_PRE_HOST_ESTIMATE;
834 else if (strcmp(tt1,"POST-DLE-ESTIMATE") == 0)
835 data_user->script->execute_on |= EXECUTE_ON_POST_DLE_ESTIMATE;
836 else if (strcmp(tt1,"POST-HOST-ESTIMATE") == 0)
837 data_user->script->execute_on |= EXECUTE_ON_POST_HOST_ESTIMATE;
838 else if (strcmp(tt1,"PRE-DLE-BACKUP") == 0)
839 data_user->script->execute_on |= EXECUTE_ON_PRE_DLE_BACKUP;
840 else if (strcmp(tt1,"PRE-HOST-BACKUP") == 0)
841 data_user->script->execute_on |= EXECUTE_ON_PRE_HOST_BACKUP;
842 else if (strcmp(tt1,"POST-DLE-BACKUP") == 0)
843 data_user->script->execute_on |= EXECUTE_ON_POST_DLE_BACKUP;
844 else if (strcmp(tt1,"POST-HOST-BACKUP") == 0)
845 data_user->script->execute_on |= EXECUTE_ON_POST_HOST_BACKUP;
846 else if (strcmp(tt1,"PRE-RECOVER") == 0)
847 data_user->script->execute_on |= EXECUTE_ON_PRE_RECOVER;
848 else if (strcmp(tt1,"POST-RECOVER") == 0)
849 data_user->script->execute_on |= EXECUTE_ON_POST_RECOVER;
850 else if (strcmp(tt1,"PRE-LEVEL-RECOVER") == 0)
851 data_user->script->execute_on |= EXECUTE_ON_PRE_LEVEL_RECOVER;
852 else if (strcmp(tt1,"POST-LEVEL-RECOVER") == 0)
853 data_user->script->execute_on |= EXECUTE_ON_POST_LEVEL_RECOVER;
854 else if (strcmp(tt1,"INTER-LEVEL-RECOVER") == 0)
855 data_user->script->execute_on |= EXECUTE_ON_INTER_LEVEL_RECOVER;
857 dbprintf("BAD EXECUTE_ON: %s\n", tt1);
862 } else if(strcmp(last_element_name, "execute_where") == 0) {
863 if (strcmp(tt, "CLIENT") == 0) {
864 data_user->script->execute_where = ES_CLIENT;
866 data_user->script->execute_where = ES_SERVER;
868 } else if(strcmp(last_element_name, "datapath") == 0) {
869 if (strcmp(tt, "AMANDA") == 0) {
870 dle->data_path = DATA_PATH_AMANDA;
871 } else if (strcmp(tt, "DIRECTTCP") == 0) {
872 dle->data_path = DATA_PATH_DIRECTTCP;
874 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
875 "XML: bad datapath value '%s'", tt);
878 } else if(strcmp(last_element_name, "directtcp") == 0) {
879 dle->directtcp_list = g_slist_append(dle->directtcp_list, tt);
881 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
882 "XML: amtext not defined for '%s'", last_element_name);
888 amxml_parse_node_CHAR(
892 amgxml_t amgxml = {NULL, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL};
893 GMarkupParser parser = {&amstart_element, &amend_element, &amtext,
895 GMarkupParseFlags flags = 0;
896 GMarkupParseContext *context;
897 GError *gerror = NULL;
901 context = g_markup_parse_context_new(&parser, flags, &amgxml, NULL);
903 g_markup_parse_context_parse(context, txt, strlen(txt), &gerror);
905 g_markup_parse_context_end_parse(context, &gerror);
906 g_markup_parse_context_free(context);
909 *errmsg = stralloc(gerror->message);
910 g_error_free(gerror);
917 amxml_parse_node_FILE(
921 amgxml_t amgxml = {NULL, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL};
922 GMarkupParser parser = {&amstart_element, &amend_element, &amtext,
924 GMarkupParseFlags flags = 0;
925 GMarkupParseContext *context;
926 GError *gerror = NULL;
931 context = g_markup_parse_context_new(&parser, flags, &amgxml, NULL);
933 while ((line = agets(file)) != NULL && !gerror) {
934 g_markup_parse_context_parse(context, line, strlen(line), &gerror);
938 g_markup_parse_context_end_parse(context, &gerror);
939 g_markup_parse_context_free(context);
942 *errmsg = stralloc(gerror->message);
943 g_error_free(gerror);
960 quoted_value = malloc(strlen(value)+1);
963 for(c=value; *c != '\0'; c++) {
964 // Check include negative value, with the 8th bit set.
966 (unsigned char)*c > 127 ||
986 base64_encode_alloc(value, strlen(value), &b64value);
987 result = vstralloc("<", tag,
988 " encoding=\"raw\" raw=\"", b64value, "\">",
994 result = vstralloc("<", tag, ">",
999 amfree(quoted_value);