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