df30221d13cb3670ad5b8d6024786b19f37ff0f8
[citadel.git] / citadel / migratenet.c
1 /*
2  * $Id$
3  * 
4  * 5.80 to 5.90 migration utility for network files
5  *
6  */
7
8 #include <stdlib.h>
9 #include <unistd.h>
10 #include <stdio.h>
11 #include <string.h>
12 #include <sys/types.h>
13 #include <dirent.h>
14 #include <errno.h>
15 #ifdef HAVE_LIMITS_H
16 #include <limits.h>
17 #endif
18 #include "citadel.h"
19 #include "citadel_ipc.h"
20 #include "tools.h"
21 #include "config.h"
22
23 struct mn_roomlist {
24         struct mn_roomlist *next;
25         char roomname[SIZ];
26 };
27
28 void logoff(int code)
29 {
30         exit(code);
31 }
32
33 int main(int argc, char **argv)
34 {
35         char buf[SIZ];
36         char hostbuf[SIZ];
37         char portbuf[SIZ];
38         DIR *dp;
39         struct dirent *d;
40         long highest = 0L;
41         char node[SIZ];
42         char room[SIZ];
43         long thighest;
44         FILE *fp;
45         FILE *roomfp;
46         char roomfilename[SIZ];
47         FILE *nodefp;
48         char nodefilename[SIZ];
49         char *listing = NULL;
50         struct mn_roomlist *mn = NULL;
51         struct mn_roomlist *mnptr = NULL;
52         CtdlIPC *ipc = NULL;
53         int r;
54
55         printf("\n\n\n\n\n"
56 "This utility migrates your network settings (room sharing with other\n"
57 "Citadel systems) from 5.80 to 5.90.  You should only do this ONCE.  It\n"
58 "will ERASE your 5.80 configuration files when it is finished, and it will\n"
59 "ERASE any 5.90 configuration files that you have already set up.\n\n"
60 "Are you sure you want to do this? ");
61
62         fgets(buf, sizeof buf, stdin);
63         if (tolower(buf[0]) != 'y') exit(0);
64
65         get_config();
66
67         ipc = CtdlIPC_new(argc, argv, hostbuf, portbuf);
68         CtdlIPC_getline(ipc, buf);
69         printf("%s\n", &buf[4]);
70         if ( (buf[0]!='2') && (strncmp(buf,"551",3)) ) {
71                 fprintf(stderr, "%s: %s\n", argv[0], &buf[4]);
72                 logoff(atoi(buf));
73         }
74
75         r = CtdlIPCInternalProgram(ipc, config.c_ipgm_secret, buf);
76         fprintf(stderr, "%s\n", buf);
77         if (r / 100 != 2) {
78                 exit(2);
79         }
80
81         if (chdir("network/systems") != 0) {
82                 perror("cannot chdir network/systems");
83                 exit(errno);
84         }
85
86         strcpy(roomfilename, tmpnam(NULL));
87         roomfp = fopen(roomfilename, "w");
88         if (roomfp == NULL) {
89                 perror("cannot open temp file");
90                 exit(errno);
91         }
92
93         strcpy(nodefilename, tmpnam(NULL));
94         nodefp = fopen(nodefilename, "w");
95         if (roomfp == NULL) {
96                 perror("cannot open temp file");
97                 exit(errno);
98         }
99
100         dp = opendir(".");
101         if (dp == NULL) {
102                 perror("cannot open directory");
103                 exit(errno);
104         }
105
106         while (d = readdir(dp), d != NULL) {
107                 fp = NULL;
108                 if ( (d->d_name[0] != '.') && strcasecmp(d->d_name, "CVS")) {
109                         fp = fopen(d->d_name, "r");
110                 }
111                 if (fp != NULL) {
112                         printf("\n*** Processing '%s'\n", d->d_name);
113
114                         fprintf(nodefp, "%s|", d->d_name);
115                         printf("Enter shared secret: ");
116                         myfgets(buf, sizeof buf, stdin);
117                         if (buf[0] == 0) strcpy(buf, config.c_net_password);
118                         fprintf(nodefp, "%s|", buf);
119                         printf("Enter host name/IP : ");
120                         myfgets(buf, sizeof buf, stdin);
121                         if (buf[0] == 0) snprintf(buf, sizeof buf, "%s.citadel.org",
122                                 d->d_name);
123                         fprintf(nodefp, "%s|", buf);
124                         printf("Enter port number  : ");
125                         fgets(buf, sizeof buf, stdin);
126                         if (buf[0] == 0) strcpy(buf, "504");
127                         fprintf(nodefp, "%s\n", buf);
128
129                         fgets(buf, sizeof buf, fp);
130                         printf("skipping: %s", buf);
131                         while (fgets(room, sizeof room, fp),
132                               (fgets(buf, sizeof buf, fp) != NULL) ) {
133                                 thighest = atol(buf),
134                                 room[strlen(room) - 1] = 0;
135                                 fprintf(roomfp, "%s|%s\n",
136                                         d->d_name, room);
137                                 if (thighest > highest) {
138                                         highest = thighest;
139                                 }
140                         }
141                         fclose(fp);
142                 }
143         }
144
145         closedir(dp);
146         fclose(roomfp);
147         fclose(nodefp);
148
149         /* Point of no return */
150         nodefp = fopen(nodefilename, "r");
151         if (nodefp != NULL) {
152                 fseek(nodefp, 0L, SEEK_END);
153                 listing = malloc(ftell(nodefp) + 1);
154                 *listing = 0;
155                 while (fgets(buf, sizeof buf, nodefp) != NULL) {
156                         strcat(listing, buf);
157                 }
158                 fclose(nodefp);
159         }
160
161         /* Set up the node table */
162         printf("Creating neighbor node table\n");
163         r = CtdlIPCSetSystemConfigByType(ipc, IGNETCFG, listing, buf);
164         free(listing);
165         listing = NULL;
166         if (r / 100 != 4) {
167                 printf("%s\n", buf);
168         }
169
170         /* Now go through the table looking for node names to enter */
171         snprintf(buf, sizeof buf, "cat %s |awk -F \"|\" '{ print $2 }' |sort -f |uniq -i",
172                 roomfilename);
173         roomfp = popen(buf, "r");
174         if (roomfp == NULL) {
175                 perror("cannot open pipe");
176                 unlink(roomfilename);
177         }
178
179         while (fgets(room, sizeof room, roomfp) != NULL) {
180                 room[strlen(room)-1] = 0;
181                 if (strlen(room) > 0) {
182                         mnptr = (struct mn_roomlist *)
183                                 malloc(sizeof (struct mn_roomlist));
184                         strcpy(mnptr->roomname, room);
185                         mnptr->next = mn;
186                         mn = mnptr;
187                 }
188         }
189
190         pclose(roomfp);
191
192         /* Enter configurations for each room... */
193         while (mn != NULL) {
194                 struct ctdlipcroom *current_room = NULL;
195         
196                 printf("Room <%s>\n", mn->roomname);
197
198                 r = CtdlIPCGotoRoom(ipc, mn->roomname, NULL,
199                                 &current_room, buf);
200                 printf("%s\n", buf);
201                 if (r / 100 != 2) goto roomerror;
202
203                 /* Hey IG, what the hell is SNET? */
204                 CtdlIPC_putline(ipc, "SNET");
205                 CtdlIPC_getline(ipc, buf);
206                 if (buf[0] != '4') goto roomerror;
207
208                 snprintf(buf, sizeof buf, "lastsent|%ld", highest);
209                 CtdlIPC_putline(ipc, buf);
210
211                 roomfp = fopen(roomfilename, "r");
212                 if (roomfp != NULL) {
213                         while (fgets(buf, sizeof buf, roomfp) != NULL) {
214                                 buf[strlen(buf)-1] = 0;
215                                 extract(node, buf, 0);
216                                 extract(room, buf, 1);
217                                 if (!strcasecmp(room, mn->roomname)) {
218                                         snprintf(buf, sizeof buf,
219                                                 "ignet_push_share|%s", node);
220                                         CtdlIPC_putline(ipc, buf);
221                                 }
222                         }
223                         fclose(roomfp);
224                 }
225
226                 CtdlIPC_putline(ipc, "000");
227
228 roomerror:      /* free this record */
229                 mnptr = mn->next;
230                 free(mn);
231                 mn = mnptr;
232         }
233
234         unlink(roomfilename);
235         unlink(nodefilename);
236
237         printf("\n\n"
238                 "If this conversion was successful, you do not need your\n"
239                 "old network configuration files.  Delete them now? "
240         );
241
242         fgets(buf, sizeof buf, stdin);
243         if (tolower(buf[0]) != 'y') exit(0);
244
245         get_config();
246         system("rm -fr ./network/systems");
247         system("rm -f ./network/mail.sysinfo");
248         system("rm -f ./network/internetmail.config");
249
250         exit(0);
251 }