X-Git-Url: https://code.citadel.org/?a=blobdiff_plain;f=citadel%2Futils%2Fctdlmigrate.c;fp=citadel%2Futils%2Fctdlmigrate.c;h=0000000000000000000000000000000000000000;hb=ee511c807bbb15b0231f7aae485c3eb38e8e01bf;hp=21dad4b24f87f331956542a95ced05e13db28ace;hpb=b9a2089d59579d13694e08b299c2aaf44ef9df6c;p=citadel.git diff --git a/citadel/utils/ctdlmigrate.c b/citadel/utils/ctdlmigrate.c deleted file mode 100644 index 21dad4b24..000000000 --- a/citadel/utils/ctdlmigrate.c +++ /dev/null @@ -1,288 +0,0 @@ -/* - * 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-2021 citadel.org - * - * 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. - * - * (Note: a useful future enhancement might be to support "-h" on both sides) - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "citadel.h" -#include "axdefs.h" -#include "sysdep.h" -#include "config.h" -#include "citadel_dirs.h" - - - -/* - * Replacement for gets() that doesn't throw a compiler warning. - * We're only using it for some simple prompts, so we don't need - * to worry about attackers exploiting it. - */ -void getz(char *buf) { - char *ptr; - - ptr = fgets(buf, SIZ, stdin); - if (!ptr) { - buf[0] = 0; - return; - } - - ptr = strchr(buf, '\n'); - if (ptr) *ptr = 0; -} - - - - - -int main(int argc, char *argv[]) { - char ctdldir[PATH_MAX]=CTDLDIR; - char yesno[5]; - char sendcommand[PATH_MAX]; - int cmdexit; - char cmd[PATH_MAX]; - char buf[PATH_MAX]; - char socket_path[PATH_MAX]; - char remote_user[SIZ]; - char remote_host[SIZ]; - char remote_sendcommand[PATH_MAX]; - FILE *sourcefp = NULL; - FILE *targetfp = NULL; - int linecount = 0; - char spinning[4] = "-\\|/" ; - int exitcode = 0; - - CtdlMakeTempFileName(socket_path, sizeof socket_path); - if (chdir(ctdldir) != 0) { - fprintf(stderr, "sendcommand: %s: %s\n", ctdldir, strerror(errno)); - exit(errno); - } - - - printf( "\033[2J\033[H\n" - "-------------------------------------------\n" - "Over-the-wire migration utility for Citadel\n" - "-------------------------------------------\n" - "\n" - "This utility is designed to migrate your Citadel installation\n" - "to a new host system via a network connection, without disturbing\n" - "the source system. The target may be a different CPU architecture\n" - "and/or operating system. The source system should be running\n" - "Citadel version %d or newer, and the target system should be running\n" - "either the same version or a newer version. You will also need\n" - "the 'rsync' utility, and OpenSSH v4 or newer.\n" - "\n" - "You must run this utility on the TARGET SYSTEM. Any existing data\n" - "on this system will be ERASED.\n" - "\n" - "Do you wish to continue? " - , - EXPORT_REV_MIN - ); - - if ((fgets(yesno, sizeof yesno, stdin) == NULL) || (tolower(yesno[0]) != 'y')) { - exit(0); - } - - printf("\n\nGreat! First we will check some things out here on our target\n" - "system to make sure it is ready to receive data.\n\n"); - - printf("Locating 'sendcommand' and checking connectivity to Citadel...\n"); - snprintf(sendcommand, sizeof sendcommand, "%s/sendcommand", ctdl_utilbin_dir); - snprintf(cmd, sizeof cmd, "%s 'NOOP'", sendcommand); - cmdexit = system(cmd); - if (cmdexit != 0) { - printf("\nctdlmigrate was unable to attach to the Citadel server\n" - "here on the target system. Is Citadel running?\n\n"); - exit(1); - } - printf("\nOK, this side is ready to go. Now we must connect to the source system.\n\n"); - - printf("Enter the host name or IP address of the source system\n" - "(example: ctdl.foo.org)\n" - "--> "); - getz(remote_host); - -get_remote_user: - printf("\nEnter the name of a user on %s who has full access to Citadel files\n" - "(usually root)\n--> ", - remote_host); - getz(remote_user); - if (IsEmptyStr(remote_user)) - goto get_remote_user; - - printf("\nEstablishing an SSH connection to the source system...\n\n"); - 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("This program was unable to establish an SSH session to the source system.\n\n"); - exitcode = cmdexit; - goto THEEND; - } - - printf("\nTesting a command over the connection...\n\n"); - snprintf(cmd, sizeof cmd, "ssh -S %s %s@%s 'echo Remote commands are executing successfully.'", - socket_path, remote_user, remote_host); - cmdexit = system(cmd); - printf("\n"); - if (cmdexit != 0) { - printf("Remote commands are not succeeding.\n\n"); - exitcode = cmdexit; - goto THEEND; - } - - printf("\nLocating the remote 'sendcommand' and Citadel installation...\n"); - snprintf(remote_sendcommand, sizeof remote_sendcommand, "/usr/local/citadel/sendcommand"); - snprintf(cmd, sizeof cmd, "ssh -S %s %s@%s %s NOOP", - socket_path, remote_user, remote_host, remote_sendcommand); - cmdexit = system(cmd); - if (cmdexit != 0) { - snprintf(remote_sendcommand, sizeof remote_sendcommand, "/usr/sbin/sendcommand"); - snprintf(cmd, sizeof cmd, "ssh -S %s %s@%s %s NOOP", - socket_path, remote_user, remote_host, remote_sendcommand); - cmdexit = system(cmd); - } - if (cmdexit != 0) { - printf("\nUnable to locate Citadel programs on the remote system. Please enter\n" - "the name of the directory on %s which contains the 'sendcommand' program.\n" - "(example: /opt/foo/citadel)\n" - "--> ", remote_host); - getz(buf); - snprintf(remote_sendcommand, sizeof remote_sendcommand, "%s/sendcommand", buf); - snprintf(cmd, sizeof cmd, "ssh -S %s %s@%s %s NOOP", - socket_path, remote_user, remote_host, remote_sendcommand); - cmdexit = system(cmd); - } - printf("\n"); - if (cmdexit != 0) { - printf("ctdlmigrate was unable to attach to the remote Citadel system.\n\n"); - exitcode = cmdexit; - goto THEEND; - } - - printf("ctdlmigrate will now begin a database migration...\n"); - printf(" if the system doesn't start working, \n"); - printf(" have a look at the syslog for pending jobs needing to be terminated.\n"); - - snprintf(cmd, sizeof cmd, "ssh -S %s %s@%s %s -w3600 MIGR export", - 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; - } - - snprintf(cmd, sizeof cmd, "%s -w3600 MIGR import", sendcommand); - targetfp = popen(cmd, "w"); - if (!targetfp) { - printf("\n%s\n\n", strerror(errno)); - exitcode = 3; - goto THEEND; - } - - while (fgets(buf, sizeof buf, sourcefp) != NULL) { - if (fwrite(buf, strlen(buf), 1, targetfp) < 1) { - exitcode = 4; - printf("%s\n", strerror(errno)); - goto FAIL; - } - ++linecount; - if ((linecount % 100) == 0) { - printf("%c\r", spinning[((linecount / 100) % 4)]); - fflush(stdout); - } - } - -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, "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, "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, "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 { - 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); - -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; - } - - unlink(socket_path); - exit(exitcode); -}