formatting
[citadel.git] / citadel / modules / migrate / serv_migrate.c
index 33b566361e7ba387f59bb79bbe8725cc80c4e7e2..31815f485903d0c76cb945c472640f6f9ff85edb 100644 (file)
@@ -1,29 +1,28 @@
-/*
- * This module dumps and/or loads the Citadel database in XML format.
- *
- * Copyright (c) 1987-2020 by the citadel.org team
- *
- * 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.
- */
-
-/*
- * Explanation of <progress> tags:
- *
- * 0%              nothing
- * 2%              finished exporting configuration
- * 7%              finished exporting users
- * 12%             finished exporting openids
- * 17%             finished exporting rooms
- * 18%             finished exporting floors
- * 25%             finished exporting visits
- * 100%            finished exporting messages
- */
+// This module dumps and/or loads the Citadel database in XML format.
+//
+// Copyright (c) 1987-2021 by the citadel.org team
+//
+// 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.
+//
+// Explanation of <progress> tags:
+//
+// 0%          started
+// 2%          finished exporting configuration
+// 7%          finished exporting users
+// 12%         finished exporting openids
+// 17%         finished exporting rooms
+// 18%         finished exporting floors
+// 25%         finished exporting visits
+// 26-99%      exporting messages
+// 100%                finished exporting messages
+//
+// These tags are inserted into the XML stream to give the reader an approximation of its progress.
 
 #include "sysdep.h"
 #include <stdlib.h>
 #include "euidindex.h"
 #include "ctdl_module.h"
 
-#define END_OF_MESSAGE "---eom---dbd---"
-
 char migr_tempfilename1[PATH_MAX];
 char migr_tempfilename2[PATH_MAX];
 FILE *migr_global_message_list;
 int total_msgs = 0;
 char *ikey = NULL;                     // If we're importing a config key we store it here.
 
+//*****************************************************************************
+//*       Code which implements the export appears in this section            *
+//*****************************************************************************
 
-/******************************************************************************
- *        Code which implements the export appears in this section            *
- ******************************************************************************/
-
-/*
- * Output a string to the client with these characters escaped:  & < > " '
- */
+// Output a string to the client with these characters escaped:  & < > " '
 void xml_strout(char *str) {
 
        char *c = str;
@@ -100,9 +94,7 @@ void xml_strout(char *str) {
 }
 
 
-/*
- * Export a user record as XML
- */
+// Export a user record as XML
 void migr_export_users_backend(char *username, void *data) {
 
        struct ctdluser u;
@@ -137,15 +129,24 @@ void migr_export_users(void) {
 
 
 void migr_export_room_msg(long msgnum, void *userdata) {
-       cprintf("%ld\n", msgnum);
+       static int count = 0;
+
+       cprintf("%ld,", msgnum);
+       if (++count%10==0) {
+               cprintf("\n");
+       }
        fprintf(migr_global_message_list, "%ld\n", msgnum);
 }
 
 
 void migr_export_rooms_backend(struct ctdlroom *buf, void *data) {
        client_write(HKEY("<room>\n"));
-       client_write(HKEY("<QRname>")); xml_strout(buf->QRname);        client_write(HKEY("</QRname>\n"));
-       client_write(HKEY("<QRpasswd>"));       xml_strout(buf->QRpasswd);      client_write(HKEY("</QRpasswd>\n"));
+       client_write(HKEY("<QRname>"));
+       xml_strout(buf->QRname);
+       client_write(HKEY("</QRname>\n"));
+       client_write(HKEY("<QRpasswd>"));
+       xml_strout(buf->QRpasswd);
+       client_write(HKEY("</QRpasswd>\n"));
        cprintf("<QRroomaide>%ld</QRroomaide>\n", buf->QRroomaide);
        cprintf("<QRhighest>%ld</QRhighest>\n", buf->QRhighest);
        cprintf("<QRgen>%ld</QRgen>\n", (long)buf->QRgen);
@@ -167,17 +168,16 @@ void migr_export_rooms_backend(struct ctdlroom *buf, void *data) {
        cprintf("<msgnum_pic>%ld</msgnum_pic>\n", buf->msgnum_pic);
        client_write(HKEY("</room>\n"));
 
-       /* message list goes inside this tag */
-
+       // message list goes inside this tag
        CtdlGetRoom(&CC->room, buf->QRname);
        client_write(HKEY("<room_messages>"));
-       client_write(HKEY("<FRname>")); xml_strout(CC->room.QRname);    client_write(HKEY("</FRname>\n"));
-       client_write(HKEY("<FRmsglist>"));
+       client_write(HKEY("<FRname>"));
+       xml_strout(buf->QRname);                        // buf->QRname rather than CC->room.QRname to guarantee consistency
+       client_write(HKEY("</FRname>\n"));
+       client_write(HKEY("<FRmsglist>\n"));
        CtdlForEachMessage(MSGS_ALL, 0L, NULL, NULL, NULL, migr_export_room_msg, NULL);
        client_write(HKEY("</FRmsglist>\n"));
        client_write(HKEY("</room_messages>\n"));
-
-
 }
 
 
@@ -189,17 +189,18 @@ void migr_export_rooms(void) {
                fclose(migr_global_message_list);
        }
 
-       /*
-        * Process the 'global' message list.  (Sort it and remove dups.
-        * Dups are ok because a message may be in more than one room, but
-        * this will be handled by exporting the reference count, not by
-        * exporting the message multiple times.)
-        */
+       // Process the 'global' message list.  (Sort it and remove dups.
+       // Dups are ok because a message may be in more than one room, but
+       // this will be handled by exporting the reference count, not by
+       // exporting the message multiple times.)
        snprintf(cmd, sizeof cmd, "sort -n <%s >%s", migr_tempfilename1, migr_tempfilename2);
-       if (system(cmd) != 0) syslog(LOG_ALERT, "Error %d", errno);
+       if (system(cmd) != 0) {
+               syslog(LOG_ERR, "migrate: error %d", errno);
+       }
        snprintf(cmd, sizeof cmd, "uniq <%s >%s", migr_tempfilename2, migr_tempfilename1);
-       if (system(cmd) != 0) syslog(LOG_ALERT, "Error %d", errno);
-
+       if (system(cmd) != 0) {
+               syslog(LOG_ERR, "migrate: error %d", errno);
+       }
 
        snprintf(cmd, sizeof cmd, "wc -l %s", migr_tempfilename1);
        FILE *fp = popen(cmd, "r");
@@ -211,7 +212,7 @@ void migr_export_rooms(void) {
        else {
                total_msgs = 1; // any nonzero just to keep it from barfing
        }
-       syslog(LOG_DEBUG, "Total messages to be exported: %d", total_msgs);
+       syslog(LOG_DEBUG, "migrate: total messages to be exported: %d", total_msgs);
 }
 
 
@@ -234,9 +235,7 @@ void migr_export_floors(void) {
 }
 
 
-/*
- * Return nonzero if the supplied string contains only characters which are valid in a sequence set.
- */
+// 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);
 
@@ -251,9 +250,7 @@ int is_sequence_set(char *s) {
 }
 
 
-/* 
- *  Traverse the visits file...
- */
+// Traverse the visits file...
 void migr_export_visits(void) {
        visit vbuf;
        struct cdbdata *cdbv;
@@ -298,12 +295,14 @@ void migr_export_message(long msgnum) {
        struct MetaData smi;
        struct CtdlMessage *msg;
        struct ser_ret smr;
+       long bytes_written = 0;
+       long this_block = 0;
+
+       // 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.
 
-       /* 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;
 
@@ -316,10 +315,10 @@ void migr_export_message(long msgnum) {
                return;
        }
 
-       /* Ok, here we go ... */
+       // Ok, here we go ...
 
        msg = CtdlFetchMessage(msgnum, 1);
-       if (msg == NULL) return;        /* fail silently */
+       if (msg == NULL) return;                                // fail silently
 
        client_write(HKEY("<message>\n"));
        GetMetaData(&smi, msgnum);
@@ -332,7 +331,7 @@ void migr_export_message(long msgnum) {
        CtdlSerializeMessage(&smr, msg);
        CM_Free(msg);
 
-       /* Predict the buffer size we need.  Expand the buffer if necessary. */
+       // 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;
@@ -340,13 +339,24 @@ void migr_export_message(long msgnum) {
        }
 
        if (encoded_msg == NULL) {
-               /* Questionable hack that hopes it'll work next time and we only lose one message */
+               // 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 */
+               // 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);
+
+               // Careful now.  If the message is gargantuan, trying to write multiple gigamegs in one
+               // big write operation can make our transport unhappy.  So we'll chunk it up 10 KB at a time.
+               bytes_written = 0;
+               while ( (bytes_written < encoded_len) && (!server_shutting_down) ) {
+                       this_block = encoded_len - bytes_written;
+                       if (this_block > 10240) {
+                               this_block = 10240;
+                       }
+                       client_write(&encoded_msg[bytes_written], this_block);
+                       bytes_written += this_block;
+               }
        }
 
        free(smr.ser);
@@ -412,7 +422,7 @@ void migr_export_messages(void) {
        Ctx = CC;
        migr_global_message_list = fopen(migr_tempfilename1, "r");
        if (migr_global_message_list != NULL) {
-               syslog(LOG_INFO, "Opened %s", migr_tempfilename1);
+               syslog(LOG_INFO, "migrate: opened %s", migr_tempfilename1);
                while ((Ctx->kill_me == 0) && 
                       (fgets(buf, sizeof(buf), migr_global_message_list) != NULL)) {
                        msgnum = atol(buf);
@@ -429,13 +439,13 @@ void migr_export_messages(void) {
                fclose(migr_global_message_list);
        }
        if (Ctx->kill_me == 0) {
-               syslog(LOG_INFO, "Exported %d messages.", count);
+               syslog(LOG_INFO, "migrate: exported %d messages.", count);
        }
        else {
-               syslog(LOG_ERR, "Export aborted due to client disconnect!");
+               syslog(LOG_ERR, "migrate: export aborted due to client disconnect!");
        }
 
-       migr_export_message(-1L);       /* This frees the encoding buffer */
+       migr_export_message(-1L);       // This frees the encoding buffer
 }
 
 
@@ -451,7 +461,7 @@ void migr_do_export(void) {
        cprintf("<version>%d</version>\n", REV_LEVEL);
        cprintf("<progress>%d</progress>\n", 0);
 
-       /* export the configuration database */
+       // export the configuration database
        migr_export_configs();
        cprintf("<progress>%d</progress>\n", 2);
        
@@ -466,23 +476,21 @@ void migr_do_export(void) {
        if (Ctx->kill_me == 0)  migr_export_visits();
        cprintf("<progress>%d</progress>\n", 25);
        if (Ctx->kill_me == 0)  migr_export_messages();
-       client_write(HKEY("</citadel_migrate_data>\n"));
        cprintf("<progress>%d</progress>\n", 100);
+       client_write(HKEY("</citadel_migrate_data>\n"));
        client_write(HKEY("000\n"));
        Ctx->dont_term = 0;
 }
 
 
-/******************************************************************************
- *                              Import code                                   *
- *    Here's the code that implements the import side.  It's going to end up  *
- *        being one big loop with lots of global variables.  I don't care.    *
- * You wouldn't run multiple concurrent imports anyway.  If this offends your *
- * delicate sensibilities  then go rewrite it in Ruby on Rails or something.  *
- ******************************************************************************/
+//                              Import code
+//   Here's the code that implements the import side.  It's going to end up
+//       being one big loop with lots of global variables.  I don't care.
+// You wouldn't run multiple concurrent imports anyway.  If this offends your
+//  delicate sensibilities  then go rewrite it in Ruby on Rails or something.
 
 
-int citadel_migrate_data = 0;          /* Are we inside a <citadel_migrate_data> tag pair? */
+int citadel_migrate_data = 0;          // Are we inside a <citadel_migrate_data> tag pair?
 StrBuf *migr_chardata = NULL;
 StrBuf *migr_MsgData = NULL;
 struct ctdluser usbuf;
@@ -496,11 +504,8 @@ visit vbuf;
 struct MetaData smi;
 long import_msgnum = 0;
 
-/*
- * This callback stores up the data which appears in between tags.
- */
-void migr_xml_chardata(void *data, const XML_Char *s, int len)
-{
+// This callback stores up the data which appears in between tags.
+void migr_xml_chardata(void *data, const XML_Char *s, int len) {
        StrBufAppendBufPlain(migr_chardata, s, len, 0);
 }
 
@@ -508,19 +513,19 @@ void migr_xml_chardata(void *data, const XML_Char *s, int len)
 void migr_xml_start(void *data, const char *el, const char **attr) {
        int i;
 
-       /*** GENERAL STUFF ***/
+       //  *** GENERAL STUFF ***
 
-       /* Reset chardata_len to zero and init buffer */
+       // Reset chardata_len to zero and init buffer
        FlushStrBuf(migr_chardata);
        FlushStrBuf(migr_MsgData);
 
        if (!strcasecmp(el, "citadel_migrate_data")) {
                ++citadel_migrate_data;
 
-               /* As soon as it looks like the input data is a genuine Citadel XML export,
-                * whack the existing database on disk to make room for the new one.
-                */
+               // As soon as it looks like the input data is a genuine Citadel XML export,
+               // whack the existing database on disk to make room for the new one.
                if (citadel_migrate_data == 1) {
+                       syslog(LOG_INFO, "migrate: erasing existing databases so we can receive the incoming import");
                        for (i = 0; i < MAXCDB; ++i) {
                                cdb_trunc(i);
                        }
@@ -529,13 +534,12 @@ void migr_xml_start(void *data, const char *el, const char **attr) {
        }
 
        if (citadel_migrate_data != 1) {
-               syslog(LOG_ALERT, "Out-of-sequence tag <%s> detected.  Warning: ODD-DATA!", el);
+               syslog(LOG_ERR, "migrate: out-of-sequence tag <%s> detected.  Warning: ODD-DATA!", el);
                return;
        }
 
-       /* When we begin receiving XML for one of these record types, clear out the associated
-        * buffer so we don't accidentally carry over any data from a previous record.
-        */
+       // When we begin receiving XML for one of these record types, clear out the associated
+       // buffer so we don't accidentally carry over any data from a previous record.
        if (!strcasecmp(el, "user"))                    memset(&usbuf, 0, sizeof (struct ctdluser));
        else if (!strcasecmp(el, "openid"))             memset(openid_url, 0, sizeof openid_url);
        else if (!strcasecmp(el, "room"))               memset(&qrbuf, 0, sizeof (struct ctdlroom));
@@ -563,8 +567,7 @@ void migr_xml_start(void *data, const char *el, const char **attr) {
 }
 
 
-int migr_userrecord(void *data, const char *el)
-{
+int migr_userrecord(void *data, const char *el) {
        if (!strcasecmp(el, "u_version"))                       usbuf.version = atoi(ChrPtr(migr_chardata));
        else if (!strcasecmp(el, "u_uid"))                      usbuf.uid = atol(ChrPtr(migr_chardata));
        else if (!strcasecmp(el, "u_password"))                 safestrncpy(usbuf.password, ChrPtr(migr_chardata), sizeof usbuf.password);
@@ -586,8 +589,7 @@ int migr_userrecord(void *data, const char *el)
 }
 
 
-int migr_roomrecord(void *data, const char *el)
-{
+int migr_roomrecord(void *data, const char *el) {
        if (!strcasecmp(el, "QRname"))                          safestrncpy(qrbuf.QRname, ChrPtr(migr_chardata), sizeof qrbuf.QRname);
        else if (!strcasecmp(el, "QRpasswd"))                   safestrncpy(qrbuf.QRpasswd, ChrPtr(migr_chardata), sizeof qrbuf.QRpasswd);
        else if (!strcasecmp(el, "QRroomaide"))                 qrbuf.QRroomaide = atol(ChrPtr(migr_chardata));
@@ -610,8 +612,7 @@ int migr_roomrecord(void *data, const char *el)
 }
 
 
-int migr_floorrecord(void *data, const char *el)
-{
+int migr_floorrecord(void *data, const char *el) {
        if (!strcasecmp(el, "f_num"))                           floornum = atoi(ChrPtr(migr_chardata));
        else if (!strcasecmp(el, "f_flags"))                    flbuf.f_flags = atoi(ChrPtr(migr_chardata));
        else if (!strcasecmp(el, "f_name"))                     safestrncpy(flbuf.f_name, ChrPtr(migr_chardata), sizeof flbuf.f_name);
@@ -623,8 +624,7 @@ int migr_floorrecord(void *data, const char *el)
 }
 
 
-int migr_visitrecord(void *data, const char *el)
-{
+int migr_visitrecord(void *data, const char *el) {
        if (!strcasecmp(el, "v_roomnum"))                       vbuf.v_roomnum = atol(ChrPtr(migr_chardata));
        else if (!strcasecmp(el, "v_roomgen"))                  vbuf.v_roomgen = atol(ChrPtr(migr_chardata));
        else if (!strcasecmp(el, "v_usernum"))                  vbuf.v_usernum = atol(ChrPtr(migr_chardata));
@@ -651,14 +651,13 @@ int migr_visitrecord(void *data, const char *el)
 }
 
 
-void migr_xml_end(void *data, const char *el)
-{
+void migr_xml_end(void *data, const char *el) {
        const char *ptr;
        int msgcount = 0;
        long msgnum = 0L;
        long *msglist = NULL;
        int msglist_alloc = 0;
-       /*** GENERAL STUFF ***/
+       // *** GENERAL STUFF ***
 
        if (!strcasecmp(el, "citadel_migrate_data")) {
                --citadel_migrate_data;
@@ -666,17 +665,16 @@ void migr_xml_end(void *data, const char *el)
        }
 
        if (citadel_migrate_data != 1) {
-               syslog(LOG_ALERT, "Out-of-sequence tag <%s> detected.  Warning: ODD-DATA!", el);
+               syslog(LOG_ERR, "migrate: out-of-sequence tag <%s> detected.  Warning: ODD-DATA!", el);
                return;
        }
 
        // syslog(LOG_DEBUG, "END TAG: <%s> DATA: <%s>\n", el, (migr_chardata_len ? migr_chardata : ""));
 
-       /*** CONFIG ***/
+       // *** CONFIG ***
 
-       if (!strcasecmp(el, "config"))
-       {
-               syslog(LOG_DEBUG, "Imported config key=%s", ikey);
+       if (!strcasecmp(el, "config")) {
+               syslog(LOG_DEBUG, "migrate: imported config key=%s", ikey);
 
                if (ikey != NULL) {
                        CtdlSetConfigStr(ikey, (char *)ChrPtr(migr_chardata));
@@ -684,25 +682,25 @@ void migr_xml_end(void *data, const char *el)
                        ikey = NULL;
                }
                else {
-                       syslog(LOG_INFO, "Closed a <config> tag but no key name was supplied.");
+                       syslog(LOG_INFO, "migrate: closed a <config> tag but no key name was supplied.");
                }
        }
 
-       /*** USER ***/
+       // *** USER ***
        else if ((!strncasecmp(el, HKEY("u_"))) && 
                 migr_userrecord(data, el))
                ; /* Nothing to do anymore */
        else if (!strcasecmp(el, "user")) {
                CtdlPutUser(&usbuf);
-               syslog(LOG_INFO, "Imported user: %s", usbuf.fullname);
+               syslog(LOG_INFO, "migrate: imported user: %s", usbuf.fullname);
        }
 
-       /*** OPENID ***/
+       // *** OPENID ***
 
        else if (!strcasecmp(el, "oid_url"))                    safestrncpy(openid_url, ChrPtr(migr_chardata), sizeof openid_url);
        else if (!strcasecmp(el, "oid_usernum"))                openid_usernum = atol(ChrPtr(migr_chardata));
 
-       else if (!strcasecmp(el, "openid")) {                   /* see serv_openid_rp.c for a description of the record format */
+       else if (!strcasecmp(el, "openid")) {                   // see serv_openid_rp.c for a description of the record format
                char *oid_data;
                int oid_data_len;
                oid_data_len = sizeof(long) + strlen(openid_url) + 1;
@@ -711,21 +709,23 @@ void migr_xml_end(void *data, const char *el)
                memcpy(&oid_data[sizeof(long)], openid_url, strlen(openid_url) + 1);
                cdb_store(CDB_EXTAUTH, openid_url, strlen(openid_url), oid_data, oid_data_len);
                free(oid_data);
-               syslog(LOG_INFO, "Imported OpenID: %s (%ld)", openid_url, openid_usernum);
+               syslog(LOG_INFO, "migrate: imported OpenID: %s (%ld)", openid_url, openid_usernum);
        }
 
-       /*** ROOM ***/
+       // *** ROOM ***
        else if ((!strncasecmp(el, HKEY("QR"))) && 
                 migr_roomrecord(data, el))
-               ; /* Nothing to do anymore */
+               ; // Nothing to do anymore
        else if (!strcasecmp(el, "room")) {
                CtdlPutRoom(&qrbuf);
-               syslog(LOG_INFO, "Imported room: %s", qrbuf.QRname);
+               syslog(LOG_INFO, "migrate: imported room: %s", qrbuf.QRname);
        }
 
-       /*** ROOM MESSAGE POINTERS ***/
+       // *** ROOM MESSAGE POINTERS ***
 
-       else if (!strcasecmp(el, "FRname"))                     safestrncpy(FRname, ChrPtr(migr_chardata), sizeof FRname);
+       else if (!strcasecmp(el, "FRname")) {
+               safestrncpy(FRname, ChrPtr(migr_chardata), sizeof FRname);
+       }
 
        else if (!strcasecmp(el, "FRmsglist")) {
                if (!IsEmptyStr(FRname)) {
@@ -733,7 +733,7 @@ void migr_xml_end(void *data, const char *el)
                        msglist_alloc = 1000;
                        msglist = malloc(sizeof(long) * msglist_alloc);
 
-                       syslog(LOG_DEBUG, "Message list for: %s", FRname);
+                       syslog(LOG_DEBUG, "migrate: message list for: %s", FRname);
 
                        ptr = ChrPtr(migr_chardata);
                        while (*ptr != 0) {
@@ -761,40 +761,39 @@ void migr_xml_end(void *data, const char *el)
                        free(msglist);
                        msglist = NULL;
                        msglist_alloc = 0;
-                       syslog(LOG_DEBUG, "Imported %d messages.", msgcount);
+                       syslog(LOG_DEBUG, "migrate: imported %d messages.", msgcount);
                        if (server_shutting_down) {
                                return;
                }
        }
 
-       /*** FLOORS ***/
+       // *** FLOORS ***
        else if ((!strncasecmp(el, HKEY("f_"))) && 
                 migr_floorrecord(data, el))
-               ; /* Nothing to do anymore */
+               ; // Nothing to do anymore
 
        else if (!strcasecmp(el, "floor")) {
                CtdlPutFloor(&flbuf, floornum);
-               syslog(LOG_INFO, "Imported floor #%d (%s)", floornum, flbuf.f_name);
+               syslog(LOG_INFO, "migrate: imported floor #%d (%s)", floornum, flbuf.f_name);
        }
 
-       /*** VISITS ***/
+       // *** VISITS ***
        else if ((!strncasecmp(el, HKEY("v_"))) && migr_visitrecord(data, el)) {
-               ; /* Nothing to do anymore */
+               ; // Nothing to do anymore
        }
        else if (!strcasecmp(el, "visit")) {
                put_visit(&vbuf);
-               syslog(LOG_INFO, "Imported visit: %ld/%ld/%ld", vbuf.v_roomnum, vbuf.v_roomgen, vbuf.v_usernum);
+               syslog(LOG_INFO, "migrate: imported visit: %ld/%ld/%ld", vbuf.v_roomnum, vbuf.v_roomgen, vbuf.v_usernum);
        }
 
-       /*** MESSAGES ***/
+       // *** MESSAGES ***
        
        else if (!strcasecmp(el, "msg_msgnum"))                 smi.meta_msgnum = import_msgnum = atol(ChrPtr(migr_chardata));
        else if (!strcasecmp(el, "msg_meta_refcount"))          smi.meta_refcount = atoi(ChrPtr(migr_chardata));
        else if (!strcasecmp(el, "msg_meta_rfc822_length"))     smi.meta_rfc822_length = atoi(ChrPtr(migr_chardata));
        else if (!strcasecmp(el, "msg_meta_content_type"))      safestrncpy(smi.meta_content_type, ChrPtr(migr_chardata), sizeof smi.meta_content_type);
 
-       else if (!strcasecmp(el, "msg_text"))
-       {
+       else if (!strcasecmp(el, "msg_text")) {
                long rc;
                struct CtdlMessage *msg;
 
@@ -816,8 +815,8 @@ void migr_xml_end(void *data, const char *el)
                }
 
                syslog(LOG_INFO,
-                      "%s message #%ld, size=%d, refcount=%d, bodylength=%ld, content-type: %s",
-                      (rc!= 0)?"failed to import ":"Imported ",
+                      "migrate: %s message #%ld, size=%d, ref=%d, body=%ld, content-type: %s",
+                      (rc!= 0)?"failed to import":"imported",
                       import_msgnum,
                       StrLength(migr_MsgData),
                       smi.meta_refcount,
@@ -827,24 +826,20 @@ void migr_xml_end(void *data, const char *el)
                memset(&smi, 0, sizeof(smi));
        }
 
-       /*** MORE GENERAL STUFF ***/
+       // *** MORE GENERAL STUFF ***
 
        FlushStrBuf(migr_chardata);
 }
 
 
-/*
- * Import begins here
- */
+// Import begins here
 void migr_do_import(void) {
-       StrBuf *Buf;
        XML_Parser xp;
-       int Finished = 0;
+       char buf[SIZ];
        
        unbuffer_output();
        migr_chardata = NewStrBufPlain(NULL, SIZ * 20);
        migr_MsgData = NewStrBufPlain(NULL, SIZ * 20);
-       Buf = NewStrBufPlain(NULL, SIZ);
        xp = XML_ParserCreate(NULL);
        if (!xp) {
                cprintf("%d Failed to create XML parser instance\n", ERROR+INTERNAL_ERROR);
@@ -860,24 +855,14 @@ void migr_do_import(void) {
 
        client_set_inbound_buf(SIZ * 10);
 
-       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);
-               }
+       while (client_getln(buf, sizeof buf) >= 0 && strcmp(buf, "000")) {
+               XML_Parse(xp, buf, strlen(buf), 0);
                if (server_shutting_down)
                        break;  // Should we break or return?
-               
-               if (StrLength(Buf) == 0)
-                       continue;
-
-               XML_Parse(xp, ChrPtr(Buf), StrLength(Buf), 0);
-               FlushStrBuf(Buf);
        }
 
        XML_Parse(xp, "", 0, 1);
        XML_ParserFree(xp);
-       FreeStrBuf(&Buf);
        FreeStrBuf(&migr_chardata);
        FreeStrBuf(&migr_MsgData);
        rebuild_euid_index();
@@ -887,12 +872,11 @@ void migr_do_import(void) {
 }
 
 
-/******************************************************************************
- *                         Dispatcher, Common code                            *
- ******************************************************************************/
-/*
- * Dump out the pathnames of directories which can be copied "as is"
- */
+// ******************************************************************************
+// *                         Dispatcher, Common code                            *
+// ******************************************************************************
+
+// 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("files|%s\n",           ctdl_file_dir);
@@ -902,25 +886,22 @@ void migr_do_listdirs(void) {
 }
 
 
-/******************************************************************************
- *                    Repair database integrity                               *
- ******************************************************************************/
+/******************************************************************************
+// *                    Repair database integrity                               *
+// ******************************************************************************
 
 StrBuf *PlainMessageBuf = NULL;
 HashList *UsedMessageIDS = NULL;
 
-int migr_restore_message_metadata(long msgnum, int refcount)
-{
-       CitContext *CCC = MyContext();
+int migr_restore_message_metadata(long msgnum, int refcount) {
        struct MetaData smi;
        struct CtdlMessage *msg;
        char *mptr = NULL;
 
-       /* 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.
-        */
+       // 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;
 
@@ -938,7 +919,7 @@ int migr_restore_message_metadata(long msgnum, int refcount)
                PlainMessageBuf = NewStrBufPlain(NULL, 10*SIZ);
        }
 
-       /* Ok, here we go ... */
+       // Ok, here we go ...
 
        msg = CtdlFetchMessage(msgnum, 1);
        if (msg == NULL) {
@@ -949,7 +930,7 @@ int migr_restore_message_metadata(long msgnum, int refcount)
        smi.meta_msgnum = msgnum;
        smi.meta_refcount = refcount;
        
-       /* restore the content type from the message body: */
+       // restore the content type from the message body:
        mptr = bmstrcasestr(msg->cm_fields[eMesageText], "Content-type:");
        if (mptr != NULL) {
                char *aptr;
@@ -967,13 +948,13 @@ int migr_restore_message_metadata(long msgnum, int refcount)
                }
        }
 
-       CCC->redirect_buffer = PlainMessageBuf;
+       CC->redirect_buffer = PlainMessageBuf;
        CtdlOutputPreLoadedMsg(msg, MT_RFC822, HEADERS_ALL, 0, 1, QP_EADDR);
-       smi.meta_rfc822_length = StrLength(CCC->redirect_buffer);
-       CCC->redirect_buffer = NULL;
+       smi.meta_rfc822_length = StrLength(CC->redirect_buffer);
+       CC->redirect_buffer = NULL;
 
        syslog(LOG_INFO,
-              "Setting message #%ld meta data to: refcount=%d, bodylength=%ld, content-type: %s",
+              "migrate: setting message #%ld meta data to: refcount=%d, bodylength=%ld, content-type: %s",
               smi.meta_msgnum,
               smi.meta_refcount,
               smi.meta_rfc822_length,
@@ -981,9 +962,7 @@ int migr_restore_message_metadata(long msgnum, int refcount)
        );
 
        PutMetaData(&smi);
-
        CM_Free(msg);
-
        return 0;
 }
 
@@ -994,9 +973,7 @@ void migr_check_room_msg(long msgnum, void *userdata) {
 
 
 void migr_check_rooms_backend(struct ctdlroom *buf, void *data) {
-
-       /* message list goes inside this tag */
-
+       // message list goes inside this tag
        CtdlGetRoom(&CC->room, buf->QRname);
        CtdlForEachMessage(MSGS_ALL, 0L, NULL, NULL, NULL, migr_check_room_msg, NULL);
 }
@@ -1007,7 +984,7 @@ void RemoveMessagesFromRooms(StrBuf *RoomNameVec, long msgnum) {
        const char *Pos = NULL;
        StrBuf *oneRoom = NewStrBuf();
 
-       syslog(LOG_INFO, "removing message pointer %ld from these rooms: %s", msgnum, ChrPtr(RoomNameVec));
+       syslog(LOG_INFO, "migrate: removing message pointer %ld from these rooms: %s", msgnum, ChrPtr(RoomNameVec));
 
        while (Pos != StrBufNOTNULL){
                StrBufExtract_NextToken(oneRoom, RoomNameVec, &Pos, '|');
@@ -1035,20 +1012,20 @@ void migr_do_restore_meta(void) {
                fclose(migr_global_message_list);
        }
 
-       /*
-        * Process the 'global' message list.  (Sort it and remove dups.
-        * Dups are ok because a message may be in more than one room, but
-        * this will be handled by exporting the reference count, not by
-        * exporting the message multiple times.)
-        */
+       // Process the 'global' message list.  (Sort it and remove dups.
+       // Dups are ok because a message may be in more than one room, but
+       // this will be handled by exporting the reference count, not by
+       // exporting the message multiple times.)
        snprintf(cmd, sizeof cmd, "sort -n <%s >%s", migr_tempfilename1, migr_tempfilename2);
-       if (system(cmd) != 0) syslog(LOG_ALERT, "Error %d", errno);
+       if (system(cmd) != 0) {
+               syslog(LOG_ERR, "migrate: error %d", errno);
+       }
 
        RoomNames = NewStrBuf();
        Ctx = CC;
        migr_global_message_list = fopen(migr_tempfilename2, "r");
        if (migr_global_message_list != NULL) {
-               syslog(LOG_INFO, "Opened %s", migr_tempfilename1);
+               syslog(LOG_INFO, "migrate: opened %s", migr_tempfilename1);
                while ((Ctx->kill_me == 0) && 
                       (fgets(buf, sizeof(buf), migr_global_message_list) != NULL)) {
                        msgnum = atol(buf);
@@ -1089,19 +1066,19 @@ void migr_do_restore_meta(void) {
                fclose(migr_global_message_list);
        }
 
-       migr_restore_message_metadata(-1L, -1); /* This frees the encoding buffer */
+       migr_restore_message_metadata(-1L, -1); // This frees the encoding buffer
        cprintf("%d system analysis completed", CIT_OK);
        Ctx->kill_me = 1;
 }
 
 
-/******************************************************************************
- *                         Dispatcher, Common code                            *
- ******************************************************************************/
+/******************************************************************************
+// *                         Dispatcher, Common code                            *
+// ******************************************************************************
 void cmd_migr(char *cmdbuf) {
        char cmd[32];
        
-       if (CtdlAccessCheck(ac_internal)) return;
+       if (CtdlAccessCheck(ac_aide)) return;
        
        if (CtdlTrySingleUser()) {
                CtdlDisableHouseKeeping();
@@ -1137,9 +1114,9 @@ void cmd_migr(char *cmdbuf) {
 }
 
 
-/******************************************************************************
- *                              Module Hook                                  *
- ******************************************************************************/
+/******************************************************************************
+// *                              Module Hook                                   *
+// ******************************************************************************
 
 CTDL_MODULE_INIT(migrate)
 {
@@ -1148,6 +1125,6 @@ CTDL_MODULE_INIT(migrate)
                CtdlRegisterProtoHook(cmd_migr, "MIGR", "Across-the-wire migration");
        }
        
-       /* return our module name for the log */
+       // return our module name for the log
        return "migrate";
 }