]> code.citadel.org Git - citadel.git/blob - citadel/serv_upgrade.c
more export stuff
[citadel.git] / citadel / serv_upgrade.c
1 /*
2  * This module imports an "unpacked" system.  The unpacked data may come from
3  * an older version of Citadel, or a different hardware architecture, or
4  * whatever.  You should only run an import when your installed system is
5  * brand new and _empty_ !!
6  */
7
8 #include <stdlib.h>
9 #include <unistd.h>
10 #include <stdio.h>
11 #include <fcntl.h>
12 #include <signal.h>
13 #include <pwd.h>
14 #include <errno.h>
15 #include <sys/types.h>
16 #include <sys/time.h>
17 #include <sys/wait.h>
18 #include <string.h>
19 #include <limits.h>
20 #include <pthread.h>
21 #include "citadel.h"
22 #include "server.h"
23 #include <syslog.h>
24 #include "sysdep_decls.h"
25 #include "citserver.h"
26 #include "support.h"
27 #include "config.h"
28 #include "dynloader.h"
29 #include "room_ops.h"
30 #include "user_ops.h"
31 #include "database.h"
32 #include "control.h"
33
34 extern struct CitContext *ContextList;
35 FILE *imfp, *exfp;
36
37 #define MODULE_NAME     "Import an unpacked system"
38 #define MODULE_AUTHOR   "Art Cancro"
39 #define MODULE_EMAIL    "ajc@uncnsrd.mt-kisco.ny.us"
40 #define MAJOR_VERSION   0
41 #define MINOR_VERSION   3
42
43 static struct DLModule_Info info = {
44         MODULE_NAME,
45         MODULE_AUTHOR,
46         MODULE_EMAIL,
47         MAJOR_VERSION,
48         MINOR_VERSION
49         };
50
51
52
53 void fpgetfield(FILE *fp, char *string)
54 {
55         int a,b;
56         strcpy(string,"");
57         a=0;
58         do {
59                 b=getc(fp);
60                 if (b<1) {
61                         string[a]=0;
62                         return;
63                         }
64                 string[a]=b;
65                 ++a;
66                 } while (b!=0);
67         }
68
69
70 void import_message(long msgnum, long msglen) {
71         char *msgtext;
72
73         msgtext = malloc(msglen);
74         if (msgtext == NULL) {
75                 lprintf(3, "ERROR: cannot allocate memory\n");
76                 lprintf(3, "Your data files are now corrupt.\n");
77                 fclose(imfp);
78                 exit(1);
79                 }
80
81         fread(msgtext, msglen, 1, imfp);
82         cdb_store(CDB_MSGMAIN, &msgnum, sizeof(long), msgtext, msglen);
83         free(msgtext);
84         }
85
86 void imp_floors(void) {
87         char key[256], tag[256], tval[256];
88         struct floor fl;
89         int floornum = 0;
90
91
92         while(fpgetfield(imfp, key), strcasecmp(key, "endsection")) {
93
94                 if (!strcasecmp(key, "floor")) {
95                         bzero(&fl, sizeof(struct floor));
96
97                         while(fpgetfield(imfp, tag),
98                              strcasecmp(tag, "endfloor")) {
99                                 fpgetfield(imfp, tval);
100
101                                 if (!strcasecmp(tag, "f_flags")) 
102                                         fl.f_flags = atoi(tval);
103                                 if (!strcasecmp(tag, "f_name")) {
104                                         lprintf(9, "Floor <%s>\n", tval);
105                                         strcpy(fl.f_name, tval);        
106                                         }
107                                 if (!strcasecmp(tag, "f_ref_count")) 
108                                         fl.f_ref_count = atoi(tval);
109                                 }
110
111                         putfloor(&fl, floornum);
112                         ++floornum;
113                         }
114                 else {
115                         lprintf(3, "ERROR: invalid floor section.\n");
116                         lprintf(3, "Your data files are now corrupt.\n");
117                         fclose(imfp);
118                         return;
119                         }
120                 }
121         }
122
123
124
125 void imp_rooms(void) {
126         char key[256];
127         char tag[256], tval[256];
128         int roomnum = 0;
129         struct quickroom qr;
130         long *msglist;
131         int num_msgs = 0;
132         long msgnum, msglen;
133         
134         while(fpgetfield(imfp, key), strcasecmp(key, "endsection")) {
135                 if (!strcasecmp(key, "room")) {
136                         bzero(&qr, sizeof(struct quickroom));
137                         msglist = NULL;
138                         num_msgs = 0;
139                         lprintf(9, "Room ");
140
141                         while(fpgetfield(imfp, tag),
142                              strcasecmp(tag, "endroom")) {
143                                 if (strcasecmp(tag, "message")) {
144                                         fpgetfield(imfp, tval);
145                                         }
146                                 else {
147                                         strcpy(tval, "");
148                                         }
149
150                                 if (!strcasecmp(tag, "qrname")) {
151                                         strcpy(qr.QRname, tval);
152                                         lprintf(9, "<%s> ", qr.QRname);
153                                         }
154                                 if (!strcasecmp(tag, "qrpasswd"))
155                                         strcpy(qr.QRpasswd, tval);
156                                 if (!strcasecmp(tag, "qrroomaide"))
157                                         qr.QRroomaide = atol(tval);
158                                 if (!strcasecmp(tag, "qrhighest"))
159                                         qr.QRhighest = atol(tval);
160                                 if (!strcasecmp(tag, "qrgen"))
161                                         qr.QRgen = atol(tval);
162                                 if (!strcasecmp(tag, "qrflags"))
163                                         qr.QRflags = atoi(tval);
164                                 if (!strcasecmp(tag, "qrdirname"))
165                                         strcpy(qr.QRdirname, tval);
166                                 if (!strcasecmp(tag, "qrinfo"))
167                                         qr.QRinfo = atol(tval);
168                                 if (!strcasecmp(tag, "qrfloor"))
169                                         qr.QRfloor = atoi(tval);
170                                 if (!strcasecmp(tag, "message")) {
171                                         fpgetfield(imfp, tval);
172                                         msgnum = atol(tval);
173                                         fpgetfield(imfp, tval);
174                                         msglen = atol(tval);
175                                         import_message(msgnum, msglen);
176                                         ++num_msgs;
177                                         msglist = realloc(msglist,
178                                                 (sizeof(long)*num_msgs) );
179                                         msglist[num_msgs - 1] = msgnum;
180                                         }
181
182                                 }
183
184                         lprintf(9, "(%d messages)\n", num_msgs);
185                         if ((roomnum!=1)&&(qr.QRflags&QR_INUSE)) {
186                                 putroom(&qr, qr.QRname);
187                                 }
188
189                         if (num_msgs > 0) {
190                                 if ((roomnum!=1)&&(qr.QRflags&QR_INUSE)) {
191                                         CC->msglist = msglist;
192                                         CC->num_msgs = num_msgs;
193                                         put_msglist(&qr);
194                                         }
195                                 free(msglist);
196                                 }
197
198                         ++roomnum;
199
200                         }
201                 else {
202                         lprintf(3, "ERROR: invalid room section.\n");
203                         lprintf(3, "Your data files are now corrupt.\n");
204                         fclose(imfp);
205                         return;
206                         }
207                 }
208         }
209
210
211
212 void import_a_user(void) {
213         char key[256], value[256];
214         char vkey[256], vvalue[256];
215         struct usersupp us;
216         struct quickroom qr;
217         struct visit vbuf;
218         int visits = 0;
219
220         bzero(&us, sizeof(struct usersupp));    
221         while(fpgetfield(imfp, key), strcasecmp(key, "enduser")) {
222                 if ((strcasecmp(key, "mail"))
223                    &&(strcasecmp(key, "visit")) ) {
224                         fpgetfield(imfp, value);
225                         }
226                 else {
227                         strcpy(value, "");
228                         }
229
230                 if (!strcasecmp(key, "usuid"))
231                         us.USuid = atoi(value);
232                 if (!strcasecmp(key, "password")) {
233                         strcpy(us.password, value);
234                         }
235
236                 if (!strcasecmp(key, "flags"))
237                         us.flags = atoi(value);
238                 if (!strcasecmp(key, "timescalled"))
239                         us.timescalled = atoi(value);
240                 if (!strcasecmp(key, "posted"))
241                         us.posted = atoi(value);
242                 if (!strcasecmp(key, "fullname")) {
243                         strcpy(us.fullname, value);
244                         lprintf(9, "User <%s> ", us.fullname);
245                         }
246                 if (!strcasecmp(key, "axlevel"))
247                         us.axlevel = atoi(value);
248                 if (!strcasecmp(key, "usscreenwidth"))
249                         us.USscreenwidth = atoi(value);
250                 if (!strcasecmp(key, "usscreenheight"))
251                         us.USscreenheight = atoi(value);
252                 if (!strcasecmp(key, "usernum")) {
253                         us.usernum = atol(value);
254                         lprintf(9, "<#%ld> ", us.usernum);
255                         }
256                 if (!strcasecmp(key, "lastcall"))
257                         us.lastcall = atol(value);
258                 if (!strcasecmp(key, "usname"))
259                         strcpy(us.USname, value);
260                 if (!strcasecmp(key, "usaddr"))
261                         strcpy(us.USaddr, value);
262                 if (!strcasecmp(key, "uscity"))
263                         strcpy(us.UScity, value);
264                 if (!strcasecmp(key, "usstate"))
265                         strcpy(us.USstate, value);
266                 if (!strcasecmp(key, "uszip"))
267                         strcpy(us.USzip, value);
268                 if (!strcasecmp(key, "usphone"))
269                         strcpy(us.USphone, value);
270                 if (!strcasecmp(key, "usemail"))
271                         strcpy(us.USemail, value);
272                 if (!strcasecmp(key, "visit")) {
273                         ++visits;
274                         bzero(&vbuf, sizeof(struct visit));
275                         bzero(&qr, sizeof(struct quickroom));
276                         while(fpgetfield(imfp, vkey),
277                           strcasecmp(vkey, "endvisit")) {
278                                 fpgetfield(imfp, vvalue);
279                                 if (!strcasecmp(vkey, "vname")) 
280                                         strcpy(qr.QRname, vvalue);
281                                 if (!strcasecmp(vkey, "vgen"))  {
282                                         qr.QRgen = atol(vvalue);
283                                         CtdlGetRelationship(&vbuf, &us, &qr);
284                                         }
285                                 if (!strcasecmp(vkey, "lastseen"))      
286                                         vbuf.v_lastseen = atol(vvalue);
287                                 if (!strcasecmp(vkey, "flags"))
288                                         vbuf.v_flags = atoi(vvalue);
289                                 }
290                         CtdlSetRelationship(&vbuf, &us, &qr);
291                         }
292                 }
293         
294         putuser(&us, us.fullname);
295
296         lprintf(9, "(%d rooms)\n", visits);
297         }
298
299
300 void imp_usersupp(void) {
301         char key[256], value[256];
302         
303         while(fpgetfield(imfp, key), strcasecmp(key, "endsection")) {
304                 if (strcasecmp(key, "user")) {
305                         fpgetfield(imfp, value);
306                         }
307                 else {
308                         strcpy(value, "");
309                         }
310
311                 if (!strcasecmp(key, "user")) {
312                         import_a_user();
313                         }
314                 }               
315         }
316
317
318 void imp_globals(void) {
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(void) { 
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(void) {
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(void) {
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         extract(import_filename, argbuf, 0);
456         imfp = fopen(import_filename, "rb");
457         if (imfp == NULL) {
458                 lprintf(9, "Cannot open %s: %s\n",
459                         import_filename, strerror(errno));
460                 cprintf("%d Cannot open file\n", ERROR);
461                 return;
462                 }
463
464         import_databases();
465         lprintf(9, "Defragmenting databases (this may take a while)...\n");
466         defrag_databases();
467         lprintf(1, "Import is finished.  Shutting down Citadel...\n");
468         cprintf("%d Import finished.  Shutting down Citadel...\n", OK);
469         master_cleanup();
470         }
471
472
473 void export_a_room(struct quickroom *qr) {
474         int b = 0;
475         int msgcount = 0;
476
477         lprintf(9,"<%s>\n", qr->QRname);
478         fprintf(exfp, "room%c", 0);
479         fprintf(exfp, "qrname%c%s%c", 0, qr->QRname, 0);
480         fprintf(exfp, "qrpasswd%c%s%c", 0, qr->QRpasswd, 0);
481         fprintf(exfp, "qrroomaide%c%ld%c", 0, qr->QRroomaide, 0);
482         fprintf(exfp, "qrhighest%c%ld%c", 0, qr->QRhighest, 0);
483         fprintf(exfp, "qrgen%c%ld%c", 0, qr->QRgen, 0);
484         fprintf(exfp, "qrflags%c%d%c", 0, qr->QRflags, 0);
485         fprintf(exfp, "qrdirname%c%s%c", 0, qr->QRdirname, 0);
486         fprintf(exfp, "qrinfo%c%ld%c", 0, qr->QRinfo, 0);
487         fprintf(exfp, "qrfloor%c%d%c", 0, qr->QRfloor, 0);
488
489         /*
490         for (b=0; b<MSGSPERRM; ++b) if (fr.FRnum[b]>=mm.MMlowest) {
491                 ++msgcount;
492                 fprintf(exfp, "message%c%ld%c", 0, fr.FRnum[b], 0);
493                 dump_message(exfp, fr.FRnum[b], fr.FRpos[b]);
494                 }
495         */
496
497         fprintf(exfp, "endroom%c", 0);
498         }
499
500
501 void export_rooms() {
502
503         lprintf(9,"Rooms\n");
504         fprintf(exfp, "rooms%c", 0);
505         ForEachRoom(export_a_room);
506         fprintf(exfp, "endsection%c", 0);
507         }
508
509
510
511
512
513
514
515 void do_export(char *argbuf) {
516         char export_filename[PATH_MAX];
517         
518         extract(export_filename, argbuf, 0);
519         exfp = fopen(export_filename, "wb");
520         if (exfp == NULL) {
521                 lprintf(9, "Cannot open %s: %s\n",
522                         export_filename, strerror(errno));
523                 cprintf("%d Cannot open file\n", ERROR);
524                 return;
525                 }
526
527         /* structure size variables */
528         lprintf(9, "Structure size variables\n");
529         fprintf(exfp, "ssv%c", 0);
530         fprintf(exfp, "maxfloors%c%d%c", 0, MAXFLOORS, 0);
531         fprintf(exfp, "endsection%c", 0);
532
533         /* Write out the server config */
534         lprintf(9,"Server config\n");
535         fprintf(exfp, "config%c", 0);
536         fprintf(exfp, "c_nodename%c%s%c", 0, config.c_nodename, 0);
537         fprintf(exfp, "c_fqdn%c%s%c", 0, config.c_fqdn, 0);
538         fprintf(exfp, "c_humannode%c%s%c", 0, config.c_humannode, 0);
539         fprintf(exfp, "c_phonenum%c%s%c", 0, config.c_phonenum, 0);
540         fprintf(exfp, "c_bbsuid%c%d%c", 0, config.c_bbsuid, 0);
541         fprintf(exfp, "c_creataide%c%d%c", 0, config.c_creataide, 0);
542         fprintf(exfp, "c_sleeping%c%d%c", 0, config.c_sleeping, 0);
543         fprintf(exfp, "c_initax%c%d%c", 0, config.c_initax, 0);
544         fprintf(exfp, "c_regiscall%c%d%c", 0, config.c_regiscall, 0);
545         fprintf(exfp, "c_twitdetect%c%d%c", 0, config.c_twitdetect, 0);
546         fprintf(exfp, "c_twitroom%c%s%c", 0, config.c_twitroom, 0);
547         fprintf(exfp, "c_defent%c%d%c", 0, config.c_defent, 0);
548         fprintf(exfp, "c_moreprompt%c%s%c", 0, config.c_moreprompt, 0);
549         fprintf(exfp, "c_restrict%c%d%c", 0, config.c_restrict, 0);
550         fprintf(exfp, "c_bbs_city%c%s%c", 0, config.c_bbs_city, 0);
551         fprintf(exfp, "c_sysadm%c%s%c", 0, config.c_sysadm, 0);
552         fprintf(exfp, "c_bucket_dir%c%s%c", 0, config.c_bucket_dir, 0);
553         fprintf(exfp, "c_setup_level%c%d%c", 0, config.c_setup_level, 0);
554         fprintf(exfp, "c_maxsessions%c%d%c", 0, config.c_maxsessions, 0);
555         fprintf(exfp, "c_net_password%c%s%c", 0, config.c_net_password, 0);
556         fprintf(exfp, "c_port_number%c%d%c", 0, config.c_port_number, 0);
557         fprintf(exfp, "endsection%c", 0);
558
559         /* Now some global stuff */
560         lprintf(9, "Globals\n");
561         get_control();
562         fprintf(exfp, "globals%c", 0);
563         fprintf(exfp, "mmhighest%c%ld%c", 0, CitControl.MMhighest, 0);
564         fprintf(exfp, "mmnextuser%c%ld%c", 0, CitControl.MMnextuser, 0);
565         fprintf(exfp, "mmflags%c%d%c", 0, CitControl.MMflags, 0);
566         fprintf(exfp, "endsection%c", 0);
567
568         export_rooms();
569         /* export_floors(exfp); */
570         /* export_usersupp(exfp); */
571         fprintf(exfp, "endfile%c", 0);
572
573         fclose(exfp);
574         lprintf(1, "Export is finished.\n");
575         cprintf("%d Export is finished.\n", OK);
576         }
577
578
579
580 struct DLModule_Info *Dynamic_Module_Init(void) {
581         CtdlRegisterProtoHook(do_import,
582                                 "IMPO",
583                                 "Import an unpacked system");
584         CtdlRegisterProtoHook(do_export,
585                                 "EXPO",
586                                 "Export the system");
587         return &info;
588         }