+char *
+xml_dumptype_properties(
+ disk_t *dp)
+{
+ xml_app_t xml_dumptype;
+
+ xml_dumptype.result = g_strdup("");
+ xml_dumptype.features = NULL;
+ if (dp && dp->config) {
+ g_hash_table_foreach(dumptype_get_property(dp->config), xml_property,
+ &xml_dumptype);
+ }
+ return xml_dumptype.result;
+}
+
+char *
+xml_estimate(
+ estimatelist_t estimatelist,
+ am_feature_t *their_features)
+{
+ estimatelist_t el;
+ char *l = NULL;
+
+ if (am_has_feature(their_features, fe_xml_estimatelist)) {
+ vstrextend(&l, " <estimate>", NULL);
+ for (el=estimatelist; el != NULL; el = el->next) {
+ switch (GPOINTER_TO_INT(el->data)) {
+ case ES_CLIENT : vstrextend(&l, "CLIENT ", NULL); break;
+ case ES_SERVER : vstrextend(&l, "SERVER ", NULL); break;
+ case ES_CALCSIZE: vstrextend(&l, "CALCSIZE ", NULL); break;
+ }
+ }
+ vstrextend(&l, "</estimate>", NULL);
+ } else { /* add the first estimate only */
+ if (am_has_feature(their_features, fe_xml_estimate)) {
+ vstrextend(&l, " <estimate>", NULL);
+ switch (GPOINTER_TO_INT(estimatelist->data)) {
+ case ES_CLIENT : vstrextend(&l, "CLIENT", NULL); break;
+ case ES_SERVER : vstrextend(&l, "SERVER", NULL); break;
+ case ES_CALCSIZE: vstrextend(&l, "CALCSIZE", NULL); break;
+ }
+ }
+ vstrextend(&l, "</estimate>", NULL);
+ if (GPOINTER_TO_INT(estimatelist->data) == ES_CALCSIZE) {
+ vstrextend(&l, " <calcsize>YES</calcsize>", NULL);
+ }
+ }
+
+ return l;
+}
+
+char *
+clean_dle_str_for_client(
+ char *dle_str,
+ am_feature_t *their_features)
+{
+ char *rval_dle_str;
+ char *hack1, *hack2;
+ char *pend, *pscript, *pproperty, *eproperty;
+ int len;
+
+ if (!dle_str)
+ return NULL;
+
+ rval_dle_str = stralloc(dle_str);
+
+ /* Remove everything between " <encrypt>SERVER-CUSTOM" and "</encrypt>\n"
+ */
+#define SC "</encrypt>\n"
+#define SC_LEN strlen(SC)
+ hack1 = strstr(rval_dle_str, " <encrypt>SERVER-CUSTOM");
+ if (hack1) {
+ hack2 = strstr(hack1, SC);
+ /* +1 is to also move the trailing '\0' */
+ memmove(hack1, hack2 + SC_LEN, strlen(hack2 + SC_LEN) + 1);
+ }
+#undef SC
+#undef SC_LEN
+
+ if (!am_has_feature(their_features, fe_dumptype_property)) {
+#define SC "</property>\n"
+#define SC_LEN strlen(SC)
+ /* remove all dle properties, they are before backup-program or script
+ properties */
+ hack1 = rval_dle_str;
+ pend = strstr(rval_dle_str, "<backup-program>");
+ pscript = strstr(rval_dle_str, "<script>");
+ if (pscript && pscript < pend)
+ pend = pscript;
+ if (!pend) /* the complete string */
+ pend = rval_dle_str + strlen(rval_dle_str);
+ while (hack1) {
+ pproperty = strstr(hack1, " <property>");
+ if (pproperty && pproperty < pend) { /* remove it */
+ eproperty = strstr(pproperty, SC);
+ len = eproperty + SC_LEN - pproperty;
+ memmove(pproperty, eproperty + SC_LEN, strlen(eproperty + SC_LEN) + 1);
+ pend -= len;
+ hack1 = pproperty;
+ } else {
+ hack1 = NULL;
+ }
+ }
+ } else {
+ }
+#undef SC
+#undef SC_LEN
+
+ return rval_dle_str;
+}
+
+
+char *
+xml_application(
+ disk_t *dp G_GNUC_UNUSED,
+ application_t *application,
+ am_feature_t *their_features)
+{
+ char *plugin;
+ char *b64plugin;
+ char *client_name;
+ xml_app_t xml_app;
+ proplist_t proplist;
+
+ xml_app.features = their_features;
+ xml_app.result = NULL;
+ plugin = application_get_plugin(application);
+ b64plugin = amxml_format_tag("plugin", plugin);
+ xml_app.result = vstralloc(" <backup-program>\n",
+ " ", b64plugin, "\n",
+ NULL);
+ proplist = application_get_property(application);
+ g_hash_table_foreach(proplist, xml_property, &xml_app);
+
+ client_name = application_get_client_name(application);
+ if (client_name && strlen(client_name) > 0 &&
+ am_has_feature(their_features, fe_application_client_name)) {
+ char *b64client_name = amxml_format_tag("client_name", client_name);
+ vstrextend(&xml_app.result, " ", b64client_name, "\n", NULL);
+ }
+
+ vstrextend(&xml_app.result, " </backup-program>\n", NULL);
+
+ amfree(b64plugin);
+
+ return xml_app.result;
+}
+
+
+char *
+xml_scripts(
+ identlist_t pp_scriptlist,
+ am_feature_t *their_features)
+{
+ char *plugin;
+ char *b64plugin;
+ char *client_name;
+ char *xml_scr;
+ char *xml_scr1;
+ char *str = "";
+ char *sep;
+ char *eo_str;
+ execute_on_t execute_on;
+ int execute_where;
+ proplist_t proplist;
+ identlist_t pp_iter;
+ pp_script_t *pp_script;
+ xml_app_t xml_app;
+
+ xml_app.features = their_features;
+
+ xml_scr = stralloc("");
+ for (pp_iter = pp_scriptlist; pp_iter != NULL;
+ pp_iter = pp_iter->next) {
+ char *pp_script_name = pp_iter->data;
+ pp_script = lookup_pp_script(pp_script_name);
+ g_assert(pp_script != NULL);
+ plugin = pp_script_get_plugin(pp_script);
+ b64plugin = amxml_format_tag("plugin", plugin);
+ xml_scr1 = vstralloc(" <script>\n",
+ " ", b64plugin, "\n",
+ NULL);
+
+ execute_where = pp_script_get_execute_where(pp_script);
+ switch (execute_where) {
+ case ES_CLIENT: str = "CLIENT"; break;
+ case ES_SERVER: str = "SERVER"; break;
+ }
+ xml_scr1 = vstrextend(&xml_scr1, " <execute_where>",
+ str, "</execute_where>\n", NULL);
+
+ execute_on = pp_script_get_execute_on(pp_script);
+ sep = "";
+ eo_str = stralloc("");
+ if (execute_on & EXECUTE_ON_PRE_DLE_AMCHECK) {
+ eo_str = vstrextend(&eo_str, sep, "PRE-DLE-AMCHECK", NULL);
+ sep = ",";
+ }
+ if (execute_on & EXECUTE_ON_PRE_HOST_AMCHECK) {
+ eo_str = vstrextend(&eo_str, sep, "PRE-HOST-AMCHECK", NULL);
+ sep = ",";
+ }
+ if (execute_on & EXECUTE_ON_POST_DLE_AMCHECK) {
+ eo_str = vstrextend(&eo_str, sep, "POST-DLE-AMCHECK", NULL);
+ sep = ",";
+ }
+ if (execute_on & EXECUTE_ON_POST_HOST_AMCHECK) {
+ eo_str = vstrextend(&eo_str, sep, "POST-HOST-AMCHECK", NULL);
+ sep = ",";
+ }
+ if (execute_on & EXECUTE_ON_PRE_DLE_ESTIMATE) {
+ eo_str = vstrextend(&eo_str, sep, "PRE-DLE-ESTIMATE", NULL);
+ sep = ",";
+ }
+ if (execute_on & EXECUTE_ON_PRE_HOST_ESTIMATE) {
+ eo_str = vstrextend(&eo_str, sep, "PRE-HOST-ESTIMATE", NULL);
+ sep = ",";
+ }
+ if (execute_on & EXECUTE_ON_POST_DLE_ESTIMATE) {
+ eo_str = vstrextend(&eo_str, sep, "POST-DLE-ESTIMATE", NULL);
+ sep = ",";
+ }
+ if (execute_on & EXECUTE_ON_POST_HOST_ESTIMATE) {
+ eo_str = vstrextend(&eo_str, sep, "POST-HOST-ESTIMATE", NULL);
+ sep = ",";
+ }
+ if (execute_on & EXECUTE_ON_PRE_DLE_BACKUP) {
+ eo_str = vstrextend(&eo_str, sep, "PRE-DLE-BACKUP", NULL);
+ sep = ",";
+ }
+ if (execute_on & EXECUTE_ON_PRE_HOST_BACKUP) {
+ eo_str = vstrextend(&eo_str, sep, "PRE-HOST-BACKUP", NULL);
+ sep = ",";
+ }
+ if (execute_on & EXECUTE_ON_POST_DLE_BACKUP) {
+ eo_str = vstrextend(&eo_str, sep, "POST-DLE-BACKUP", NULL);
+ sep = ",";
+ }
+ if (execute_on & EXECUTE_ON_POST_HOST_BACKUP) {
+ eo_str = vstrextend(&eo_str, sep, "POST-HOST-BACKUP", NULL);
+ sep = ",";
+ }
+ if (execute_on & EXECUTE_ON_PRE_RECOVER) {
+ eo_str = vstrextend(&eo_str, sep, "PRE-RECOVER", NULL);
+ sep = ",";
+ }
+ if (execute_on & EXECUTE_ON_POST_RECOVER) {
+ eo_str = vstrextend(&eo_str, sep, "POST-RECOVER", NULL);
+ sep = ",";
+ }
+ if (execute_on & EXECUTE_ON_PRE_LEVEL_RECOVER) {
+ eo_str = vstrextend(&eo_str, sep, "PRE-LEVEL-RECOVER", NULL);
+ sep = ",";
+ }
+ if (execute_on & EXECUTE_ON_POST_LEVEL_RECOVER) {
+ eo_str = vstrextend(&eo_str, sep, "POST-LEVEL-RECOVER", NULL);
+ sep = ",";
+ }
+ if (execute_on & EXECUTE_ON_INTER_LEVEL_RECOVER) {
+ eo_str = vstrextend(&eo_str, sep, "INTER-LEVEL-RECOVER", NULL);
+ sep = ",";
+ }
+ if (execute_on != 0)
+ xml_scr1 = vstrextend(&xml_scr1,
+ " <execute_on>", eo_str,
+ "</execute_on>\n", NULL);
+ amfree(eo_str);
+ proplist = pp_script_get_property(pp_script);
+ xml_app.result = stralloc("");
+ g_hash_table_foreach(proplist, xml_property, &xml_app);
+
+ client_name = pp_script_get_client_name(pp_script);
+ if (client_name && strlen(client_name) > 0 &&
+ am_has_feature(their_features, fe_script_client_name)) {
+ char *b64client_name = amxml_format_tag("client_name",
+ client_name);
+ vstrextend(&xml_app.result, " ", b64client_name, "\n", NULL);
+ }
+
+ xml_scr = vstrextend(&xml_scr, xml_scr1, xml_app.result, " </script>\n", NULL);
+ amfree(b64plugin);
+ amfree(xml_app.result);
+ amfree(xml_scr1);
+ }
+ return xml_scr;
+}
+
+
+void
+disable_skip_disk(
+ disklist_t *origqp)
+{
+ disk_t *dp;
+
+ for (dp = origqp->head; dp != NULL; dp = dp->next) {
+ if (dp->ignore || dp->strategy == DS_SKIP)
+ dp->todo = 0;
+ }
+}
+
+
+char *
+match_disklist(
+ disklist_t *origqp,
+ int sargc,
+ char ** sargv)