* Began (but did not finish) applying GPL3+ declarations to each source file. This...
[citadel.git] / citadel / ctdlmigrate.c
index 1cd12dd47f8c1e21bbf4fc9c878f8d034f55ffd9..65f06c64409198b388946c1618bd11684f7f5494 100644 (file)
@@ -3,9 +3,27 @@
  *
  * Across-the-wire migration utility for Citadel
  *
+ * Yes, we used goto, and gets(), and committed all sorts of other heinous sins here.
+ * The scope of this program isn't wide enough to make a difference.  If you don't like
+ * it you can rewrite it.
+ *
  * Copyright (c) 2009 citadel.org
  *
- * This program is licensed to you under the terms of the GNU General Public License v3
+ *  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 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
+ *
+ * (Note: a useful future enhancement might be to support "-h" on both sides)
  *
  */
 
@@ -74,8 +92,8 @@ int main(int argc, char *argv[])
        char remote_user[256];
        char remote_host[256];
        char remote_sendcommand[PATH_MAX];
-       FILE *source_artv;
-       FILE *target_artv;
+       FILE *sourcefp = NULL;
+       FILE *targetfp = NULL;
        int linecount = 0;
        char spinning[4] = "-\\|/" ;
        int exitcode = 0;
@@ -83,7 +101,7 @@ int main(int argc, char *argv[])
        calc_dirs_n_files(relh, home, relhome, ctdldir, 0);
        CtdlMakeTempFileName(socket_path, sizeof socket_path);
 
-       system("clear");
+       cmdexit = system("clear");
        printf( "-------------------------------------------\n"
                "Over-the-wire migration utility for Citadel\n"
                "-------------------------------------------\n"
@@ -136,9 +154,9 @@ int main(int argc, char *argv[])
        unlink(socket_path);
        snprintf(cmd, sizeof cmd, "ssh -MNf -S %s %s@%s", socket_path, remote_user, remote_host);
        cmdexit = system(cmd);
+       printf("\n");
        if (cmdexit != 0) {
-               printf("\nctdlmigrate was unable to establish an SSH connection to the\n"
-                       "source system, and cannot continue.\n\n");
+               printf("This program was unable to establish an SSH session to the source system.\n\n");
                exitcode = cmdexit;
                goto THEEND;
        }
@@ -187,23 +205,23 @@ int main(int argc, char *argv[])
 
        snprintf(cmd, sizeof cmd, "ssh -S %s %s@%s %s -w3600 MIGR export",
                socket_path, remote_user, remote_host, remote_sendcommand);
-       source_artv = popen(cmd, "r");
-       if (!source_artv) {
+       sourcefp = popen(cmd, "r");
+       if (!sourcefp) {
                printf("\n%s\n\n", strerror(errno));
                exitcode = 2;
                goto THEEND;
        }
 
        snprintf(cmd, sizeof cmd, "%s -w3600 MIGR import", sendcommand);
-       target_artv = popen(cmd, "w");
-       if (!target_artv) {
+       targetfp = popen(cmd, "w");
+       if (!targetfp) {
                printf("\n%s\n\n", strerror(errno));
                exitcode = 3;
                goto THEEND;
        }
 
-       while (fgets(buf, sizeof buf, source_artv) != NULL) {
-               if (fwrite(buf, strlen(buf), 1, target_artv) < 1) {
+       while (fgets(buf, sizeof buf, sourcefp) != NULL) {
+               if (fwrite(buf, strlen(buf), 1, targetfp) < 1) {
                        exitcode = 4;
                        printf("%s\n", strerror(errno));
                        goto FAIL;
@@ -215,13 +233,82 @@ int main(int argc, char *argv[])
                }
        }
 
-FAIL:  pclose(source_artv);
-       pclose(target_artv);
+FAIL:  if (sourcefp) pclose(sourcefp);
+       if (targetfp) pclose(targetfp);
+       if (exitcode != 0) goto THEEND;
+
+       /* We need to copy a bunch of other stuff, and will do so using rsync */
+
+       snprintf(cmd, sizeof cmd, "ssh -S %s %s@%s %s MIGR listdirs",
+               socket_path, remote_user, remote_host, remote_sendcommand);
+       sourcefp = popen(cmd, "r");
+       if (!sourcefp) {
+               printf("\n%s\n\n", strerror(errno));
+               exitcode = 2;
+               goto THEEND;
+       }
+       while ((fgets(buf, sizeof buf, sourcefp)) && (strcmp(buf, "000"))) {
+               buf[strlen(buf)-1] = 0;
+
+               if (!strncasecmp(buf, "bio|", 4)) {
+                       snprintf(cmd, sizeof cmd, "rsync -va --rsh='ssh -S %s' %s@%s:%s/ %s/",
+                               socket_path, remote_user, remote_host, &buf[4], ctdl_bio_dir);
+               }
+               else if (!strncasecmp(buf, "files|", 6)) {
+                       snprintf(cmd, sizeof cmd, "rsync -va --rsh='ssh -S %s' %s@%s:%s/ %s/",
+                               socket_path, remote_user, remote_host, &buf[6], ctdl_file_dir);
+               }
+               else if (!strncasecmp(buf, "userpics|", 9)) {
+                       snprintf(cmd, sizeof cmd, "rsync -va --rsh='ssh -S %s' %s@%s:%s/ %s/",
+                               socket_path, remote_user, remote_host, &buf[9], ctdl_usrpic_dir);
+               }
+               else if (!strncasecmp(buf, "messages|", 9)) {
+                       snprintf(cmd, sizeof cmd, "rsync -va --rsh='ssh -S %s' %s@%s:%s/ %s/",
+                               socket_path, remote_user, remote_host, &buf[9], ctdl_message_dir);
+               }
+               else if (!strncasecmp(buf, "netconfigs|", 11)) {
+                       snprintf(cmd, sizeof cmd, "rsync -va --rsh='ssh -S %s' %s@%s:%s/ %s/",
+                               socket_path, remote_user, remote_host, &buf[11], ctdl_netcfg_dir);
+               }
+               else if (!strncasecmp(buf, "keys|", 5)) {
+                       snprintf(cmd, sizeof cmd, "rsync -va --rsh='ssh -S %s' %s@%s:%s/ %s/",
+                               socket_path, remote_user, remote_host, &buf[5], ctdl_key_dir);
+               }
+               else if (!strncasecmp(buf, "images|", 7)) {
+                       snprintf(cmd, sizeof cmd, "rsync -va --rsh='ssh -S %s' %s@%s:%s/ %s/",
+                               socket_path, remote_user, remote_host, &buf[7], ctdl_image_dir);
+               }
+               else if (!strncasecmp(buf, "info|", 5)) {
+                       snprintf(cmd, sizeof cmd, "rsync -va --rsh='ssh -S %s' %s@%s:%s/ %s/",
+                               socket_path, remote_user, remote_host, &buf[5], ctdl_info_dir);
+               }
+               else {
+                       strcpy(cmd, "false");   /* cheap and sleazy way to throw an error */
+               }
+               printf("%s\n", cmd);
+               cmdexit = system(cmd);
+               if (cmdexit != 0) {
+                       exitcode += cmdexit;
+               }
+       }
+       pclose(sourcefp);
 
-       // FIXME handle -h on both sides
-       // FIXME kill the master ssh session
-       printf("If this program was finished we would do more.  FIXME\n");
+THEEND:        if (exitcode == 0) {
+               printf("\n\n *** Citadel migration was successful! *** \n\n");
+       }
+       else {
+               printf("\n\n *** Citadel migration was unsuccessful. *** \n\n");
+       }
+       printf("\nShutting down the socket connection...\n\n");
+       snprintf(cmd, sizeof cmd, "ssh -S %s -N -O exit %s@%s",
+               socket_path, remote_user, remote_host);
+       cmdexit = system(cmd);
+       printf("\n");
+       if (cmdexit != 0) {
+               printf("There was an error shutting down the socket.\n\n");
+               exitcode = cmdexit;
+       }
 
-THEEND:        unlink(socket_path);
+       unlink(socket_path);
        exit(exitcode);
 }