]> code.citadel.org Git - citadel.git/blob - citadel/serv_upgrade.c
* Unified the "unpacked database" format for both upgrades and
[citadel.git] / citadel / serv_upgrade.c
1 #include <stdlib.h>
2 #include <unistd.h>
3 #include <stdio.h>
4 #include <fcntl.h>
5 #include <signal.h>
6 #include <pwd.h>
7 #include <errno.h>
8 #include <sys/types.h>
9 #include <sys/time.h>
10 #include <sys/wait.h>
11 #include <string.h>
12 #include <limits.h>
13 #include <pthread.h>
14 #include "citadel.h"
15 #include "server.h"
16 #include <syslog.h>
17 #include "sysdep_decls.h"
18 #include "citserver.h"
19 #include "support.h"
20 #include "config.h"
21 #include "dynloader.h"
22 #include "room_ops.h"
23 #include "user_ops.h"
24 #include "database.h"
25 #include "control.h"
26
27 extern struct CitContext *ContextList;
28 FILE *imfp;
29
30 #define MODULE_NAME     "Import an unpacked system"
31 #define MODULE_AUTHOR   "Art Cancro"
32 #define MODULE_EMAIL    "ajc@uncnsrd.mt-kisco.ny.us"
33 #define MAJOR_VERSION   0
34 #define MINOR_VERSION   2
35
36 static struct DLModule_Info info = {
37   MODULE_NAME,
38   MODULE_AUTHOR,
39   MODULE_EMAIL,
40   MAJOR_VERSION,
41   MINOR_VERSION
42 };
43
44
45
46
47 void fpgetfield(fp,string)
48 FILE *fp;
49 char string[];
50 {
51         int a,b;
52         strcpy(string,"");
53         a=0;
54         do {
55                 b=getc(fp);
56                 if (b<1) {
57                         string[a]=0;
58                         return;
59                         }
60                 string[a]=b;
61                 ++a;
62                 } while (b!=0);
63         }
64
65
66 void import_message(long msgnum, long msglen) {
67         char *msgtext;
68
69         msgtext = malloc(msglen);
70         if (msgtext == NULL) {
71                 lprintf(3, "ERROR: cannot allocate memory\n");
72                 lprintf(3, "Your data files are now corrupt.\n");
73                 fclose(imfp);
74                 exit(1);
75                 }
76
77         fread(msgtext, msglen, 1, imfp);
78         cdb_store(CDB_MSGMAIN, &msgnum, sizeof(long), msgtext, msglen);
79         free(msgtext);
80         }
81
82 void imp_floors() {
83         char key[256], tag[256], tval[256];
84         struct floor fl;
85         int floornum = 0;
86
87
88         while(fpgetfield(imfp, key), strcasecmp(key, "endsection")) {
89
90                 if (!strcasecmp(key, "floor")) {
91                         bzero(&fl, sizeof(struct floor));
92
93                         while(fpgetfield(imfp, tag),
94                              strcasecmp(tag, "endfloor")) {
95                                 fpgetfield(imfp, tval);
96
97                                 if (!strcasecmp(tag, "f_flags")) 
98                                         fl.f_flags = atoi(tval);
99                                 if (!strcasecmp(tag, "f_name")) {
100                                         lprintf(9, "Floor <%s>\n", tval);
101                                         strcpy(fl.f_name, tval);        
102                                         }
103                                 if (!strcasecmp(tag, "f_ref_count")) 
104                                         fl.f_ref_count = atoi(tval);
105                                 }
106
107                         putfloor(&fl, floornum);
108                         ++floornum;
109                         }
110                 else {
111                         lprintf(3, "ERROR: invalid floor section.\n");
112                         lprintf(3, "Your data files are now corrupt.\n");
113                         fclose(imfp);
114                         return;
115                         }
116                 }
117         }
118
119
120
121 void imp_rooms() {
122         char key[256];
123         char tag[256], tval[256];
124         int roomnum = 0;
125         struct quickroom qr;
126         long *msglist;
127         int num_msgs = 0;
128         long msgnum, msglen;
129         
130         while(fpgetfield(imfp, key), strcasecmp(key, "endsection")) {
131                 if (!strcasecmp(key, "room")) {
132                         bzero(&qr, sizeof(struct quickroom));
133                         msglist = NULL;
134                         num_msgs = 0;
135                         lprintf(9, "Room ");
136
137                         while(fpgetfield(imfp, tag),
138                              strcasecmp(tag, "endroom")) {
139                                 if (strcasecmp(tag, "message")) {
140                                         fpgetfield(imfp, tval);
141                                         }
142                                 else {
143                                         strcpy(tval, "");
144                                         }
145
146                                 if (!strcasecmp(tag, "qrname")) {
147                                         strcpy(qr.QRname, tval);
148                                         lprintf(9, "<%s>", qr.QRname);
149                                         }
150                                 if (!strcasecmp(tag, "qrpasswd"))
151                                         strcpy(qr.QRpasswd, tval);
152                                 if (!strcasecmp(tag, "qrroomaide"))
153                                         qr.QRroomaide = atol(tval);
154                                 if (!strcasecmp(tag, "qrhighest"))
155                                         qr.QRhighest = atol(tval);
156                                 if (!strcasecmp(tag, "qrgen"))
157                                         qr.QRgen = atol(tval);
158                                 if (!strcasecmp(tag, "qrflags"))
159                                         qr.QRflags = atoi(tval);
160                                 if (!strcasecmp(tag, "qrdirname"))
161                                         strcpy(qr.QRdirname, tval);
162                                 if (!strcasecmp(tag, "qrinfo"))
163                                         qr.QRinfo = atol(tval);
164                                 if (!strcasecmp(tag, "qrfloor"))
165                                         qr.QRfloor = atoi(tval);
166                                 if (!strcasecmp(tag, "message")) {
167                                         lprintf(9, ".");
168                                         fpgetfield(imfp, tval);
169                                         msgnum = atol(tval);
170                                         fpgetfield(imfp, tval);
171                                         msglen = atol(tval);
172                                         import_message(msgnum, msglen);
173                                         ++num_msgs;
174                                         msglist = realloc(msglist,
175                                                 (sizeof(long)*num_msgs) );
176                                         msglist[num_msgs - 1] = msgnum;
177                                         }
178
179                                 }
180
181                         lprintf(9, "\n");
182                         if ((roomnum!=1)&&(qr.QRflags&QR_INUSE)) {
183                                 putroom(&qr, qr.QRname);
184                                 }
185
186                         if (num_msgs > 0) {
187                                 if ((roomnum!=1)&&(qr.QRflags&QR_INUSE)) {
188                                         CC->msglist = msglist;
189                                         CC->num_msgs = num_msgs;
190                                         put_msglist(&qr);
191                                         }
192                                 free(msglist);
193                                 }
194
195                         ++roomnum;
196
197                         }
198                 else {
199                         lprintf(3, "ERROR: invalid room section.\n");
200                         lprintf(3, "Your data files are now corrupt.\n");
201                         fclose(imfp);
202                         return;
203                         }
204                 }
205         }
206
207
208
209
210
211 void import_a_user() {
212         char key[256], value[256];
213         char vkey[256], vvalue[256];
214         struct usersupp us;
215         struct quickroom qr;
216         struct visit vbuf;
217
218         bzero(&us, sizeof(struct usersupp));    
219         while(fpgetfield(imfp, key), strcasecmp(key, "enduser")) {
220                 if ((strcasecmp(key, "mail"))
221                    &&(strcasecmp(key, "visit")) ) {
222                         fpgetfield(imfp, value);
223                         }
224                 else {
225                         strcpy(value, "");
226                         }
227
228                 if (!strcasecmp(key, "usuid"))
229                         us.USuid = atoi(value);
230                 if (!strcasecmp(key, "password")) {
231                         strcpy(us.password, value);
232                         }
233
234                 if (!strcasecmp(key, "flags"))
235                         us.flags = atoi(value);
236                 if (!strcasecmp(key, "timescalled"))
237                         us.timescalled = atoi(value);
238                 if (!strcasecmp(key, "posted"))
239                         us.posted = atoi(value);
240                 if (!strcasecmp(key, "fullname")) {
241                         strcpy(us.fullname, value);
242                         lprintf(9, "User <%s>", us.fullname);
243                         }
244                 if (!strcasecmp(key, "axlevel"))
245                         us.axlevel = atoi(value);
246                 if (!strcasecmp(key, "usscreenwidth"))
247                         us.USscreenwidth = atoi(value);
248                 if (!strcasecmp(key, "usscreenheight"))
249                         us.USscreenheight = atoi(value);
250                 if (!strcasecmp(key, "usernum"))
251                         us.usernum = atol(value);
252                 if (!strcasecmp(key, "lastcall"))
253                         us.lastcall = atol(value);
254                 if (!strcasecmp(key, "usname"))
255                         strcpy(us.USname, value);
256                 if (!strcasecmp(key, "usaddr"))
257                         strcpy(us.USaddr, value);
258                 if (!strcasecmp(key, "uscity"))
259                         strcpy(us.UScity, value);
260                 if (!strcasecmp(key, "usstate"))
261                         strcpy(us.USstate, value);
262                 if (!strcasecmp(key, "uszip"))
263                         strcpy(us.USzip, value);
264                 if (!strcasecmp(key, "usphone"))
265                         strcpy(us.USphone, value);
266                 if (!strcasecmp(key, "usemail"))
267                         strcpy(us.USemail, value);
268                 if (!strcasecmp(key, "visit")) {
269                         lprintf(9,"v");
270                         bzero(&vbuf, sizeof(struct visit));
271                         bzero(&qr, sizeof(struct quickroom));
272                         while(fpgetfield(imfp, vkey),
273                           strcasecmp(vkey, "endvisit")) {
274                                 fpgetfield(imfp, vvalue);
275                                 if (!strcasecmp(vkey, "vname")) 
276                                         strcpy(qr.QRname, vvalue);
277                                 if (!strcasecmp(vkey, "vgen"))  {
278                                         qr.QRgen = atol(vvalue);
279                                         CtdlGetRelationship(&vbuf, &us, &qr);
280                                         }
281                                 if (!strcasecmp(vkey, "lastseen"))      
282                                         vbuf.v_lastseen = atol(vvalue);
283                                 if (!strcasecmp(vkey, "flags"))
284                                         vbuf.v_flags = atoi(vvalue);
285                                 }
286                         CtdlSetRelationship(&vbuf, &us, &qr);
287                         }
288                 }
289         
290         putuser(&us, us.fullname);
291
292         lprintf(9, "\n");
293         }
294
295
296 void imp_usersupp() {
297         char key[256], value[256];
298         
299         while(fpgetfield(imfp, key), strcasecmp(key, "endsection")) {
300                 if (strcasecmp(key, "user")) {
301                         fpgetfield(imfp, value);
302                         }
303                 else {
304                         strcpy(value, "");
305                         }
306                 lprintf(9, " %s = %s\n", key, value);
307
308                 if (!strcasecmp(key, "user")) {
309                         import_a_user();
310                         }
311                 }               
312         }
313
314
315
316
317
318 void imp_globals() {
319         char key[256], value[256];
320
321         get_control();
322         while(fpgetfield(imfp, key), strcasecmp(key, "endsection")) {
323                 fpgetfield(imfp, value);
324                 lprintf(9, " %s = %s\n", key, value);
325
326                 if (!strcasecmp(key, "mmhighest"))
327                         CitControl.MMhighest = atol(value);
328                 if (!strcasecmp(key, "mmnextuser"))
329                         CitControl.MMnextuser = atol(value);
330
331                 }
332         put_control();
333         }
334
335
336
337 void imp_config() { 
338         char key[256], value[256];
339         FILE *fp;
340
341         while(fpgetfield(imfp, key), strcasecmp(key, "endsection")) {
342                 fpgetfield(imfp, value);
343                 lprintf(9, " %s = %s\n", key, value);
344
345                 if (!strcasecmp(key, "c_nodename"))
346                         strcpy(config.c_nodename, value);
347                 if (!strcasecmp(key, "c_fqdn"))
348                         strcpy(config.c_fqdn, value);
349                 if (!strcasecmp(key, "c_humannode"))
350                         strcpy(config.c_humannode, value);
351                 if (!strcasecmp(key, "c_phonenum"))
352                         strcpy(config.c_phonenum, value);
353                 if (!strcasecmp(key, "c_phonenum"))
354                         strcpy(config.c_phonenum, value);
355                 if (!strcasecmp(key, "c_bbsuid"))
356                         config.c_bbsuid = atoi(value);
357                 if (!strcasecmp(key, "c_creataide"))
358                         config.c_creataide = atoi(value);
359                 if (!strcasecmp(key, "c_sleeping"))
360                         config.c_sleeping = atoi(value);
361                 if (!strcasecmp(key, "c_initax"))
362                         config.c_initax = atoi(value);
363                 if (!strcasecmp(key, "c_regiscall"))
364                         config.c_regiscall = atoi(value);
365                 if (!strcasecmp(key, "c_twitdetect"))
366                         config.c_twitdetect = atoi(value);
367                 if (!strcasecmp(key, "c_twitroom"))
368                         strcpy(config.c_twitroom, value);
369                 if (!strcasecmp(key, "c_defent"))
370                         config.c_defent = atoi(value);
371                 if (!strcasecmp(key, "c_moreprompt"))
372                         strcpy(config.c_moreprompt, value);
373                 if (!strcasecmp(key, "c_restrict"))
374                         config.c_restrict = atoi(value);
375                 if (!strcasecmp(key, "c_bbs_city"))
376                         strcpy(config.c_bbs_city, value);
377                 if (!strcasecmp(key, "c_sysadm"))
378                         strcpy(config.c_sysadm, value);
379                 if (!strcasecmp(key, "c_bucket_dir"))
380                         strcpy(config.c_bucket_dir, value);
381                 if (!strcasecmp(key, "c_setup_level"))
382                         config.c_setup_level = atoi(value);
383                 if (!strcasecmp(key, "c_maxsessions"))
384                         config.c_maxsessions = atoi(value);
385                 if (!strcasecmp(key, "c_net_password"))
386                         strcpy(config.c_net_password, value);
387                 if (!strcasecmp(key, "c_port_number"))
388                         config.c_port_number = atoi(value);
389                 }
390
391         fp = fopen("citadel.config", "wb");
392         fwrite(&config, sizeof(struct config), 1, fp);
393         fclose(fp);
394         }
395                 
396                 
397
398
399
400 void imp_ssv() {
401         char key[256], value[256];
402         int ssv_maxfloors = MAXFLOORS;
403         
404         while(fpgetfield(imfp, key), strcasecmp(key, "endsection")) {
405                 fpgetfield(imfp, value);
406                 lprintf(9, " %s = %s\n", key, value);
407                 
408                 if (!strcasecmp(key, "maxfloors")) {
409                         ssv_maxfloors = atol(value);
410                         if (ssv_maxfloors > MAXFLOORS) {
411                                 lprintf(3, "ERROR: maxfloors is %d, need %d\n",
412                                         ssv_maxfloors, MAXFLOORS);
413                                 fclose(imfp);
414                                 return;
415                                 }
416                         }
417                 }
418         }
419
420
421
422
423
424
425
426 void import_databases() {
427         char section[256];
428
429         lprintf(9, " ** IMPORTING ** \n");
430         while (fpgetfield(imfp, section), strcasecmp(section, "endfile")) {
431                 lprintf(9, "Section: <%s>\n", section);
432
433                 if (!strcasecmp(section, "ssv"))                imp_ssv();
434                 else if (!strcasecmp(section, "config"))        imp_config();
435                 else if (!strcasecmp(section, "globals"))       imp_globals();
436                 else if (!strcasecmp(section, "usersupp"))      imp_usersupp();
437                 else if (!strcasecmp(section, "rooms"))         imp_rooms();
438                 else if (!strcasecmp(section, "floors"))        imp_floors();
439                 else {
440                         lprintf(3, "ERROR: invalid import section.\n");
441                         lprintf(3, "Your data files are now corrupt.\n");
442                         fclose(imfp);
443                         return;
444                         }
445
446                 }
447
448         }
449
450
451
452 void do_import(char *argbuf) {
453         char import_filename[PATH_MAX];
454         
455
456         if (num_parms(argbuf) != 1) {
457                 cprintf("%d usage: IMPO unpacked_filename\n", ERROR);
458                 return;
459                 }
460         extract(import_filename, argbuf, 0);
461         imfp = fopen(import_filename, "rb");
462         if (imfp == NULL) {
463                 lprintf(9, "Cannot open %s: %s\n",
464                         import_filename, strerror(errno));
465                 cprintf("%d Cannot open file\n", ERROR);
466                 return;
467                 }
468
469         import_databases();
470         cprintf("%d ok\n", OK);
471         }
472
473
474 struct DLModule_Info *Dynamic_Module_Init(void) {
475         CtdlRegisterProtoHook(do_import,
476                                 "IMPO",
477                                 "Import an unpacked Cit5");
478         return &info;
479         }