* serv_migrate.c: message encoding buffer is now static in order to avoid endlessly...
[citadel.git] / citadel / modules / migrate / serv_migrate.c
index 4441a09b9363a834bd807396cbc3426170d97825..07027db060f74c1f702e6682a251607f1f17bde0 100644 (file)
@@ -1,5 +1,6 @@
 /*
- * $Id: serv_migrate.c 7274 2009-03-27 15:11:14Z ajc $
+ * $Id$
+ *
  * Copyright (c) 2000-2009 by the citadel.org development team
  *
  * This module dumps and/or loads the Citadel database in XML format.
@@ -254,6 +255,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 */
 
@@ -267,14 +287,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);
@@ -333,6 +360,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 */
 }
 
 
@@ -895,6 +924,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
  */
@@ -917,6 +963,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);
                }
@@ -942,5 +991,5 @@ CTDL_MODULE_INIT(migrate)
        }
        
        /* return our Subversion id for the Log */
-       return "$Id: serv_migrate.c 7274 2009-03-27 15:11:14Z ajc $";
+       return "$Id$";
 }