- 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);
- 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);
-
- 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);
- if (cmdexit != 0) {
- printf("\nctdlmigrate was unable to establish an SSH connection to the\n"
- "source system, and cannot continue.\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");
-
- 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) {
- 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) {
- 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) {
- exitcode = 4;
- printf("%s\n", strerror(errno));
- goto FAIL;
- }
- ++linecount;
- if ((linecount % 100) == 0) {
- printf("%c\r", spinning[((linecount / 100) % 4)]);
- fflush(stdout);
- }
- }
-
-FAIL: pclose(source_artv);
- pclose(target_artv);
-
- // 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: unlink(socket_path);
- exit(exitcode);
+ getz(yesno, 1, NULL, "Do you wish to continue? ");
+ puts(yesno);
+ if (tolower(yesno[0]) != 'y') {
+ cmdexit = 1;
+ }
+
+ if (!cmdexit) {
+ printf( "\033[2J\033[H\n"
+ "\033[32m╔═══════════════════════════════════════════════╗\n"
+ "║ ║\n"
+ "║ \033[33mValidate source and target systems\033[32m ║\n"
+ "║ ║\n"
+ "╚═══════════════════════════════════════════════╝\033[0m\n"
+ "\n\n");
+
+ printf("First we must validate that the local target system is running\n");
+ printf("and ready to receive data.\n");
+ printf("Checking connectivity to Citadel in %s...\n", ctdldir);
+ local_admin_socket = uds_connectsock("citadel-admin.socket");
+ if (local_admin_socket < 0) {
+ cmdexit = 1;
+ }
+ }
+
+ if (!cmdexit) {
+ serv_gets(local_admin_socket, buf);
+ puts(buf);
+ if (buf[0] != '2') {
+ cmdexit = 1;
+ }
+ }
+
+ if (!cmdexit) {
+ serv_puts(local_admin_socket, "ECHO Connection to Citadel Server succeeded.");
+ serv_gets(local_admin_socket, buf);
+ puts(buf);
+ if (buf[0] != '2') {
+ cmdexit = 1;
+ }
+ }
+
+ if (!cmdexit) {
+ printf("\n");
+ printf("OK, this side is ready to go. Now we must connect to the source system.\n\n");
+
+ getz(remote_host, sizeof remote_host, NULL, "Enter the name or IP address of the source system: ");
+ getz(remote_user, sizeof remote_user, "admin", " Enter the user name of an administrator account: ");
+ getz(remote_pass, sizeof remote_pass, NULL, " Enter the password for this account: ");
+
+ remote_server_socket = tcp_connectsock(remote_host, remote_port);
+ if (remote_server_socket < 0) {
+ cmdexit = 1;
+ }
+ }
+
+ if (!cmdexit) {
+ serv_gets(remote_server_socket, buf);
+ puts(buf);
+ if (buf[0] != '2') {
+ cmdexit = 1;
+ }
+ }
+
+ if (!cmdexit) {
+ serv_printf(remote_server_socket, "USER %s\n", remote_user);
+ serv_gets(remote_server_socket, buf);
+ puts(buf);
+ if (buf[0] != '3') {
+ cmdexit = 1;
+ }
+ }
+
+ if (!cmdexit) {
+ serv_printf(remote_server_socket, "PASS %s\n", remote_pass);
+ serv_gets(remote_server_socket, buf);
+ puts(buf);
+ if (buf[0] != '2') {
+ cmdexit = 1;
+ }
+ }
+
+ if (!cmdexit) {
+ printf( "\033[2J\033[H\n"
+ "\033[32m╔═══════════════════════════════════════════════════════════════════╗\n"
+ "║ ║\n"
+ "║ \033[33mMigrating from: %-50s\033[32m║\n"
+ "║ ║\n"
+ "╠═══════════════════════════════════════════════════════════════════╣\n"
+ "║ ║\n"
+ "║ Lines received: 0 Percent complete: 0 ║\n"
+ "║ ║\n"
+ "╚═══════════════════════════════════════════════════════════════════╝\033[0m\n"
+ "\n", remote_host
+ );
+ }
+
+ if (!cmdexit) {
+ serv_puts(remote_server_socket, "MIGR export");
+ serv_gets(remote_server_socket, buf);
+ if (buf[0] != '1') {
+ printf("\n\033[31m%s\033[0m\n", buf);
+ cmdexit = 3;
+ }
+ }
+
+ if (!cmdexit) {
+ serv_puts(local_admin_socket, "MIGR import");
+ serv_gets(local_admin_socket, buf);
+ if (buf[0] != '4') {
+ printf("\n\033[31m%s\033[0m\n", buf);
+ cmdexit = 3;
+ }
+ }
+
+ if (!cmdexit) {
+ char *ptr;
+ time_t last_update = time(NULL);
+
+ while (serv_gets(remote_server_socket, buf), strcmp(buf, "000")) {
+ ptr = strchr(buf, '\n');
+ if (ptr) *ptr = 0; // remove the newline character
+ ++linecount;
+ if (!strncasecmp(buf, "<progress>", 10)) {
+ progress = atoi(&buf[10]);
+ printf("\033[8;65H\033[33m%d\033[0m\033[12;0H\n", progress);
+ }
+ if (time(NULL) != last_update) {
+ last_update = time(NULL);
+ printf("\033[8;19H\033[33m%d\033[0m\033[12;0H\n", linecount);
+ }
+ serv_puts(local_admin_socket, buf);
+ }
+
+ serv_puts(local_admin_socket, "000");
+ }
+
+ if ( (cmdexit == 0) && (progress < 100) ) {
+ printf("\033[31mERROR: source stream ended before 100 percent of data was received.\033[0m\n");
+ ctdlmigrate_exit(86);
+ }
+
+ // FIXME restart the local server here
+
+ close(remote_server_socket);
+ close(local_admin_socket);
+ ctdlmigrate_exit(cmdexit);