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);
102 if (dle->application_property)
103 g_hash_table_destroy(dle->application_property);
104 for(scriptlist = dle->scriptlist; scriptlist != NULL;
105 scriptlist = scriptlist->next) {
106 free_script_data((script_t *)scriptlist->data);
108 slist_free_full(dle->scriptlist, g_free);
109 slist_free_full(dle->directtcp_list, g_free);
117 amfree(script->plugin);
118 amfree(script->client_name);
119 if (script->property)
120 g_hash_table_destroy(script->property);
129 dle->program_is_application_api = 0;
131 dle->estimatelist = NULL;
134 dle->compress = COMP_NONE;
135 dle->encrypt = ENCRYPT_NONE;
137 dle->levellist = NULL;
138 dle->dumpdate = NULL;
139 dle->compprog = NULL;
140 dle->srv_encrypt = NULL;
141 dle->clnt_encrypt = NULL;
142 dle->srv_decrypt_opt = NULL;
143 dle->clnt_decrypt_opt = NULL;
144 dle->create_index = 0;
146 dle->exclude_file = NULL;
147 dle->exclude_list = NULL;
148 dle->include_file = NULL;
149 dle->include_list = NULL;
150 dle->exclude_optional = 0;
151 dle->include_optional = 0;
152 dle->application_property = NULL;
153 dle->scriptlist = NULL;
154 dle->data_path = DATA_PATH_AMANDA;
155 dle->directtcp_list = NULL;
156 dle->application_client_name = NULL;
161 /* Called for open tags <foo bar="baz"> */
162 static void amstart_element(GMarkupParseContext *context,
163 const gchar *element_name,
164 const gchar **attribute_names,
165 const gchar **attribute_values,
169 /* Called for close tags </foo> */
170 static void amend_element(GMarkupParseContext *context,
171 const gchar *element_name,
175 /* Called for character data */
176 /* text is not nul-terminated */
177 static void amtext(GMarkupParseContext *context,
183 /* Called for open tags <foo bar="baz"> */
186 G_GNUC_UNUSED GMarkupParseContext *context,
187 const gchar *element_name,
188 G_GNUC_UNUSED const gchar **attribute_names,
189 G_GNUC_UNUSED const gchar **attribute_values,
193 amgxml_t *data_user = user_data;
195 GSList *last_element = data_user->element_names;
196 char *last_element_name = NULL;
197 dle_t *dle = data_user->dle;
198 const gchar **at_names, **at_values;
201 last_element_name = last_element->data;
203 data_user->raw = NULL;
204 data_user->encoding = NULL;
206 if (attribute_names) {
207 for(at_names = attribute_names, at_values = attribute_values;
208 *at_names != NULL && at_values != NULL;
209 at_names++, at_values++) {
210 if (strcmp(*at_names, "encoding") == 0) {
211 data_user->encoding = stralloc(*at_values);
212 } else if (strcmp(*at_names, "raw") == 0) {
213 data_user->raw = base64_decode_alloc_string((char *)*at_values);
215 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
216 "XML: Invalid attribute '%s' for %s element",
217 *at_names, element_name);
223 if (strcmp(element_name, "dle") == 0) {
224 if (last_element != NULL) {
225 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
226 "XML: Invalid dle element");
229 for(adle = data_user->dles; adle != NULL && adle->next != NULL;
231 data_user->dle = alloc_dle();
233 data_user->dles = data_user->dle;
235 adle->next = data_user->dle;
237 data_user->has_calcsize = 0;
238 data_user->has_estimate = 0;
239 data_user->has_record = 0;
240 data_user->has_spindle = 0;
241 data_user->has_compress = 0;
242 data_user->has_encrypt = 0;
243 data_user->has_kencrypt = 0;
244 data_user->has_datapath = 0;
245 data_user->has_exclude = 0;
246 data_user->has_include = 0;
247 data_user->has_index = 0;
248 data_user->has_backup_program = 0;
249 data_user->has_plugin = 0;
250 data_user->has_optional = 0;
251 data_user->property_name = NULL;
252 data_user->property_data = NULL;
253 data_user->property = NULL;
254 data_user->script = NULL;
255 data_user->alevel = NULL;
256 data_user->encoding = NULL;
257 data_user->raw = NULL;
258 } else if(strcmp(element_name, "disk" ) == 0 ||
259 strcmp(element_name, "diskdevice" ) == 0 ||
260 strcmp(element_name, "calcsize" ) == 0 ||
261 strcmp(element_name, "estimate" ) == 0 ||
262 strcmp(element_name, "program" ) == 0 ||
263 strcmp(element_name, "auth" ) == 0 ||
264 strcmp(element_name, "index" ) == 0 ||
265 strcmp(element_name, "dumpdate" ) == 0 ||
266 strcmp(element_name, "level" ) == 0 ||
267 strcmp(element_name, "record" ) == 0 ||
268 strcmp(element_name, "spindle" ) == 0 ||
269 strcmp(element_name, "compress" ) == 0 ||
270 strcmp(element_name, "encrypt" ) == 0 ||
271 strcmp(element_name, "kencrypt" ) == 0 ||
272 strcmp(element_name, "datapath" ) == 0 ||
273 strcmp(element_name, "exclude" ) == 0 ||
274 strcmp(element_name, "include" ) == 0) {
275 if (strcmp(last_element_name, "dle") != 0) {
276 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
277 "XML: Invalid %s element", element_name);
280 if ((strcmp(element_name, "disk" ) == 0 && dle->disk) ||
281 (strcmp(element_name, "diskdevice" ) == 0 && dle->device) ||
282 (strcmp(element_name, "calcsize" ) == 0 && data_user->has_calcsize) ||
283 (strcmp(element_name, "estimate" ) == 0 && data_user->has_estimate) ||
284 (strcmp(element_name, "record" ) == 0 && data_user->has_record) ||
285 (strcmp(element_name, "spindle" ) == 0 && data_user->has_spindle) ||
286 (strcmp(element_name, "program" ) == 0 && dle->program) ||
287 (strcmp(element_name, "auth" ) == 0 && dle->auth) ||
288 (strcmp(element_name, "index" ) == 0 && data_user->has_index) ||
289 (strcmp(element_name, "dumpdate" ) == 0 && dle->dumpdate) ||
290 (strcmp(element_name, "compress" ) == 0 && data_user->has_compress) ||
291 (strcmp(element_name, "encrypt" ) == 0 && data_user->has_encrypt) ||
292 (strcmp(element_name, "kencrypt" ) == 0 && data_user->has_kencrypt) ||
293 (strcmp(element_name, "datapath" ) == 0 && data_user->has_datapath) ||
294 (strcmp(element_name, "exclude" ) == 0 && data_user->has_exclude) ||
295 (strcmp(element_name, "include" ) == 0 && data_user->has_include)) {
296 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
297 "XML: Duplicate %s element", element_name);
300 if (strcmp(element_name, "calcsize" ) == 0) data_user->has_calcsize = 1;
301 if (strcmp(element_name, "estimate" ) == 0) data_user->has_estimate = 1;
302 if (strcmp(element_name, "record" ) == 0) data_user->has_record = 1;
303 if (strcmp(element_name, "spindle" ) == 0) data_user->has_spindle = 1;
304 if (strcmp(element_name, "index" ) == 0) data_user->has_index = 1;
305 if (strcmp(element_name, "compress" ) == 0) data_user->has_compress = 1;
306 if (strcmp(element_name, "encrypt" ) == 0) data_user->has_encrypt = 1;
307 if (strcmp(element_name, "kencrypt" ) == 0) data_user->has_kencrypt = 1;
308 if (strcmp(element_name, "datapath" ) == 0) data_user->has_datapath = 1;
309 if (strcmp(element_name, "exclude" ) == 0) data_user->has_exclude = 1;
310 if (strcmp(element_name, "include" ) == 0) data_user->has_include = 1;
311 if (strcmp(element_name, "exclude") == 0 || strcmp(element_name, "include") == 0)
312 data_user->has_optional = 0;
313 if (strcmp(element_name, "level") == 0) {
314 data_user->alevel = g_new0(level_t, 1);
316 } else if (strcmp(element_name, "server") == 0) {
317 if (strcmp(last_element_name, "level") != 0) {
318 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
319 "XML: Invalid %s element", element_name);
322 } else if(strcmp(element_name, "custom-compress-program") == 0) {
323 if (strcmp(last_element_name, "compress") != 0) {
324 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
325 "XML: Invalid %s element", element_name);
329 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
330 "XML: Duplicate %s element", element_name);
333 } else if (strcmp(element_name, "custom-encrypt-program") == 0 ||
334 strcmp(element_name, "decrypt-option") == 0) {
335 if (strcmp(last_element_name, "encrypt") != 0) {
336 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
337 "XML: Invalid %s element", element_name);
340 if (strcmp(element_name, "custom-encrypt-program") == 0 &&
342 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
343 "XML: Duplicate %s element", element_name);
346 if (strcmp(element_name, "decrypt-option") == 0 &&
347 dle->clnt_decrypt_opt) {
348 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
349 "XML: Duplicate %s element", element_name);
352 } else if(strcmp(element_name, "plugin") == 0) {
353 if (strcmp(last_element_name, "backup-program") != 0 &&
354 strcmp(last_element_name, "script") != 0) {
355 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
356 "XML: Invalid %s element", element_name);
359 if (data_user->has_plugin) {
360 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
361 "XML: Duplicate %s element in '%s'", element_name,
365 } else if(strcmp(element_name, "property") == 0) {
366 if (strcmp(last_element_name, "backup-program") != 0 &&
367 strcmp(last_element_name, "script") != 0) {
368 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
369 "XML: Invalid %s element", element_name);
372 data_user->property_data = malloc(sizeof(property_t));
373 data_user->property_data->append = 0;
374 data_user->property_data->priority = 0;
375 data_user->property_data->values = NULL;
376 } else if(strcmp(element_name, "name") == 0) {
377 if (strcmp(last_element_name, "property") != 0) {
378 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
379 "XML: Invalid %s element", element_name);
382 if (data_user->property_name) {
383 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
384 "XML: Duplicate %s element in '%s'", element_name,
388 } else if(strcmp(element_name, "priority") == 0) {
389 if (strcmp(last_element_name, "property") != 0) {
390 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
391 "XML: Invalid %s element", element_name);
394 } else if(strcmp(element_name, "value") == 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, "file") == 0 ||
401 strcmp(element_name, "list") == 0 ||
402 strcmp(element_name, "optional") == 0) {
403 if (strcmp(last_element_name, "exclude") != 0 &&
404 strcmp(last_element_name, "include") != 0) {
405 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
406 "XML: Invalid %s element", element_name);
409 if (strcmp(element_name, "optional") == 0 && data_user->has_optional) {
410 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
411 "XML: Duplicate %s element", element_name);
414 if (strcmp(element_name, "optional") == 0) data_user->has_optional = 1;
415 } else if (strcmp(element_name, "backup-program") == 0) {
416 if (data_user->has_backup_program) {
417 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
418 "XML: Duplicate %s element", element_name);
421 data_user->has_backup_program = 1;
422 data_user->property =
423 g_hash_table_new_full(g_str_hash, g_str_equal, &g_free, &free_property_t);
424 data_user->has_plugin = 0;
426 } else if (strcmp(element_name, "script") == 0) {
427 data_user->property =
428 g_hash_table_new_full(g_str_hash, g_str_equal, &g_free, &free_property_t);
429 data_user->script = malloc(sizeof(script_t));
430 data_user->script->plugin = NULL;
431 data_user->script->execute_on = 0;
432 data_user->script->execute_where = ES_CLIENT;
433 data_user->script->property = NULL;
434 data_user->script->client_name = NULL;
435 data_user->script->result = NULL;
436 data_user->has_plugin = 0;
437 } else if (strcmp(element_name, "execute_on") == 0) {
438 } else if (strcmp(element_name, "execute_where") == 0) {
439 } else if (strcmp(element_name, "directtcp") == 0) {
440 if (strcmp(last_element_name, "datapath") != 0) {
441 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
442 "XML: Invalid %s element", element_name);
445 } else if (strcmp(element_name, "client_name") == 0) {
447 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
448 "XML: Invalid %s element", element_name);
451 data_user->element_names = g_slist_prepend(data_user->element_names,
452 stralloc(element_name));
455 /* Called for close tags </foo> */
458 G_GNUC_UNUSED GMarkupParseContext *context,
459 const gchar *element_name,
463 amgxml_t *data_user = user_data;
464 GSList *last_element = data_user->element_names;
465 char *last_element_name = NULL;
466 dle_t *dle = data_user->dle;
469 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
470 "XML: Invalid closing tag");
473 last_element_name = last_element->data;
474 if (strcmp(last_element_name, element_name) != 0) {
475 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
476 "XML: Invalid closing tag '%s'", element_name);
480 if (strcmp(element_name, "property") == 0) {
481 g_hash_table_insert(data_user->property,
482 data_user->property_name,
483 data_user->property_data);
484 data_user->property_name = NULL;
485 data_user->property_data = NULL;
486 } else if (strcmp(element_name, "dle") == 0) {
487 if (dle->program_is_application_api &&
489 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
490 "XML: program set to APPLICATION but no application set");
493 if (dle->device == NULL && dle->disk)
494 dle->device = stralloc(dle->disk);
495 if (dle->estimatelist == NULL)
496 dle->estimatelist = g_slist_append(dle->estimatelist, ES_CLIENT);
497 /* Add check of required field */
498 data_user->dle = NULL;
499 } else if (strcmp(element_name, "backup-program") == 0) {
500 if (dle->program == NULL) {
501 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
502 "XML: No plugin set for application");
505 dle->application_property = data_user->property;
506 data_user->property = NULL;
507 } else if (strcmp(element_name, "script") == 0) {
508 if (data_user->script->plugin == NULL) {
509 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
510 "XML: No plugin set for script");
513 data_user->script->property = data_user->property;
514 data_user->property = NULL;
515 dle->scriptlist = g_slist_append(dle->scriptlist, data_user->script);
516 data_user->script = NULL;
517 } else if (strcmp(element_name, "level") == 0) {
518 dle->levellist = g_slist_append(dle->levellist, data_user->alevel);
519 data_user->alevel = NULL;
521 g_free(data_user->element_names->data);
522 data_user->element_names = g_slist_delete_link(data_user->element_names,
523 data_user->element_names);
526 /* Called for character data */
527 /* text is not nul-terminated */
530 G_GNUC_UNUSED GMarkupParseContext *context,
537 amgxml_t *data_user = user_data;
538 GSList *last_element = data_user->element_names;
539 char *last_element_name;
540 GSList *last_element2;
541 char *last_element2_name;
542 dle_t *dle = data_user->dle;
546 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
547 "XML: Invalid text");
550 last_element_name = last_element->data;
552 tt = malloc(text_len + 1);
553 strncpy(tt,text,text_len);
556 //check if it is only space
557 if (match_no_newline("^[ \f\n\r\t\v]*$", tt)) {
562 if (data_user->raw) {
564 tt = stralloc(data_user->raw);
565 } else if (strlen(tt) > 0) {
566 /* remove trailing space */
567 char *ttt = tt + strlen(tt) - 1;
575 //check if it is only space
576 if (match_no_newline("^[ \f\n\r\t\v]*$", tt)) {
581 if (strcmp(last_element_name, "dle") == 0 ||
582 strcmp(last_element_name, "backup-program") == 0 ||
583 strcmp(last_element_name, "exclude") == 0 ||
584 strcmp(last_element_name, "include") == 0) {
585 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
586 "XML: %s doesn't have text '%s'", last_element_name, tt);
589 } else if(strcmp(last_element_name, "disk") == 0) {
590 if (dle->disk != NULL) {
591 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
592 "XML: multiple text in %s", last_element_name);
597 } else if(strcmp(last_element_name, "diskdevice") == 0) {
598 if (dle->device != 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, "calcsize") == 0) {
606 if (strcasecmp(tt,"yes") == 0) {
607 dle->estimatelist = g_slist_append(dle->estimatelist,
608 GINT_TO_POINTER(ES_CALCSIZE));
611 } else if(strcmp(last_element_name, "estimate") == 0) {
613 while (strlen(ttt) > 0) {
614 if (BSTRNCMP(ttt,"CLIENT") == 0) {
615 dle->estimatelist = g_slist_append(dle->estimatelist,
616 GINT_TO_POINTER(ES_CLIENT));
617 ttt += strlen("client");
618 } else if (BSTRNCMP(ttt,"CALCSIZE") == 0) {
619 if (!data_user->has_calcsize)
620 dle->estimatelist = g_slist_append(dle->estimatelist,
621 GINT_TO_POINTER(ES_CALCSIZE));
622 ttt += strlen("calcsize");
623 } else if (BSTRNCMP(ttt,"SERVER") == 0) {
624 dle->estimatelist = g_slist_append(dle->estimatelist,
625 GINT_TO_POINTER(ES_SERVER));
626 ttt += strlen("server");
628 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
629 "XML: bad estimate: %s", tt);
636 } else if(strcmp(last_element_name, "program") == 0) {
637 if (dle->program != NULL) {
638 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
639 "XML: multiple text in %s", last_element_name);
643 if (strcmp(tt, "APPLICATION") == 0) {
644 dle->program_is_application_api = 1;
650 } else if(strcmp(last_element_name, "plugin") == 0) {
651 last_element2 = g_slist_nth(data_user->element_names, 1);
652 if (!last_element2) {
653 error("Invalid name text");
655 last_element2_name = last_element2->data;
656 if (strcmp(last_element2_name, "backup-program") == 0) {
658 } else if (strcmp(last_element2_name, "script") == 0) {
659 data_user->script->plugin = tt;
661 error("plugin outside of backup-program");
663 data_user->has_plugin = 1;
664 } else if(strcmp(last_element_name, "name") == 0) {
665 last_element2 = g_slist_nth(data_user->element_names, 1);
666 if (!last_element2) {
667 error("Invalid name text");
669 last_element2_name = last_element2->data;
670 if (strcmp(last_element2_name, "property") == 0) {
671 data_user->property_name = tt;
673 error("name outside of property");
675 } else if(strcmp(last_element_name, "priority") == 0) {
676 last_element2 = g_slist_nth(data_user->element_names, 1);
677 if (!last_element2) {
678 error("Invalid priority text");
680 last_element2_name = last_element2->data;
681 if (strcmp(last_element2_name, "property") == 0) {
682 if (strcasecmp(tt,"yes") == 0) {
683 data_user->property_data->priority = 1;
686 error("priority outside of property");
689 } else if(strcmp(last_element_name, "value") == 0) {
690 last_element2 = g_slist_nth(data_user->element_names, 1);
691 if (!last_element2) {
692 error("Invalid name text");
694 last_element2_name = last_element2->data;
695 if (strcmp(last_element2_name, "property") == 0) {
696 data_user->property_data->values =
697 g_slist_append(data_user->property_data->values, tt);
699 error("value outside of property");
701 } else if(strcmp(last_element_name, "auth") == 0) {
702 if (dle->auth != NULL) {
703 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
704 "XML: multiple text in %s", last_element_name);
708 } else if(strcmp(last_element_name, "level") == 0) {
709 data_user->alevel->level = atoi(tt);
711 } else if (strcmp(last_element_name, "server") == 0) {
712 if (strcasecmp(tt,"no") == 0) {
713 data_user->alevel->server = 0;
714 } else if (strcasecmp(tt,"yes") == 0) {
715 data_user->alevel->server = 1;
717 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
718 "XML: Invalid %s (%s)", last_element_name, tt);
723 } else if(strcmp(last_element_name, "index") == 0) {
724 if (strcasecmp(tt,"no") == 0) {
725 dle->create_index = 0;
726 } else if (strcasecmp(tt,"yes") == 0) {
727 dle->create_index = 1;
729 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
730 "XML: Invalid %s (%s)", last_element_name, tt);
735 } else if(strcmp(last_element_name, "dumpdate") == 0) {
736 if (dle->dumpdate != NULL) {
737 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
738 "XML: multiple text in %s", last_element_name);
743 } else if(strcmp(last_element_name, "record") == 0) {
744 if (strcasecmp(tt, "no") == 0) {
746 } else if (strcasecmp(tt, "yes") == 0) {
749 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
750 "XML: Invalid %s (%s)", last_element_name, tt);
755 } else if(strcmp(last_element_name, "spindle") == 0) {
756 dle->spindle = atoi(tt);
758 } else if(strcmp(last_element_name, "compress") == 0) {
759 if (strcmp(tt, "FAST") == 0) {
760 dle->compress = COMP_FAST;
761 } else if (strcmp(tt, "BEST") == 0) {
762 dle->compress = COMP_BEST;
763 } else if (BSTRNCMP(tt, "CUSTOM") == 0) {
764 dle->compress = COMP_CUST;
765 } else if (strcmp(tt, "SERVER-FAST") == 0) {
766 dle->compress = COMP_SERVER_FAST;
767 } else if (strcmp(tt, "SERVER-BEST") == 0) {
768 dle->compress = COMP_SERVER_BEST;
769 } else if (BSTRNCMP(tt, "SERVER-CUSTOM") == 0) {
770 dle->compress = COMP_SERVER_CUST;
772 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
773 "XML: Invalid %s (%s)", last_element_name, tt);
778 } else if(strcmp(last_element_name, "custom-compress-program") == 0) {
779 if (dle->compprog != NULL) {
780 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
781 "XML: multiple text in %s", last_element_name);
786 } else if(strcmp(last_element_name, "encrypt") == 0) {
787 if (BSTRNCMP(tt,"NO") == 0) {
788 dle->encrypt = ENCRYPT_NONE;
789 } else if (BSTRNCMP(tt, "CUSTOM") == 0) {
790 dle->encrypt = ENCRYPT_CUST;
791 } else if (BSTRNCMP(tt, "SERVER-CUSTOM") == 0) {
792 dle->encrypt = ENCRYPT_SERV_CUST;
794 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
795 "XML: Invalid %s (%s)", last_element_name, tt);
800 } else if(strcmp(last_element_name, "kencrypt") == 0) {
801 if (strcasecmp(tt,"no") == 0) {
803 } else if (strcasecmp(tt,"yes") == 0) {
806 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
807 "XML: Invalid %s (%s)", last_element_name, tt);
812 } else if(strcmp(last_element_name, "custom-encrypt-program") == 0) {
813 last_element2 = g_slist_nth(data_user->element_names, 1);
814 if (!last_element2) {
815 error("XML: optional");
817 last_element2_name = last_element2->data;
818 if (dle->encrypt == ENCRYPT_SERV_CUST)
819 dle->srv_encrypt = tt;
821 dle->clnt_encrypt = tt;
822 } else if(strcmp(last_element_name, "decrypt-option") == 0) {
823 last_element2 = g_slist_nth(data_user->element_names, 1);
824 if (!last_element2) {
825 error("XML: optional");
827 last_element2_name = last_element2->data;
828 if (dle->encrypt == ENCRYPT_SERV_CUST)
829 dle->srv_decrypt_opt = tt;
831 dle->clnt_decrypt_opt = tt;
832 } else if(strcmp(last_element_name, "exclude") == 0 ||
833 strcmp(last_element_name, "include") == 0) {
834 data_user->has_optional = 0;
836 } else if(strcmp(last_element_name, "file") == 0) {
837 last_element2 = g_slist_nth(data_user->element_names, 1);
838 if (!last_element2) {
839 error("XML: optional");
841 last_element2_name = last_element2->data;
842 if (strcmp(last_element2_name, "exclude") == 0) {
843 dle->exclude_file = append_sl(dle->exclude_file, tt);
844 } else if (strcmp(last_element2_name, "include") == 0) {
845 dle->include_file = append_sl(dle->include_file, tt);
849 } else if(strcmp(last_element_name, "list") == 0) {
850 last_element2 = g_slist_nth(data_user->element_names, 1);
851 if (!last_element2) {
852 error("XML: optional");
854 last_element2_name = last_element2->data;
855 if (strcmp(last_element2_name, "exclude") == 0) {
856 dle->exclude_list = append_sl(dle->exclude_list, tt);
857 } else if (strcmp(last_element2_name, "include") == 0) {
858 dle->include_list = append_sl(dle->include_list, tt);
862 } else if(strcmp(last_element_name, "optional") == 0) {
864 last_element2 = g_slist_nth(data_user->element_names, 1);
865 if (!last_element2) {
866 error("XML: optional");
868 last_element2_name = last_element2->data;
869 if (strcmp(last_element2_name, "exclude") == 0) {
870 dle->exclude_optional = 1;
871 } else if (strcmp(last_element2_name, "include") == 0) {
872 dle->include_optional = 1;
874 error("bad optional");
876 data_user->has_optional = 1;
878 } else if(strcmp(last_element_name, "script") == 0) {
880 } else if(strcmp(last_element_name, "execute_on") == 0) {
884 sep = strchr(tt1,',');
887 if (strcmp(tt1,"PRE-AMCHECK") == 0)
888 data_user->script->execute_on |= EXECUTE_ON_PRE_AMCHECK;
889 else if (strcmp(tt1,"PRE-DLE-AMCHECK") == 0)
890 data_user->script->execute_on |= EXECUTE_ON_PRE_DLE_AMCHECK;
891 else if (strcmp(tt1,"PRE-HOST-AMCHECK") == 0)
892 data_user->script->execute_on |= EXECUTE_ON_PRE_HOST_AMCHECK;
893 else if (strcmp(tt1,"POST-AMCHECK") == 0)
894 data_user->script->execute_on |= EXECUTE_ON_POST_AMCHECK;
895 else if (strcmp(tt1,"POST-DLE-AMCHECK") == 0)
896 data_user->script->execute_on |= EXECUTE_ON_POST_DLE_AMCHECK;
897 else if (strcmp(tt1,"POST-HOST-AMCHECK") == 0)
898 data_user->script->execute_on |= EXECUTE_ON_POST_HOST_AMCHECK;
899 else if (strcmp(tt1,"PRE-ESTIMATE") == 0)
900 data_user->script->execute_on |= EXECUTE_ON_PRE_ESTIMATE;
901 else if (strcmp(tt1,"PRE-DLE-ESTIMATE") == 0)
902 data_user->script->execute_on |= EXECUTE_ON_PRE_DLE_ESTIMATE;
903 else if (strcmp(tt1,"PRE-HOST-ESTIMATE") == 0)
904 data_user->script->execute_on |= EXECUTE_ON_PRE_HOST_ESTIMATE;
905 else if (strcmp(tt1,"POST-ESTIMATE") == 0)
906 data_user->script->execute_on |= EXECUTE_ON_POST_ESTIMATE;
907 else if (strcmp(tt1,"POST-DLE-ESTIMATE") == 0)
908 data_user->script->execute_on |= EXECUTE_ON_POST_DLE_ESTIMATE;
909 else if (strcmp(tt1,"POST-HOST-ESTIMATE") == 0)
910 data_user->script->execute_on |= EXECUTE_ON_POST_HOST_ESTIMATE;
911 else if (strcmp(tt1,"PRE-BACKUP") == 0)
912 data_user->script->execute_on |= EXECUTE_ON_PRE_BACKUP;
913 else if (strcmp(tt1,"PRE-DLE-BACKUP") == 0)
914 data_user->script->execute_on |= EXECUTE_ON_PRE_DLE_BACKUP;
915 else if (strcmp(tt1,"PRE-HOST-BACKUP") == 0)
916 data_user->script->execute_on |= EXECUTE_ON_PRE_HOST_BACKUP;
917 else if (strcmp(tt1,"POST-BACKUP") == 0)
918 data_user->script->execute_on |= EXECUTE_ON_POST_BACKUP;
919 else if (strcmp(tt1,"POST-DLE-BACKUP") == 0)
920 data_user->script->execute_on |= EXECUTE_ON_POST_DLE_BACKUP;
921 else if (strcmp(tt1,"POST-HOST-BACKUP") == 0)
922 data_user->script->execute_on |= EXECUTE_ON_POST_HOST_BACKUP;
923 else if (strcmp(tt1,"PRE-RECOVER") == 0)
924 data_user->script->execute_on |= EXECUTE_ON_PRE_RECOVER;
925 else if (strcmp(tt1,"POST-RECOVER") == 0)
926 data_user->script->execute_on |= EXECUTE_ON_POST_RECOVER;
927 else if (strcmp(tt1,"PRE-LEVEL-RECOVER") == 0)
928 data_user->script->execute_on |= EXECUTE_ON_PRE_LEVEL_RECOVER;
929 else if (strcmp(tt1,"POST-LEVEL-RECOVER") == 0)
930 data_user->script->execute_on |= EXECUTE_ON_POST_LEVEL_RECOVER;
931 else if (strcmp(tt1,"INTER-LEVEL-RECOVER") == 0)
932 data_user->script->execute_on |= EXECUTE_ON_INTER_LEVEL_RECOVER;
934 dbprintf("BAD EXECUTE_ON: %s\n", tt1);
939 } else if(strcmp(last_element_name, "execute_where") == 0) {
940 if (strcmp(tt, "CLIENT") == 0) {
941 data_user->script->execute_where = ES_CLIENT;
943 data_user->script->execute_where = ES_SERVER;
946 } else if(strcmp(last_element_name, "datapath") == 0) {
947 if (strcmp(tt, "AMANDA") == 0) {
948 dle->data_path = DATA_PATH_AMANDA;
949 } else if (strcmp(tt, "DIRECTTCP") == 0) {
950 dle->data_path = DATA_PATH_DIRECTTCP;
952 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
953 "XML: bad datapath value '%s'", tt);
956 } else if(strcmp(last_element_name, "directtcp") == 0) {
957 dle->directtcp_list = g_slist_append(dle->directtcp_list, tt);
958 } else if(strcmp(last_element_name, "client_name") == 0) {
959 last_element2 = g_slist_nth(data_user->element_names, 1);
960 if (!last_element2) {
961 error("Invalid client_name text");
963 last_element2_name = last_element2->data;
964 if (strcmp(last_element2_name, "backup-program") == 0) {
965 dle->application_client_name = tt;
966 g_debug("set dle->application_client_name: %s", dle->application_client_name);
967 } else if (strcmp(last_element2_name, "script") == 0) {
968 data_user->script->client_name = tt;
969 g_debug("set data_user->script->client_name: %s", data_user->script->client_name);
971 error("client_name outside of script or backup-program");
974 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
975 "XML: amtext not defined for '%s'", last_element_name);
982 amxml_parse_node_CHAR(
986 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};
987 GMarkupParser parser = {&amstart_element, &amend_element, &amtext,
989 GMarkupParseFlags flags = 0;
990 GMarkupParseContext *context;
991 GError *gerror = NULL;
995 context = g_markup_parse_context_new(&parser, flags, &amgxml, NULL);
997 g_markup_parse_context_parse(context, txt, strlen(txt), &gerror);
999 g_markup_parse_context_end_parse(context, &gerror);
1000 g_markup_parse_context_free(context);
1003 *errmsg = stralloc(gerror->message);
1004 g_error_free(gerror);
1011 amxml_parse_node_FILE(
1015 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};
1016 GMarkupParser parser = {&amstart_element, &amend_element, &amtext,
1018 GMarkupParseFlags flags = 0;
1019 GMarkupParseContext *context;
1020 GError *gerror = NULL;
1025 context = g_markup_parse_context_new(&parser, flags, &amgxml, NULL);
1027 while ((line = agets(file)) != NULL && !gerror) {
1028 g_markup_parse_context_parse(context, line, strlen(line), &gerror);
1032 g_markup_parse_context_end_parse(context, &gerror);
1033 g_markup_parse_context_free(context);
1036 *errmsg = stralloc(gerror->message);
1037 g_error_free(gerror);
1054 quoted_value = malloc(strlen(value)+1);
1057 for(c=value; *c != '\0'; c++) {
1058 // Check include negative value, with the 8th bit set.
1060 (unsigned char)*c > 127 ||
1080 base64_encode_alloc(value, strlen(value), &b64value);
1081 result = vstralloc("<", tag,
1082 " encoding=\"raw\" raw=\"", b64value, "\">",
1088 result = vstralloc("<", tag, ">",
1093 amfree(quoted_value);