X-Git-Url: https://code.citadel.org/?a=blobdiff_plain;f=citadel%2Fmodules%2Fmigrate%2Fserv_migrate.c;h=39ffc73b9782f664d84d6f1afe5690d227e7814a;hb=9e7955f89c38690b915739864bae178fff0f6474;hp=31d2eceea2e41140c3aa325c73e17e927a1de958;hpb=f1ee61891901850ebbdee1e9440b363dc6df540a;p=citadel.git diff --git a/citadel/modules/migrate/serv_migrate.c b/citadel/modules/migrate/serv_migrate.c index 31d2eceea..39ffc73b9 100644 --- a/citadel/modules/migrate/serv_migrate.c +++ b/citadel/modules/migrate/serv_migrate.c @@ -1,21 +1,15 @@ /* * This module dumps and/or loads the Citadel database in XML format. * - * Copyright (c) 1987-2010 by the citadel.org team + * Copyright (c) 1987-2012 by the citadel.org team * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. + * This program is open source software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "sysdep.h" @@ -55,12 +49,8 @@ #include "user_ops.h" #include "control.h" #include "euidindex.h" - - #include "ctdl_module.h" - - #define END_OF_MESSAGE "---eom---dbd---" char migr_tempfilename1[PATH_MAX]; @@ -68,14 +58,10 @@ char migr_tempfilename2[PATH_MAX]; FILE *migr_global_message_list; - - /* * Code which implements the export appears in this section */ - - /* * Output a string to the client with these characters escaped: & < > */ @@ -84,8 +70,11 @@ void xml_strout(char *str) { char *c = str; while (*c != 0) { - if (*c == '&') { - client_write("&", 5); + if (*c == '\"') { + client_write(""", 6); + } + else if (*c == '\'') { + client_write("'", 6); } else if (*c == '<') { client_write("<", 4); @@ -93,6 +82,9 @@ void xml_strout(char *str) { else if (*c == '>') { client_write(">", 4); } + else if (*c == '&') { + client_write("&", 5); + } else { client_write(c, 1); } @@ -140,7 +132,11 @@ void migr_export_rooms_backend(struct ctdlroom *buf, void *data) { cprintf("%ld\n", buf->QRhighest); cprintf("%ld\n", (long)buf->QRgen); cprintf("%u\n", buf->QRflags); - client_write("", 11); xml_strout(buf->QRdirname); client_write("\n", 13); + if (buf->QRflags & QR_DIRECTORY) { + client_write("", 11); + xml_strout(buf->QRdirname); + client_write("\n", 13); + } cprintf("%ld\n", buf->QRinfo); cprintf("%d\n", buf->QRfloor); cprintf("%ld\n", (long)buf->QRmtime); @@ -180,7 +176,7 @@ void migr_export_rooms(void) { * this will be handled by exporting the reference count, not by * exporting the message multiple times.) */ - snprintf(cmd, sizeof cmd, "sort <%s >%s", migr_tempfilename1, migr_tempfilename2); + snprintf(cmd, sizeof cmd, "sort -n <%s >%s", migr_tempfilename1, migr_tempfilename2); if (system(cmd) != 0) syslog(LOG_ALERT, "Error %d\n", errno); snprintf(cmd, sizeof cmd, "uniq <%s >%s", migr_tempfilename2, migr_tempfilename1); if (system(cmd) != 0) syslog(LOG_ALERT, "Error %d\n", errno); @@ -206,6 +202,23 @@ void migr_export_floors(void) { } +/* + * Return nonzero if the supplied string contains only characters which are valid in a sequence set. + */ +int is_sequence_set(char *s) { + if (!s) return(0); + + char *c = s; + char ch; + while (ch = *c++, ch) { + if (!strchr("0123456789*,:", ch)) { + return(0); + } + } + return(1); +} + + /* * Traverse the visits file... @@ -229,7 +242,7 @@ void migr_export_visits(void) { cprintf("%ld\n", vbuf.v_usernum); client_write("", 8); - if (!IsEmptyStr(vbuf.v_seen)) { + if ( (!IsEmptyStr(vbuf.v_seen)) && (is_sequence_set(vbuf.v_seen)) ) { xml_strout(vbuf.v_seen); } else { @@ -237,7 +250,12 @@ void migr_export_visits(void) { } client_write("", 9); - client_write("", 12); xml_strout(vbuf.v_answered); client_write("\n", 14); + if ( (!IsEmptyStr(vbuf.v_answered)) && (is_sequence_set(vbuf.v_answered)) ) { + client_write("", 12); + xml_strout(vbuf.v_answered); + client_write("\n", 14); + } + cprintf("%u\n", vbuf.v_flags); cprintf("%d\n", vbuf.v_view); client_write("\n", 9); @@ -279,8 +297,8 @@ void migr_export_message(long msgnum) { client_write("", 23); xml_strout(smi.meta_content_type); client_write("\n", 25); client_write("", 10); - serialize_message(&smr, msg); - CtdlFreeMessage(msg); + CtdlSerializeMessage(&smr, msg); + CM_Free(msg); /* Predict the buffer size we need. Expand the buffer if necessary. */ int encoded_len = smr.len * 15 / 10 ; @@ -341,7 +359,7 @@ void migr_export_messages(void) { migr_global_message_list = fopen(migr_tempfilename1, "r"); if (migr_global_message_list != NULL) { syslog(LOG_INFO, "Opened %s\n", migr_tempfilename1); - while ((Ctx->kill_me != 1) && + while ((Ctx->kill_me == 0) && (fgets(buf, sizeof(buf), migr_global_message_list) != NULL)) { msgnum = atol(buf); if (msgnum > 0L) { @@ -351,7 +369,7 @@ void migr_export_messages(void) { } fclose(migr_global_message_list); } - if (Ctx->kill_me != 1) + if (Ctx->kill_me == 0) syslog(LOG_INFO, "Exported %d messages.\n", count); else syslog(LOG_ERR, "Export aborted due to client disconnect! \n"); @@ -362,8 +380,6 @@ void migr_export_messages(void) { void migr_do_export(void) { - struct config *buf; - buf = &config; CitContext *Ctx; Ctx = CC; @@ -391,7 +407,6 @@ void migr_do_export(void) { cprintf("%d\n", config.c_restrict); client_write("", 17); xml_strout(config.c_site_location); client_write("\n", 19); client_write("", 10); xml_strout(config.c_sysadm); client_write("\n", 12); - cprintf("%d\n", config.c_setup_level); cprintf("%d\n", config.c_maxsessions); client_write("", 11); xml_strout(config.c_ip_addr); client_write("\n", 13); cprintf("%d\n", config.c_port_number); @@ -427,7 +442,6 @@ void migr_do_export(void) { cprintf("%d\n", config.c_pop3s_port); cprintf("%d\n", config.c_smtps_port); cprintf("%d\n", config.c_auto_cull); - cprintf("%d\n", config.c_instant_expunge); cprintf("%d\n", config.c_allow_spoofing); cprintf("%d\n", config.c_journal_email); cprintf("%d\n", config.c_journal_pubmsgs); @@ -462,12 +476,12 @@ void migr_do_export(void) { cprintf("%d\n", CitControl.version); client_write("\n", 11); - if (Ctx->kill_me != 1) migr_export_users(); - if (Ctx->kill_me != 1) migr_export_openids(); - if (Ctx->kill_me != 1) migr_export_rooms(); - if (Ctx->kill_me != 1) migr_export_floors(); - if (Ctx->kill_me != 1) migr_export_visits(); - if (Ctx->kill_me != 1) migr_export_messages(); + if (Ctx->kill_me == 0) migr_export_users(); + if (Ctx->kill_me == 0) migr_export_openids(); + if (Ctx->kill_me == 0) migr_export_rooms(); + if (Ctx->kill_me == 0) migr_export_floors(); + if (Ctx->kill_me == 0) migr_export_visits(); + if (Ctx->kill_me == 0) migr_export_messages(); client_write("\n", 24); client_write("000\n", 4); Ctx->dont_term = 0; @@ -510,6 +524,7 @@ void migr_xml_chardata(void *data, const XML_Char *s, int len) { old_len = migr_chardata_len; new_len = old_len + len; + new_buffer = realloc(migr_chardata, new_len + 1); if (new_buffer != NULL) { memcpy(&new_buffer[old_len], s, len); @@ -626,7 +641,6 @@ void migr_xml_end(void *data, const char *el) { else if (!strcasecmp(el, "c_restrict")) config.c_restrict = atoi(migr_chardata); else if (!strcasecmp(el, "c_site_location")) safestrncpy(config.c_site_location, migr_chardata, sizeof config.c_site_location); else if (!strcasecmp(el, "c_sysadm")) safestrncpy(config.c_sysadm, migr_chardata, sizeof config.c_sysadm); - else if (!strcasecmp(el, "c_setup_level")) config.c_setup_level = atoi(migr_chardata); else if (!strcasecmp(el, "c_maxsessions")) config.c_maxsessions = atoi(migr_chardata); else if (!strcasecmp(el, "c_ip_addr")) safestrncpy(config.c_ip_addr, migr_chardata, sizeof config.c_ip_addr); else if (!strcasecmp(el, "c_port_number")) config.c_port_number = atoi(migr_chardata); @@ -662,7 +676,6 @@ void migr_xml_end(void *data, const char *el) { else if (!strcasecmp(el, "c_pop3s_port")) config.c_pop3s_port = atoi(migr_chardata); else if (!strcasecmp(el, "c_smtps_port")) config.c_smtps_port = atoi(migr_chardata); else if (!strcasecmp(el, "c_auto_cull")) config.c_auto_cull = atoi(migr_chardata); - else if (!strcasecmp(el, "c_instant_expunge")) config.c_instant_expunge = atoi(migr_chardata); else if (!strcasecmp(el, "c_allow_spoofing")) config.c_allow_spoofing = atoi(migr_chardata); else if (!strcasecmp(el, "c_journal_email")) config.c_journal_email = atoi(migr_chardata); else if (!strcasecmp(el, "c_journal_pubmsgs")) config.c_journal_pubmsgs = atoi(migr_chardata); @@ -799,7 +812,7 @@ void migr_xml_end(void *data, const char *el) { msglist = NULL; msglist_alloc = 0; syslog(LOG_DEBUG, "Imported %d messages.\n", msgcount); - if (CtdlThreadCheckStop()) { + if (server_shutting_down) { return; } } @@ -856,6 +869,7 @@ void migr_xml_end(void *data, const char *el) { cdb_store(CDB_MSGMAIN, &import_msgnum, sizeof(long), decoded_msg, msglen); free(decoded_msg); decoded_msg = NULL; + smi.meta_msgnum = import_msgnum; PutMetaData(&smi); syslog(LOG_INFO, "Imported message #%ld, size=%ld, refcount=%d, content-type: %s\n", import_msgnum, msglen, smi.meta_refcount, smi.meta_content_type); @@ -877,12 +891,12 @@ void migr_xml_end(void *data, const char *el) { * Import begins here */ void migr_do_import(void) { - char buf[SIZ]; + StrBuf *Buf; XML_Parser xp; - int linelen; + int Finished = 0; unbuffer_output(); - + Buf = NewStrBufPlain(NULL, SIZ); xp = XML_ParserCreate(NULL); if (!xp) { cprintf("%d Failed to create XML parser instance\n", ERROR+INTERNAL_ERROR); @@ -896,22 +910,28 @@ void migr_do_import(void) { cprintf("%d sock it to me\n", SEND_LISTING); unbuffer_output(); - while (client_getln(buf, sizeof buf) >= 0 && strcmp(buf, "000")) { - linelen = strlen(buf); - strcpy(&buf[linelen++], "\n"); + client_set_inbound_buf(SIZ * 10); - if (CtdlThreadCheckStop()) + while (!Finished && client_read_random_blob(Buf, -1) >= 0) { + if ((StrLength(Buf) > 4) && + !strcmp(ChrPtr(Buf) + StrLength(Buf) - 4, "000\n")) + { + Finished = 1; + StrBufCutAt(Buf, StrLength(Buf) - 4, NULL); + } + if (server_shutting_down) break; // Should we break or return? - if (buf[0] == '\0') + if (StrLength(Buf) == 0) continue; - XML_Parse(xp, buf, linelen, 0); + XML_Parse(xp, ChrPtr(Buf), StrLength(Buf), 0); + FlushStrBuf(Buf); } XML_Parse(xp, "", 0, 1); XML_ParserFree(xp); - + FreeStrBuf(&Buf); rebuild_euid_index(); rebuild_usersbynumber(); CC->dont_term = 0; @@ -985,6 +1005,6 @@ CTDL_MODULE_INIT(migrate) CtdlRegisterProtoHook(cmd_migr, "ARTV", "Across-the-wire migration (legacy syntax)"); } - /* return our Subversion id for the Log */ + /* return our module name for the log */ return "migrate"; }