More removal of $Id$ tags
[citadel.git] / citadel / modules / migrate / serv_migrate.c
index b440ff3b4ebecb75ae8c2f91a058cd277d6e6b29..d1b6cfca05a94337ffdcea99ecb7a5e5a9543c7e 100644 (file)
@@ -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"
 
@@ -159,7 +154,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("<room_messages>", 15);
        client_write("<FRname>", 8);    xml_strout(CC->room.QRname);    client_write("</FRname>\n", 10);
        client_write("<FRmsglist>", 11);
@@ -175,7 +170,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);
        }
 
@@ -199,7 +194,7 @@ void migr_export_floors(void) {
         for (i=0; i < MAXFLOORS; ++i) {
                client_write("<floor>\n", 8);
                cprintf("<f_num>%d</f_num>\n", i);
-                getfloor(&qfbuf, i);
+                CtdlGetFloor(&qfbuf, i);
                buf = &qfbuf;
                cprintf("<f_flags>%u</f_flags>\n", buf->f_flags);
                client_write("<f_name>", 8); xml_strout(buf->f_name); client_write("</f_name>\n", 10);
@@ -216,16 +211,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("<visit>\n", 8);
@@ -255,6 +250,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 +282,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,7 +335,7 @@ 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");
@@ -334,6 +355,8 @@ void migr_export_messages(void) {
                CtdlLogPrintf(CTDL_INFO, "Exported %d messages.\n", count);
        else
                CtdlLogPrintf(CTDL_ERR, "Export aborted due to client disconnect! \n");
+
+       migr_export_message(-1L);       /* This frees the encoding buffer */
 }
 
 
@@ -341,7 +364,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 +495,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;
@@ -536,7 +559,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 +573,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;
@@ -692,7 +715,7 @@ 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);
+               CtdlPutUser(&usbuf);
                CtdlLogPrintf(CTDL_INFO, "Imported user: %s\n", usbuf.fullname);
        }
 
@@ -733,7 +756,7 @@ 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);
+               CtdlPutRoom(&qrbuf);
                CtdlLogPrintf(CTDL_INFO, "Imported room: %s\n", qrbuf.QRname);
        }
 
@@ -770,7 +793,7 @@ 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;
@@ -791,7 +814,7 @@ 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);
+               CtdlPutFloor(&flbuf, floornum);
                CtdlLogPrintf(CTDL_INFO, "Imported floor #%d (%s)\n", floornum, flbuf.f_name);
        }
 
@@ -896,6 +919,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 +958,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 +986,5 @@ CTDL_MODULE_INIT(migrate)
        }
        
        /* return our Subversion id for the Log */
-       return "$Id$";
+       return "migrate";
 }