/* text is not nul-terminated */ static void amtext( G_GNUC_UNUSED GMarkupParseContext *context, const gchar *text, gsize text_len, gpointer user_data, GError **gerror) { char *tt; amgxml_t *data_user = user_data; GSList *last_element = data_user->element_names; char *last_element_name; 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, "XML: Invalid text"); return; } last_element_name = last_element->data; tt = malloc(text_len + 1); strncpy(tt,text,text_len); tt[text_len] = '\0'; //check if it is only space if (match_no_newline("^[ \f\n\r\t\v]*$", tt)) { amfree(tt); return; } if (data_user->raw) { amfree(tt); tt = stralloc(data_user->raw); } //check if it is only space if (match_no_newline("^[ \f\n\r\t\v]*$", tt)) { amfree(tt); return; } if (strcmp(last_element_name, "dle") == 0 || strcmp(last_element_name, "backup-program") == 0 || strcmp(last_element_name, "exclude") == 0 || 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); 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); return; } dle->disk = tt; } else if(strcmp(last_element_name, "diskdevice") == 0) { if (dle->device != NULL) { g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, "XML: multiple text in %s", last_element_name); return; } dle->device = tt; } else if(strcmp(last_element_name, "calcsize") == 0) { if (strcasecmp(tt,"yes") == 0) { dle->estimatelist = g_slist_append(dle->estimatelist, GINT_TO_POINTER(ES_CALCSIZE)); } amfree(tt); } else if(strcmp(last_element_name, "estimate") == 0) { 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); return; } dle->program = tt; if (strcmp(tt, "APPLICATION") == 0) { dle->program_is_application_api = 1; dle->program = NULL; } } else if(strcmp(last_element_name, "plugin") == 0) { last_element2 = g_slist_nth(data_user->element_names, 1); if (!last_element2) { error("Invalid name text"); } last_element2_name = last_element2->data; if (strcmp(last_element2_name, "backup-program") == 0) { dle->program = tt; } else if (strcmp(last_element2_name, "script") == 0) { data_user->script->plugin = tt; } else { error("plugin outside of backup-program"); } data_user->has_plugin = 1; } else if(strcmp(last_element_name, "name") == 0) { last_element2 = g_slist_nth(data_user->element_names, 1); if (!last_element2) { error("Invalid name text"); } last_element2_name = last_element2->data; if (strcmp(last_element2_name, "property") == 0) { data_user->property_name = tt; } else { error("name outside of property"); } } else if(strcmp(last_element_name, "priority") == 0) { last_element2 = g_slist_nth(data_user->element_names, 1); if (!last_element2) { error("Invalid priority text"); } last_element2_name = last_element2->data; if (strcmp(last_element2_name, "property") == 0) { if (strcasecmp(tt,"yes") == 0) { data_user->property_data->priority = 1; } } else { error("priority outside of property"); } } else if(strcmp(last_element_name, "value") == 0) { last_element2 = g_slist_nth(data_user->element_names, 1); if (!last_element2) { error("Invalid name text"); } last_element2_name = last_element2->data; if (strcmp(last_element2_name, "property") == 0) { data_user->property_data->values = g_slist_append(data_user->property_data->values, tt); } else { error("value outside of property"); } } else if(strcmp(last_element_name, "auth") == 0) { if (dle->auth != NULL) { g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, "XML: multiple text in %s", last_element_name); return; } dle->auth = tt; } else if(strcmp(last_element_name, "level") == 0) { 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) { dle->create_index = 0; } else if (strcasecmp(tt,"yes") == 0) { dle->create_index = 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, "dumpdate") == 0) { if (dle->dumpdate != 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->dumpdate = tt; } else if(strcmp(last_element_name, "record") == 0) { if (strcasecmp(tt, "no") == 0) { dle->record = 0; } else if (strcasecmp(tt, "yes") == 0) { dle->record = 1; } else { g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, "XML: Invalid %s (%s)", last_element_name, tt); return; } } else if(strcmp(last_element_name, "spindle") == 0) { dle->spindle = atoi(tt); } else if(strcmp(last_element_name, "compress") == 0) { if (strcmp(tt, "FAST") == 0) { dle->compress = COMP_FAST; } else if (strcmp(tt, "BEST") == 0) { dle->compress = COMP_BEST; } else if (BSTRNCMP(tt, "CUSTOM") == 0) { dle->compress = COMP_CUST; } else if (strcmp(tt, "SERVER-FAST") == 0) { dle->compress = COMP_SERVER_FAST; } else if (strcmp(tt, "SERVER-BEST") == 0) { dle->compress = COMP_SERVER_BEST; } else if (BSTRNCMP(tt, "SERVER-CUSTOM") == 0) { dle->compress = COMP_SERVER_CUST; } 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, "custom-compress-program") == 0) { if (dle->compprog != 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->compprog = tt; } else if(strcmp(last_element_name, "encrypt") == 0) { if (BSTRNCMP(tt,"NO") == 0) { dle->encrypt = ENCRYPT_NONE; } else if (BSTRNCMP(tt, "CUSTOM") == 0) { dle->encrypt = ENCRYPT_CUST; } else if (BSTRNCMP(tt, "SERVER-CUSTOM") == 0) { dle->encrypt = ENCRYPT_SERV_CUST; } 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, "kencrypt") == 0) { if (strcasecmp(tt,"no") == 0) { dle->kencrypt = 0; } else if (strcasecmp(tt,"yes") == 0) { dle->kencrypt = 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, "custom-encrypt-program") == 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_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; } else if(strcmp(last_element_name, "exclude") == 0 || strcmp(last_element_name, "include") == 0) { data_user->has_optional = 0; } else if(strcmp(last_element_name, "file") == 0) { last_element2 = g_slist_nth(data_user->element_names, 1); if (!last_element2) { error("XML: optional"); } last_element2_name = last_element2->data; if (strcmp(last_element2_name, "exclude") == 0) { dle->exclude_file = append_sl(dle->exclude_file, tt); } else if (strcmp(last_element2_name, "include") == 0) { dle->include_file = append_sl(dle->include_file, tt); } else { error("bad file"); } } else if(strcmp(last_element_name, "list") == 0) { last_element2 = g_slist_nth(data_user->element_names, 1); if (!last_element2) { error("XML: optional"); } last_element2_name = last_element2->data; if (strcmp(last_element2_name, "exclude") == 0) { dle->exclude_list = append_sl(dle->exclude_list, tt); } else if (strcmp(last_element2_name, "include") == 0) { dle->include_list = append_sl(dle->include_list, tt); } else { 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"); } last_element2_name = last_element2->data; if (strcmp(last_element2_name, "exclude") == 0) { dle->exclude_optional = 1; } else if (strcmp(last_element2_name, "include") == 0) { dle->include_optional = 1; } else { error("bad optional"); } data_user->has_optional = 1; amfree(tt); } else if(strcmp(last_element_name, "script") == 0) { } else if(strcmp(last_element_name, "execute_on") == 0) { char *sep; char *tt1 = tt; do { sep = strchr(tt1,','); if (sep) *sep = '\0'; 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-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-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-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-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-DLE-BACKUP") == 0) data_user->script->execute_on |= EXECUTE_ON_POST_DLE_BACKUP; else if (strcmp(tt1,"POST-HOST-BACKUP") == 0) data_user->script->execute_on |= EXECUTE_ON_POST_HOST_BACKUP; else if (strcmp(tt1,"PRE-RECOVER") == 0) data_user->script->execute_on |= EXECUTE_ON_PRE_RECOVER; else if (strcmp(tt1,"POST-RECOVER") == 0) data_user->script->execute_on |= EXECUTE_ON_POST_RECOVER; else if (strcmp(tt1,"PRE-LEVEL-RECOVER") == 0) data_user->script->execute_on |= EXECUTE_ON_PRE_LEVEL_RECOVER; else if (strcmp(tt1,"POST-LEVEL-RECOVER") == 0) data_user->script->execute_on |= EXECUTE_ON_POST_LEVEL_RECOVER; else if (strcmp(tt1,"INTER-LEVEL-RECOVER") == 0) data_user->script->execute_on |= EXECUTE_ON_INTER_LEVEL_RECOVER; else dbprintf("BAD EXECUTE_ON: %s\n", tt1); if (sep) tt1 = sep+1; } while (sep); amfree(tt); } else if(strcmp(last_element_name, "execute_where") == 0) { if (strcmp(tt, "CLIENT") == 0) { data_user->script->execute_where = ES_CLIENT; } else { data_user->script->execute_where = ES_SERVER; } } else { g_set_error(gerror, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, "XML: amtext not defined for '%s'", last_element_name); return; } }
static gboolean test_match(void) { gboolean ok = TRUE; struct { char *expr, *str; gboolean should_match, should_match_no_newline; } tests[] = { /* literal, unanchored matching */ { "a", "a", TRUE, TRUE }, { "a", "A", FALSE, FALSE }, { "a", "ab", TRUE, TRUE }, { "a", "ba", TRUE, TRUE }, { "a", "bab", TRUE, TRUE }, /* dot */ { ".", "", FALSE, FALSE }, { ".", "a", TRUE, TRUE }, { "..", "a", FALSE, FALSE }, { "..", "bc", TRUE, TRUE }, /* brackets */ { "[abc]", "xbx", TRUE, TRUE }, { "[abc]", "xyz", FALSE, FALSE }, { "[^abc]", "cba", FALSE, FALSE }, { "[^abc]", "xyz", TRUE, TRUE }, { "[a-c]", "b", TRUE, TRUE }, { "[^a-c]", "-", TRUE, TRUE }, { "[1-9-]", "-", TRUE, TRUE }, { "[ab\\-cd]", "-", FALSE, FALSE }, /* NOTE! */ /* anchors */ { "^xy", "xyz", TRUE, TRUE }, { "^xy", "wxyz", FALSE, FALSE }, { "yz$", "xyz", TRUE, TRUE }, { "yz$", "yza", FALSE, FALSE }, { "^123$", "123", TRUE, TRUE }, { "^123$", "0123", FALSE, FALSE }, { "^123$", "1234", FALSE, FALSE }, /* capture groups */ { "([a-c])([x-y])", "pqaxyr", TRUE, TRUE }, { "([a-c])([x-y])", "paqrxy", FALSE, FALSE }, { "([a-c])/\\1", "a/b", FALSE, FALSE }, { "([a-c])/\\1", "c/c", TRUE, TRUE }, /* * */ { ">[0-9]*<", "><", TRUE, TRUE }, { ">[0-9]*<", ">3<", TRUE, TRUE }, { ">[0-9]*<", ">34<", TRUE, TRUE }, { ">[0-9]*<", ">345<", TRUE, TRUE }, { ">[0-9]*<", ">x<", FALSE, FALSE }, /* | */ { ":(abc|ABC);", ":abc;", TRUE, TRUE }, { ":(abc|ABC);", ":ABC;", TRUE, TRUE }, { ":(abc|ABC);", ":abcBC;", FALSE, FALSE }, /* + */ { ">[0-9]+<", "><", FALSE, FALSE }, { ">[0-9]+<", ">3<", TRUE, TRUE }, { ">[0-9]+<", ">34<", TRUE, TRUE }, { ">[0-9]+<", ">345<", TRUE, TRUE }, { ">[0-9]+<", ">x<", FALSE, FALSE }, /* { .. } */ { ">[0-9]{0,1}<", "><", TRUE, TRUE }, { ">[0-9]{0,1}<", ">9<", TRUE, TRUE }, { ">[0-9]{0,1}<", ">98<", FALSE, FALSE }, { ">[0-9]{2,3}<", "><", FALSE, FALSE }, { ">[0-9]{2,3}<", ">5<", FALSE, FALSE }, { ">[0-9]{2,3}<", ">55<", TRUE, TRUE }, { ">[0-9]{2,3}<", ">555<", TRUE, TRUE }, { ">[0-9]{2,3}<", ">5555<", FALSE, FALSE }, /* quoting metacharacters */ { "\\\\", "\\", TRUE, TRUE }, { "\\,", ",", TRUE, TRUE }, { "\\[", "[", TRUE, TRUE }, { "\\*", "*", TRUE, TRUE }, { "\\?", "?", TRUE, TRUE }, { "\\+", "+", TRUE, TRUE }, { "\\.", ".", TRUE, TRUE }, { "\\|", "|", TRUE, TRUE }, { "\\^", "^", TRUE, TRUE }, { "\\$", "$", TRUE, TRUE }, /* differences between match and match_no_newline */ { "x.y", "x\ny", FALSE, TRUE }, { "x[^yz]y", "x\ny", FALSE, TRUE }, { "^y", "x\ny", TRUE, FALSE }, { "x$", "x\ny", TRUE, FALSE }, { NULL, NULL, FALSE, FALSE }, }, *t; for (t = tests; t->expr; t++) { gboolean matched = match(t->expr, t->str); if (!!matched != !!t->should_match) { ok = FALSE; if (t->should_match) { g_fprintf(stderr, "%s should have matched regular expr %s\n", t->str, t->expr); } else { g_fprintf(stderr, "%s unexpectedly matched regular expr %s\n", t->str, t->expr); } } matched = match_no_newline(t->expr, t->str); if (!!matched != !!t->should_match_no_newline) { ok = FALSE; if (t->should_match) { g_fprintf(stderr, "%s should have matched (no_newline) regular expr %s\n", t->str, t->expr); } else { g_fprintf(stderr, "%s unexpectedly matched (no_newline) regular expr %s\n", t->str, t->expr); } } } return ok; }