X-Git-Url: https://code.citadel.org/?a=blobdiff_plain;f=citadel%2Fmodules%2Fmigrate%2Fserv_migrate.c;h=d8a742acd5f04b3aa62fd3e089e06d097b90b456;hb=2b95d70900730dd2913788e01948572069fc1587;hp=b440ff3b4ebecb75ae8c2f91a058cd277d6e6b29;hpb=4d157f04e639af03e4a8dd6dd84de84ef1ffa490;p=citadel.git diff --git a/citadel/modules/migrate/serv_migrate.c b/citadel/modules/migrate/serv_migrate.c index b440ff3b4..d8a742acd 100644 --- a/citadel/modules/migrate/serv_migrate.c +++ b/citadel/modules/migrate/serv_migrate.c @@ -1,14 +1,12 @@ /* - * $Id$ - * - * Copyright (c) 2000-2009 by the citadel.org development team - * * This module dumps and/or loads the Citadel database in XML format. * + * Copyright (c) 1987-2010 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, or (at your option) - * any later version. + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -17,9 +15,7 @@ * * 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., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "sysdep.h" @@ -57,7 +53,6 @@ #include "database.h" #include "msgbase.h" #include "user_ops.h" -#include "room_ops.h" #include "control.h" #include "euidindex.h" @@ -89,8 +84,11 @@ void xml_strout(char *str) { char *c = str; while (*c != 0) { - if (*c == '&') { - client_write("&", 5); + if (*c == '\"') { + client_write(""", 4); + } + else if (*c == '\'') { + client_write("'", 4); } else if (*c == '<') { client_write("<", 4); @@ -98,6 +96,9 @@ void xml_strout(char *str) { else if (*c == '>') { client_write(">", 4); } + else if (*c == '&') { + client_write("&", 5); + } else { client_write(c, 1); } @@ -159,7 +160,7 @@ void migr_export_rooms_backend(struct ctdlroom *buf, void *data) { /* message list goes inside this tag */ - getroom(&CC->room, buf->QRname); + CtdlGetRoom(&CC->room, buf->QRname); client_write("", 15); client_write("", 8); xml_strout(CC->room.QRname); client_write("\n", 10); client_write("", 11); @@ -175,7 +176,7 @@ void migr_export_rooms(void) { char cmd[SIZ]; migr_global_message_list = fopen(migr_tempfilename1, "w"); if (migr_global_message_list != NULL) { - ForEachRoom(migr_export_rooms_backend, NULL); + CtdlForEachRoom(migr_export_rooms_backend, NULL); fclose(migr_global_message_list); } @@ -185,10 +186,10 @@ 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); - if (system(cmd) != 0) CtdlLogPrintf(CTDL_ALERT, "Error %d\n", errno); + 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) CtdlLogPrintf(CTDL_ALERT, "Error %d\n", errno); + if (system(cmd) != 0) syslog(LOG_ALERT, "Error %d\n", errno); } @@ -199,7 +200,7 @@ void migr_export_floors(void) { for (i=0; i < MAXFLOORS; ++i) { client_write("\n", 8); cprintf("%d\n", i); - getfloor(&qfbuf, i); + CtdlGetFloor(&qfbuf, i); buf = &qfbuf; cprintf("%u\n", buf->f_flags); client_write("", 8); xml_strout(buf->f_name); client_write("\n", 10); @@ -216,16 +217,16 @@ void migr_export_floors(void) { * Traverse the visits file... */ void migr_export_visits(void) { - struct visit vbuf; + visit vbuf; struct cdbdata *cdbv; cdb_rewind(CDB_VISIT); while (cdbv = cdb_next_item(CDB_VISIT), cdbv != NULL) { - memset(&vbuf, 0, sizeof(struct visit)); + memset(&vbuf, 0, sizeof(visit)); memcpy(&vbuf, cdbv->ptr, - ((cdbv->len > sizeof(struct visit)) ? - sizeof(struct visit) : cdbv->len)); + ((cdbv->len > sizeof(visit)) ? + sizeof(visit) : cdbv->len)); cdb_free(cdbv); client_write("\n", 8); @@ -255,6 +256,25 @@ void migr_export_message(long msgnum) { struct CtdlMessage *msg; struct ser_ret smr; + /* We can use a static buffer here because there will never be more than + * one of this operation happening at any given time, and it's really best + * to just keep it allocated once instead of torturing malloc/free. + * Call this function with msgnum "-1" to free the buffer when finished. + */ + static int encoded_alloc = 0; + static char *encoded_msg = NULL; + + if (msgnum < 0) { + if ((encoded_alloc == 0) && (encoded_msg != NULL)) { + free(encoded_msg); + encoded_alloc = 0; + encoded_msg = NULL; + } + return; + } + + /* Ok, here we go ... */ + msg = CtdlFetchMessage(msgnum, 1); if (msg == NULL) return; /* fail silently */ @@ -268,14 +288,21 @@ void migr_export_message(long msgnum) { serialize_message(&smr, msg); CtdlFreeMessage(msg); - int encoded_len = 0; - int encoded_alloc = smr.len * 14 / 10; /* well-tested formula for predicting encoded size */ - char *encoded_msg = malloc(encoded_alloc); + /* Predict the buffer size we need. Expand the buffer if necessary. */ + int encoded_len = smr.len * 15 / 10 ; + if (encoded_len > encoded_alloc) { + encoded_alloc = encoded_len; + encoded_msg = realloc(encoded_msg, encoded_alloc); + } - if (encoded_msg != NULL) { + if (encoded_msg == NULL) { + /* Questionable hack that hopes it'll work next time and we only lose one message */ + encoded_alloc = 0; + } + else { + /* Once we do the encoding we know the exact size */ encoded_len = CtdlEncodeBase64(encoded_msg, (char *)smr.ser, smr.len, 1); client_write(encoded_msg, encoded_len); - free(encoded_msg); } free(smr.ser); @@ -314,12 +341,12 @@ void migr_export_messages(void) { char buf[SIZ]; long msgnum; int count = 0; - t_context *Ctx; + CitContext *Ctx; Ctx = CC; migr_global_message_list = fopen(migr_tempfilename1, "r"); if (migr_global_message_list != NULL) { - CtdlLogPrintf(CTDL_INFO, "Opened %s\n", migr_tempfilename1); + syslog(LOG_INFO, "Opened %s\n", migr_tempfilename1); while ((Ctx->kill_me != 1) && (fgets(buf, sizeof(buf), migr_global_message_list) != NULL)) { msgnum = atol(buf); @@ -331,9 +358,11 @@ void migr_export_messages(void) { fclose(migr_global_message_list); } if (Ctx->kill_me != 1) - CtdlLogPrintf(CTDL_INFO, "Exported %d messages.\n", count); + syslog(LOG_INFO, "Exported %d messages.\n", count); else - CtdlLogPrintf(CTDL_ERR, "Export aborted due to client disconnect! \n"); + syslog(LOG_ERR, "Export aborted due to client disconnect! \n"); + + migr_export_message(-1L); /* This frees the encoding buffer */ } @@ -341,7 +370,7 @@ void migr_export_messages(void) { void migr_do_export(void) { struct config *buf; buf = &config; - t_context *Ctx; + CitContext *Ctx; Ctx = CC; cprintf("%d Exporting all Citadel databases.\n", LISTING_FOLLOWS); @@ -472,7 +501,7 @@ long openid_usernum = 0; char FRname[ROOMNAMELEN]; struct floor flbuf; int floornum = 0; -struct visit vbuf; +visit vbuf; struct MetaData smi; long import_msgnum = 0; char *decoded_msg = NULL; @@ -524,7 +553,7 @@ void migr_xml_start(void *data, const char *el, const char **attr) { } if (citadel_migrate_data != 1) { - CtdlLogPrintf(CTDL_ALERT, "Out-of-sequence tag <%s> detected. Warning: ODD-DATA!\n"); + syslog(LOG_ALERT, "Out-of-sequence tag <%s> detected. Warning: ODD-DATA!\n", el); return; } @@ -536,7 +565,7 @@ void migr_xml_start(void *data, const char *el, const char **attr) { else if (!strcasecmp(el, "room")) memset(&qrbuf, 0, sizeof (struct ctdlroom)); else if (!strcasecmp(el, "room_messages")) memset(FRname, 0, sizeof FRname); else if (!strcasecmp(el, "floor")) memset(&flbuf, 0, sizeof (struct floor)); - else if (!strcasecmp(el, "visit")) memset(&vbuf, 0, sizeof (struct visit)); + else if (!strcasecmp(el, "visit")) memset(&vbuf, 0, sizeof (visit)); else if (!strcasecmp(el, "message")) { memset(&smi, 0, sizeof (struct MetaData)); @@ -550,7 +579,7 @@ void migr_xml_start(void *data, const char *el, const char **attr) { } -void migr_xml_end(void *data, const char *el, const char **attr) { +void migr_xml_end(void *data, const char *el) { char *ptr; int msgcount = 0; long msgnum = 0L; @@ -569,7 +598,7 @@ void migr_xml_end(void *data, const char *el, const char **attr) { } if (citadel_migrate_data != 1) { - CtdlLogPrintf(CTDL_ALERT, "Out-of-sequence tag <%s> detected. Warning: ODD-DATA!\n"); + syslog(LOG_ALERT, "Out-of-sequence tag <%s> detected. Warning: ODD-DATA!\n", el); return; } @@ -578,14 +607,14 @@ void migr_xml_end(void *data, const char *el, const char **attr) { migr_chardata_len = 0; } - // CtdlLogPrintf(CTDL_DEBUG, "END TAG: <%s> DATA: <%s>\n", el, (migr_chardata_len ? migr_chardata : "")); + // syslog(LOG_DEBUG, "END TAG: <%s> DATA: <%s>\n", el, (migr_chardata_len ? migr_chardata : "")); /*** CONFIG ***/ if (!strcasecmp(el, "config")) { config.c_enable_fulltext = 0; /* always disable */ put_config(); - CtdlLogPrintf(CTDL_INFO, "Completed import of server configuration\n"); + syslog(LOG_INFO, "Completed import of server configuration\n"); } else if (!strcasecmp(el, "c_nodename")) safestrncpy(config.c_nodename, migr_chardata, sizeof config.c_nodename); @@ -674,7 +703,7 @@ void migr_xml_end(void *data, const char *el, const char **attr) { else if (!strcasecmp(el, "control")) { CitControl.MMfulltext = (-1L); /* always flush */ put_control(); - CtdlLogPrintf(CTDL_INFO, "Completed import of control record\n"); + syslog(LOG_INFO, "Completed import of control record\n"); } /*** USER ***/ @@ -692,8 +721,8 @@ void migr_xml_end(void *data, const char *el, const char **attr) { else if (!strcasecmp(el, "u_fullname")) safestrncpy(usbuf.fullname, migr_chardata, sizeof usbuf.fullname); else if (!strcasecmp(el, "user")) { - putuser(&usbuf); - CtdlLogPrintf(CTDL_INFO, "Imported user: %s\n", usbuf.fullname); + CtdlPutUser(&usbuf); + syslog(LOG_INFO, "Imported user: %s\n", usbuf.fullname); } /*** OPENID ***/ @@ -710,7 +739,7 @@ void migr_xml_end(void *data, const char *el, const char **attr) { memcpy(&oid_data[sizeof(long)], openid_url, strlen(openid_url) + 1); cdb_store(CDB_OPENID, openid_url, strlen(openid_url), oid_data, oid_data_len); free(oid_data); - CtdlLogPrintf(CTDL_INFO, "Imported OpenID: %s (%ld)\n", openid_url, openid_usernum); + syslog(LOG_INFO, "Imported OpenID: %s (%ld)\n", openid_url, openid_usernum); } /*** ROOM ***/ @@ -733,8 +762,8 @@ void migr_xml_end(void *data, const char *el, const char **attr) { else if (!strcasecmp(el, "QRdefaultview")) qrbuf.QRdefaultview = atoi(migr_chardata); else if (!strcasecmp(el, "room")) { - putroom(&qrbuf); - CtdlLogPrintf(CTDL_INFO, "Imported room: %s\n", qrbuf.QRname); + CtdlPutRoom(&qrbuf); + syslog(LOG_INFO, "Imported room: %s\n", qrbuf.QRname); } /*** ROOM MESSAGE POINTERS ***/ @@ -747,7 +776,7 @@ void migr_xml_end(void *data, const char *el, const char **attr) { msglist_alloc = 1000; msglist = malloc(sizeof(long) * msglist_alloc); - CtdlLogPrintf(CTDL_DEBUG, "Message list for: %s\n", FRname); + syslog(LOG_DEBUG, "Message list for: %s\n", FRname); ptr = migr_chardata; while (*ptr != 0) { @@ -770,12 +799,12 @@ void migr_xml_end(void *data, const char *el, const char **attr) { } } if (msgcount > 0) { - CtdlSaveMsgPointersInRoom(FRname, msglist, msgcount, 0, NULL); + CtdlSaveMsgPointersInRoom(FRname, msglist, msgcount, 0, NULL, 1); } free(msglist); msglist = NULL; msglist_alloc = 0; - CtdlLogPrintf(CTDL_DEBUG, "Imported %d messages.\n", msgcount); + syslog(LOG_DEBUG, "Imported %d messages.\n", msgcount); if (CtdlThreadCheckStop()) { return; } @@ -791,8 +820,8 @@ void migr_xml_end(void *data, const char *el, const char **attr) { else if (!strcasecmp(el, "f_ep_expire_value")) flbuf.f_ep.expire_value = atoi(migr_chardata); else if (!strcasecmp(el, "floor")) { - putfloor(&flbuf, floornum); - CtdlLogPrintf(CTDL_INFO, "Imported floor #%d (%s)\n", floornum, flbuf.f_name); + CtdlPutFloor(&flbuf, floornum); + syslog(LOG_INFO, "Imported floor #%d (%s)\n", floornum, flbuf.f_name); } /*** VISITS ***/ @@ -814,7 +843,7 @@ void migr_xml_end(void *data, const char *el, const char **attr) { else if (!strcasecmp(el, "visit")) { put_visit(&vbuf); - CtdlLogPrintf(CTDL_INFO, "Imported visit: %ld/%ld/%ld\n", vbuf.v_roomnum, vbuf.v_roomgen, vbuf.v_usernum); + syslog(LOG_INFO, "Imported visit: %ld/%ld/%ld\n", vbuf.v_roomnum, vbuf.v_roomgen, vbuf.v_usernum); } /*** MESSAGES ***/ @@ -834,7 +863,7 @@ void migr_xml_end(void *data, const char *el, const char **attr) { free(decoded_msg); decoded_msg = NULL; PutMetaData(&smi); - CtdlLogPrintf(CTDL_INFO, "Imported message #%ld, size=%ld, refcount=%d, content-type: %s\n", + syslog(LOG_INFO, "Imported message #%ld, size=%ld, refcount=%d, content-type: %s\n", import_msgnum, msglen, smi.meta_refcount, smi.meta_content_type); } @@ -896,6 +925,23 @@ void migr_do_import(void) { +/* + * Dump out the pathnames of directories which can be copied "as is" + */ +void migr_do_listdirs(void) { + cprintf("%d Don't forget these:\n", LISTING_FOLLOWS); + cprintf("bio|%s\n", ctdl_bio_dir); + cprintf("files|%s\n", ctdl_file_dir); + cprintf("userpics|%s\n", ctdl_usrpic_dir); + cprintf("messages|%s\n", ctdl_message_dir); + cprintf("netconfigs|%s\n", ctdl_netcfg_dir); + cprintf("keys|%s\n", ctdl_key_dir); + cprintf("images|%s\n", ctdl_image_dir); + cprintf("info|%s\n", ctdl_info_dir); + cprintf("000\n"); +} + + /* * Common code appears in this section */ @@ -918,6 +964,9 @@ void cmd_migr(char *cmdbuf) { else if (!strcasecmp(cmd, "import")) { migr_do_import(); } + else if (!strcasecmp(cmd, "listdirs")) { + migr_do_listdirs(); + } else { cprintf("%d illegal command\n", ERROR + ILLEGAL_VALUE); } @@ -943,5 +992,5 @@ CTDL_MODULE_INIT(migrate) } /* return our Subversion id for the Log */ - return "$Id$"; + return "migrate"; }