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 g_slist_free_full(dle->levellist);
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 free_sl(dle->exclude_file);
98 free_sl(dle->exclude_list);
99 free_sl(dle->include_file);
100 free_sl(dle->include_list);
101 if (dle->application_property)
102 g_hash_table_destroy(dle->application_property);
103 for(scriptlist = dle->scriptlist; scriptlist != NULL;
104 scriptlist = scriptlist->next) {
105 free_script_data((script_t *)scriptlist->data);
107 g_slist_free_full(dle->scriptlist);
108 g_slist_free_full(dle->directtcp_list);
116 amfree(script->plugin);
117 if (script->property)
118 g_hash_table_destroy(script->property);
127 dle->program_is_application_api = 0;
129 dle->estimatelist = NULL;
132 dle->compress = COMP_NONE;
133 dle->encrypt = ENCRYPT_NONE;
135 dle->levellist = NULL;
136 dle->dumpdate = NULL;
137 dle->compprog = NULL;
138 dle->srv_encrypt = NULL;
139 dle->clnt_encrypt = NULL;
140 dle->srv_decrypt_opt = NULL;
141 dle->clnt_decrypt_opt = NULL;
142 dle->create_index = 0;
144 dle->exclude_file = NULL;
145 dle->exclude_list = NULL;
146 dle->include_file = NULL;
147 dle->include_list = NULL;
148 dle->exclude_optional = 0;
149 dle->include_optional = 0;
150 dle->application_property = NULL;
151 dle->scriptlist = NULL;
152 dle->data_path = DATA_PATH_AMANDA;
153 dle->directtcp_list = NULL;
158 /* Called for open tags <foo bar="baz"> */
159 static void amstart_element(GMarkupParseContext *context,
160 const gchar *element_name,
161 const gchar **attribute_names,
162 const gchar **attribute_values,
166 /* Called for close tags </foo> */
167 static void amend_element(GMarkupParseContext *context,
168 const gchar *element_name,
172 /* Called for character data */
173 /* text is not nul-terminated */
174 static void amtext(GMarkupParseContext *context,
180 /* Called for open tags <foo bar="baz"> */
183 G_GNUC_UNUSED GMarkupParseContext *context,
184 const gchar *element_name,
185 G_GNUC_UNUSED const gchar **attribute_names,
186 G_GNUC_UNUSED const gchar **attribute_values,
190 amgxml_t *data_user = user_data;
192 GSList *last_element = data_user->element_names;
193 char *last_element_name = NULL;
194 dle_t *dle = data_user->dle;
195 const gchar **at_names, **at_values;
198 last_element_name = last_element->data;
200 data_user->raw = NULL;
201 data_user->encoding = NULL;
203 if (attribute_names) {
204 for(at_names = attribute_names, at_values = attribute_values;
205 *at_names != NULL && at_values != NULL;
206 at_names++, at_values++) {
207 if (strcmp(*at_names, "encoding") == 0) {
208 data_user->encoding = stralloc(*at_values);
209 } else if (strcmp(*at_names, "raw") == 0) {
210 data_user->raw = base64_decode_alloc_string((char *)*at_values);
212 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
213 "XML: Invalid attribute '%s' for %s element",
214 *at_names, element_name);
220 if (strcmp(element_name, "dle") == 0) {
221 if (last_element != NULL) {
222 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
223 "XML: Invalid dle element");
226 for(adle = data_user->dles; adle != NULL && adle->next != NULL;
228 data_user->dle = alloc_dle();
230 data_user->dles = data_user->dle;
232 adle->next = data_user->dle;
234 data_user->has_calcsize = 0;
235 data_user->has_estimate = 0;
236 data_user->has_record = 0;
237 data_user->has_spindle = 0;
238 data_user->has_compress = 0;
239 data_user->has_encrypt = 0;
240 data_user->has_kencrypt = 0;
241 data_user->has_datapath = 0;
242 data_user->has_exclude = 0;
243 data_user->has_include = 0;
244 data_user->has_index = 0;
245 data_user->has_backup_program = 0;
246 data_user->has_plugin = 0;
247 data_user->has_optional = 0;
248 data_user->property_name = NULL;
249 data_user->property_data = NULL;
250 data_user->property = NULL;
251 data_user->script = NULL;
252 data_user->alevel = NULL;
253 data_user->encoding = NULL;
254 data_user->raw = NULL;
255 } else if(strcmp(element_name, "disk" ) == 0 ||
256 strcmp(element_name, "diskdevice" ) == 0 ||
257 strcmp(element_name, "calcsize" ) == 0 ||
258 strcmp(element_name, "estimate" ) == 0 ||
259 strcmp(element_name, "program" ) == 0 ||
260 strcmp(element_name, "auth" ) == 0 ||
261 strcmp(element_name, "index" ) == 0 ||
262 strcmp(element_name, "dumpdate" ) == 0 ||
263 strcmp(element_name, "level" ) == 0 ||
264 strcmp(element_name, "record" ) == 0 ||
265 strcmp(element_name, "spindle" ) == 0 ||
266 strcmp(element_name, "compress" ) == 0 ||
267 strcmp(element_name, "encrypt" ) == 0 ||
268 strcmp(element_name, "kencrypt" ) == 0 ||
269 strcmp(element_name, "datapath" ) == 0 ||
270 strcmp(element_name, "exclude" ) == 0 ||
271 strcmp(element_name, "include" ) == 0) {
272 if (strcmp(last_element_name, "dle") != 0) {
273 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
274 "XML: Invalid %s element", element_name);
277 if ((strcmp(element_name, "disk" ) == 0 && dle->disk) ||
278 (strcmp(element_name, "diskdevice" ) == 0 && dle->device) ||
279 (strcmp(element_name, "calcsize" ) == 0 && data_user->has_calcsize) ||
280 (strcmp(element_name, "estimate" ) == 0 && data_user->has_estimate) ||
281 (strcmp(element_name, "record" ) == 0 && data_user->has_record) ||
282 (strcmp(element_name, "spindle" ) == 0 && data_user->has_spindle) ||
283 (strcmp(element_name, "program" ) == 0 && dle->program) ||
284 (strcmp(element_name, "auth" ) == 0 && dle->auth) ||
285 (strcmp(element_name, "index" ) == 0 && data_user->has_index) ||
286 (strcmp(element_name, "dumpdate" ) == 0 && dle->dumpdate) ||
287 (strcmp(element_name, "compress" ) == 0 && data_user->has_compress) ||
288 (strcmp(element_name, "encrypt" ) == 0 && data_user->has_encrypt) ||
289 (strcmp(element_name, "kencrypt" ) == 0 && data_user->has_kencrypt) ||
290 (strcmp(element_name, "datapath" ) == 0 && data_user->has_datapath) ||
291 (strcmp(element_name, "exclude" ) == 0 && data_user->has_exclude) ||
292 (strcmp(element_name, "include" ) == 0 && data_user->has_include)) {
293 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
294 "XML: Duplicate %s element", element_name);
297 if (strcmp(element_name, "calcsize" ) == 0) data_user->has_calcsize = 1;
298 if (strcmp(element_name, "estimate" ) == 0) data_user->has_estimate = 1;
299 if (strcmp(element_name, "record" ) == 0) data_user->has_record = 1;
300 if (strcmp(element_name, "spindle" ) == 0) data_user->has_spindle = 1;
301 if (strcmp(element_name, "index" ) == 0) data_user->has_index = 1;
302 if (strcmp(element_name, "compress" ) == 0) data_user->has_compress = 1;
303 if (strcmp(element_name, "encrypt" ) == 0) data_user->has_encrypt = 1;
304 if (strcmp(element_name, "kencrypt" ) == 0) data_user->has_kencrypt = 1;
305 if (strcmp(element_name, "datapath" ) == 0) data_user->has_datapath = 1;
306 if (strcmp(element_name, "exclude" ) == 0) data_user->has_exclude = 1;
307 if (strcmp(element_name, "include" ) == 0) data_user->has_include = 1;
308 if (strcmp(element_name, "exclude") == 0 || strcmp(element_name, "include") == 0)
309 data_user->has_optional = 0;
310 if (strcmp(element_name, "level") == 0) {
311 data_user->alevel = g_new0(level_t, 1);
313 } else if (strcmp(element_name, "server") == 0) {
314 if (strcmp(last_element_name, "level") != 0) {
315 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
316 "XML: Invalid %s element", element_name);
319 } else if(strcmp(element_name, "custom-compress-program") == 0) {
320 if (strcmp(last_element_name, "compress") != 0) {
321 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
322 "XML: Invalid %s element", element_name);
326 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
327 "XML: Duplicate %s element", element_name);
330 } else if (strcmp(element_name, "custom-encrypt-program") == 0 ||
331 strcmp(element_name, "decrypt-option") == 0) {
332 if (strcmp(last_element_name, "encrypt") != 0) {
333 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
334 "XML: Invalid %s element", element_name);
337 if (strcmp(element_name, "custom-encrypt-program") == 0 &&
339 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
340 "XML: Duplicate %s element", element_name);
343 if (strcmp(element_name, "decrypt-option") == 0 &&
344 dle->clnt_decrypt_opt) {
345 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
346 "XML: Duplicate %s element", element_name);
349 } else if(strcmp(element_name, "plugin") == 0) {
350 if (strcmp(last_element_name, "backup-program") != 0 &&
351 strcmp(last_element_name, "script") != 0) {
352 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
353 "XML: Invalid %s element", element_name);
356 if (data_user->has_plugin) {
357 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
358 "XML: Duplicate %s element in '%s'", element_name,
362 } else if(strcmp(element_name, "property") == 0) {
363 if (strcmp(last_element_name, "backup-program") != 0 &&
364 strcmp(last_element_name, "script") != 0) {
365 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
366 "XML: Invalid %s element", element_name);
369 data_user->property_data = malloc(sizeof(property_t));
370 data_user->property_data->append = 0;
371 data_user->property_data->priority = 0;
372 data_user->property_data->values = NULL;
373 } else if(strcmp(element_name, "name") == 0) {
374 if (strcmp(last_element_name, "property") != 0) {
375 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
376 "XML: Invalid %s element", element_name);
379 if (data_user->property_name) {
380 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
381 "XML: Duplicate %s element in '%s'", element_name,
385 } else if(strcmp(element_name, "priority") == 0) {
386 if (strcmp(last_element_name, "property") != 0) {
387 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
388 "XML: Invalid %s element", element_name);
391 } else if(strcmp(element_name, "value") == 0) {
392 if (strcmp(last_element_name, "property") != 0) {
393 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
394 "XML: Invalid %s element", element_name);
397 } else if(strcmp(element_name, "file") == 0 ||
398 strcmp(element_name, "list") == 0 ||
399 strcmp(element_name, "optional") == 0) {
400 if (strcmp(last_element_name, "exclude") != 0 &&
401 strcmp(last_element_name, "include") != 0) {
402 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
403 "XML: Invalid %s element", element_name);
406 if (strcmp(element_name, "optional") == 0 && data_user->has_optional) {
407 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
408 "XML: Duplicate %s element", element_name);
411 if (strcmp(element_name, "optional") == 0) data_user->has_optional = 1;
412 } else if (strcmp(element_name, "backup-program") == 0) {
413 if (data_user->has_backup_program) {
414 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
415 "XML: Duplicate %s element", element_name);
418 data_user->has_backup_program = 1;
419 data_user->property =
420 g_hash_table_new_full(g_str_hash, g_str_equal, &g_free, &free_property_t);
421 data_user->has_plugin = 0;
423 } else if (strcmp(element_name, "script") == 0) {
424 data_user->property =
425 g_hash_table_new_full(g_str_hash, g_str_equal, &g_free, &free_property_t);
426 data_user->script = malloc(sizeof(script_t));
427 data_user->script->plugin = NULL;
428 data_user->script->execute_on = 0;
429 data_user->script->execute_where = ES_CLIENT;
430 data_user->script->property = NULL;
431 data_user->script->result = NULL;
432 data_user->has_plugin = 0;
433 } else if (strcmp(element_name, "execute_on") == 0) {
434 } else if (strcmp(element_name, "execute_where") == 0) {
435 } else if (strcmp(element_name, "directtcp") == 0) {
436 if (strcmp(last_element_name, "datapath") != 0) {
437 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
438 "XML: Invalid %s element", element_name);
442 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
443 "XML: Invalid %s element", element_name);
446 data_user->element_names = g_slist_prepend(data_user->element_names,
447 stralloc(element_name));
450 /* Called for close tags </foo> */
453 G_GNUC_UNUSED GMarkupParseContext *context,
454 const gchar *element_name,
458 amgxml_t *data_user = user_data;
459 GSList *last_element = data_user->element_names;
460 char *last_element_name = NULL;
461 dle_t *dle = data_user->dle;
464 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
465 "XML: Invalid closing tag");
468 last_element_name = last_element->data;
469 if (strcmp(last_element_name, element_name) != 0) {
470 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
471 "XML: Invalid closing tag '%s'", element_name);
475 if (strcmp(element_name, "property") == 0) {
476 g_hash_table_insert(data_user->property,
477 data_user->property_name,
478 data_user->property_data);
479 data_user->property_name = NULL;
480 data_user->property_data = NULL;
481 } else if (strcmp(element_name, "dle") == 0) {
482 if (dle->program_is_application_api &&
484 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
485 "XML: program set to APPLICATION but no application set");
488 if (dle->device == NULL && dle->disk)
489 dle->device = stralloc(dle->disk);
490 if (dle->estimatelist == NULL)
491 dle->estimatelist = g_slist_append(dle->estimatelist, ES_CLIENT);
492 /* Add check of required field */
493 data_user->dle = NULL;
494 } else if (strcmp(element_name, "backup-program") == 0) {
495 if (dle->program == NULL) {
496 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
497 "XML: No plugin set for application");
500 dle->application_property = data_user->property;
501 data_user->property = NULL;
502 } else if (strcmp(element_name, "script") == 0) {
503 if (data_user->script->plugin == NULL) {
504 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
505 "XML: No plugin set for script");
508 data_user->script->property = data_user->property;
509 data_user->property = NULL;
510 dle->scriptlist = g_slist_append(dle->scriptlist, data_user->script);
511 data_user->script = NULL;
512 } else if (strcmp(element_name, "level") == 0) {
513 dle->levellist = g_slist_append(dle->levellist, data_user->alevel);
514 data_user->alevel = NULL;
516 g_free(data_user->element_names->data);
517 data_user->element_names = g_slist_delete_link(data_user->element_names,
518 data_user->element_names);
521 /* Called for character data */
522 /* text is not nul-terminated */
525 G_GNUC_UNUSED GMarkupParseContext *context,
532 amgxml_t *data_user = user_data;
533 GSList *last_element = data_user->element_names;
534 char *last_element_name;
535 GSList *last_element2;
536 char *last_element2_name;
537 dle_t *dle = data_user->dle;
541 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
542 "XML: Invalid text");
545 last_element_name = last_element->data;
547 tt = malloc(text_len + 1);
548 strncpy(tt,text,text_len);
551 //check if it is only space
552 if (match_no_newline("^[ \f\n\r\t\v]*$", tt)) {
557 if (data_user->raw) {
559 tt = stralloc(data_user->raw);
560 } else if (strlen(tt) > 0) {
561 /* remove trailing space */
562 char *ttt = tt + strlen(tt) - 1;
570 //check if it is only space
571 if (match_no_newline("^[ \f\n\r\t\v]*$", tt)) {
576 if (strcmp(last_element_name, "dle") == 0 ||
577 strcmp(last_element_name, "backup-program") == 0 ||
578 strcmp(last_element_name, "exclude") == 0 ||
579 strcmp(last_element_name, "include") == 0) {
580 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
581 "XML: %s doesn't have text '%s'", last_element_name, tt);
584 } else if(strcmp(last_element_name, "disk") == 0) {
585 if (dle->disk != NULL) {
586 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
587 "XML: multiple text in %s", last_element_name);
592 } else if(strcmp(last_element_name, "diskdevice") == 0) {
593 if (dle->device != NULL) {
594 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
595 "XML: multiple text in %s", last_element_name);
600 } else if(strcmp(last_element_name, "calcsize") == 0) {
601 if (strcasecmp(tt,"yes") == 0) {
602 dle->estimatelist = g_slist_append(dle->estimatelist,
603 GINT_TO_POINTER(ES_CALCSIZE));
606 } else if(strcmp(last_element_name, "estimate") == 0) {
608 while (strlen(ttt) > 0) {
609 if (BSTRNCMP(ttt,"CLIENT") == 0) {
610 dle->estimatelist = g_slist_append(dle->estimatelist,
611 GINT_TO_POINTER(ES_CLIENT));
612 ttt += strlen("client");
613 } else if (BSTRNCMP(ttt,"CALCSIZE") == 0) {
614 if (!data_user->has_calcsize)
615 dle->estimatelist = g_slist_append(dle->estimatelist,
616 GINT_TO_POINTER(ES_CALCSIZE));
617 ttt += strlen("calcsize");
618 } else if (BSTRNCMP(ttt,"SERVER") == 0) {
619 dle->estimatelist = g_slist_append(dle->estimatelist,
620 GINT_TO_POINTER(ES_SERVER));
621 ttt += strlen("server");
623 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
624 "XML: bad estimate: %s", tt);
631 } else if(strcmp(last_element_name, "program") == 0) {
632 if (dle->program != NULL) {
633 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
634 "XML: multiple text in %s", last_element_name);
638 if (strcmp(tt, "APPLICATION") == 0) {
639 dle->program_is_application_api = 1;
645 } else if(strcmp(last_element_name, "plugin") == 0) {
646 last_element2 = g_slist_nth(data_user->element_names, 1);
647 if (!last_element2) {
648 error("Invalid name text");
650 last_element2_name = last_element2->data;
651 if (strcmp(last_element2_name, "backup-program") == 0) {
653 } else if (strcmp(last_element2_name, "script") == 0) {
654 data_user->script->plugin = tt;
656 error("plugin outside of backup-program");
658 data_user->has_plugin = 1;
659 } else if(strcmp(last_element_name, "name") == 0) {
660 last_element2 = g_slist_nth(data_user->element_names, 1);
661 if (!last_element2) {
662 error("Invalid name text");
664 last_element2_name = last_element2->data;
665 if (strcmp(last_element2_name, "property") == 0) {
666 data_user->property_name = tt;
668 error("name outside of property");
670 } else if(strcmp(last_element_name, "priority") == 0) {
671 last_element2 = g_slist_nth(data_user->element_names, 1);
672 if (!last_element2) {
673 error("Invalid priority text");
675 last_element2_name = last_element2->data;
676 if (strcmp(last_element2_name, "property") == 0) {
677 if (strcasecmp(tt,"yes") == 0) {
678 data_user->property_data->priority = 1;
681 error("priority outside of property");
684 } else if(strcmp(last_element_name, "value") == 0) {
685 last_element2 = g_slist_nth(data_user->element_names, 1);
686 if (!last_element2) {
687 error("Invalid name text");
689 last_element2_name = last_element2->data;
690 if (strcmp(last_element2_name, "property") == 0) {
691 data_user->property_data->values =
692 g_slist_append(data_user->property_data->values, tt);
694 error("value outside of property");
696 } else if(strcmp(last_element_name, "auth") == 0) {
697 if (dle->auth != NULL) {
698 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
699 "XML: multiple text in %s", last_element_name);
703 } else if(strcmp(last_element_name, "level") == 0) {
704 data_user->alevel->level = atoi(tt);
706 } else if (strcmp(last_element_name, "server") == 0) {
707 if (strcasecmp(tt,"no") == 0) {
708 data_user->alevel->server = 0;
709 } else if (strcasecmp(tt,"yes") == 0) {
710 data_user->alevel->server = 1;
712 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
713 "XML: Invalid %s (%s)", last_element_name, tt);
718 } else if(strcmp(last_element_name, "index") == 0) {
719 if (strcasecmp(tt,"no") == 0) {
720 dle->create_index = 0;
721 } else if (strcasecmp(tt,"yes") == 0) {
722 dle->create_index = 1;
724 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
725 "XML: Invalid %s (%s)", last_element_name, tt);
730 } else if(strcmp(last_element_name, "dumpdate") == 0) {
731 if (dle->dumpdate != NULL) {
732 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
733 "XML: multiple text in %s", last_element_name);
738 } else if(strcmp(last_element_name, "record") == 0) {
739 if (strcasecmp(tt, "no") == 0) {
741 } else if (strcasecmp(tt, "yes") == 0) {
744 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
745 "XML: Invalid %s (%s)", last_element_name, tt);
750 } else if(strcmp(last_element_name, "spindle") == 0) {
751 dle->spindle = atoi(tt);
753 } else if(strcmp(last_element_name, "compress") == 0) {
754 if (strcmp(tt, "FAST") == 0) {
755 dle->compress = COMP_FAST;
756 } else if (strcmp(tt, "BEST") == 0) {
757 dle->compress = COMP_BEST;
758 } else if (BSTRNCMP(tt, "CUSTOM") == 0) {
759 dle->compress = COMP_CUST;
760 } else if (strcmp(tt, "SERVER-FAST") == 0) {
761 dle->compress = COMP_SERVER_FAST;
762 } else if (strcmp(tt, "SERVER-BEST") == 0) {
763 dle->compress = COMP_SERVER_BEST;
764 } else if (BSTRNCMP(tt, "SERVER-CUSTOM") == 0) {
765 dle->compress = COMP_SERVER_CUST;
767 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
768 "XML: Invalid %s (%s)", last_element_name, tt);
773 } else if(strcmp(last_element_name, "custom-compress-program") == 0) {
774 if (dle->compprog != NULL) {
775 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
776 "XML: multiple text in %s", last_element_name);
781 } else if(strcmp(last_element_name, "encrypt") == 0) {
782 if (BSTRNCMP(tt,"NO") == 0) {
783 dle->encrypt = ENCRYPT_NONE;
784 } else if (BSTRNCMP(tt, "CUSTOM") == 0) {
785 dle->encrypt = ENCRYPT_CUST;
786 } else if (BSTRNCMP(tt, "SERVER-CUSTOM") == 0) {
787 dle->encrypt = ENCRYPT_SERV_CUST;
789 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
790 "XML: Invalid %s (%s)", last_element_name, tt);
795 } else if(strcmp(last_element_name, "kencrypt") == 0) {
796 if (strcasecmp(tt,"no") == 0) {
798 } else if (strcasecmp(tt,"yes") == 0) {
801 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
802 "XML: Invalid %s (%s)", last_element_name, tt);
807 } else if(strcmp(last_element_name, "custom-encrypt-program") == 0) {
808 last_element2 = g_slist_nth(data_user->element_names, 1);
809 if (!last_element2) {
810 error("XML: optional");
812 last_element2_name = last_element2->data;
813 if (dle->encrypt == ENCRYPT_SERV_CUST)
814 dle->srv_encrypt = tt;
816 dle->clnt_encrypt = tt;
817 } else if(strcmp(last_element_name, "decrypt-option") == 0) {
818 last_element2 = g_slist_nth(data_user->element_names, 1);
819 if (!last_element2) {
820 error("XML: optional");
822 last_element2_name = last_element2->data;
823 if (dle->encrypt == ENCRYPT_SERV_CUST)
824 dle->srv_decrypt_opt = tt;
826 dle->clnt_decrypt_opt = tt;
827 } else if(strcmp(last_element_name, "exclude") == 0 ||
828 strcmp(last_element_name, "include") == 0) {
829 data_user->has_optional = 0;
831 } else if(strcmp(last_element_name, "file") == 0) {
832 last_element2 = g_slist_nth(data_user->element_names, 1);
833 if (!last_element2) {
834 error("XML: optional");
836 last_element2_name = last_element2->data;
837 if (strcmp(last_element2_name, "exclude") == 0) {
838 dle->exclude_file = append_sl(dle->exclude_file, tt);
839 } else if (strcmp(last_element2_name, "include") == 0) {
840 dle->include_file = append_sl(dle->include_file, tt);
844 } else if(strcmp(last_element_name, "list") == 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_list = append_sl(dle->exclude_list, tt);
852 } else if (strcmp(last_element2_name, "include") == 0) {
853 dle->include_list = append_sl(dle->include_list, tt);
857 } else if(strcmp(last_element_name, "optional") == 0) {
859 last_element2 = g_slist_nth(data_user->element_names, 1);
860 if (!last_element2) {
861 error("XML: optional");
863 last_element2_name = last_element2->data;
864 if (strcmp(last_element2_name, "exclude") == 0) {
865 dle->exclude_optional = 1;
866 } else if (strcmp(last_element2_name, "include") == 0) {
867 dle->include_optional = 1;
869 error("bad optional");
871 data_user->has_optional = 1;
873 } else if(strcmp(last_element_name, "script") == 0) {
875 } else if(strcmp(last_element_name, "execute_on") == 0) {
879 sep = strchr(tt1,',');
882 if (strcmp(tt1,"PRE-DLE-AMCHECK") == 0)
883 data_user->script->execute_on |= EXECUTE_ON_PRE_DLE_AMCHECK;
884 else if (strcmp(tt1,"PRE-HOST-AMCHECK") == 0)
885 data_user->script->execute_on |= EXECUTE_ON_PRE_HOST_AMCHECK;
886 else if (strcmp(tt1,"POST-DLE-AMCHECK") == 0)
887 data_user->script->execute_on |= EXECUTE_ON_POST_DLE_AMCHECK;
888 else if (strcmp(tt1,"POST-HOST-AMCHECK") == 0)
889 data_user->script->execute_on |= EXECUTE_ON_POST_HOST_AMCHECK;
890 else if (strcmp(tt1,"PRE-DLE-ESTIMATE") == 0)
891 data_user->script->execute_on |= EXECUTE_ON_PRE_DLE_ESTIMATE;
892 else if (strcmp(tt1,"PRE-HOST-ESTIMATE") == 0)
893 data_user->script->execute_on |= EXECUTE_ON_PRE_HOST_ESTIMATE;
894 else if (strcmp(tt1,"POST-DLE-ESTIMATE") == 0)
895 data_user->script->execute_on |= EXECUTE_ON_POST_DLE_ESTIMATE;
896 else if (strcmp(tt1,"POST-HOST-ESTIMATE") == 0)
897 data_user->script->execute_on |= EXECUTE_ON_POST_HOST_ESTIMATE;
898 else if (strcmp(tt1,"PRE-DLE-BACKUP") == 0)
899 data_user->script->execute_on |= EXECUTE_ON_PRE_DLE_BACKUP;
900 else if (strcmp(tt1,"PRE-HOST-BACKUP") == 0)
901 data_user->script->execute_on |= EXECUTE_ON_PRE_HOST_BACKUP;
902 else if (strcmp(tt1,"POST-DLE-BACKUP") == 0)
903 data_user->script->execute_on |= EXECUTE_ON_POST_DLE_BACKUP;
904 else if (strcmp(tt1,"POST-HOST-BACKUP") == 0)
905 data_user->script->execute_on |= EXECUTE_ON_POST_HOST_BACKUP;
906 else if (strcmp(tt1,"PRE-RECOVER") == 0)
907 data_user->script->execute_on |= EXECUTE_ON_PRE_RECOVER;
908 else if (strcmp(tt1,"POST-RECOVER") == 0)
909 data_user->script->execute_on |= EXECUTE_ON_POST_RECOVER;
910 else if (strcmp(tt1,"PRE-LEVEL-RECOVER") == 0)
911 data_user->script->execute_on |= EXECUTE_ON_PRE_LEVEL_RECOVER;
912 else if (strcmp(tt1,"POST-LEVEL-RECOVER") == 0)
913 data_user->script->execute_on |= EXECUTE_ON_POST_LEVEL_RECOVER;
914 else if (strcmp(tt1,"INTER-LEVEL-RECOVER") == 0)
915 data_user->script->execute_on |= EXECUTE_ON_INTER_LEVEL_RECOVER;
917 dbprintf("BAD EXECUTE_ON: %s\n", tt1);
922 } else if(strcmp(last_element_name, "execute_where") == 0) {
923 if (strcmp(tt, "CLIENT") == 0) {
924 data_user->script->execute_where = ES_CLIENT;
926 data_user->script->execute_where = ES_SERVER;
929 } else if(strcmp(last_element_name, "datapath") == 0) {
930 if (strcmp(tt, "AMANDA") == 0) {
931 dle->data_path = DATA_PATH_AMANDA;
932 } else if (strcmp(tt, "DIRECTTCP") == 0) {
933 dle->data_path = DATA_PATH_DIRECTTCP;
935 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
936 "XML: bad datapath value '%s'", tt);
939 } else if(strcmp(last_element_name, "directtcp") == 0) {
940 dle->directtcp_list = g_slist_append(dle->directtcp_list, tt);
942 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
943 "XML: amtext not defined for '%s'", last_element_name);
950 amxml_parse_node_CHAR(
954 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};
955 GMarkupParser parser = {&amstart_element, &amend_element, &amtext,
957 GMarkupParseFlags flags = 0;
958 GMarkupParseContext *context;
959 GError *gerror = NULL;
963 context = g_markup_parse_context_new(&parser, flags, &amgxml, NULL);
965 g_markup_parse_context_parse(context, txt, strlen(txt), &gerror);
967 g_markup_parse_context_end_parse(context, &gerror);
968 g_markup_parse_context_free(context);
971 *errmsg = stralloc(gerror->message);
972 g_error_free(gerror);
979 amxml_parse_node_FILE(
983 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};
984 GMarkupParser parser = {&amstart_element, &amend_element, &amtext,
986 GMarkupParseFlags flags = 0;
987 GMarkupParseContext *context;
988 GError *gerror = NULL;
993 context = g_markup_parse_context_new(&parser, flags, &amgxml, NULL);
995 while ((line = agets(file)) != NULL && !gerror) {
996 g_markup_parse_context_parse(context, line, strlen(line), &gerror);
1000 g_markup_parse_context_end_parse(context, &gerror);
1001 g_markup_parse_context_free(context);
1004 *errmsg = stralloc(gerror->message);
1005 g_error_free(gerror);
1022 quoted_value = malloc(strlen(value)+1);
1025 for(c=value; *c != '\0'; c++) {
1026 // Check include negative value, with the 8th bit set.
1028 (unsigned char)*c > 127 ||
1048 base64_encode_alloc(value, strlen(value), &b64value);
1049 result = vstralloc("<", tag,
1050 " encoding=\"raw\" raw=\"", b64value, "\">",
1056 result = vstralloc("<", tag, ">",
1061 amfree(quoted_value);