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_ !!
17 #include <sys/types.h>
26 #include "sysdep_decls.h"
27 #include "citserver.h"
30 #include "dynloader.h"
36 extern struct CitContext *ContextList;
39 #define MODULE_NAME "Import an unpacked system"
40 #define MODULE_AUTHOR "Art Cancro"
41 #define MODULE_EMAIL "ajc@uncnsrd.mt-kisco.ny.us"
42 #define MAJOR_VERSION 0
43 #define MINOR_VERSION 3
45 static struct DLModule_Info info = {
55 void fpgetfield(FILE *fp, char *string)
72 void import_message(long msgnum, long msglen) {
75 msgtext = malloc(msglen);
76 if (msgtext == NULL) {
77 lprintf(3, "ERROR: cannot allocate memory\n");
78 lprintf(3, "Your data files are now corrupt.\n");
83 fread(msgtext, msglen, 1, imfp);
84 cdb_store(CDB_MSGMAIN, &msgnum, sizeof(long), msgtext, msglen);
88 void imp_floors(void) {
89 char key[256], tag[256], tval[256];
94 while(fpgetfield(imfp, key), strcasecmp(key, "endsection")) {
96 if (!strcasecmp(key, "floor")) {
97 bzero(&fl, sizeof(struct floor));
99 while(fpgetfield(imfp, tag),
100 strcasecmp(tag, "endfloor")) {
101 fpgetfield(imfp, tval);
103 if (!strcasecmp(tag, "f_flags"))
104 fl.f_flags = atoi(tval);
105 if (!strcasecmp(tag, "f_name")) {
106 lprintf(9, "Floor <%s>\n", tval);
107 strcpy(fl.f_name, tval);
109 if (!strcasecmp(tag, "f_ref_count"))
110 fl.f_ref_count = atoi(tval);
113 putfloor(&fl, floornum);
117 lprintf(3, "ERROR: invalid floor section.\n");
118 lprintf(3, "Your data files are now corrupt.\n");
127 void imp_rooms(void) {
129 char tag[256], tval[256];
136 while(fpgetfield(imfp, key), strcasecmp(key, "endsection")) {
137 if (!strcasecmp(key, "room")) {
138 bzero(&qr, sizeof(struct quickroom));
143 while(fpgetfield(imfp, tag),
144 strcasecmp(tag, "endroom")) {
145 if (strcasecmp(tag, "message")) {
146 fpgetfield(imfp, tval);
152 if (!strcasecmp(tag, "qrname")) {
153 strcpy(qr.QRname, tval);
154 lprintf(9, "<%s> ", qr.QRname);
156 if (!strcasecmp(tag, "qrpasswd"))
157 strcpy(qr.QRpasswd, tval);
158 if (!strcasecmp(tag, "qrroomaide"))
159 qr.QRroomaide = atol(tval);
160 if (!strcasecmp(tag, "qrhighest"))
161 qr.QRhighest = atol(tval);
162 if (!strcasecmp(tag, "qrgen"))
163 qr.QRgen = atol(tval);
164 if (!strcasecmp(tag, "qrflags"))
165 qr.QRflags = atoi(tval);
166 if (!strcasecmp(tag, "qrdirname"))
167 strcpy(qr.QRdirname, tval);
168 if (!strcasecmp(tag, "qrinfo"))
169 qr.QRinfo = atol(tval);
170 if (!strcasecmp(tag, "qrfloor"))
171 qr.QRfloor = atoi(tval);
172 if (!strcasecmp(tag, "message")) {
173 fpgetfield(imfp, tval);
175 fpgetfield(imfp, tval);
177 import_message(msgnum, msglen);
179 msglist = realloc(msglist,
180 (sizeof(long)*num_msgs) );
181 msglist[num_msgs - 1] = msgnum;
186 lprintf(9, "(%d messages)\n", num_msgs);
187 if ((roomnum!=1)&&(qr.QRflags&QR_INUSE)) {
188 putroom(&qr, qr.QRname);
192 if ((roomnum!=1)&&(qr.QRflags&QR_INUSE)) {
193 CC->msglist = msglist;
194 CC->num_msgs = num_msgs;
204 lprintf(3, "ERROR: invalid room section.\n");
205 lprintf(3, "Your data files are now corrupt.\n");
214 void import_a_user(void) {
215 char key[256], value[256];
216 char vkey[256], vvalue[256];
222 bzero(&us, sizeof(struct usersupp));
223 while(fpgetfield(imfp, key), strcasecmp(key, "enduser")) {
224 if ((strcasecmp(key, "mail"))
225 &&(strcasecmp(key, "visit")) ) {
226 fpgetfield(imfp, value);
232 if (!strcasecmp(key, "usuid"))
233 us.USuid = atoi(value);
234 if (!strcasecmp(key, "password")) {
235 strcpy(us.password, value);
238 if (!strcasecmp(key, "flags"))
239 us.flags = atoi(value);
240 if (!strcasecmp(key, "timescalled"))
241 us.timescalled = atoi(value);
242 if (!strcasecmp(key, "posted"))
243 us.posted = atoi(value);
244 if (!strcasecmp(key, "fullname")) {
245 strcpy(us.fullname, value);
246 lprintf(9, "User <%s> ", us.fullname);
248 if (!strcasecmp(key, "axlevel"))
249 us.axlevel = atoi(value);
250 if (!strcasecmp(key, "usscreenwidth"))
251 us.USscreenwidth = atoi(value);
252 if (!strcasecmp(key, "usscreenheight"))
253 us.USscreenheight = atoi(value);
254 if (!strcasecmp(key, "usernum")) {
255 us.usernum = atol(value);
256 lprintf(9, "<#%ld> ", us.usernum);
258 if (!strcasecmp(key, "lastcall"))
259 us.lastcall = atol(value);
260 if (!strcasecmp(key, "usname"))
261 strcpy(us.USname, value);
262 if (!strcasecmp(key, "usaddr"))
263 strcpy(us.USaddr, value);
264 if (!strcasecmp(key, "uscity"))
265 strcpy(us.UScity, value);
266 if (!strcasecmp(key, "usstate"))
267 strcpy(us.USstate, value);
268 if (!strcasecmp(key, "uszip"))
269 strcpy(us.USzip, value);
270 if (!strcasecmp(key, "usphone"))
271 strcpy(us.USphone, value);
272 if (!strcasecmp(key, "usemail"))
273 strcpy(us.USemail, value);
274 if (!strcasecmp(key, "visit")) {
276 bzero(&vbuf, sizeof(struct visit));
277 bzero(&qr, sizeof(struct quickroom));
278 while(fpgetfield(imfp, vkey),
279 strcasecmp(vkey, "endvisit")) {
280 fpgetfield(imfp, vvalue);
281 if (!strcasecmp(vkey, "vname"))
282 strcpy(qr.QRname, vvalue);
283 if (!strcasecmp(vkey, "vgen")) {
284 qr.QRgen = atol(vvalue);
285 CtdlGetRelationship(&vbuf, &us, &qr);
287 if (!strcasecmp(vkey, "lastseen"))
288 vbuf.v_lastseen = atol(vvalue);
289 if (!strcasecmp(vkey, "flags"))
290 vbuf.v_flags = atoi(vvalue);
292 CtdlSetRelationship(&vbuf, &us, &qr);
296 putuser(&us, us.fullname);
298 lprintf(9, "(%d rooms)\n", visits);
302 void imp_usersupp(void) {
303 char key[256], value[256];
305 while(fpgetfield(imfp, key), strcasecmp(key, "endsection")) {
306 if (strcasecmp(key, "user")) {
307 fpgetfield(imfp, value);
313 if (!strcasecmp(key, "user")) {
320 void imp_globals(void) {
321 char key[256], value[256];
324 while(fpgetfield(imfp, key), strcasecmp(key, "endsection")) {
325 fpgetfield(imfp, value);
326 lprintf(9, " %s = %s\n", key, value);
328 if (!strcasecmp(key, "mmhighest"))
329 CitControl.MMhighest = atol(value);
330 if (!strcasecmp(key, "mmnextuser"))
331 CitControl.MMnextuser = atol(value);
339 void imp_config(void) {
340 char key[256], value[256];
343 while(fpgetfield(imfp, key), strcasecmp(key, "endsection")) {
344 fpgetfield(imfp, value);
345 lprintf(9, " %s = %s\n", key, value);
347 if (!strcasecmp(key, "c_nodename"))
348 strcpy(config.c_nodename, value);
349 if (!strcasecmp(key, "c_fqdn"))
350 strcpy(config.c_fqdn, value);
351 if (!strcasecmp(key, "c_humannode"))
352 strcpy(config.c_humannode, value);
353 if (!strcasecmp(key, "c_phonenum"))
354 strcpy(config.c_phonenum, value);
355 if (!strcasecmp(key, "c_phonenum"))
356 strcpy(config.c_phonenum, value);
357 if (!strcasecmp(key, "c_bbsuid"))
358 config.c_bbsuid = atoi(value);
359 if (!strcasecmp(key, "c_creataide"))
360 config.c_creataide = atoi(value);
361 if (!strcasecmp(key, "c_sleeping"))
362 config.c_sleeping = atoi(value);
363 if (!strcasecmp(key, "c_initax"))
364 config.c_initax = atoi(value);
365 if (!strcasecmp(key, "c_regiscall"))
366 config.c_regiscall = atoi(value);
367 if (!strcasecmp(key, "c_twitdetect"))
368 config.c_twitdetect = atoi(value);
369 if (!strcasecmp(key, "c_twitroom"))
370 strcpy(config.c_twitroom, value);
371 if (!strcasecmp(key, "c_defent"))
372 config.c_defent = atoi(value);
373 if (!strcasecmp(key, "c_moreprompt"))
374 strcpy(config.c_moreprompt, value);
375 if (!strcasecmp(key, "c_restrict"))
376 config.c_restrict = atoi(value);
377 if (!strcasecmp(key, "c_bbs_city"))
378 strcpy(config.c_bbs_city, value);
379 if (!strcasecmp(key, "c_sysadm"))
380 strcpy(config.c_sysadm, value);
381 if (!strcasecmp(key, "c_bucket_dir"))
382 strcpy(config.c_bucket_dir, value);
383 if (!strcasecmp(key, "c_setup_level"))
384 config.c_setup_level = atoi(value);
385 if (!strcasecmp(key, "c_maxsessions"))
386 config.c_maxsessions = atoi(value);
387 if (!strcasecmp(key, "c_net_password"))
388 strcpy(config.c_net_password, value);
389 if (!strcasecmp(key, "c_port_number"))
390 config.c_port_number = atoi(value);
393 fp = fopen("citadel.config", "wb");
394 fwrite(&config, sizeof(struct config), 1, fp);
403 char key[256], value[256];
404 int ssv_maxfloors = MAXFLOORS;
406 while(fpgetfield(imfp, key), strcasecmp(key, "endsection")) {
407 fpgetfield(imfp, value);
408 lprintf(9, " %s = %s\n", key, value);
410 if (!strcasecmp(key, "maxfloors")) {
411 ssv_maxfloors = atol(value);
412 if (ssv_maxfloors > MAXFLOORS) {
413 lprintf(3, "ERROR: maxfloors is %d, need %d\n",
414 ssv_maxfloors, MAXFLOORS);
428 void import_databases(void) {
431 lprintf(9, " ** IMPORTING ** \n");
432 while (fpgetfield(imfp, section), strcasecmp(section, "endfile")) {
433 lprintf(9, "Section: <%s>\n", section);
435 if (!strcasecmp(section, "ssv")) imp_ssv();
436 else if (!strcasecmp(section, "config")) imp_config();
437 else if (!strcasecmp(section, "globals")) imp_globals();
438 else if (!strcasecmp(section, "usersupp")) imp_usersupp();
439 else if (!strcasecmp(section, "rooms")) imp_rooms();
440 else if (!strcasecmp(section, "floors")) imp_floors();
442 lprintf(3, "ERROR: invalid import section.\n");
443 lprintf(3, "Your data files are now corrupt.\n");
454 void do_import(char *argbuf) {
455 char import_filename[PATH_MAX];
457 extract(import_filename, argbuf, 0);
458 imfp = fopen(import_filename, "rb");
460 lprintf(9, "Cannot open %s: %s\n",
461 import_filename, strerror(errno));
462 cprintf("%d Cannot open file\n", ERROR);
467 lprintf(9, "Defragmenting databases (this may take a while)...\n");
469 lprintf(1, "Import is finished. Shutting down Citadel...\n");
470 cprintf("%d Import finished. Shutting down Citadel...\n", OK);
475 void dump_message(long msg_num) {
476 struct cdbdata *dmsgtext;
478 dmsgtext = cdb_fetch(CDB_MSGMAIN, &msg_num, sizeof(long));
480 if (dmsgtext == NULL) {
481 lprintf(9, "%d Can't find message %ld\n", msg_num);
485 fprintf(exfp, "message%c%ld%c", 0, msg_num, 0);
486 fprintf(exfp, "%ld%c", (long)dmsgtext->len, 0);
487 fwrite(dmsgtext->ptr, dmsgtext->len, 1, exfp);
493 void export_a_room(struct quickroom *qr) {
497 lprintf(9,"<%s>\n", qr->QRname);
498 fprintf(exfp, "room%c", 0);
499 fprintf(exfp, "qrname%c%s%c", 0, qr->QRname, 0);
500 fprintf(exfp, "qrpasswd%c%s%c", 0, qr->QRpasswd, 0);
501 fprintf(exfp, "qrroomaide%c%ld%c", 0, qr->QRroomaide, 0);
502 fprintf(exfp, "qrhighest%c%ld%c", 0, qr->QRhighest, 0);
503 fprintf(exfp, "qrgen%c%ld%c", 0, qr->QRgen, 0);
504 fprintf(exfp, "qrflags%c%d%c", 0, qr->QRflags, 0);
505 fprintf(exfp, "qrdirname%c%s%c", 0, qr->QRdirname, 0);
506 fprintf(exfp, "qrinfo%c%ld%c", 0, qr->QRinfo, 0);
507 fprintf(exfp, "qrfloor%c%d%c", 0, qr->QRfloor, 0);
510 if (CC->num_msgs > 0) for (b=0; b<(CC->num_msgs); ++b) {
512 lprintf(9, "Message #%ld\n", MessageFromList(b));
513 dump_message(MessageFromList(b));
516 fprintf(exfp, "endroom%c", 0);
520 void export_rooms(void) {
521 lprintf(9,"Rooms\n");
522 fprintf(exfp, "rooms%c", 0);
523 ForEachRoom(export_a_room);
524 fprintf(exfp, "endsection%c", 0);
529 void export_floors(void) {
533 fprintf(exfp, "floors%c", 0);
534 for (floornum=0; floornum<MAXFLOORS; ++floornum) {
535 getfloor(&fl, floornum);
536 fprintf(exfp, "floor%c", 0);
537 fprintf(exfp, "f_flags%c%d%c", 0, fl.f_flags, 0);
538 fprintf(exfp, "f_name%c%s%c", 0, fl.f_name, 0);
539 fprintf(exfp, "f_ref_count%c%d%c", 0, fl.f_ref_count, 0);
540 fprintf(exfp, "endfloor%c", 0);
542 fprintf(exfp, "endsection%c", 0);
548 void export_a_user(struct usersupp *us) {
549 struct cdbdata *cdbvisit;
550 struct visit *visits;
554 lprintf(9, "User <%s>\n", us->fullname);
556 fprintf(exfp, "user%c", 0);
557 fprintf(exfp, "usuid%c%d%c", 0, us->USuid, 0);
558 fprintf(exfp, "password%c%s%c", 0, us->password, 0);
559 fprintf(exfp, "flags%c%d%c", 0, us->flags, 0);
560 fprintf(exfp, "timescalled%c%d%c", 0, us->timescalled, 0);
561 fprintf(exfp, "posted%c%d%c", 0, us->posted, 0);
562 fprintf(exfp, "fullname%c%s%c", 0, us->fullname, 0);
563 fprintf(exfp, "axlevel%c%d%c", 0, us->axlevel, 0);
564 fprintf(exfp, "usscreenwidth%c%d%c", 0, us->USscreenwidth, 0);
565 fprintf(exfp, "usscreenheight%c%d%c", 0, us->USscreenheight, 0);
566 fprintf(exfp, "usernum%c%ld%c", 0, us->usernum, 0);
567 fprintf(exfp, "lastcall%c%ld%c", 0, us->lastcall, 0);
568 fprintf(exfp, "usname%c%s%c", 0, us->USname, 0);
569 fprintf(exfp, "usaddr%c%s%c", 0, us->USaddr, 0);
570 fprintf(exfp, "uscity%c%s%c", 0, us->UScity, 0);
571 fprintf(exfp, "usstate%c%s%c", 0, us->USstate, 0);
572 fprintf(exfp, "uszip%c%s%c", 0, us->USzip, 0);
573 fprintf(exfp, "usphone%c%s%c", 0, us->USphone, 0);
574 fprintf(exfp, "usemail%c%s%c", 0, us->USemail, 0);
577 cdbvisit = cdb_fetch(CDB_VISIT, &CC->usersupp.usernum, sizeof(long));
578 if (cdbvisit != NULL) {
579 if ((num_visits = cdbvisit->len / sizeof(struct visit)) == 0) {
583 visits = (struct visit *)
584 malloc(num_visits * sizeof(struct visit));
585 memcpy(visits, cdbvisit->ptr,
586 (num_visits * sizeof(struct visit)));
589 if (num_visits > 0) for (a=0; a<num_visits; ++a) {
590 fprintf(exfp, "visit%c", 0);
591 fprintf(exfp, "vname%c%s%c", 0,
592 visits[a].v_roomname, 0);
593 fprintf(exfp, "vgen%c%ld%c", 0,
594 visits[a].v_generation, 0);
595 fprintf(exfp, "lastseen%c%ld%c", 0,
596 visits[a].v_lastseen, 0);
597 fprintf(exfp, "flags%c%d%c", 0,
598 visits[a].v_flags, 0);
599 fprintf(exfp, "endvisit%c", 0);
605 fprintf(exfp, "enduser%c", 0);
609 void export_usersupp(void) {
610 lprintf(9, "Users\n");
611 fprintf(exfp, "usersupp%c", 0);
613 ForEachUser(export_a_user);
615 fprintf(exfp, "endsection%c", 0);
619 void do_export(char *argbuf) {
620 char export_filename[PATH_MAX];
622 extract(export_filename, argbuf, 0);
623 exfp = fopen(export_filename, "wb");
625 lprintf(9, "Cannot open %s: %s\n",
626 export_filename, strerror(errno));
627 cprintf("%d Cannot open file\n", ERROR);
631 /* structure size variables */
632 lprintf(9, "Structure size variables\n");
633 fprintf(exfp, "ssv%c", 0);
634 fprintf(exfp, "maxfloors%c%d%c", 0, MAXFLOORS, 0);
635 fprintf(exfp, "endsection%c", 0);
637 /* Write out the server config */
638 lprintf(9,"Server config\n");
639 fprintf(exfp, "config%c", 0);
640 fprintf(exfp, "c_nodename%c%s%c", 0, config.c_nodename, 0);
641 fprintf(exfp, "c_fqdn%c%s%c", 0, config.c_fqdn, 0);
642 fprintf(exfp, "c_humannode%c%s%c", 0, config.c_humannode, 0);
643 fprintf(exfp, "c_phonenum%c%s%c", 0, config.c_phonenum, 0);
644 fprintf(exfp, "c_bbsuid%c%d%c", 0, config.c_bbsuid, 0);
645 fprintf(exfp, "c_creataide%c%d%c", 0, config.c_creataide, 0);
646 fprintf(exfp, "c_sleeping%c%d%c", 0, config.c_sleeping, 0);
647 fprintf(exfp, "c_initax%c%d%c", 0, config.c_initax, 0);
648 fprintf(exfp, "c_regiscall%c%d%c", 0, config.c_regiscall, 0);
649 fprintf(exfp, "c_twitdetect%c%d%c", 0, config.c_twitdetect, 0);
650 fprintf(exfp, "c_twitroom%c%s%c", 0, config.c_twitroom, 0);
651 fprintf(exfp, "c_defent%c%d%c", 0, config.c_defent, 0);
652 fprintf(exfp, "c_moreprompt%c%s%c", 0, config.c_moreprompt, 0);
653 fprintf(exfp, "c_restrict%c%d%c", 0, config.c_restrict, 0);
654 fprintf(exfp, "c_bbs_city%c%s%c", 0, config.c_bbs_city, 0);
655 fprintf(exfp, "c_sysadm%c%s%c", 0, config.c_sysadm, 0);
656 fprintf(exfp, "c_bucket_dir%c%s%c", 0, config.c_bucket_dir, 0);
657 fprintf(exfp, "c_setup_level%c%d%c", 0, config.c_setup_level, 0);
658 fprintf(exfp, "c_maxsessions%c%d%c", 0, config.c_maxsessions, 0);
659 fprintf(exfp, "c_net_password%c%s%c", 0, config.c_net_password, 0);
660 fprintf(exfp, "c_port_number%c%d%c", 0, config.c_port_number, 0);
661 fprintf(exfp, "endsection%c", 0);
663 /* Now some global stuff */
664 lprintf(9, "Globals\n");
666 fprintf(exfp, "globals%c", 0);
667 fprintf(exfp, "mmhighest%c%ld%c", 0, CitControl.MMhighest, 0);
668 fprintf(exfp, "mmnextuser%c%ld%c", 0, CitControl.MMnextuser, 0);
669 fprintf(exfp, "mmflags%c%d%c", 0, CitControl.MMflags, 0);
670 fprintf(exfp, "endsection%c", 0);
672 /* Export all of the databases */
677 fprintf(exfp, "endfile%c", 0);
679 lprintf(1, "Export is finished.\n");
680 cprintf("%d Export is finished.\n", OK);
685 struct DLModule_Info *Dynamic_Module_Init(void) {
686 CtdlRegisterProtoHook(do_import,
688 "Import an unpacked system");
689 CtdlRegisterProtoHook(do_export,
691 "Export the system");