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));
83 scriptlist_t scriptlist;
88 g_slist_free(dle->estimatelist);
89 slist_free_full(dle->levellist, g_free);
90 amfree(dle->dumpdate);
91 amfree(dle->compprog);
92 amfree(dle->srv_encrypt);
93 amfree(dle->clnt_encrypt);
94 amfree(dle->srv_decrypt_opt);
95 amfree(dle->clnt_decrypt_opt);
97 amfree(dle->application_client_name);
98 free_sl(dle->exclude_file);
99 free_sl(dle->exclude_list);
100 free_sl(dle->include_file);
101 free_sl(dle->include_list);
103 g_hash_table_destroy(dle->property);
104 if (dle->application_property)
105 g_hash_table_destroy(dle->application_property);
106 for(scriptlist = dle->scriptlist; scriptlist != NULL;
107 scriptlist = scriptlist->next) {
108 free_script_data((script_t *)scriptlist->data);
110 slist_free_full(dle->scriptlist, g_free);
111 slist_free_full(dle->directtcp_list, g_free);
119 amfree(script->plugin);
120 amfree(script->client_name);
121 if (script->property)
122 g_hash_table_destroy(script->property);
131 dle->program_is_application_api = 0;
133 dle->estimatelist = NULL;
136 dle->compress = COMP_NONE;
137 dle->encrypt = ENCRYPT_NONE;
139 dle->levellist = NULL;
140 dle->dumpdate = NULL;
141 dle->compprog = NULL;
142 dle->srv_encrypt = NULL;
143 dle->clnt_encrypt = NULL;
144 dle->srv_decrypt_opt = NULL;
145 dle->clnt_decrypt_opt = NULL;
146 dle->create_index = 0;
148 dle->exclude_file = NULL;
149 dle->exclude_list = NULL;
150 dle->include_file = NULL;
151 dle->include_list = NULL;
152 dle->exclude_optional = 0;
153 dle->include_optional = 0;
154 dle->property = NULL;
155 dle->application_property = NULL;
156 dle->scriptlist = NULL;
157 dle->data_path = DATA_PATH_AMANDA;
158 dle->directtcp_list = NULL;
159 dle->application_client_name = NULL;
164 /* Called for open tags <foo bar="baz"> */
165 static void amstart_element(GMarkupParseContext *context,
166 const gchar *element_name,
167 const gchar **attribute_names,
168 const gchar **attribute_values,
172 /* Called for close tags </foo> */
173 static void amend_element(GMarkupParseContext *context,
174 const gchar *element_name,
178 /* Called for character data */
179 /* text is not nul-terminated */
180 static void amtext(GMarkupParseContext *context,
186 /* Called for open tags <foo bar="baz"> */
189 G_GNUC_UNUSED GMarkupParseContext *context,
190 const gchar *element_name,
191 G_GNUC_UNUSED const gchar **attribute_names,
192 G_GNUC_UNUSED const gchar **attribute_values,
196 amgxml_t *data_user = user_data;
198 GSList *last_element = data_user->element_names;
199 char *last_element_name = NULL;
200 dle_t *dle = data_user->dle;
201 const gchar **at_names, **at_values;
204 last_element_name = last_element->data;
206 data_user->raw = NULL;
207 data_user->encoding = NULL;
209 if (attribute_names) {
210 for(at_names = attribute_names, at_values = attribute_values;
211 *at_names != NULL && at_values != NULL;
212 at_names++, at_values++) {
213 if (strcmp(*at_names, "encoding") == 0) {
214 data_user->encoding = stralloc(*at_values);
215 } else if (strcmp(*at_names, "raw") == 0) {
216 data_user->raw = base64_decode_alloc_string((char *)*at_values);
218 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
219 "XML: Invalid attribute '%s' for %s element",
220 *at_names, element_name);
226 if (strcmp(element_name, "dle") == 0) {
227 if (last_element != NULL) {
228 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
229 "XML: Invalid dle element");
232 for(adle = data_user->dles; adle != NULL && adle->next != NULL;
234 data_user->dle = alloc_dle();
236 data_user->dles = data_user->dle;
238 adle->next = data_user->dle;
240 data_user->has_calcsize = 0;
241 data_user->has_estimate = 0;
242 data_user->has_record = 0;
243 data_user->has_spindle = 0;
244 data_user->has_compress = 0;
245 data_user->has_encrypt = 0;
246 data_user->has_kencrypt = 0;
247 data_user->has_datapath = 0;
248 data_user->has_exclude = 0;
249 data_user->has_include = 0;
250 data_user->has_index = 0;
251 data_user->has_backup_program = 0;
252 data_user->has_plugin = 0;
253 data_user->has_optional = 0;
254 data_user->property_name = NULL;
255 data_user->property_data = NULL;
256 data_user->property =
257 g_hash_table_new_full(g_str_hash, g_str_equal, &g_free, &free_property_t);
258 data_user->script = NULL;
259 data_user->alevel = NULL;
260 data_user->encoding = NULL;
261 data_user->raw = NULL;
262 } else if(strcmp(element_name, "disk" ) == 0 ||
263 strcmp(element_name, "diskdevice" ) == 0 ||
264 strcmp(element_name, "calcsize" ) == 0 ||
265 strcmp(element_name, "estimate" ) == 0 ||
266 strcmp(element_name, "program" ) == 0 ||
267 strcmp(element_name, "auth" ) == 0 ||
268 strcmp(element_name, "index" ) == 0 ||
269 strcmp(element_name, "dumpdate" ) == 0 ||
270 strcmp(element_name, "level" ) == 0 ||
271 strcmp(element_name, "record" ) == 0 ||
272 strcmp(element_name, "spindle" ) == 0 ||
273 strcmp(element_name, "compress" ) == 0 ||
274 strcmp(element_name, "encrypt" ) == 0 ||
275 strcmp(element_name, "kencrypt" ) == 0 ||
276 strcmp(element_name, "datapath" ) == 0 ||
277 strcmp(element_name, "exclude" ) == 0 ||
278 strcmp(element_name, "include" ) == 0) {
279 if (strcmp(last_element_name, "dle") != 0) {
280 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
281 "XML: Invalid %s element", element_name);
284 if ((strcmp(element_name, "disk" ) == 0 && dle->disk) ||
285 (strcmp(element_name, "diskdevice" ) == 0 && dle->device) ||
286 (strcmp(element_name, "calcsize" ) == 0 && data_user->has_calcsize) ||
287 (strcmp(element_name, "estimate" ) == 0 && data_user->has_estimate) ||
288 (strcmp(element_name, "record" ) == 0 && data_user->has_record) ||
289 (strcmp(element_name, "spindle" ) == 0 && data_user->has_spindle) ||
290 (strcmp(element_name, "program" ) == 0 && dle->program) ||
291 (strcmp(element_name, "auth" ) == 0 && dle->auth) ||
292 (strcmp(element_name, "index" ) == 0 && data_user->has_index) ||
293 (strcmp(element_name, "dumpdate" ) == 0 && dle->dumpdate) ||
294 (strcmp(element_name, "compress" ) == 0 && data_user->has_compress) ||
295 (strcmp(element_name, "encrypt" ) == 0 && data_user->has_encrypt) ||
296 (strcmp(element_name, "kencrypt" ) == 0 && data_user->has_kencrypt) ||
297 (strcmp(element_name, "datapath" ) == 0 && data_user->has_datapath) ||
298 (strcmp(element_name, "exclude" ) == 0 && data_user->has_exclude) ||
299 (strcmp(element_name, "include" ) == 0 && data_user->has_include)) {
300 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
301 "XML: Duplicate %s element", element_name);
304 if (strcmp(element_name, "calcsize" ) == 0) data_user->has_calcsize = 1;
305 if (strcmp(element_name, "estimate" ) == 0) data_user->has_estimate = 1;
306 if (strcmp(element_name, "record" ) == 0) data_user->has_record = 1;
307 if (strcmp(element_name, "spindle" ) == 0) data_user->has_spindle = 1;
308 if (strcmp(element_name, "index" ) == 0) data_user->has_index = 1;
309 if (strcmp(element_name, "compress" ) == 0) data_user->has_compress = 1;
310 if (strcmp(element_name, "encrypt" ) == 0) data_user->has_encrypt = 1;
311 if (strcmp(element_name, "kencrypt" ) == 0) data_user->has_kencrypt = 1;
312 if (strcmp(element_name, "datapath" ) == 0) data_user->has_datapath = 1;
313 if (strcmp(element_name, "exclude" ) == 0) data_user->has_exclude = 1;
314 if (strcmp(element_name, "include" ) == 0) data_user->has_include = 1;
315 if (strcmp(element_name, "exclude") == 0 || strcmp(element_name, "include") == 0)
316 data_user->has_optional = 0;
317 if (strcmp(element_name, "level") == 0) {
318 data_user->alevel = g_new0(am_level_t, 1);
320 } else if (strcmp(element_name, "server") == 0) {
321 if (strcmp(last_element_name, "level") != 0) {
322 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
323 "XML: Invalid %s element", element_name);
326 } else if(strcmp(element_name, "custom-compress-program") == 0) {
327 if (strcmp(last_element_name, "compress") != 0) {
328 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
329 "XML: Invalid %s element", element_name);
333 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
334 "XML: Duplicate %s element", element_name);
337 } else if (strcmp(element_name, "custom-encrypt-program") == 0 ||
338 strcmp(element_name, "decrypt-option") == 0) {
339 if (strcmp(last_element_name, "encrypt") != 0) {
340 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
341 "XML: Invalid %s element", element_name);
344 if (strcmp(element_name, "custom-encrypt-program") == 0 &&
346 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
347 "XML: Duplicate %s element", element_name);
350 if (strcmp(element_name, "decrypt-option") == 0 &&
351 dle->clnt_decrypt_opt) {
352 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
353 "XML: Duplicate %s element", element_name);
356 } else if(strcmp(element_name, "plugin") == 0) {
357 if (strcmp(last_element_name, "backup-program") != 0 &&
358 strcmp(last_element_name, "script") != 0) {
359 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
360 "XML: Invalid %s element", element_name);
363 if (data_user->has_plugin) {
364 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
365 "XML: Duplicate %s element in '%s'", element_name,
369 } else if(strcmp(element_name, "property") == 0) {
371 (strcmp(last_element_name, "backup-program") != 0 &&
372 strcmp(last_element_name, "script") != 0 &&
373 strcmp(last_element_name, "dle") != 0)) {
374 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
375 "XML: Invalid %s element", element_name);
378 data_user->property_data = malloc(sizeof(property_t));
379 data_user->property_data->append = 0;
380 data_user->property_data->priority = 0;
381 data_user->property_data->values = NULL;
382 } else if(strcmp(element_name, "name") == 0) {
383 if (strcmp(last_element_name, "property") != 0) {
384 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
385 "XML: Invalid %s element", element_name);
388 if (data_user->property_name) {
389 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
390 "XML: Duplicate %s element in '%s'", element_name,
394 } else if(strcmp(element_name, "priority") == 0) {
395 if (strcmp(last_element_name, "property") != 0) {
396 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
397 "XML: Invalid %s element", element_name);
400 } else if(strcmp(element_name, "value") == 0) {
401 if (strcmp(last_element_name, "property") != 0) {
402 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
403 "XML: Invalid %s element", element_name);
406 } else if(strcmp(element_name, "file") == 0 ||
407 strcmp(element_name, "list") == 0 ||
408 strcmp(element_name, "optional") == 0) {
409 if (strcmp(last_element_name, "exclude") != 0 &&
410 strcmp(last_element_name, "include") != 0) {
411 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
412 "XML: Invalid %s element", element_name);
415 if (strcmp(element_name, "optional") == 0 && data_user->has_optional) {
416 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
417 "XML: Duplicate %s element", element_name);
420 if (strcmp(element_name, "optional") == 0) data_user->has_optional = 1;
421 } else if (strcmp(element_name, "backup-program") == 0) {
422 if (data_user->has_backup_program) {
423 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
424 "XML: Duplicate %s element", element_name);
427 data_user->has_backup_program = 1;
428 data_user->property =
429 g_hash_table_new_full(g_str_hash, g_str_equal, &g_free, &free_property_t);
430 data_user->has_plugin = 0;
432 } else if (strcmp(element_name, "script") == 0) {
433 data_user->property =
434 g_hash_table_new_full(g_str_hash, g_str_equal, &g_free, &free_property_t);
435 data_user->script = malloc(sizeof(script_t));
436 data_user->script->plugin = NULL;
437 data_user->script->execute_on = 0;
438 data_user->script->execute_where = ES_CLIENT;
439 data_user->script->property = NULL;
440 data_user->script->client_name = NULL;
441 data_user->script->result = NULL;
442 data_user->has_plugin = 0;
443 } else if (strcmp(element_name, "execute_on") == 0) {
444 } else if (strcmp(element_name, "execute_where") == 0) {
445 } else if (strcmp(element_name, "directtcp") == 0) {
446 if (strcmp(last_element_name, "datapath") != 0) {
447 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
448 "XML: Invalid %s element", element_name);
451 } else if (strcmp(element_name, "client_name") == 0) {
453 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
454 "XML: Invalid %s element", element_name);
457 data_user->element_names = g_slist_prepend(data_user->element_names,
458 stralloc(element_name));
461 /* Called for close tags </foo> */
464 G_GNUC_UNUSED GMarkupParseContext *context,
465 const gchar *element_name,
469 amgxml_t *data_user = user_data;
470 GSList *last_element = data_user->element_names;
471 char *last_element_name = NULL;
472 dle_t *dle = data_user->dle;
475 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
476 "XML: Invalid closing tag");
479 last_element_name = last_element->data;
480 if (strcmp(last_element_name, element_name) != 0) {
481 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
482 "XML: Invalid closing tag '%s'", element_name);
486 if (strcmp(element_name, "property") == 0) {
487 g_hash_table_insert(data_user->property,
488 data_user->property_name,
489 data_user->property_data);
490 data_user->property_name = NULL;
491 data_user->property_data = NULL;
492 } else if (strcmp(element_name, "dle") == 0) {
493 if (dle->program_is_application_api &&
495 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
496 "XML: program set to APPLICATION but no application set");
499 if (dle->device == NULL && dle->disk)
500 dle->device = stralloc(dle->disk);
501 if (dle->estimatelist == NULL)
502 dle->estimatelist = g_slist_append(dle->estimatelist, ES_CLIENT);
503 /* Add check of required field */
504 data_user->property = NULL;
505 data_user->dle = NULL;
506 } else if (strcmp(element_name, "backup-program") == 0) {
507 if (dle->program == NULL) {
508 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
509 "XML: No plugin set for application");
512 dle->application_property = data_user->property;
513 data_user->property = dle->property;
514 } else if (strcmp(element_name, "script") == 0) {
515 if (data_user->script->plugin == NULL) {
516 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
517 "XML: No plugin set for script");
520 data_user->script->property = data_user->property;
521 data_user->property = dle->property;
522 dle->scriptlist = g_slist_append(dle->scriptlist, data_user->script);
523 data_user->script = NULL;
524 } else if (strcmp(element_name, "level") == 0) {
525 dle->levellist = g_slist_append(dle->levellist, data_user->alevel);
526 data_user->alevel = NULL;
528 g_free(data_user->element_names->data);
529 data_user->element_names = g_slist_delete_link(data_user->element_names,
530 data_user->element_names);
533 /* Called for character data */
534 /* text is not nul-terminated */
537 G_GNUC_UNUSED GMarkupParseContext *context,
544 amgxml_t *data_user = user_data;
545 GSList *last_element = data_user->element_names;
546 char *last_element_name;
547 GSList *last_element2;
548 char *last_element2_name;
549 dle_t *dle = data_user->dle;
552 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
553 "XML: Invalid text");
556 last_element_name = last_element->data;
558 tt = malloc(text_len + 8 + 1);
559 strncpy(tt,text,text_len);
562 //check if it is only space
563 if (match_no_newline("^[ \f\n\r\t\v]*$", tt)) {
568 if (data_user->raw) {
570 tt = stralloc(data_user->raw);
571 } else if (strlen(tt) > 0) {
572 /* remove trailing space */
573 char *ttt = tt + strlen(tt) - 1;
581 //check if it is only space
582 if (match_no_newline("^[ \f\n\r\t\v]*$", tt)) {
587 if (strcmp(last_element_name, "dle") == 0 ||
588 strcmp(last_element_name, "backup-program") == 0 ||
589 strcmp(last_element_name, "exclude") == 0 ||
590 strcmp(last_element_name, "include") == 0) {
591 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
592 "XML: %s doesn't have text '%s'", last_element_name, tt);
595 } else if(strcmp(last_element_name, "disk") == 0) {
596 if (dle->disk != NULL) {
597 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
598 "XML: multiple text in %s", last_element_name);
603 } else if(strcmp(last_element_name, "diskdevice") == 0) {
604 if (dle->device != NULL) {
605 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
606 "XML: multiple text in %s", last_element_name);
611 } else if(strcmp(last_element_name, "calcsize") == 0) {
612 if (strcasecmp(tt,"yes") == 0) {
613 dle->estimatelist = g_slist_append(dle->estimatelist,
614 GINT_TO_POINTER(ES_CALCSIZE));
617 } else if(strcmp(last_element_name, "estimate") == 0) {
619 while (strlen(ttt) > 0) {
620 if (BSTRNCMP(ttt,"CLIENT") == 0) {
621 dle->estimatelist = g_slist_append(dle->estimatelist,
622 GINT_TO_POINTER(ES_CLIENT));
623 ttt += strlen("client");
624 } else if (BSTRNCMP(ttt,"CALCSIZE") == 0) {
625 if (!data_user->has_calcsize)
626 dle->estimatelist = g_slist_append(dle->estimatelist,
627 GINT_TO_POINTER(ES_CALCSIZE));
628 ttt += strlen("calcsize");
629 } else if (BSTRNCMP(ttt,"SERVER") == 0) {
630 dle->estimatelist = g_slist_append(dle->estimatelist,
631 GINT_TO_POINTER(ES_SERVER));
632 ttt += strlen("server");
634 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
635 "XML: bad estimate: %s", tt);
642 } else if(strcmp(last_element_name, "program") == 0) {
643 if (dle->program != NULL) {
644 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
645 "XML: multiple text in %s", last_element_name);
649 if (strcmp(tt, "APPLICATION") == 0) {
650 dle->program_is_application_api = 1;
656 } else if(strcmp(last_element_name, "plugin") == 0) {
657 last_element2 = g_slist_nth(data_user->element_names, 1);
658 if (!last_element2) {
659 error("Invalid name text");
661 last_element2_name = last_element2->data;
662 if (strcmp(last_element2_name, "backup-program") == 0) {
664 } else if (strcmp(last_element2_name, "script") == 0) {
665 data_user->script->plugin = tt;
667 error("plugin outside of backup-program");
669 data_user->has_plugin = 1;
670 } else if(strcmp(last_element_name, "name") == 0) {
671 last_element2 = g_slist_nth(data_user->element_names, 1);
672 if (!last_element2) {
673 error("Invalid name text");
675 last_element2_name = last_element2->data;
676 if (strcmp(last_element2_name, "property") == 0) {
677 data_user->property_name = tt;
679 error("name outside of property");
681 } else if(strcmp(last_element_name, "priority") == 0) {
682 last_element2 = g_slist_nth(data_user->element_names, 1);
683 if (!last_element2) {
684 error("Invalid priority text");
686 last_element2_name = last_element2->data;
687 if (strcmp(last_element2_name, "property") == 0) {
688 if (strcasecmp(tt,"yes") == 0) {
689 data_user->property_data->priority = 1;
692 error("priority outside of property");
695 } else if(strcmp(last_element_name, "value") == 0) {
696 last_element2 = g_slist_nth(data_user->element_names, 1);
697 if (!last_element2) {
698 error("Invalid name text");
700 last_element2_name = last_element2->data;
701 if (strcmp(last_element2_name, "property") == 0) {
702 data_user->property_data->values =
703 g_slist_append(data_user->property_data->values, tt);
705 error("value outside of property");
707 } else if(strcmp(last_element_name, "auth") == 0) {
708 if (dle->auth != NULL) {
709 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
710 "XML: multiple text in %s", last_element_name);
714 } else if(strcmp(last_element_name, "level") == 0) {
715 data_user->alevel->level = atoi(tt);
717 } else if (strcmp(last_element_name, "server") == 0) {
718 if (strcasecmp(tt,"no") == 0) {
719 data_user->alevel->server = 0;
720 } else if (strcasecmp(tt,"yes") == 0) {
721 data_user->alevel->server = 1;
723 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
724 "XML: Invalid %s (%s)", last_element_name, tt);
729 } else if(strcmp(last_element_name, "index") == 0) {
730 if (strcasecmp(tt,"no") == 0) {
731 dle->create_index = 0;
732 } else if (strcasecmp(tt,"yes") == 0) {
733 dle->create_index = 1;
735 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
736 "XML: Invalid %s (%s)", last_element_name, tt);
741 } else if(strcmp(last_element_name, "dumpdate") == 0) {
742 if (dle->dumpdate != NULL) {
743 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
744 "XML: multiple text in %s", last_element_name);
749 } else if(strcmp(last_element_name, "record") == 0) {
750 if (strcasecmp(tt, "no") == 0) {
752 } else if (strcasecmp(tt, "yes") == 0) {
755 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
756 "XML: Invalid %s (%s)", last_element_name, tt);
761 } else if(strcmp(last_element_name, "spindle") == 0) {
762 dle->spindle = atoi(tt);
764 } else if(strcmp(last_element_name, "compress") == 0) {
765 if (strcmp(tt, "FAST") == 0) {
766 dle->compress = COMP_FAST;
767 } else if (strcmp(tt, "BEST") == 0) {
768 dle->compress = COMP_BEST;
769 } else if (BSTRNCMP(tt, "CUSTOM") == 0) {
770 dle->compress = COMP_CUST;
771 } else if (strcmp(tt, "SERVER-FAST") == 0) {
772 dle->compress = COMP_SERVER_FAST;
773 } else if (strcmp(tt, "SERVER-BEST") == 0) {
774 dle->compress = COMP_SERVER_BEST;
775 } else if (BSTRNCMP(tt, "SERVER-CUSTOM") == 0) {
776 dle->compress = COMP_SERVER_CUST;
778 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
779 "XML: Invalid %s (%s)", last_element_name, tt);
784 } else if(strcmp(last_element_name, "custom-compress-program") == 0) {
785 if (dle->compprog != NULL) {
786 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
787 "XML: multiple text in %s", last_element_name);
792 } else if(strcmp(last_element_name, "encrypt") == 0) {
793 if (BSTRNCMP(tt,"NO") == 0) {
794 dle->encrypt = ENCRYPT_NONE;
795 } else if (BSTRNCMP(tt, "CUSTOM") == 0) {
796 dle->encrypt = ENCRYPT_CUST;
797 } else if (BSTRNCMP(tt, "SERVER-CUSTOM") == 0) {
798 dle->encrypt = ENCRYPT_SERV_CUST;
800 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
801 "XML: Invalid %s (%s)", last_element_name, tt);
806 } else if(strcmp(last_element_name, "kencrypt") == 0) {
807 if (strcasecmp(tt,"no") == 0) {
809 } else if (strcasecmp(tt,"yes") == 0) {
812 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
813 "XML: Invalid %s (%s)", last_element_name, tt);
818 } else if(strcmp(last_element_name, "custom-encrypt-program") == 0) {
819 last_element2 = g_slist_nth(data_user->element_names, 1);
820 if (!last_element2) {
821 error("XML: optional");
823 last_element2_name = last_element2->data;
824 if (dle->encrypt == ENCRYPT_SERV_CUST)
825 dle->srv_encrypt = tt;
827 dle->clnt_encrypt = tt;
828 } else if(strcmp(last_element_name, "decrypt-option") == 0) {
829 last_element2 = g_slist_nth(data_user->element_names, 1);
830 if (!last_element2) {
831 error("XML: optional");
833 last_element2_name = last_element2->data;
834 if (dle->encrypt == ENCRYPT_SERV_CUST)
835 dle->srv_decrypt_opt = tt;
837 dle->clnt_decrypt_opt = tt;
838 } else if(strcmp(last_element_name, "exclude") == 0 ||
839 strcmp(last_element_name, "include") == 0) {
840 data_user->has_optional = 0;
842 } else if(strcmp(last_element_name, "file") == 0) {
843 last_element2 = g_slist_nth(data_user->element_names, 1);
844 if (!last_element2) {
845 error("XML: optional");
847 last_element2_name = last_element2->data;
848 if (strcmp(last_element2_name, "exclude") == 0) {
849 dle->exclude_file = append_sl(dle->exclude_file, tt);
850 } else if (strcmp(last_element2_name, "include") == 0) {
851 dle->include_file = append_sl(dle->include_file, tt);
855 } else if(strcmp(last_element_name, "list") == 0) {
856 last_element2 = g_slist_nth(data_user->element_names, 1);
857 if (!last_element2) {
858 error("XML: optional");
860 last_element2_name = last_element2->data;
861 if (strcmp(last_element2_name, "exclude") == 0) {
862 dle->exclude_list = append_sl(dle->exclude_list, tt);
863 } else if (strcmp(last_element2_name, "include") == 0) {
864 dle->include_list = append_sl(dle->include_list, tt);
868 } else if(strcmp(last_element_name, "optional") == 0) {
869 last_element2 = g_slist_nth(data_user->element_names, 1);
870 if (!last_element2) {
871 error("XML: optional");
873 last_element2_name = last_element2->data;
874 if (strcmp(last_element2_name, "exclude") == 0) {
875 dle->exclude_optional = 1;
876 } else if (strcmp(last_element2_name, "include") == 0) {
877 dle->include_optional = 1;
879 error("bad optional");
881 data_user->has_optional = 1;
883 } else if(strcmp(last_element_name, "script") == 0) {
885 } else if(strcmp(last_element_name, "execute_on") == 0) {
889 sep = strchr(tt1,',');
892 if (strcmp(tt1,"PRE-AMCHECK") == 0)
893 data_user->script->execute_on |= EXECUTE_ON_PRE_AMCHECK;
894 else if (strcmp(tt1,"PRE-DLE-AMCHECK") == 0)
895 data_user->script->execute_on |= EXECUTE_ON_PRE_DLE_AMCHECK;
896 else if (strcmp(tt1,"PRE-HOST-AMCHECK") == 0)
897 data_user->script->execute_on |= EXECUTE_ON_PRE_HOST_AMCHECK;
898 else if (strcmp(tt1,"POST-AMCHECK") == 0)
899 data_user->script->execute_on |= EXECUTE_ON_POST_AMCHECK;
900 else if (strcmp(tt1,"POST-DLE-AMCHECK") == 0)
901 data_user->script->execute_on |= EXECUTE_ON_POST_DLE_AMCHECK;
902 else if (strcmp(tt1,"POST-HOST-AMCHECK") == 0)
903 data_user->script->execute_on |= EXECUTE_ON_POST_HOST_AMCHECK;
904 else if (strcmp(tt1,"PRE-ESTIMATE") == 0)
905 data_user->script->execute_on |= EXECUTE_ON_PRE_ESTIMATE;
906 else if (strcmp(tt1,"PRE-DLE-ESTIMATE") == 0)
907 data_user->script->execute_on |= EXECUTE_ON_PRE_DLE_ESTIMATE;
908 else if (strcmp(tt1,"PRE-HOST-ESTIMATE") == 0)
909 data_user->script->execute_on |= EXECUTE_ON_PRE_HOST_ESTIMATE;
910 else if (strcmp(tt1,"POST-ESTIMATE") == 0)
911 data_user->script->execute_on |= EXECUTE_ON_POST_ESTIMATE;
912 else if (strcmp(tt1,"POST-DLE-ESTIMATE") == 0)
913 data_user->script->execute_on |= EXECUTE_ON_POST_DLE_ESTIMATE;
914 else if (strcmp(tt1,"POST-HOST-ESTIMATE") == 0)
915 data_user->script->execute_on |= EXECUTE_ON_POST_HOST_ESTIMATE;
916 else if (strcmp(tt1,"PRE-BACKUP") == 0)
917 data_user->script->execute_on |= EXECUTE_ON_PRE_BACKUP;
918 else if (strcmp(tt1,"PRE-DLE-BACKUP") == 0)
919 data_user->script->execute_on |= EXECUTE_ON_PRE_DLE_BACKUP;
920 else if (strcmp(tt1,"PRE-HOST-BACKUP") == 0)
921 data_user->script->execute_on |= EXECUTE_ON_PRE_HOST_BACKUP;
922 else if (strcmp(tt1,"POST-BACKUP") == 0)
923 data_user->script->execute_on |= EXECUTE_ON_POST_BACKUP;
924 else if (strcmp(tt1,"POST-DLE-BACKUP") == 0)
925 data_user->script->execute_on |= EXECUTE_ON_POST_DLE_BACKUP;
926 else if (strcmp(tt1,"POST-HOST-BACKUP") == 0)
927 data_user->script->execute_on |= EXECUTE_ON_POST_HOST_BACKUP;
928 else if (strcmp(tt1,"PRE-RECOVER") == 0)
929 data_user->script->execute_on |= EXECUTE_ON_PRE_RECOVER;
930 else if (strcmp(tt1,"POST-RECOVER") == 0)
931 data_user->script->execute_on |= EXECUTE_ON_POST_RECOVER;
932 else if (strcmp(tt1,"PRE-LEVEL-RECOVER") == 0)
933 data_user->script->execute_on |= EXECUTE_ON_PRE_LEVEL_RECOVER;
934 else if (strcmp(tt1,"POST-LEVEL-RECOVER") == 0)
935 data_user->script->execute_on |= EXECUTE_ON_POST_LEVEL_RECOVER;
936 else if (strcmp(tt1,"INTER-LEVEL-RECOVER") == 0)
937 data_user->script->execute_on |= EXECUTE_ON_INTER_LEVEL_RECOVER;
939 dbprintf("BAD EXECUTE_ON: %s\n", tt1);
944 } else if(strcmp(last_element_name, "execute_where") == 0) {
945 if (strcmp(tt, "CLIENT") == 0) {
946 data_user->script->execute_where = ES_CLIENT;
948 data_user->script->execute_where = ES_SERVER;
951 } else if(strcmp(last_element_name, "datapath") == 0) {
952 if (strcmp(tt, "AMANDA") == 0) {
953 dle->data_path = DATA_PATH_AMANDA;
954 } else if (strcmp(tt, "DIRECTTCP") == 0) {
955 dle->data_path = DATA_PATH_DIRECTTCP;
957 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
958 "XML: bad datapath value '%s'", tt);
961 } else if(strcmp(last_element_name, "directtcp") == 0) {
962 dle->directtcp_list = g_slist_append(dle->directtcp_list, tt);
963 } else if(strcmp(last_element_name, "client_name") == 0) {
964 last_element2 = g_slist_nth(data_user->element_names, 1);
965 if (!last_element2) {
966 error("Invalid client_name text");
968 last_element2_name = last_element2->data;
969 if (strcmp(last_element2_name, "backup-program") == 0) {
970 dle->application_client_name = tt;
971 g_debug("set dle->application_client_name: %s", dle->application_client_name);
972 } else if (strcmp(last_element2_name, "script") == 0) {
973 data_user->script->client_name = tt;
974 g_debug("set data_user->script->client_name: %s", data_user->script->client_name);
976 error("client_name outside of script or backup-program");
979 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
980 "XML: amtext not defined for '%s'", last_element_name);
987 amxml_parse_node_CHAR(
991 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};
992 GMarkupParser parser = {&amstart_element, &amend_element, &amtext,
994 GMarkupParseFlags flags = 0;
995 GMarkupParseContext *context;
996 GError *gerror = NULL;
1000 context = g_markup_parse_context_new(&parser, flags, &amgxml, NULL);
1002 g_markup_parse_context_parse(context, txt, strlen(txt), &gerror);
1004 g_markup_parse_context_end_parse(context, &gerror);
1005 g_markup_parse_context_free(context);
1008 *errmsg = stralloc(gerror->message);
1009 g_error_free(gerror);
1016 amxml_parse_node_FILE(
1020 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};
1021 GMarkupParser parser = {&amstart_element, &amend_element, &amtext,
1023 GMarkupParseFlags flags = 0;
1024 GMarkupParseContext *context;
1025 GError *gerror = NULL;
1030 context = g_markup_parse_context_new(&parser, flags, &amgxml, NULL);
1032 while ((line = agets(file)) != NULL && !gerror) {
1033 g_markup_parse_context_parse(context, line, strlen(line), &gerror);
1037 g_markup_parse_context_end_parse(context, &gerror);
1038 g_markup_parse_context_free(context);
1041 *errmsg = stralloc(gerror->message);
1042 g_error_free(gerror);
1059 quoted_value = malloc(strlen(value)+1);
1062 for(c=value; *c != '\0'; c++) {
1063 // Check include negative value, with the 8th bit set.
1065 (unsigned char)*c > 127 ||
1085 base64_encode_alloc(value, strlen(value), &b64value);
1086 result = vstralloc("<", tag,
1087 " encoding=\"raw\" raw=\"", b64value, "\">",
1093 result = vstralloc("<", tag, ">",
1098 amfree(quoted_value);