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
40 typedef struct amgxml_s {
43 GSList *element_names;
54 int has_backup_program;
58 property_t *property_data;
72 dle = malloc(sizeof(dle_t));
83 dle->program_is_application_api = 0;
89 dle->compress = COMP_NONE;
90 dle->encrypt = ENCRYPT_NONE;
95 dle->srv_encrypt = NULL;
96 dle->clnt_encrypt = NULL;
97 dle->srv_decrypt_opt = NULL;
98 dle->clnt_decrypt_opt = NULL;
99 dle->create_index = 0;
101 dle->exclude_file = NULL;
102 dle->exclude_list = NULL;
103 dle->include_file = NULL;
104 dle->include_list = NULL;
105 dle->exclude_optional = 0;
106 dle->include_optional = 0;
107 dle->application_property = NULL;
108 dle->scriptlist = NULL;
113 /* Called for open tags <foo bar="baz"> */
114 static void amstart_element(GMarkupParseContext *context,
115 const gchar *element_name,
116 const gchar **attribute_names,
117 const gchar **attribute_values,
121 /* Called for close tags </foo> */
122 static void amend_element(GMarkupParseContext *context,
123 const gchar *element_name,
127 /* Called for character data */
128 /* text is not nul-terminated */
129 static void amtext(GMarkupParseContext *context,
135 /* Called for open tags <foo bar="baz"> */
138 G_GNUC_UNUSED GMarkupParseContext *context,
139 const gchar *element_name,
140 G_GNUC_UNUSED const gchar **attribute_names,
141 G_GNUC_UNUSED const gchar **attribute_values,
145 amgxml_t *data_user = user_data;
147 GSList *last_element = data_user->element_names;
148 char *last_element_name = NULL;
149 dle_t *dle = data_user->dle;
150 const gchar **at_names, **at_values;
153 last_element_name = last_element->data;
155 data_user->raw = NULL;
156 data_user->encoding = NULL;
158 if (attribute_names) {
159 for(at_names = attribute_names, at_values = attribute_values;
160 *at_names != NULL && at_values != NULL;
161 at_names++, at_values++) {
162 if (strcmp(*at_names, "encoding") == 0) {
163 data_user->encoding = stralloc(*at_values);
164 } else if (strcmp(*at_names, "raw") == 0) {
165 data_user->raw = base64_decode_alloc_string((char *)*at_values);
167 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
168 "XML: Invalid attribute '%s' for %s element",
169 *at_names, element_name);
175 if (strcmp(element_name, "dle") == 0) {
176 if (last_element != NULL) {
177 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
178 "XML: Invalid dle element");
181 for(adle = data_user->dles; adle != NULL && adle->next != NULL;
183 data_user->dle = alloc_dle();
185 data_user->dles = data_user->dle;
187 adle->next = data_user->dle;
189 data_user->has_calcsize = 0;
190 data_user->has_estimate = 0;
191 data_user->has_record = 0;
192 data_user->has_spindle = 0;
193 data_user->has_compress = 0;
194 data_user->has_encrypt = 0;
195 data_user->has_kencrypt = 0;
196 data_user->has_exclude = 0;
197 data_user->has_include = 0;
198 data_user->has_index = 0;
199 data_user->has_backup_program = 0;
200 data_user->has_plugin = 0;
201 data_user->has_optional = 0;
202 data_user->property_name = NULL;
203 data_user->property_data = NULL;
204 } else if(strcmp(element_name, "disk" ) == 0 ||
205 strcmp(element_name, "diskdevice" ) == 0 ||
206 strcmp(element_name, "calcsize" ) == 0 ||
207 strcmp(element_name, "estimate" ) == 0 ||
208 strcmp(element_name, "program" ) == 0 ||
209 strcmp(element_name, "auth" ) == 0 ||
210 strcmp(element_name, "index" ) == 0 ||
211 strcmp(element_name, "dumpdate" ) == 0 ||
212 strcmp(element_name, "level" ) == 0 ||
213 strcmp(element_name, "record" ) == 0 ||
214 strcmp(element_name, "spindle" ) == 0 ||
215 strcmp(element_name, "compress" ) == 0 ||
216 strcmp(element_name, "encrypt" ) == 0 ||
217 strcmp(element_name, "kencrypt" ) == 0 ||
218 strcmp(element_name, "exclude" ) == 0 ||
219 strcmp(element_name, "include" ) == 0) {
220 if (strcmp(last_element_name, "dle") != 0) {
221 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
222 "XML: Invalid %s element", element_name);
225 if ((strcmp(element_name, "disk" ) == 0 && dle->disk) ||
226 (strcmp(element_name, "diskdevice" ) == 0 && dle->device) ||
227 (strcmp(element_name, "calcsize" ) == 0 && data_user->has_calcsize) ||
228 (strcmp(element_name, "estimate" ) == 0 && data_user->has_estimate) ||
229 (strcmp(element_name, "record" ) == 0 && data_user->has_record) ||
230 (strcmp(element_name, "spindle" ) == 0 && data_user->has_spindle) ||
231 (strcmp(element_name, "program" ) == 0 && dle->program) ||
232 (strcmp(element_name, "auth" ) == 0 && dle->auth) ||
233 (strcmp(element_name, "index" ) == 0 && data_user->has_index) ||
234 (strcmp(element_name, "dumpdate" ) == 0 && dle->dumpdate) ||
235 (strcmp(element_name, "compress" ) == 0 && data_user->has_compress) ||
236 (strcmp(element_name, "encrypt" ) == 0 && data_user->has_encrypt) ||
237 (strcmp(element_name, "kencrypt" ) == 0 && data_user->has_kencrypt) ||
238 (strcmp(element_name, "exclude" ) == 0 && data_user->has_exclude) ||
239 (strcmp(element_name, "include" ) == 0 && data_user->has_include)) {
240 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
241 "XML: Duplicate %s element", element_name);
244 if (strcmp(element_name, "calcsize" ) == 0) data_user->has_calcsize = 1;
245 if (strcmp(element_name, "estimate" ) == 0) data_user->has_estimate = 1;
246 if (strcmp(element_name, "record" ) == 0) data_user->has_record = 1;
247 if (strcmp(element_name, "spindle" ) == 0) data_user->has_spindle = 1;
248 if (strcmp(element_name, "index" ) == 0) data_user->has_index = 1;
249 if (strcmp(element_name, "compress" ) == 0) data_user->has_compress = 1;
250 if (strcmp(element_name, "encrypt" ) == 0) data_user->has_encrypt = 1;
251 if (strcmp(element_name, "kencrypt" ) == 0) data_user->has_kencrypt = 1;
252 if (strcmp(element_name, "exclude" ) == 0) data_user->has_exclude = 1;
253 if (strcmp(element_name, "include" ) == 0) data_user->has_include = 1;
254 if (strcmp(element_name, "exclude") == 0 || strcmp(element_name, "include") == 0)
255 data_user->has_optional = 0;
256 } else if(strcmp(element_name, "custom-compress-program") == 0) {
257 if (strcmp(last_element_name, "compress") != 0) {
258 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
259 "XML: Invalid %s element", element_name);
263 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
264 "XML: Duplicate %s element", element_name);
267 } else if (strcmp(element_name, "custom-encrypt-program") == 0 ||
268 strcmp(element_name, "decrypt-option") == 0) {
269 if (strcmp(last_element_name, "encrypt") != 0) {
270 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
271 "XML: Invalid %s element", element_name);
274 if (strcmp(element_name, "custom-encrypt-program") == 0 &&
276 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
277 "XML: Duplicate %s element", element_name);
280 if (strcmp(element_name, "decrypt-option") == 0 &&
281 dle->clnt_decrypt_opt) {
282 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
283 "XML: Duplicate %s element", element_name);
286 } else if(strcmp(element_name, "plugin") == 0) {
287 if (strcmp(last_element_name, "backup-program") != 0 &&
288 strcmp(last_element_name, "script") != 0) {
289 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
290 "XML: Invalid %s element", element_name);
293 if (data_user->has_plugin) {
294 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
295 "XML: Duplicate %s element in '%s'", element_name,
299 } else if(strcmp(element_name, "property") == 0) {
300 if (strcmp(last_element_name, "backup-program") != 0 &&
301 strcmp(last_element_name, "script") != 0) {
302 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
303 "XML: Invalid %s element", element_name);
306 data_user->property_data = malloc(sizeof(property_t));
307 data_user->property_data->append = 0;
308 data_user->property_data->priority = 0;
309 data_user->property_data->values = NULL;
310 } else if(strcmp(element_name, "name") == 0) {
311 if (strcmp(last_element_name, "property") != 0) {
312 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
313 "XML: Invalid %s element", element_name);
316 if (data_user->property_name) {
317 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
318 "XML: Duplicate %s element in '%s'", element_name,
322 } else if(strcmp(element_name, "priority") == 0) {
323 if (strcmp(last_element_name, "property") != 0) {
324 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
325 "XML: Invalid %s element", element_name);
328 } else if(strcmp(element_name, "value") == 0) {
329 if (strcmp(last_element_name, "property") != 0) {
330 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
331 "XML: Invalid %s element", element_name);
334 } else if(strcmp(element_name, "file") == 0 ||
335 strcmp(element_name, "list") == 0 ||
336 strcmp(element_name, "optional") == 0) {
337 if (strcmp(last_element_name, "exclude") != 0 &&
338 strcmp(last_element_name, "include") != 0) {
339 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
340 "XML: Invalid %s element", element_name);
343 if (strcmp(element_name, "optional") == 0 && data_user->has_optional) {
344 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
345 "XML: Duplicate %s element", element_name);
348 if (strcmp(element_name, "optional") == 0) data_user->has_optional = 1;
349 } else if (strcmp(element_name, "backup-program") == 0) {
350 if (data_user->has_backup_program) {
351 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
352 "XML: Duplicate %s element", element_name);
355 data_user->has_backup_program = 1;
356 data_user->property =
357 g_hash_table_new_full(g_str_hash, g_str_equal, NULL, NULL);
358 data_user->has_plugin = 0;
360 } else if (strcmp(element_name, "script") == 0) {
361 data_user->property =
362 g_hash_table_new_full(g_str_hash, g_str_equal, NULL, NULL);
363 data_user->script = malloc(sizeof(script_t));
364 data_user->script->plugin = NULL;
365 data_user->script->execute_on = 0;
366 data_user->script->execute_where = ES_CLIENT;
367 data_user->script->property = NULL;
368 data_user->script->result = NULL;
369 data_user->has_plugin = 0;
370 } else if (strcmp(element_name, "execute_on") == 0) {
371 } else if (strcmp(element_name, "execute_where") == 0) {
373 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
374 "XML: Invalid %s element", element_name);
377 data_user->element_names = g_slist_prepend(data_user->element_names,
378 stralloc(element_name));
381 /* Called for close tags </foo> */
384 G_GNUC_UNUSED GMarkupParseContext *context,
385 const gchar *element_name,
389 amgxml_t *data_user = user_data;
390 GSList *last_element = data_user->element_names;
391 char *last_element_name = NULL;
392 dle_t *dle = data_user->dle;
395 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
396 "XML: Invalid closing tag");
399 last_element_name = last_element->data;
400 if (strcmp(last_element_name, element_name) != 0) {
401 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
402 "XML: Invalid closing tag '%s'", element_name);
406 if (strcmp(element_name, "property") == 0) {
407 g_hash_table_insert(data_user->property,
408 data_user->property_name,
409 data_user->property_data);
410 data_user->property_name = NULL;
411 data_user->property_data = NULL;
412 } else if (strcmp(element_name, "dle") == 0) {
413 if (dle->disk == NULL) {
414 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
415 "XML: No disk provided in DLE element");
418 if (dle->program_is_application_api &&
420 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
421 "XML: program set to APPLICATION but no application set");
424 if (dle->device == NULL && dle->disk)
425 dle->device = stralloc(dle->disk);
426 /* Add check of required field */
427 data_user->dle = NULL;
428 } else if (strcmp(element_name, "backup-program") == 0) {
429 if (dle->program == NULL) {
430 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
431 "XML: No plugin set for application");
434 dle->application_property = data_user->property;
435 data_user->property = NULL;
436 } else if (strcmp(element_name, "script") == 0) {
437 if (data_user->script->plugin == NULL) {
438 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
439 "XML: No plugin set for script");
442 data_user->script->property = data_user->property;
443 data_user->property = NULL;
444 dle->scriptlist = g_slist_append(dle->scriptlist, data_user->script);
445 data_user->script = NULL;
447 g_free(data_user->element_names->data);
448 data_user->element_names = g_slist_delete_link(data_user->element_names,
449 data_user->element_names);
452 /* Called for character data */
453 /* text is not nul-terminated */
456 G_GNUC_UNUSED GMarkupParseContext *context,
463 amgxml_t *data_user = user_data;
464 GSList *last_element = data_user->element_names;
465 char *last_element_name;
466 GSList *last_element2;
467 char *last_element2_name;
468 dle_t *dle = data_user->dle;
472 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
473 "XML: Invalid text");
476 last_element_name = last_element->data;
478 tt = malloc(text_len + 1);
479 strncpy(tt,text,text_len);
482 //check if it is only space
483 if (match_no_newline("^[ \f\n\r\t\v]*$", tt)) {
488 if (data_user->raw) {
490 tt = stralloc(data_user->raw);
493 //check if it is only space
494 if (match_no_newline("^[ \f\n\r\t\v]*$", tt)) {
499 if (strcmp(last_element_name, "dle") == 0 ||
500 strcmp(last_element_name, "backup-program") == 0 ||
501 strcmp(last_element_name, "exclude") == 0 ||
502 strcmp(last_element_name, "include") == 0) {
503 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
504 "XML: %s doesn't have text '%s'", last_element_name, tt);
506 } else if(strcmp(last_element_name, "disk") == 0) {
507 if (dle->disk != NULL) {
508 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
509 "XML: multiple text in %s", last_element_name);
513 } else if(strcmp(last_element_name, "diskdevice") == 0) {
514 if (dle->device != NULL) {
515 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
516 "XML: multiple text in %s", last_element_name);
520 } else if(strcmp(last_element_name, "calcsize") == 0) {
521 if (strcasecmp(tt,"yes") == 0) {
525 } else if(strcmp(last_element_name, "estimate") == 0) {
526 if (strcasecmp(tt,"client") == 0) {
527 dle->estimate = ES_CLIENT;
528 } else if (strcasecmp(tt,"calcsize") == 0) {
529 dle->estimate = ES_CALCSIZE;
531 } else if (strcasecmp(tt,"server") == 0) {
532 dle->estimate = ES_SERVER;
535 } else if(strcmp(last_element_name, "program") == 0) {
536 if (dle->program != NULL) {
537 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
538 "XML: multiple text in %s", last_element_name);
542 if (strcmp(tt, "APPLICATION") == 0) {
543 dle->program_is_application_api = 1;
546 } else if(strcmp(last_element_name, "plugin") == 0) {
547 last_element2 = g_slist_nth(data_user->element_names, 1);
548 if (!last_element2) {
549 error("Invalid name text");
551 last_element2_name = last_element2->data;
552 if (strcmp(last_element2_name, "backup-program") == 0) {
554 } else if (strcmp(last_element2_name, "script") == 0) {
555 data_user->script->plugin = tt;
557 error("plugin outside of backup-program");
559 data_user->has_plugin = 1;
560 } else if(strcmp(last_element_name, "name") == 0) {
561 last_element2 = g_slist_nth(data_user->element_names, 1);
562 if (!last_element2) {
563 error("Invalid name text");
565 last_element2_name = last_element2->data;
566 if (strcmp(last_element2_name, "property") == 0) {
567 data_user->property_name = tt;
569 error("name outside of property");
571 } else if(strcmp(last_element_name, "priority") == 0) {
572 last_element2 = g_slist_nth(data_user->element_names, 1);
573 if (!last_element2) {
574 error("Invalid priority text");
576 last_element2_name = last_element2->data;
577 if (strcmp(last_element2_name, "property") == 0) {
578 if (strcasecmp(tt,"yes") == 0) {
579 data_user->property_data->priority = 1;
582 error("priority outside of property");
584 } else if(strcmp(last_element_name, "value") == 0) {
585 last_element2 = g_slist_nth(data_user->element_names, 1);
586 if (!last_element2) {
587 error("Invalid name text");
589 last_element2_name = last_element2->data;
590 if (strcmp(last_element2_name, "property") == 0) {
591 data_user->property_data->values =
592 g_slist_append(data_user->property_data->values, tt);
594 error("value outside of property");
596 } else if(strcmp(last_element_name, "auth") == 0) {
597 if (dle->auth != NULL) {
598 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
599 "XML: multiple text in %s", last_element_name);
603 } else if(strcmp(last_element_name, "level") == 0) {
604 dle->level = g_slist_append(dle->level, GINT_TO_POINTER(atoi(tt)));
606 } else if(strcmp(last_element_name, "index") == 0) {
607 if (strcasecmp(tt,"no") == 0) {
608 dle->create_index = 0;
609 } else if (strcasecmp(tt,"yes") == 0) {
610 dle->create_index = 1;
612 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
613 "XML: Invalid %s (%s)", last_element_name, tt);
618 } else if(strcmp(last_element_name, "dumpdate") == 0) {
619 if (dle->dumpdate != NULL) {
620 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
621 "XML: multiple text in %s", last_element_name);
626 } else if(strcmp(last_element_name, "record") == 0) {
627 if (strcasecmp(tt, "no") == 0) {
629 } else if (strcasecmp(tt, "yes") == 0) {
632 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
633 "XML: Invalid %s (%s)", last_element_name, tt);
636 } else if(strcmp(last_element_name, "spindle") == 0) {
637 dle->spindle = atoi(tt);
638 } else if(strcmp(last_element_name, "compress") == 0) {
639 if (strcmp(tt, "FAST") == 0) {
640 dle->compress = COMP_FAST;
641 } else if (strcmp(tt, "BEST") == 0) {
642 dle->compress = COMP_BEST;
643 } else if (BSTRNCMP(tt, "CUSTOM") == 0) {
644 dle->compress = COMP_CUST;
645 } else if (strcmp(tt, "SERVER-FAST") == 0) {
646 dle->compress = COMP_SERVER_FAST;
647 } else if (strcmp(tt, "SERVER-BEST") == 0) {
648 dle->compress = COMP_SERVER_BEST;
649 } else if (BSTRNCMP(tt, "SERVER-CUSTOM") == 0) {
650 dle->compress = COMP_SERVER_CUST;
652 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
653 "XML: Invalid %s (%s)", last_element_name, tt);
658 } else if(strcmp(last_element_name, "custom-compress-program") == 0) {
659 if (dle->compprog != NULL) {
660 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
661 "XML: multiple text in %s", last_element_name);
666 } else if(strcmp(last_element_name, "encrypt") == 0) {
667 if (BSTRNCMP(tt,"NO") == 0) {
668 dle->encrypt = ENCRYPT_NONE;
669 } else if (BSTRNCMP(tt, "CUSTOM") == 0) {
670 dle->encrypt = ENCRYPT_CUST;
671 } else if (BSTRNCMP(tt, "SERVER-CUSTOM") == 0) {
672 dle->encrypt = ENCRYPT_SERV_CUST;
674 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
675 "XML: Invalid %s (%s)", last_element_name, tt);
680 } else if(strcmp(last_element_name, "kencrypt") == 0) {
681 if (strcasecmp(tt,"no") == 0) {
683 } else if (strcasecmp(tt,"yes") == 0) {
686 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
687 "XML: Invalid %s (%s)", last_element_name, tt);
692 } else if(strcmp(last_element_name, "custom-encrypt-program") == 0) {
693 last_element2 = g_slist_nth(data_user->element_names, 1);
694 if (!last_element2) {
695 error("XML: optional");
697 last_element2_name = last_element2->data;
698 dle->clnt_encrypt = tt;
699 } else if(strcmp(last_element_name, "decrypt-option") == 0) {
700 last_element2 = g_slist_nth(data_user->element_names, 1);
701 if (!last_element2) {
702 error("XML: optional");
704 last_element2_name = last_element2->data;
705 dle->clnt_decrypt_opt = tt;
706 } else if(strcmp(last_element_name, "exclude") == 0 ||
707 strcmp(last_element_name, "include") == 0) {
708 data_user->has_optional = 0;
709 } else if(strcmp(last_element_name, "file") == 0) {
710 last_element2 = g_slist_nth(data_user->element_names, 1);
711 if (!last_element2) {
712 error("XML: optional");
714 last_element2_name = last_element2->data;
715 if (strcmp(last_element2_name, "exclude") == 0) {
716 dle->exclude_file = append_sl(dle->exclude_file, tt);
717 } else if (strcmp(last_element2_name, "include") == 0) {
718 dle->include_file = append_sl(dle->include_file, tt);
722 } else if(strcmp(last_element_name, "list") == 0) {
723 last_element2 = g_slist_nth(data_user->element_names, 1);
724 if (!last_element2) {
725 error("XML: optional");
727 last_element2_name = last_element2->data;
728 if (strcmp(last_element2_name, "exclude") == 0) {
729 dle->exclude_list = append_sl(dle->exclude_list, tt);
730 } else if (strcmp(last_element2_name, "include") == 0) {
731 dle->include_list = append_sl(dle->include_list, tt);
735 } else if(strcmp(last_element_name, "optional") == 0) {
737 last_element2 = g_slist_nth(data_user->element_names, 1);
738 if (!last_element2) {
739 error("XML: optional");
741 last_element2_name = last_element2->data;
742 if (strcmp(last_element2_name, "exclude") == 0) {
743 dle->exclude_optional = 1;
744 } else if (strcmp(last_element2_name, "include") == 0) {
745 dle->include_optional = 1;
747 error("bad optional");
749 data_user->has_optional = 1;
751 } else if(strcmp(last_element_name, "script") == 0) {
752 } else if(strcmp(last_element_name, "execute_on") == 0) {
756 sep = strchr(tt1,',');
759 if (strcmp(tt1,"PRE-DLE-AMCHECK") == 0)
760 data_user->script->execute_on |= EXECUTE_ON_PRE_DLE_AMCHECK;
761 else if (strcmp(tt1,"PRE-HOST-AMCHECK") == 0)
762 data_user->script->execute_on |= EXECUTE_ON_PRE_HOST_AMCHECK;
763 else if (strcmp(tt1,"POST-DLE-AMCHECK") == 0)
764 data_user->script->execute_on |= EXECUTE_ON_POST_DLE_AMCHECK;
765 else if (strcmp(tt1,"POST-HOST-AMCHECK") == 0)
766 data_user->script->execute_on |= EXECUTE_ON_POST_HOST_AMCHECK;
767 else if (strcmp(tt1,"PRE-DLE-ESTIMATE") == 0)
768 data_user->script->execute_on |= EXECUTE_ON_PRE_DLE_ESTIMATE;
769 else if (strcmp(tt1,"PRE-HOST-ESTIMATE") == 0)
770 data_user->script->execute_on |= EXECUTE_ON_PRE_HOST_ESTIMATE;
771 else if (strcmp(tt1,"POST-DLE-ESTIMATE") == 0)
772 data_user->script->execute_on |= EXECUTE_ON_POST_DLE_ESTIMATE;
773 else if (strcmp(tt1,"POST-HOST-ESTIMATE") == 0)
774 data_user->script->execute_on |= EXECUTE_ON_POST_HOST_ESTIMATE;
775 else if (strcmp(tt1,"PRE-DLE-BACKUP") == 0)
776 data_user->script->execute_on |= EXECUTE_ON_PRE_DLE_BACKUP;
777 else if (strcmp(tt1,"PRE-HOST-BACKUP") == 0)
778 data_user->script->execute_on |= EXECUTE_ON_PRE_HOST_BACKUP;
779 else if (strcmp(tt1,"POST-DLE-BACKUP") == 0)
780 data_user->script->execute_on |= EXECUTE_ON_POST_DLE_BACKUP;
781 else if (strcmp(tt1,"POST-HOST-BACKUP") == 0)
782 data_user->script->execute_on |= EXECUTE_ON_POST_HOST_BACKUP;
783 else if (strcmp(tt1,"PRE-RECOVER") == 0)
784 data_user->script->execute_on |= EXECUTE_ON_PRE_RECOVER;
785 else if (strcmp(tt1,"POST-RECOVER") == 0)
786 data_user->script->execute_on |= EXECUTE_ON_POST_RECOVER;
787 else if (strcmp(tt1,"PRE-LEVEL-RECOVER") == 0)
788 data_user->script->execute_on |= EXECUTE_ON_PRE_LEVEL_RECOVER;
789 else if (strcmp(tt1,"POST-LEVEL-RECOVER") == 0)
790 data_user->script->execute_on |= EXECUTE_ON_POST_LEVEL_RECOVER;
791 else if (strcmp(tt1,"INTER-LEVEL-RECOVER") == 0)
792 data_user->script->execute_on |= EXECUTE_ON_INTER_LEVEL_RECOVER;
794 dbprintf("BAD EXECUTE_ON: %s\n", tt1);
799 } else if(strcmp(last_element_name, "execute_where") == 0) {
800 if (strcmp(tt, "CLIENT") == 0) {
801 data_user->script->execute_where = ES_CLIENT;
803 data_user->script->execute_where = ES_SERVER;
806 g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
807 "XML: amtext not defined for '%s'", last_element_name);
813 amxml_parse_node_CHAR(
817 amgxml_t amgxml = {NULL, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL};
818 GMarkupParser parser = {&amstart_element, &amend_element, &amtext,
820 GMarkupParseFlags flags = 0;
821 GMarkupParseContext *context;
822 GError *gerror = NULL;
826 context = g_markup_parse_context_new(&parser, flags, &amgxml, NULL);
828 g_markup_parse_context_parse(context, txt, strlen(txt), &gerror);
830 g_markup_parse_context_end_parse(context, &gerror);
831 g_markup_parse_context_free(context);
834 *errmsg = stralloc(gerror->message);
835 g_error_free(gerror);
842 amxml_parse_node_FILE(
846 amgxml_t amgxml = {NULL, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL};
847 GMarkupParser parser = {&amstart_element, &amend_element, &amtext,
849 GMarkupParseFlags flags = 0;
850 GMarkupParseContext *context;
851 GError *gerror = NULL;
856 context = g_markup_parse_context_new(&parser, flags, &amgxml, NULL);
858 while ((line = agets(file)) != NULL && !gerror) {
859 g_markup_parse_context_parse(context, line, strlen(line), &gerror);
863 g_markup_parse_context_end_parse(context, &gerror);
864 g_markup_parse_context_free(context);
867 *errmsg = stralloc(gerror->message);
868 g_error_free(gerror);
885 quoted_value = malloc(strlen(value)+1);
888 for(c=value; *c != '\0'; c++) {
889 // Check include negative value, with the 8th bit set.
891 (unsigned char)*c > 127 ||
911 base64_encode_alloc(value, strlen(value), &b64value);
912 result = vstralloc("<", tag,
913 " encoding=\"raw\" raw=\"", b64value, "\">",
919 result = vstralloc("<", tag, ">",
924 amfree(quoted_value);