X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=common-src%2Famxml.c;h=ba7f951923af8dbaee4fe20f3eeca60b836253aa;hb=d28952249e392eb31bc8eecc53f6c477f30c617b;hp=b6e96c41c9e07117dbe36f3095eb9d17675a5ffc;hpb=2627875b7d18858bc1f9f7652811e4d8c15a23eb;p=debian%2Famanda diff --git a/common-src/amxml.c b/common-src/amxml.c index b6e96c4..ba7f951 100644 --- a/common-src/amxml.c +++ b/common-src/amxml.c @@ -1,6 +1,7 @@ /* * Amanda, The Advanced Maryland Automatic Network Disk Archiver * Copyright (c) 1991-1998 University of Maryland at College Park + * Copyright (c) 2007-2012 Zmanda, Inc. All Rights Reserved. * All Rights Reserved. * * Permission to use, copy, modify, distribute, and sell this software and its @@ -33,6 +34,7 @@ #include "amanda.h" #include "util.h" #include "amxml.h" +#include "match.h" #include "glib.h" #include "conffile.h" #include "base64.h" @@ -48,6 +50,7 @@ typedef struct amgxml_s { int has_compress; int has_encrypt; int has_kencrypt; + int has_datapath; int has_exclude; int has_include; int has_index; @@ -58,9 +61,9 @@ typedef struct amgxml_s { property_t *property_data; proplist_t property; script_t *script; + am_level_t *alevel; char *encoding; char *raw; - } amgxml_t; @@ -74,6 +77,52 @@ alloc_dle(void) return dle; } +void +free_dle( + dle_t *dle) +{ + scriptlist_t scriptlist; + + amfree(dle->disk); + amfree(dle->device); + amfree(dle->program); + g_slist_free(dle->estimatelist); + slist_free_full(dle->levellist, g_free); + amfree(dle->dumpdate); + amfree(dle->compprog); + amfree(dle->srv_encrypt); + amfree(dle->clnt_encrypt); + amfree(dle->srv_decrypt_opt); + amfree(dle->clnt_decrypt_opt); + amfree(dle->auth); + amfree(dle->application_client_name); + free_sl(dle->exclude_file); + free_sl(dle->exclude_list); + free_sl(dle->include_file); + free_sl(dle->include_list); + if (dle->property) + g_hash_table_destroy(dle->property); + if (dle->application_property) + g_hash_table_destroy(dle->application_property); + for(scriptlist = dle->scriptlist; scriptlist != NULL; + scriptlist = scriptlist->next) { + free_script_data((script_t *)scriptlist->data); + } + slist_free_full(dle->scriptlist, g_free); + slist_free_full(dle->directtcp_list, g_free); + amfree(dle); +} + +void +free_script_data( + script_t *script) +{ + amfree(script->plugin); + amfree(script->client_name); + if (script->property) + g_hash_table_destroy(script->property); +} + void init_dle( dle_t *dle) @@ -82,14 +131,13 @@ init_dle( dle->device = NULL; dle->program_is_application_api = 0; dle->program = NULL; - dle->calcsize = 0; - dle->estimate = 0; + dle->estimatelist = NULL; dle->record = 1; dle->spindle = 0; dle->compress = COMP_NONE; dle->encrypt = ENCRYPT_NONE; dle->kencrypt = 0; - dle->level = NULL; + dle->levellist = NULL; dle->dumpdate = NULL; dle->compprog = NULL; dle->srv_encrypt = NULL; @@ -104,8 +152,12 @@ init_dle( dle->include_list = NULL; dle->exclude_optional = 0; dle->include_optional = 0; + dle->property = NULL; dle->application_property = NULL; dle->scriptlist = NULL; + dle->data_path = DATA_PATH_AMANDA; + dle->directtcp_list = NULL; + dle->application_client_name = NULL; dle->next = NULL; } @@ -193,6 +245,7 @@ amstart_element( data_user->has_compress = 0; data_user->has_encrypt = 0; data_user->has_kencrypt = 0; + data_user->has_datapath = 0; data_user->has_exclude = 0; data_user->has_include = 0; data_user->has_index = 0; @@ -201,6 +254,13 @@ amstart_element( data_user->has_optional = 0; data_user->property_name = NULL; data_user->property_data = NULL; + data_user->property = + g_hash_table_new_full(g_str_hash, g_str_equal, &g_free, &free_property_t); + data_user->script = NULL; + data_user->alevel = NULL; + data_user->dle->property = data_user->property; + data_user->encoding = NULL; + data_user->raw = NULL; } else if(strcmp(element_name, "disk" ) == 0 || strcmp(element_name, "diskdevice" ) == 0 || strcmp(element_name, "calcsize" ) == 0 || @@ -215,6 +275,7 @@ amstart_element( strcmp(element_name, "compress" ) == 0 || strcmp(element_name, "encrypt" ) == 0 || strcmp(element_name, "kencrypt" ) == 0 || + strcmp(element_name, "datapath" ) == 0 || strcmp(element_name, "exclude" ) == 0 || strcmp(element_name, "include" ) == 0) { if (strcmp(last_element_name, "dle") != 0) { @@ -235,6 +296,7 @@ amstart_element( (strcmp(element_name, "compress" ) == 0 && data_user->has_compress) || (strcmp(element_name, "encrypt" ) == 0 && data_user->has_encrypt) || (strcmp(element_name, "kencrypt" ) == 0 && data_user->has_kencrypt) || + (strcmp(element_name, "datapath" ) == 0 && data_user->has_datapath) || (strcmp(element_name, "exclude" ) == 0 && data_user->has_exclude) || (strcmp(element_name, "include" ) == 0 && data_user->has_include)) { g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, @@ -248,11 +310,21 @@ amstart_element( if (strcmp(element_name, "index" ) == 0) data_user->has_index = 1; if (strcmp(element_name, "compress" ) == 0) data_user->has_compress = 1; if (strcmp(element_name, "encrypt" ) == 0) data_user->has_encrypt = 1; - if (strcmp(element_name, "kencrypt" ) == 0) data_user->has_kencrypt = 1; + if (strcmp(element_name, "kencrypt" ) == 0) data_user->has_kencrypt = 1; + if (strcmp(element_name, "datapath" ) == 0) data_user->has_datapath = 1; if (strcmp(element_name, "exclude" ) == 0) data_user->has_exclude = 1; if (strcmp(element_name, "include" ) == 0) data_user->has_include = 1; if (strcmp(element_name, "exclude") == 0 || strcmp(element_name, "include") == 0) data_user->has_optional = 0; + if (strcmp(element_name, "level") == 0) { + data_user->alevel = g_new0(am_level_t, 1); + } + } else if (strcmp(element_name, "server") == 0) { + if (strcmp(last_element_name, "level") != 0) { + g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, + "XML: Invalid %s element", element_name); + return; + } } else if(strcmp(element_name, "custom-compress-program") == 0) { if (strcmp(last_element_name, "compress") != 0) { g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, @@ -297,8 +369,10 @@ amstart_element( return; } } else if(strcmp(element_name, "property") == 0) { - if (strcmp(last_element_name, "backup-program") != 0 && - strcmp(last_element_name, "script") != 0) { + if (!last_element || + (strcmp(last_element_name, "backup-program") != 0 && + strcmp(last_element_name, "script") != 0 && + strcmp(last_element_name, "dle") != 0)) { g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, "XML: Invalid %s element", element_name); return; @@ -354,21 +428,29 @@ amstart_element( } else { data_user->has_backup_program = 1; data_user->property = - g_hash_table_new_full(g_str_hash, g_str_equal, NULL, NULL); + g_hash_table_new_full(g_str_hash, g_str_equal, &g_free, &free_property_t); data_user->has_plugin = 0; } } else if (strcmp(element_name, "script") == 0) { data_user->property = - g_hash_table_new_full(g_str_hash, g_str_equal, NULL, NULL); + g_hash_table_new_full(g_str_hash, g_str_equal, &g_free, &free_property_t); data_user->script = malloc(sizeof(script_t)); data_user->script->plugin = NULL; data_user->script->execute_on = 0; data_user->script->execute_where = ES_CLIENT; data_user->script->property = NULL; + data_user->script->client_name = NULL; data_user->script->result = NULL; data_user->has_plugin = 0; } else if (strcmp(element_name, "execute_on") == 0) { } else if (strcmp(element_name, "execute_where") == 0) { + } else if (strcmp(element_name, "directtcp") == 0) { + if (strcmp(last_element_name, "datapath") != 0) { + g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, + "XML: Invalid %s element", element_name); + return; + } + } else if (strcmp(element_name, "client_name") == 0) { } else { g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, "XML: Invalid %s element", element_name); @@ -410,11 +492,6 @@ amend_element( data_user->property_name = NULL; data_user->property_data = NULL; } else if (strcmp(element_name, "dle") == 0) { - if (dle->disk == NULL) { - g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, - "XML: No disk provided in DLE element"); - return; - } if (dle->program_is_application_api && !dle->program) { g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, @@ -423,7 +500,10 @@ amend_element( } if (dle->device == NULL && dle->disk) dle->device = stralloc(dle->disk); + if (dle->estimatelist == NULL) + dle->estimatelist = g_slist_append(dle->estimatelist, ES_CLIENT); /* Add check of required field */ + data_user->property = NULL; data_user->dle = NULL; } else if (strcmp(element_name, "backup-program") == 0) { if (dle->program == NULL) { @@ -432,7 +512,7 @@ amend_element( return; } dle->application_property = data_user->property; - data_user->property = NULL; + data_user->property = dle->property; } else if (strcmp(element_name, "script") == 0) { if (data_user->script->plugin == NULL) { g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, @@ -440,9 +520,12 @@ amend_element( return; } data_user->script->property = data_user->property; - data_user->property = NULL; + data_user->property = dle->property; dle->scriptlist = g_slist_append(dle->scriptlist, data_user->script); data_user->script = NULL; + } else if (strcmp(element_name, "level") == 0) { + dle->levellist = g_slist_append(dle->levellist, data_user->alevel); + data_user->alevel = NULL; } g_free(data_user->element_names->data); data_user->element_names = g_slist_delete_link(data_user->element_names, @@ -466,7 +549,6 @@ amtext( GSList *last_element2; char *last_element2_name; dle_t *dle = data_user->dle; - int i; if (!last_element) { g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, @@ -475,7 +557,7 @@ amtext( } last_element_name = last_element->data; - tt = malloc(text_len + 1); + tt = malloc(text_len + 8 + 1); strncpy(tt,text,text_len); tt[text_len] = '\0'; @@ -488,6 +570,14 @@ amtext( if (data_user->raw) { amfree(tt); tt = stralloc(data_user->raw); + } else if (strlen(tt) > 0) { + /* remove trailing space */ + char *ttt = tt + strlen(tt) - 1; + while(*ttt == ' ') { + ttt--; + } + ttt++; + *ttt = '\0'; } //check if it is only space @@ -502,11 +592,13 @@ amtext( strcmp(last_element_name, "include") == 0) { g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, "XML: %s doesn't have text '%s'", last_element_name, tt); + amfree(tt); return; } else if(strcmp(last_element_name, "disk") == 0) { if (dle->disk != NULL) { g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, "XML: multiple text in %s", last_element_name); + amfree(tt); return; } dle->disk = tt; @@ -514,34 +606,54 @@ amtext( if (dle->device != NULL) { g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, "XML: multiple text in %s", last_element_name); + amfree(tt); return; } dle->device = tt; } else if(strcmp(last_element_name, "calcsize") == 0) { if (strcasecmp(tt,"yes") == 0) { - dle->calcsize = 1; + dle->estimatelist = g_slist_append(dle->estimatelist, + GINT_TO_POINTER(ES_CALCSIZE)); } amfree(tt); } else if(strcmp(last_element_name, "estimate") == 0) { - if (strcasecmp(tt,"client") == 0) { - dle->estimate = ES_CLIENT; - } else if (strcasecmp(tt,"calcsize") == 0) { - dle->estimate = ES_CALCSIZE; - dle->calcsize = 1; - } else if (strcasecmp(tt,"server") == 0) { - dle->estimate = ES_SERVER; + char *ttt = tt; + while (strlen(ttt) > 0) { + if (BSTRNCMP(ttt,"CLIENT") == 0) { + dle->estimatelist = g_slist_append(dle->estimatelist, + GINT_TO_POINTER(ES_CLIENT)); + ttt += strlen("client"); + } else if (BSTRNCMP(ttt,"CALCSIZE") == 0) { + if (!data_user->has_calcsize) + dle->estimatelist = g_slist_append(dle->estimatelist, + GINT_TO_POINTER(ES_CALCSIZE)); + ttt += strlen("calcsize"); + } else if (BSTRNCMP(ttt,"SERVER") == 0) { + dle->estimatelist = g_slist_append(dle->estimatelist, + GINT_TO_POINTER(ES_SERVER)); + ttt += strlen("server"); + } else { + g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, + "XML: bad estimate: %s", tt); + return; + } + while (*ttt == ' ') + ttt++; } amfree(tt); } else if(strcmp(last_element_name, "program") == 0) { if (dle->program != NULL) { g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, "XML: multiple text in %s", last_element_name); + amfree(tt); return; } - dle->program = tt; if (strcmp(tt, "APPLICATION") == 0) { dle->program_is_application_api = 1; dle->program = NULL; + amfree(tt); + } else { + dle->program = tt; } } else if(strcmp(last_element_name, "plugin") == 0) { last_element2 = g_slist_nth(data_user->element_names, 1); @@ -581,6 +693,7 @@ amtext( } else { error("priority outside of property"); } + amfree(tt); } else if(strcmp(last_element_name, "value") == 0) { last_element2 = g_slist_nth(data_user->element_names, 1); if (!last_element2) { @@ -601,7 +714,19 @@ amtext( } dle->auth = tt; } else if(strcmp(last_element_name, "level") == 0) { - dle->level = g_slist_append(dle->level, GINT_TO_POINTER(atoi(tt))); + data_user->alevel->level = atoi(tt); + amfree(tt); + } else if (strcmp(last_element_name, "server") == 0) { + if (strcasecmp(tt,"no") == 0) { + data_user->alevel->server = 0; + } else if (strcasecmp(tt,"yes") == 0) { + data_user->alevel->server = 1; + } else { + g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, + "XML: Invalid %s (%s)", last_element_name, tt); + amfree(tt); + return; + } amfree(tt); } else if(strcmp(last_element_name, "index") == 0) { if (strcasecmp(tt,"no") == 0) { @@ -631,10 +756,13 @@ amtext( } else { g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, "XML: Invalid %s (%s)", last_element_name, tt); + amfree(tt); return; } + amfree(tt); } else if(strcmp(last_element_name, "spindle") == 0) { dle->spindle = atoi(tt); + amfree(tt); } else if(strcmp(last_element_name, "compress") == 0) { if (strcmp(tt, "FAST") == 0) { dle->compress = COMP_FAST; @@ -695,17 +823,24 @@ amtext( error("XML: optional"); } last_element2_name = last_element2->data; - dle->clnt_encrypt = tt; + if (dle->encrypt == ENCRYPT_SERV_CUST) + dle->srv_encrypt = tt; + else + dle->clnt_encrypt = tt; } else if(strcmp(last_element_name, "decrypt-option") == 0) { last_element2 = g_slist_nth(data_user->element_names, 1); if (!last_element2) { error("XML: optional"); } last_element2_name = last_element2->data; - dle->clnt_decrypt_opt = tt; + if (dle->encrypt == ENCRYPT_SERV_CUST) + dle->srv_decrypt_opt = tt; + else + dle->clnt_decrypt_opt = tt; } else if(strcmp(last_element_name, "exclude") == 0 || strcmp(last_element_name, "include") == 0) { data_user->has_optional = 0; + amfree(tt); } else if(strcmp(last_element_name, "file") == 0) { last_element2 = g_slist_nth(data_user->element_names, 1); if (!last_element2) { @@ -733,7 +868,6 @@ amtext( error("bad list"); } } else if(strcmp(last_element_name, "optional") == 0) { - i = atoi(tt); last_element2 = g_slist_nth(data_user->element_names, 1); if (!last_element2) { error("XML: optional"); @@ -749,6 +883,7 @@ amtext( data_user->has_optional = 1; amfree(tt); } else if(strcmp(last_element_name, "script") == 0) { + amfree(tt); } else if(strcmp(last_element_name, "execute_on") == 0) { char *sep; char *tt1 = tt; @@ -756,26 +891,38 @@ amtext( sep = strchr(tt1,','); if (sep) *sep = '\0'; - if (strcmp(tt1,"PRE-DLE-AMCHECK") == 0) + if (strcmp(tt1,"PRE-AMCHECK") == 0) + data_user->script->execute_on |= EXECUTE_ON_PRE_AMCHECK; + else if (strcmp(tt1,"PRE-DLE-AMCHECK") == 0) data_user->script->execute_on |= EXECUTE_ON_PRE_DLE_AMCHECK; else if (strcmp(tt1,"PRE-HOST-AMCHECK") == 0) data_user->script->execute_on |= EXECUTE_ON_PRE_HOST_AMCHECK; + else if (strcmp(tt1,"POST-AMCHECK") == 0) + data_user->script->execute_on |= EXECUTE_ON_POST_AMCHECK; else if (strcmp(tt1,"POST-DLE-AMCHECK") == 0) data_user->script->execute_on |= EXECUTE_ON_POST_DLE_AMCHECK; else if (strcmp(tt1,"POST-HOST-AMCHECK") == 0) data_user->script->execute_on |= EXECUTE_ON_POST_HOST_AMCHECK; + else if (strcmp(tt1,"PRE-ESTIMATE") == 0) + data_user->script->execute_on |= EXECUTE_ON_PRE_ESTIMATE; else if (strcmp(tt1,"PRE-DLE-ESTIMATE") == 0) data_user->script->execute_on |= EXECUTE_ON_PRE_DLE_ESTIMATE; else if (strcmp(tt1,"PRE-HOST-ESTIMATE") == 0) data_user->script->execute_on |= EXECUTE_ON_PRE_HOST_ESTIMATE; + else if (strcmp(tt1,"POST-ESTIMATE") == 0) + data_user->script->execute_on |= EXECUTE_ON_POST_ESTIMATE; else if (strcmp(tt1,"POST-DLE-ESTIMATE") == 0) data_user->script->execute_on |= EXECUTE_ON_POST_DLE_ESTIMATE; else if (strcmp(tt1,"POST-HOST-ESTIMATE") == 0) data_user->script->execute_on |= EXECUTE_ON_POST_HOST_ESTIMATE; + else if (strcmp(tt1,"PRE-BACKUP") == 0) + data_user->script->execute_on |= EXECUTE_ON_PRE_BACKUP; else if (strcmp(tt1,"PRE-DLE-BACKUP") == 0) data_user->script->execute_on |= EXECUTE_ON_PRE_DLE_BACKUP; else if (strcmp(tt1,"PRE-HOST-BACKUP") == 0) data_user->script->execute_on |= EXECUTE_ON_PRE_HOST_BACKUP; + else if (strcmp(tt1,"POST-BACKUP") == 0) + data_user->script->execute_on |= EXECUTE_ON_POST_BACKUP; else if (strcmp(tt1,"POST-DLE-BACKUP") == 0) data_user->script->execute_on |= EXECUTE_ON_POST_DLE_BACKUP; else if (strcmp(tt1,"POST-HOST-BACKUP") == 0) @@ -802,9 +949,38 @@ amtext( } else { data_user->script->execute_where = ES_SERVER; } + amfree(tt); + } else if(strcmp(last_element_name, "datapath") == 0) { + if (strcmp(tt, "AMANDA") == 0) { + dle->data_path = DATA_PATH_AMANDA; + } else if (strcmp(tt, "DIRECTTCP") == 0) { + dle->data_path = DATA_PATH_DIRECTTCP; + } else { + g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, + "XML: bad datapath value '%s'", tt); + } + amfree(tt); + } else if(strcmp(last_element_name, "directtcp") == 0) { + dle->directtcp_list = g_slist_append(dle->directtcp_list, tt); + } else if(strcmp(last_element_name, "client_name") == 0) { + last_element2 = g_slist_nth(data_user->element_names, 1); + if (!last_element2) { + error("Invalid client_name text"); + } + last_element2_name = last_element2->data; + if (strcmp(last_element2_name, "backup-program") == 0) { + dle->application_client_name = tt; +g_debug("set dle->application_client_name: %s", dle->application_client_name); + } else if (strcmp(last_element2_name, "script") == 0) { + data_user->script->client_name = tt; +g_debug("set data_user->script->client_name: %s", data_user->script->client_name); + } else { + error("client_name outside of script or backup-program"); + } } else { g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, "XML: amtext not defined for '%s'", last_element_name); + amfree(tt); return; } } @@ -814,7 +990,7 @@ amxml_parse_node_CHAR( char *txt, char **errmsg) { - 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}; + 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}; GMarkupParser parser = {&amstart_element, &amend_element, &amtext, NULL, NULL}; GMarkupParseFlags flags = 0; @@ -843,7 +1019,7 @@ amxml_parse_node_FILE( FILE *file, char **errmsg) { - 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}; + 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}; GMarkupParser parser = {&amstart_element, &amend_element, &amtext, NULL, NULL}; GMarkupParseFlags flags = 0;