2 * Amanda, The Advanced Maryland Automatic Network Disk Archiver
3 * Copyright (c) 1991-1998 University of Maryland at College Park
4 * Copyright (c) 2007-2012 Zmanda, Inc. All Rights Reserved.
7 * Permission to use, copy, modify, distribute, and sell this software and its
8 * documentation for any purpose is hereby granted without fee, provided that
9 * the above copyright notice appear in all copies and that both that
10 * copyright notice and this permission notice appear in supporting
11 * documentation, and that the name of U.M. not be used in advertising or
12 * publicity pertaining to distribution of the software without specific,
13 * written prior permission. U.M. makes no representations about the
14 * suitability of this software for any purpose. It is provided "as is"
15 * without express or implied warranty.
17 * U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M.
19 * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
20 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
21 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
22 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
24 * Authors: the Amanda Development Team. Its members are listed in a
25 * file named AUTHORS, in the root directory of this distribution.
29 * $Id: amxml.c 5151 2007-02-06 15:41:53Z martineau $
31 * xml parsing of amanda protocol packet
42 typedef struct amgxml_s {
45 GSList *element_names;
57 int has_backup_program;
61 property_t *property_data;
75 dle = malloc(sizeof(dle_t));
84 scriptlist_t scriptlist;
89 g_slist_free(dle->estimatelist);
90 slist_free_full(dle->levellist, g_free);
91 amfree(dle->dumpdate);
92 amfree(dle->compprog);
93 amfree(dle->srv_encrypt);
94 amfree(dle->clnt_encrypt);
95 amfree(dle->srv_decrypt_opt);
96 amfree(dle->clnt_decrypt_opt);
98 amfree(dle->application_client_name);
99 free_sl(dle->exclude_file);
100 free_sl(dle->exclude_list);
101 free_sl(dle->include_file);
102 free_sl(dle->include_list);
104 g_hash_table_destroy(dle->property);
105 if (dle->application_property)
106 g_hash_table_destroy(dle->application_property);
107 for(scriptlist = dle->scriptlist; scriptlist != NULL;
108 scriptlist = scriptlist->next) {
109 free_script_data((script_t *)scriptlist->data);
111 slist_free_full(dle->scriptlist, g_free);
112 slist_free_full(dle->directtcp_list, g_free);
120 amfree(script->plugin);
121 amfree(script->client_name);
122 if (script->property)
123 g_hash_table_destroy(script->property);
132 dle->program_is_application_api = 0;
134 dle->estimatelist = NULL;
137 dle->compress = COMP_NONE;
138 dle->encrypt = ENCRYPT_NONE;
140 dle->levellist = NULL;
141 dle->dumpdate = NULL;
142 dle->compprog = NULL;
143 dle->srv_encrypt = NULL;
144 dle->clnt_encrypt = NULL;
145 dle->srv_decrypt_opt = NULL;
146 dle->clnt_decrypt_opt = NULL;
147 dle->create_index = 0;
149 dle->exclude_file = NULL;
150 dle->exclude_list = NULL;
151 dle->include_file = NULL;
152 dle->include_list = NULL;
153 dle->exclude_optional = 0;
154 dle->include_optional = 0;
155 dle->property = NULL;
156 dle->application_property = NULL;
157 dle->scriptlist = NULL;
158 dle->data_path = DATA_PATH_AMANDA;
159 dle->directtcp_list = NULL;
160 dle->application_client_name = NULL;
165 /* Called for open tags <foo bar="baz"> */
166 static void amstart_element(GMarkupParseContext *context,
167 const gchar *element_name,
168 const gchar **attribute_names,
169 const gchar **attribute_values,
173 /* Called for close tags </foo> */
174 static void amend_element(GMarkupParseContext *context,
175 const gchar *element_name,
179 /* Called for character data */
180 /* text is not nul-terminated */
181 static void amtext(GMarkupParseContext *context,
187 /* Called for open tags <foo bar="baz"> */
190 G_GNUC_UNUSED GMarkupParseContext *context,
191 const gchar *element_name,
192 G_GNUC_UNUSED const gchar **attribute_names,
193 G_GNUC_UNUSED const gchar **attribute_values,
197 amgxml_t *data_user = user_data;
199 GSList *last_element = data_user->element_names;
200 char *last_element_name = NULL;
201 dle_t *dle = data_user->dle;
202 const gchar **at_names, **at_values;
205 last_element_name = last_element->data;
207 data_user->raw = NULL;
208 data_user->encoding = NULL;
210 if (attribute_names) {
211 for(at_names = attribute_names, at_values = attribute_values;
212 *at_names != NULL && at_values != NULL;
213 at_names++, at_values++) {
214 if (strcmp(*at_names, "encoding") == 0) {
215 data_user->encoding = stralloc(*at_values);
216 } else if (strcmp(*at_names, "raw") == 0) {
217 data_user->raw = base64_decode_alloc_string((char *)*at_values);
219 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
220 "XML: Invalid attribute '%s' for %s element",
221 *at_names, element_name);
227 if (strcmp(element_name, "dle") == 0) {
228 if (last_element != NULL) {
229 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
230 "XML: Invalid dle element");
233 for(adle = data_user->dles; adle != NULL && adle->next != NULL;
235 data_user->dle = alloc_dle();
237 data_user->dles = data_user->dle;
239 adle->next = data_user->dle;
241 data_user->has_calcsize = 0;
242 data_user->has_estimate = 0;
243 data_user->has_record = 0;
244 data_user->has_spindle = 0;
245 data_user->has_compress = 0;
246 data_user->has_encrypt = 0;
247 data_user->has_kencrypt = 0;
248 data_user->has_datapath = 0;
249 data_user->has_exclude = 0;
250 data_user->has_include = 0;
251 data_user->has_index = 0;
252 data_user->has_backup_program = 0;
253 data_user->has_plugin = 0;
254 data_user->has_optional = 0;
255 data_user->property_name = NULL;
256 data_user->property_data = NULL;
257 data_user->property =
258 g_hash_table_new_full(g_str_hash, g_str_equal, &g_free, &free_property_t);
259 data_user->script = NULL;
260 data_user->alevel = NULL;
261 data_user->dle->property = data_user->property;
262 data_user->encoding = NULL;
263 data_user->raw = NULL;
264 } else if(strcmp(element_name, "disk" ) == 0 ||
265 strcmp(element_name, "diskdevice" ) == 0 ||
266 strcmp(element_name, "calcsize" ) == 0 ||
267 strcmp(element_name, "estimate" ) == 0 ||
268 strcmp(element_name, "program" ) == 0 ||
269 strcmp(element_name, "auth" ) == 0 ||
270 strcmp(element_name, "index" ) == 0 ||
271 strcmp(element_name, "dumpdate" ) == 0 ||
272 strcmp(element_name, "level" ) == 0 ||
273 strcmp(element_name, "record" ) == 0 ||
274 strcmp(element_name, "spindle" ) == 0 ||
275 strcmp(element_name, "compress" ) == 0 ||
276 strcmp(element_name, "encrypt" ) == 0 ||
277 strcmp(element_name, "kencrypt" ) == 0 ||
278 strcmp(element_name, "datapath" ) == 0 ||
279 strcmp(element_name, "exclude" ) == 0 ||
280 strcmp(element_name, "include" ) == 0) {
281 if (strcmp(last_element_name, "dle") != 0) {
282 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
283 "XML: Invalid %s element", element_name);
286 if ((strcmp(element_name, "disk" ) == 0 && dle->disk) ||
287 (strcmp(element_name, "diskdevice" ) == 0 && dle->device) ||
288 (strcmp(element_name, "calcsize" ) == 0 && data_user->has_calcsize) ||
289 (strcmp(element_name, "estimate" ) == 0 && data_user->has_estimate) ||
290 (strcmp(element_name, "record" ) == 0 && data_user->has_record) ||
291 (strcmp(element_name, "spindle" ) == 0 && data_user->has_spindle) ||
292 (strcmp(element_name, "program" ) == 0 && dle->program) ||
293 (strcmp(element_name, "auth" ) == 0 && dle->auth) ||
294 (strcmp(element_name, "index" ) == 0 && data_user->has_index) ||
295 (strcmp(element_name, "dumpdate" ) == 0 && dle->dumpdate) ||
296 (strcmp(element_name, "compress" ) == 0 && data_user->has_compress) ||
297 (strcmp(element_name, "encrypt" ) == 0 && data_user->has_encrypt) ||
298 (strcmp(element_name, "kencrypt" ) == 0 && data_user->has_kencrypt) ||
299 (strcmp(element_name, "datapath" ) == 0 && data_user->has_datapath) ||
300 (strcmp(element_name, "exclude" ) == 0 && data_user->has_exclude) ||
301 (strcmp(element_name, "include" ) == 0 && data_user->has_include)) {
302 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
303 "XML: Duplicate %s element", element_name);
306 if (strcmp(element_name, "calcsize" ) == 0) data_user->has_calcsize = 1;
307 if (strcmp(element_name, "estimate" ) == 0) data_user->has_estimate = 1;
308 if (strcmp(element_name, "record" ) == 0) data_user->has_record = 1;
309 if (strcmp(element_name, "spindle" ) == 0) data_user->has_spindle = 1;
310 if (strcmp(element_name, "index" ) == 0) data_user->has_index = 1;
311 if (strcmp(element_name, "compress" ) == 0) data_user->has_compress = 1;
312 if (strcmp(element_name, "encrypt" ) == 0) data_user->has_encrypt = 1;
313 if (strcmp(element_name, "kencrypt" ) == 0) data_user->has_kencrypt = 1;
314 if (strcmp(element_name, "datapath" ) == 0) data_user->has_datapath = 1;
315 if (strcmp(element_name, "exclude" ) == 0) data_user->has_exclude = 1;
316 if (strcmp(element_name, "include" ) == 0) data_user->has_include = 1;
317 if (strcmp(element_name, "exclude") == 0 || strcmp(element_name, "include") == 0)
318 data_user->has_optional = 0;
319 if (strcmp(element_name, "level") == 0) {
320 data_user->alevel = g_new0(am_level_t, 1);
322 } else if (strcmp(element_name, "server") == 0) {
323 if (strcmp(last_element_name, "level") != 0) {
324 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
325 "XML: Invalid %s element", element_name);
328 } else if(strcmp(element_name, "custom-compress-program") == 0) {
329 if (strcmp(last_element_name, "compress") != 0) {
330 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
331 "XML: Invalid %s element", element_name);
335 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
336 "XML: Duplicate %s element", element_name);
339 } else if (strcmp(element_name, "custom-encrypt-program") == 0 ||
340 strcmp(element_name, "decrypt-option") == 0) {
341 if (strcmp(last_element_name, "encrypt") != 0) {
342 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
343 "XML: Invalid %s element", element_name);
346 if (strcmp(element_name, "custom-encrypt-program") == 0 &&
348 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
349 "XML: Duplicate %s element", element_name);
352 if (strcmp(element_name, "decrypt-option") == 0 &&
353 dle->clnt_decrypt_opt) {
354 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
355 "XML: Duplicate %s element", element_name);
358 } else if(strcmp(element_name, "plugin") == 0) {
359 if (strcmp(last_element_name, "backup-program") != 0 &&
360 strcmp(last_element_name, "script") != 0) {
361 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
362 "XML: Invalid %s element", element_name);
365 if (data_user->has_plugin) {
366 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
367 "XML: Duplicate %s element in '%s'", element_name,
371 } else if(strcmp(element_name, "property") == 0) {
373 (strcmp(last_element_name, "backup-program") != 0 &&
374 strcmp(last_element_name, "script") != 0 &&
375 strcmp(last_element_name, "dle") != 0)) {
376 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
377 "XML: Invalid %s element", element_name);
380 data_user->property_data = malloc(sizeof(property_t));
381 data_user->property_data->append = 0;
382 data_user->property_data->priority = 0;
383 data_user->property_data->values = NULL;
384 } else if(strcmp(element_name, "name") == 0) {
385 if (strcmp(last_element_name, "property") != 0) {
386 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
387 "XML: Invalid %s element", element_name);
390 if (data_user->property_name) {
391 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
392 "XML: Duplicate %s element in '%s'", element_name,
396 } else if(strcmp(element_name, "priority") == 0) {
397 if (strcmp(last_element_name, "property") != 0) {
398 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
399 "XML: Invalid %s element", element_name);
402 } else if(strcmp(element_name, "value") == 0) {
403 if (strcmp(last_element_name, "property") != 0) {
404 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
405 "XML: Invalid %s element", element_name);
408 } else if(strcmp(element_name, "file") == 0 ||
409 strcmp(element_name, "list") == 0 ||
410 strcmp(element_name, "optional") == 0) {
411 if (strcmp(last_element_name, "exclude") != 0 &&
412 strcmp(last_element_name, "include") != 0) {
413 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
414 "XML: Invalid %s element", element_name);
417 if (strcmp(element_name, "optional") == 0 && data_user->has_optional) {
418 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
419 "XML: Duplicate %s element", element_name);
422 if (strcmp(element_name, "optional") == 0) data_user->has_optional = 1;
423 } else if (strcmp(element_name, "backup-program") == 0) {
424 if (data_user->has_backup_program) {
425 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
426 "XML: Duplicate %s element", element_name);
429 data_user->has_backup_program = 1;
430 data_user->property =
431 g_hash_table_new_full(g_str_hash, g_str_equal, &g_free, &free_property_t);
432 data_user->has_plugin = 0;
434 } else if (strcmp(element_name, "script") == 0) {
435 data_user->property =
436 g_hash_table_new_full(g_str_hash, g_str_equal, &g_free, &free_property_t);
437 data_user->script = malloc(sizeof(script_t));
438 data_user->script->plugin = NULL;
439 data_user->script->execute_on = 0;
440 data_user->script->execute_where = ES_CLIENT;
441 data_user->script->property = NULL;
442 data_user->script->client_name = NULL;
443 data_user->script->result = NULL;
444 data_user->has_plugin = 0;
445 } else if (strcmp(element_name, "execute_on") == 0) {
446 } else if (strcmp(element_name, "execute_where") == 0) {
447 } else if (strcmp(element_name, "directtcp") == 0) {
448 if (strcmp(last_element_name, "datapath") != 0) {
449 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
450 "XML: Invalid %s element", element_name);
453 } else if (strcmp(element_name, "client_name") == 0) {
455 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
456 "XML: Invalid %s element", element_name);
459 data_user->element_names = g_slist_prepend(data_user->element_names,
460 stralloc(element_name));
463 /* Called for close tags </foo> */
466 G_GNUC_UNUSED GMarkupParseContext *context,
467 const gchar *element_name,
471 amgxml_t *data_user = user_data;
472 GSList *last_element = data_user->element_names;
473 char *last_element_name = NULL;
474 dle_t *dle = data_user->dle;
477 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
478 "XML: Invalid closing tag");
481 last_element_name = last_element->data;
482 if (strcmp(last_element_name, element_name) != 0) {
483 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
484 "XML: Invalid closing tag '%s'", element_name);
488 if (strcmp(element_name, "property") == 0) {
489 g_hash_table_insert(data_user->property,
490 data_user->property_name,
491 data_user->property_data);
492 data_user->property_name = NULL;
493 data_user->property_data = NULL;
494 } else if (strcmp(element_name, "dle") == 0) {
495 if (dle->program_is_application_api &&
497 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
498 "XML: program set to APPLICATION but no application set");
501 if (dle->device == NULL && dle->disk)
502 dle->device = stralloc(dle->disk);
503 if (dle->estimatelist == NULL)
504 dle->estimatelist = g_slist_append(dle->estimatelist, ES_CLIENT);
505 /* Add check of required field */
506 data_user->property = NULL;
507 data_user->dle = NULL;
508 } else if (strcmp(element_name, "backup-program") == 0) {
509 if (dle->program == NULL) {
510 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
511 "XML: No plugin set for application");
514 dle->application_property = data_user->property;
515 data_user->property = dle->property;
516 } else if (strcmp(element_name, "script") == 0) {
517 if (data_user->script->plugin == NULL) {
518 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
519 "XML: No plugin set for script");
522 data_user->script->property = data_user->property;
523 data_user->property = dle->property;
524 dle->scriptlist = g_slist_append(dle->scriptlist, data_user->script);
525 data_user->script = NULL;
526 } else if (strcmp(element_name, "level") == 0) {
527 dle->levellist = g_slist_append(dle->levellist, data_user->alevel);
528 data_user->alevel = NULL;
530 g_free(data_user->element_names->data);
531 data_user->element_names = g_slist_delete_link(data_user->element_names,
532 data_user->element_names);
535 /* Called for character data */
536 /* text is not nul-terminated */
539 G_GNUC_UNUSED GMarkupParseContext *context,
546 amgxml_t *data_user = user_data;
547 GSList *last_element = data_user->element_names;
548 char *last_element_name;
549 GSList *last_element2;
550 char *last_element2_name;
551 dle_t *dle = data_user->dle;
554 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
555 "XML: Invalid text");
558 last_element_name = last_element->data;
560 tt = malloc(text_len + 8 + 1);
561 strncpy(tt,text,text_len);
564 //check if it is only space
565 if (match_no_newline("^[ \f\n\r\t\v]*$", tt)) {
570 if (data_user->raw) {
572 tt = stralloc(data_user->raw);
573 } else if (strlen(tt) > 0) {
574 /* remove trailing space */
575 char *ttt = tt + strlen(tt) - 1;
583 //check if it is only space
584 if (match_no_newline("^[ \f\n\r\t\v]*$", tt)) {
589 if (strcmp(last_element_name, "dle") == 0 ||
590 strcmp(last_element_name, "backup-program") == 0 ||
591 strcmp(last_element_name, "exclude") == 0 ||
592 strcmp(last_element_name, "include") == 0) {
593 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
594 "XML: %s doesn't have text '%s'", last_element_name, tt);
597 } else if(strcmp(last_element_name, "disk") == 0) {
598 if (dle->disk != NULL) {
599 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
600 "XML: multiple text in %s", last_element_name);
605 } else if(strcmp(last_element_name, "diskdevice") == 0) {
606 if (dle->device != NULL) {
607 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
608 "XML: multiple text in %s", last_element_name);
613 } else if(strcmp(last_element_name, "calcsize") == 0) {
614 if (strcasecmp(tt,"yes") == 0) {
615 dle->estimatelist = g_slist_append(dle->estimatelist,
616 GINT_TO_POINTER(ES_CALCSIZE));
619 } else if(strcmp(last_element_name, "estimate") == 0) {
621 while (strlen(ttt) > 0) {
622 if (BSTRNCMP(ttt,"CLIENT") == 0) {
623 dle->estimatelist = g_slist_append(dle->estimatelist,
624 GINT_TO_POINTER(ES_CLIENT));
625 ttt += strlen("client");
626 } else if (BSTRNCMP(ttt,"CALCSIZE") == 0) {
627 if (!data_user->has_calcsize)
628 dle->estimatelist = g_slist_append(dle->estimatelist,
629 GINT_TO_POINTER(ES_CALCSIZE));
630 ttt += strlen("calcsize");
631 } else if (BSTRNCMP(ttt,"SERVER") == 0) {
632 dle->estimatelist = g_slist_append(dle->estimatelist,
633 GINT_TO_POINTER(ES_SERVER));
634 ttt += strlen("server");
636 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
637 "XML: bad estimate: %s", tt);
644 } else if(strcmp(last_element_name, "program") == 0) {
645 if (dle->program != NULL) {
646 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
647 "XML: multiple text in %s", last_element_name);
651 if (strcmp(tt, "APPLICATION") == 0) {
652 dle->program_is_application_api = 1;
658 } else if(strcmp(last_element_name, "plugin") == 0) {
659 last_element2 = g_slist_nth(data_user->element_names, 1);
660 if (!last_element2) {
661 error("Invalid name text");
663 last_element2_name = last_element2->data;
664 if (strcmp(last_element2_name, "backup-program") == 0) {
666 } else if (strcmp(last_element2_name, "script") == 0) {
667 data_user->script->plugin = tt;
669 error("plugin outside of backup-program");
671 data_user->has_plugin = 1;
672 } else if(strcmp(last_element_name, "name") == 0) {
673 last_element2 = g_slist_nth(data_user->element_names, 1);
674 if (!last_element2) {
675 error("Invalid name text");
677 last_element2_name = last_element2->data;
678 if (strcmp(last_element2_name, "property") == 0) {
679 data_user->property_name = tt;
681 error("name outside of property");
683 } else if(strcmp(last_element_name, "priority") == 0) {
684 last_element2 = g_slist_nth(data_user->element_names, 1);
685 if (!last_element2) {
686 error("Invalid priority text");
688 last_element2_name = last_element2->data;
689 if (strcmp(last_element2_name, "property") == 0) {
690 if (strcasecmp(tt,"yes") == 0) {
691 data_user->property_data->priority = 1;
694 error("priority outside of property");
697 } else if(strcmp(last_element_name, "value") == 0) {
698 last_element2 = g_slist_nth(data_user->element_names, 1);
699 if (!last_element2) {
700 error("Invalid name text");
702 last_element2_name = last_element2->data;
703 if (strcmp(last_element2_name, "property") == 0) {
704 data_user->property_data->values =
705 g_slist_append(data_user->property_data->values, tt);
707 error("value outside of property");
709 } else if(strcmp(last_element_name, "auth") == 0) {
710 if (dle->auth != NULL) {
711 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
712 "XML: multiple text in %s", last_element_name);
716 } else if(strcmp(last_element_name, "level") == 0) {
717 data_user->alevel->level = atoi(tt);
719 } else if (strcmp(last_element_name, "server") == 0) {
720 if (strcasecmp(tt,"no") == 0) {
721 data_user->alevel->server = 0;
722 } else if (strcasecmp(tt,"yes") == 0) {
723 data_user->alevel->server = 1;
725 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
726 "XML: Invalid %s (%s)", last_element_name, tt);
731 } else if(strcmp(last_element_name, "index") == 0) {
732 if (strcasecmp(tt,"no") == 0) {
733 dle->create_index = 0;
734 } else if (strcasecmp(tt,"yes") == 0) {
735 dle->create_index = 1;
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, "dumpdate") == 0) {
744 if (dle->dumpdate != NULL) {
745 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
746 "XML: multiple text in %s", last_element_name);
751 } else if(strcmp(last_element_name, "record") == 0) {
752 if (strcasecmp(tt, "no") == 0) {
754 } else if (strcasecmp(tt, "yes") == 0) {
757 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
758 "XML: Invalid %s (%s)", last_element_name, tt);
763 } else if(strcmp(last_element_name, "spindle") == 0) {
764 dle->spindle = atoi(tt);
766 } else if(strcmp(last_element_name, "compress") == 0) {
767 if (strcmp(tt, "FAST") == 0) {
768 dle->compress = COMP_FAST;
769 } else if (strcmp(tt, "BEST") == 0) {
770 dle->compress = COMP_BEST;
771 } else if (BSTRNCMP(tt, "CUSTOM") == 0) {
772 dle->compress = COMP_CUST;
773 } else if (strcmp(tt, "SERVER-FAST") == 0) {
774 dle->compress = COMP_SERVER_FAST;
775 } else if (strcmp(tt, "SERVER-BEST") == 0) {
776 dle->compress = COMP_SERVER_BEST;
777 } else if (BSTRNCMP(tt, "SERVER-CUSTOM") == 0) {
778 dle->compress = COMP_SERVER_CUST;
780 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
781 "XML: Invalid %s (%s)", last_element_name, tt);
786 } else if(strcmp(last_element_name, "custom-compress-program") == 0) {
787 if (dle->compprog != NULL) {
788 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
789 "XML: multiple text in %s", last_element_name);
794 } else if(strcmp(last_element_name, "encrypt") == 0) {
795 if (BSTRNCMP(tt,"NO") == 0) {
796 dle->encrypt = ENCRYPT_NONE;
797 } else if (BSTRNCMP(tt, "CUSTOM") == 0) {
798 dle->encrypt = ENCRYPT_CUST;
799 } else if (BSTRNCMP(tt, "SERVER-CUSTOM") == 0) {
800 dle->encrypt = ENCRYPT_SERV_CUST;
802 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
803 "XML: Invalid %s (%s)", last_element_name, tt);
808 } else if(strcmp(last_element_name, "kencrypt") == 0) {
809 if (strcasecmp(tt,"no") == 0) {
811 } else if (strcasecmp(tt,"yes") == 0) {
814 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
815 "XML: Invalid %s (%s)", last_element_name, tt);
820 } else if(strcmp(last_element_name, "custom-encrypt-program") == 0) {
821 last_element2 = g_slist_nth(data_user->element_names, 1);
822 if (!last_element2) {
823 error("XML: optional");
825 last_element2_name = last_element2->data;
826 if (dle->encrypt == ENCRYPT_SERV_CUST)
827 dle->srv_encrypt = tt;
829 dle->clnt_encrypt = tt;
830 } else if(strcmp(last_element_name, "decrypt-option") == 0) {
831 last_element2 = g_slist_nth(data_user->element_names, 1);
832 if (!last_element2) {
833 error("XML: optional");
835 last_element2_name = last_element2->data;
836 if (dle->encrypt == ENCRYPT_SERV_CUST)
837 dle->srv_decrypt_opt = tt;
839 dle->clnt_decrypt_opt = tt;
840 } else if(strcmp(last_element_name, "exclude") == 0 ||
841 strcmp(last_element_name, "include") == 0) {
842 data_user->has_optional = 0;
844 } else if(strcmp(last_element_name, "file") == 0) {
845 last_element2 = g_slist_nth(data_user->element_names, 1);
846 if (!last_element2) {
847 error("XML: optional");
849 last_element2_name = last_element2->data;
850 if (strcmp(last_element2_name, "exclude") == 0) {
851 dle->exclude_file = append_sl(dle->exclude_file, tt);
852 } else if (strcmp(last_element2_name, "include") == 0) {
853 dle->include_file = append_sl(dle->include_file, tt);
857 } else if(strcmp(last_element_name, "list") == 0) {
858 last_element2 = g_slist_nth(data_user->element_names, 1);
859 if (!last_element2) {
860 error("XML: optional");
862 last_element2_name = last_element2->data;
863 if (strcmp(last_element2_name, "exclude") == 0) {
864 dle->exclude_list = append_sl(dle->exclude_list, tt);
865 } else if (strcmp(last_element2_name, "include") == 0) {
866 dle->include_list = append_sl(dle->include_list, tt);
870 } else if(strcmp(last_element_name, "optional") == 0) {
871 last_element2 = g_slist_nth(data_user->element_names, 1);
872 if (!last_element2) {
873 error("XML: optional");
875 last_element2_name = last_element2->data;
876 if (strcmp(last_element2_name, "exclude") == 0) {
877 dle->exclude_optional = 1;
878 } else if (strcmp(last_element2_name, "include") == 0) {
879 dle->include_optional = 1;
881 error("bad optional");
883 data_user->has_optional = 1;
885 } else if(strcmp(last_element_name, "script") == 0) {
887 } else if(strcmp(last_element_name, "execute_on") == 0) {
891 sep = strchr(tt1,',');
894 if (strcmp(tt1,"PRE-AMCHECK") == 0)
895 data_user->script->execute_on |= EXECUTE_ON_PRE_AMCHECK;
896 else if (strcmp(tt1,"PRE-DLE-AMCHECK") == 0)
897 data_user->script->execute_on |= EXECUTE_ON_PRE_DLE_AMCHECK;
898 else if (strcmp(tt1,"PRE-HOST-AMCHECK") == 0)
899 data_user->script->execute_on |= EXECUTE_ON_PRE_HOST_AMCHECK;
900 else if (strcmp(tt1,"POST-AMCHECK") == 0)
901 data_user->script->execute_on |= EXECUTE_ON_POST_AMCHECK;
902 else if (strcmp(tt1,"POST-DLE-AMCHECK") == 0)
903 data_user->script->execute_on |= EXECUTE_ON_POST_DLE_AMCHECK;
904 else if (strcmp(tt1,"POST-HOST-AMCHECK") == 0)
905 data_user->script->execute_on |= EXECUTE_ON_POST_HOST_AMCHECK;
906 else if (strcmp(tt1,"PRE-ESTIMATE") == 0)
907 data_user->script->execute_on |= EXECUTE_ON_PRE_ESTIMATE;
908 else if (strcmp(tt1,"PRE-DLE-ESTIMATE") == 0)
909 data_user->script->execute_on |= EXECUTE_ON_PRE_DLE_ESTIMATE;
910 else if (strcmp(tt1,"PRE-HOST-ESTIMATE") == 0)
911 data_user->script->execute_on |= EXECUTE_ON_PRE_HOST_ESTIMATE;
912 else if (strcmp(tt1,"POST-ESTIMATE") == 0)
913 data_user->script->execute_on |= EXECUTE_ON_POST_ESTIMATE;
914 else if (strcmp(tt1,"POST-DLE-ESTIMATE") == 0)
915 data_user->script->execute_on |= EXECUTE_ON_POST_DLE_ESTIMATE;
916 else if (strcmp(tt1,"POST-HOST-ESTIMATE") == 0)
917 data_user->script->execute_on |= EXECUTE_ON_POST_HOST_ESTIMATE;
918 else if (strcmp(tt1,"PRE-BACKUP") == 0)
919 data_user->script->execute_on |= EXECUTE_ON_PRE_BACKUP;
920 else if (strcmp(tt1,"PRE-DLE-BACKUP") == 0)
921 data_user->script->execute_on |= EXECUTE_ON_PRE_DLE_BACKUP;
922 else if (strcmp(tt1,"PRE-HOST-BACKUP") == 0)
923 data_user->script->execute_on |= EXECUTE_ON_PRE_HOST_BACKUP;
924 else if (strcmp(tt1,"POST-BACKUP") == 0)
925 data_user->script->execute_on |= EXECUTE_ON_POST_BACKUP;
926 else if (strcmp(tt1,"POST-DLE-BACKUP") == 0)
927 data_user->script->execute_on |= EXECUTE_ON_POST_DLE_BACKUP;
928 else if (strcmp(tt1,"POST-HOST-BACKUP") == 0)
929 data_user->script->execute_on |= EXECUTE_ON_POST_HOST_BACKUP;
930 else if (strcmp(tt1,"PRE-RECOVER") == 0)
931 data_user->script->execute_on |= EXECUTE_ON_PRE_RECOVER;
932 else if (strcmp(tt1,"POST-RECOVER") == 0)
933 data_user->script->execute_on |= EXECUTE_ON_POST_RECOVER;
934 else if (strcmp(tt1,"PRE-LEVEL-RECOVER") == 0)
935 data_user->script->execute_on |= EXECUTE_ON_PRE_LEVEL_RECOVER;
936 else if (strcmp(tt1,"POST-LEVEL-RECOVER") == 0)
937 data_user->script->execute_on |= EXECUTE_ON_POST_LEVEL_RECOVER;
938 else if (strcmp(tt1,"INTER-LEVEL-RECOVER") == 0)
939 data_user->script->execute_on |= EXECUTE_ON_INTER_LEVEL_RECOVER;
941 dbprintf("BAD EXECUTE_ON: %s\n", tt1);
946 } else if(strcmp(last_element_name, "execute_where") == 0) {
947 if (strcmp(tt, "CLIENT") == 0) {
948 data_user->script->execute_where = ES_CLIENT;
950 data_user->script->execute_where = ES_SERVER;
953 } else if(strcmp(last_element_name, "datapath") == 0) {
954 if (strcmp(tt, "AMANDA") == 0) {
955 dle->data_path = DATA_PATH_AMANDA;
956 } else if (strcmp(tt, "DIRECTTCP") == 0) {
957 dle->data_path = DATA_PATH_DIRECTTCP;
959 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
960 "XML: bad datapath value '%s'", tt);
963 } else if(strcmp(last_element_name, "directtcp") == 0) {
964 dle->directtcp_list = g_slist_append(dle->directtcp_list, tt);
965 } else if(strcmp(last_element_name, "client_name") == 0) {
966 last_element2 = g_slist_nth(data_user->element_names, 1);
967 if (!last_element2) {
968 error("Invalid client_name text");
970 last_element2_name = last_element2->data;
971 if (strcmp(last_element2_name, "backup-program") == 0) {
972 dle->application_client_name = tt;
973 g_debug("set dle->application_client_name: %s", dle->application_client_name);
974 } else if (strcmp(last_element2_name, "script") == 0) {
975 data_user->script->client_name = tt;
976 g_debug("set data_user->script->client_name: %s", data_user->script->client_name);
978 error("client_name outside of script or backup-program");
981 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
982 "XML: amtext not defined for '%s'", last_element_name);
989 amxml_parse_node_CHAR(
993 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};
994 GMarkupParser parser = {&amstart_element, &amend_element, &amtext,
996 GMarkupParseFlags flags = 0;
997 GMarkupParseContext *context;
998 GError *gerror = NULL;
1002 context = g_markup_parse_context_new(&parser, flags, &amgxml, NULL);
1004 g_markup_parse_context_parse(context, txt, strlen(txt), &gerror);
1006 g_markup_parse_context_end_parse(context, &gerror);
1007 g_markup_parse_context_free(context);
1010 *errmsg = stralloc(gerror->message);
1011 g_error_free(gerror);
1018 amxml_parse_node_FILE(
1022 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};
1023 GMarkupParser parser = {&amstart_element, &amend_element, &amtext,
1025 GMarkupParseFlags flags = 0;
1026 GMarkupParseContext *context;
1027 GError *gerror = NULL;
1032 context = g_markup_parse_context_new(&parser, flags, &amgxml, NULL);
1034 while ((line = agets(file)) != NULL && !gerror) {
1035 g_markup_parse_context_parse(context, line, strlen(line), &gerror);
1039 g_markup_parse_context_end_parse(context, &gerror);
1040 g_markup_parse_context_free(context);
1043 *errmsg = stralloc(gerror->message);
1044 g_error_free(gerror);
1061 quoted_value = malloc(strlen(value)+1);
1064 for(c=value; *c != '\0'; c++) {
1065 // Check include negative value, with the 8th bit set.
1067 (unsigned char)*c > 127 ||
1087 base64_encode_alloc(value, strlen(value), &b64value);
1088 result = vstralloc("<", tag,
1089 " encoding=\"raw\" raw=\"", b64value, "\">",
1095 result = vstralloc("<", tag, ">",
1100 amfree(quoted_value);