c50f4dc2a069845b7db2c8dabf3162ffd02c39ea
[citadel.git] / citadel / modules / vandelay / serv_vandelay.c
1 /*
2  * $Id$
3  *
4  * This is the "Art Vandelay" module.  It is an importer/exporter.
5  *
6  */
7
8 #include "sysdep.h"
9 #include <stdlib.h>
10 #include <unistd.h>
11 #include <stdio.h>
12 #include <fcntl.h>
13 #include <signal.h>
14 #include <pwd.h>
15 #include <errno.h>
16 #include <sys/types.h>
17
18 #if TIME_WITH_SYS_TIME
19 # include <sys/time.h>
20 # include <time.h>
21 #else
22 # if HAVE_SYS_TIME_H
23 #  include <sys/time.h>
24 # else
25 #  include <time.h>
26 # endif
27 #endif
28
29 #include <sys/wait.h>
30 #include <string.h>
31 #include <ctype.h>
32 #include <limits.h>
33 #include "citadel.h"
34 #include "server.h"
35 #include "citserver.h"
36 #include "support.h"
37 #include "config.h"
38 #include "database.h"
39 #include "msgbase.h"
40 #include "tools.h"
41 #include "user_ops.h"
42 #include "room_ops.h"
43 #include "control.h"
44 #include "euidindex.h"
45
46
47 #include "ctdl_module.h"
48
49
50
51
52 #define END_OF_MESSAGE  "---eom---dbd---"
53
54 char artv_tempfilename1[PATH_MAX];
55 char artv_tempfilename2[PATH_MAX];
56 FILE *artv_global_message_list;
57
58 void artv_export_users_backend(struct ctdluser *buf, void *data) {
59         cprintf("user\n");
60 /*
61 #include "artv_serialize.h"
62 #include "dtds/user-defs.h"
63 #include "undef_data.h"
64 */
65         cprintf("%d\n", buf->version);
66         cprintf("%ld\n", (long)buf->uid);
67         cprintf("%s\n", buf->password);
68         cprintf("%u\n", buf->flags);
69         cprintf("%ld\n", buf->timescalled);
70         cprintf("%ld\n", buf->posted);
71         cprintf("%d\n", buf->axlevel);
72         cprintf("%ld\n", buf->usernum);
73         cprintf("%ld\n", (long)buf->lastcall);
74         cprintf("%d\n", buf->USuserpurge);
75         cprintf("%s\n", buf->fullname);
76         cprintf("%d\n", buf->USscreenwidth);
77         cprintf("%d\n", buf->USscreenheight);
78 }
79
80 void artv_dump_users_backend(struct ctdluser *buf, void *data) {
81         cprintf("user\n");
82
83 #include "artv_dump.h"
84 #include "dtds/user-defs.h"
85 #include "undef_data.h"
86 }
87
88
89 void artv_export_users(void) {
90         ForEachUser(artv_export_users_backend, NULL);
91 }
92
93 void artv_dump_users(void) {
94         ForEachUser(artv_dump_users_backend, NULL);
95 }
96
97
98 void artv_export_room_msg(long msgnum, void *userdata) {
99         cprintf("%ld\n", msgnum);
100         fprintf(artv_global_message_list, "%ld\n", msgnum);
101 }
102
103 void artv_dump_room_msg(long msgnum, void *userdata) {
104         cprintf(" msgnum: %ld\n", msgnum);
105         fprintf(artv_global_message_list, "%ld\n", msgnum);
106 }//// TODO
107
108
109 void artv_export_rooms_backend(struct ctdlroom *buf, void *data) {
110         cprintf("room\n");
111 /*
112 #include "artv_serialize.h"
113 #include "dtds/room-defs.h"
114 #include "undef_data.h"
115 */
116         cprintf("%s\n", buf->QRname);
117         cprintf("%s\n", buf->QRpasswd);
118         cprintf("%ld\n", buf->QRroomaide);
119         cprintf("%ld\n", buf->QRhighest);
120         cprintf("%ld\n", (long)buf->QRgen);
121         cprintf("%u\n", buf->QRflags);
122         cprintf("%s\n", buf->QRdirname);
123         cprintf("%ld\n", buf->QRinfo);
124         cprintf("%d\n", buf->QRfloor);
125         cprintf("%ld\n", (long)buf->QRmtime);
126         cprintf("%d\n", buf->QRep.expire_mode);
127         cprintf("%d\n", buf->QRep.expire_value);
128         cprintf("%ld\n", buf->QRnumber);
129         cprintf("%d\n", buf->QRorder);
130         cprintf("%u\n", buf->QRflags2);
131         cprintf("%d\n", buf->QRdefaultview);
132
133         getroom(&CC->room, buf->QRname);
134         /* format of message list export is all message numbers output
135          * one per line terminated by a 0.
136          */
137 //*/
138         getroom(&CC->room, buf->QRname);
139         /* format of message list export is all message numbers output
140          * one per line terminated by a 0.
141          */
142         CtdlForEachMessage(MSGS_ALL, 0L, NULL, NULL, NULL,
143                 artv_export_room_msg, NULL);
144         cprintf("0\n");
145
146 }
147
148 void artv_dump_rooms_backend(struct ctdlroom *buf, void *data) {
149         cprintf("room\n");
150
151 #include "artv_dump.h"
152 #include "dtds/room-defs.h"
153 #include "undef_data.h"
154
155         getroom(&CC->room, buf->QRname);
156         /* format of message list export is all message numbers output
157          * one per line terminated by a 0.
158          */
159 //*/
160         getroom(&CC->room, buf->QRname);
161         /* format of message list export is all message numbers output
162          * one per line terminated by a 0.
163          */
164         CtdlForEachMessage(MSGS_ALL, 0L, NULL, NULL, NULL,
165                 artv_dump_room_msg, NULL);
166         cprintf("\n\n");
167
168 }
169
170
171
172 void artv_export_rooms(void) {
173         char cmd[SIZ];
174         artv_global_message_list = fopen(artv_tempfilename1, "w");
175         if (artv_global_message_list != NULL) {
176                 ForEachRoom(artv_export_rooms_backend, NULL);
177                 fclose(artv_global_message_list);
178         }
179
180         /*
181          * Process the 'global' message list.  (Sort it and remove dups.
182          * Dups are ok because a message may be in more than one room, but
183          * this will be handled by exporting the reference count, not by
184          * exporting the message multiple times.)
185          */
186         snprintf(cmd, sizeof cmd, "sort <%s >%s", artv_tempfilename1, artv_tempfilename2);
187         system(cmd);
188         snprintf(cmd, sizeof cmd, "uniq <%s >%s", artv_tempfilename2, artv_tempfilename1);
189         system(cmd);
190 }
191
192 void artv_dump_rooms(void) {
193         char cmd[SIZ];
194         artv_global_message_list = fopen(artv_tempfilename1, "w");
195         if (artv_global_message_list != NULL) {
196                 ForEachRoom(artv_dump_rooms_backend, NULL);
197                 fclose(artv_global_message_list);
198         }
199
200         /*
201          * Process the 'global' message list.  (Sort it and remove dups.
202          * Dups are ok because a message may be in more than one room, but
203          * this will be handled by exporting the reference count, not by
204          * exporting the message multiple times.)
205          */
206         snprintf(cmd, sizeof cmd, "sort <%s >%s", artv_tempfilename1, artv_tempfilename2);
207         system(cmd);
208         snprintf(cmd, sizeof cmd, "uniq <%s >%s", artv_tempfilename2, artv_tempfilename1);
209         system(cmd);
210 }
211
212
213 void artv_export_floors(void) {
214         struct floor qfbuf, *buf;
215         int i;
216
217         for (i=0; i < MAXFLOORS; ++i) {
218                 cprintf("floor\n");
219                 cprintf("%d\n", i);
220                 getfloor(&qfbuf, i);
221                 buf = &qfbuf;
222 /*
223 #include "artv_serialize.h"
224 #include "dtds/floor-defs.h"
225 #include "undef_data.h"
226 /*/
227                 cprintf("%u\n", buf->f_flags);
228                 cprintf("%s\n", buf->f_name);
229                 cprintf("%d\n", buf->f_ref_count);
230                 cprintf("%d\n", buf->f_ep.expire_mode);
231                 cprintf("%d\n", buf->f_ep.expire_value);
232 //*/
233         }
234 }
235
236 void artv_dump_floors(void) {
237         struct floor qfbuf, *buf;
238         int i;
239
240         for (i=0; i < MAXFLOORS; ++i) {
241                 cprintf("floor\n");
242                 cprintf("%d\n", i);
243                 getfloor(&qfbuf, i);
244                 buf = &qfbuf;
245
246 #include "artv_serialize.h"
247 #include "dtds/floor-defs.h"
248 #include "undef_data.h"
249         }
250 }
251
252
253
254
255
256 /* 
257  *  Traverse the visits file...
258  */
259 void artv_export_visits(void) {
260         struct visit vbuf;
261         struct cdbdata *cdbv;
262
263         cdb_rewind(CDB_VISIT);
264
265         while (cdbv = cdb_next_item(CDB_VISIT), cdbv != NULL) {
266                 memset(&vbuf, 0, sizeof(struct visit));
267                 memcpy(&vbuf, cdbv->ptr,
268                        ((cdbv->len > sizeof(struct visit)) ?
269                         sizeof(struct visit) : cdbv->len));
270                 cdb_free(cdbv);
271
272                 cprintf("visit\n");
273                 cprintf("%ld\n", vbuf.v_roomnum);
274                 cprintf("%ld\n", vbuf.v_roomgen);
275                 cprintf("%ld\n", vbuf.v_usernum);
276
277                 if (!IsEmptyStr(vbuf.v_seen)) {
278                         cprintf("%s\n", vbuf.v_seen);
279                 }
280                 else {
281                         cprintf("%ld\n", vbuf.v_lastseen);
282                 }
283
284                 cprintf("%s\n", vbuf.v_answered);
285                 cprintf("%u\n", vbuf.v_flags);
286                 cprintf("%d\n", vbuf.v_view);
287         }
288 }
289
290 /* 
291  *  Traverse the visits file...
292  */
293 void artv_dump_visits(void) {
294         struct visit vbuf;
295         struct cdbdata *cdbv;
296
297         cdb_rewind(CDB_VISIT);
298
299         while (cdbv = cdb_next_item(CDB_VISIT), cdbv != NULL) {
300                 memset(&vbuf, 0, sizeof(struct visit));
301                 memcpy(&vbuf, cdbv->ptr,
302                        ((cdbv->len > sizeof(struct visit)) ?
303                         sizeof(struct visit) : cdbv->len));
304                 cdb_free(cdbv);
305
306                 cprintf("---visit---\n");
307                 cprintf(" Room-Num: %ld\n", vbuf.v_roomnum);
308                 cprintf(" Room-Gen%ld\n", vbuf.v_roomgen);
309                 cprintf(" User-Num%ld\n", vbuf.v_usernum);
310
311                 if (!IsEmptyStr(vbuf.v_seen)) {
312                         cprintf(" Seen: %s\n", vbuf.v_seen);
313                 }
314                 else {
315                         cprintf(" LastSeen: %ld\n", vbuf.v_lastseen);
316                 }
317
318                 cprintf(" Answered: %s\n", vbuf.v_answered);
319                 cprintf(" Flags: %u\n", vbuf.v_flags);
320                 cprintf(" View: %d\n", vbuf.v_view);
321         }
322 }
323
324
325 void artv_export_message(long msgnum) {
326         struct MetaData smi;
327         struct CtdlMessage *msg;
328         struct ser_ret smr;
329         FILE *fp;
330         char buf[SIZ];
331         char tempfile[PATH_MAX];
332
333         msg = CtdlFetchMessage(msgnum, 1);
334         if (msg == NULL) return;        /* fail silently */
335
336         cprintf("message\n");
337         GetMetaData(&smi, msgnum);
338         cprintf("%ld\n", msgnum);
339         cprintf("%d\n", smi.meta_refcount);
340         cprintf("%s\n", smi.meta_content_type);
341
342         serialize_message(&smr, msg);
343         CtdlFreeMessage(msg);
344
345         /* write it in base64 */
346         CtdlMakeTempFileName(tempfile, sizeof tempfile);
347         snprintf(buf, sizeof buf, "%s -e >%s", file_base64, tempfile);
348         fp = popen(buf, "w");
349         fwrite(smr.ser, smr.len, 1, fp);
350         pclose(fp);
351
352         free(smr.ser);
353
354         fp = fopen(tempfile, "r");
355         unlink(tempfile);
356         if (fp != NULL) {
357                 while (fgets(buf, sizeof(buf), fp) != NULL) {
358                         buf[strlen(buf)-1] = 0;
359                         cprintf("%s\n", buf);
360                 }
361                 fclose(fp);
362         }
363         cprintf("%s\n", END_OF_MESSAGE);
364 }
365
366 void artv_dump_message(long msgnum) {
367         struct MetaData smi;
368         struct CtdlMessage *msg;
369         struct ser_ret smr;
370         FILE *fp;
371         char buf[SIZ];
372         char tempfile[PATH_MAX];
373
374         msg = CtdlFetchMessage(msgnum, 1);
375         if (msg == NULL) return;        /* fail silently */
376
377         cprintf("message\n");
378         GetMetaData(&smi, msgnum);
379         cprintf(" MessageNum: %ld\n", msgnum);
380         cprintf(" MetaRefcount: %d\n", smi.meta_refcount);
381         cprintf(" MetaContentType: %s\n", smi.meta_content_type);
382
383         serialize_message(&smr, msg);
384         CtdlFreeMessage(msg);
385
386         /* write it in base64 * /
387         CtdlMakeTempFileName(tempfile, sizeof tempfile);
388         snprintf(buf, sizeof buf, "%s -e >%s", file_base64, tempfile);
389         fp = popen(buf, "w");
390         fwrite(smr.ser, smr.len, 1, fp);
391         pclose(fp);
392
393         free(smr.ser);
394
395         fp = fopen(tempfile, "r");
396         unlink(tempfile);
397         if (fp != NULL) {
398                 while (fgets(buf, sizeof(buf), fp) != NULL) {
399                         buf[strlen(buf)-1] = 0;
400                         cprintf("%s\n", buf);
401                 }
402                 fclose(fp);
403                 }*/
404         cprintf("%s\n", END_OF_MESSAGE);
405 }
406
407
408
409 void artv_export_messages(void) {
410         char buf[SIZ];
411         long msgnum;
412         int count = 0;
413         t_context *Ctx;
414
415         Ctx = CC;
416         artv_global_message_list = fopen(artv_tempfilename1, "r");
417         if (artv_global_message_list != NULL) {
418                 lprintf(CTDL_INFO, "Opened %s\n", artv_tempfilename1);
419                 while ((Ctx->kill_me != 1) && 
420                        (fgets(buf, sizeof(buf), artv_global_message_list) != NULL)) {
421                         msgnum = atol(buf);
422                         if (msgnum > 0L) {
423                                 artv_export_message(msgnum);
424                                 ++count;
425                         }
426                 }
427                 fclose(artv_global_message_list);
428         }
429         if (Ctx->kill_me != 1)
430                 lprintf(CTDL_INFO, "Exported %d messages.\n", count);
431         else
432                 lprintf(CTDL_ERR, "Export aborted due to client disconnect! \n");
433 }
434
435 void artv_dump_messages(void) {
436         char buf[SIZ];
437         long msgnum;
438         int count = 0;
439         t_context *Ctx;
440
441         Ctx = CC;
442         artv_global_message_list = fopen(artv_tempfilename1, "r");
443         if (artv_global_message_list != NULL) {
444                 lprintf(CTDL_INFO, "Opened %s\n", artv_tempfilename1);
445                 while ((Ctx->kill_me != 1) && 
446                        (fgets(buf, sizeof(buf), artv_global_message_list) != NULL)) {
447                         msgnum = atol(buf);
448                         if (msgnum > 0L) {
449                                 artv_dump_message(msgnum);
450                                 ++count;
451                         }
452                 }
453                 fclose(artv_global_message_list);
454         }
455         if (Ctx->kill_me != 1)
456                 lprintf(CTDL_INFO, "Exported %d messages.\n", count);
457         else
458                 lprintf(CTDL_ERR, "Export aborted due to client disconnect! \n");
459 }
460
461
462
463
464 void artv_do_export(void) {
465         struct config *buf;
466         buf = &config;
467         t_context *Ctx;
468
469         Ctx = CC;
470         cprintf("%d Exporting all Citadel databases.\n", LISTING_FOLLOWS);
471
472         cprintf("version\n%d\n", REV_LEVEL);
473
474         /* export the config file (this is done using x-macros) */
475         cprintf("config\n");
476
477 #include "artv_serialize.h"
478 #include "dtds/config-defs.h"
479 #include "undef_data.h"
480
481         /* Export the control file */
482         get_control();
483         cprintf("control\n");
484         cprintf("%ld\n", CitControl.MMhighest);
485         cprintf("%u\n", CitControl.MMflags);
486         cprintf("%ld\n", CitControl.MMnextuser);
487         cprintf("%ld\n", CitControl.MMnextroom);
488         cprintf("%d\n", CitControl.version);
489         if (Ctx->kill_me != 1)
490                 artv_export_users();
491         if (Ctx->kill_me != 1)
492                 artv_export_rooms();
493         if (Ctx->kill_me != 1)
494                 artv_export_floors();
495         if (Ctx->kill_me != 1)
496                 artv_export_visits();
497         if (Ctx->kill_me != 1)
498                 artv_export_messages();
499
500         cprintf("000\n");
501 }
502
503 void artv_do_dump(void) {
504         struct config *buf;
505         buf = &config;
506         t_context *Ctx;
507
508         Ctx = CC;
509         cprintf("%d dumping Citadel structures.\n", LISTING_FOLLOWS);
510
511         cprintf("version\n%d\n", REV_LEVEL);
512
513         /* export the config file (this is done using x-macros) */
514         cprintf("config\n");
515
516 #include "artv_serialize.h"
517 #include "dtds/config-defs.h"
518 #include "undef_data.h"
519
520         /* Export the control file */
521         get_control();
522         cprintf("control\n");
523         cprintf("%ld\n", CitControl.MMhighest);
524         cprintf("%u\n", CitControl.MMflags);
525         cprintf("%ld\n", CitControl.MMnextuser);
526         cprintf("%ld\n", CitControl.MMnextroom);
527         cprintf("%d\n", CitControl.version);
528         if (Ctx->kill_me != 1)
529                 artv_dump_users();
530         if (Ctx->kill_me != 1)
531                 artv_dump_rooms();
532         if (Ctx->kill_me != 1)
533                 artv_dump_floors();
534         if (Ctx->kill_me != 1)
535                 artv_dump_visits();
536         if (Ctx->kill_me != 1)
537                 artv_dump_messages();
538
539         cprintf("000\n");
540 }
541
542
543
544 void artv_import_config(void) {
545         char cbuf[SIZ];
546         struct config *buf;
547         buf = &config;
548
549         lprintf(CTDL_DEBUG, "Importing config file\n");
550
551 #include "artv_deserialize.h"
552 #include "dtds/config-defs.h"
553 #include "undef_data.h"
554
555         config.c_enable_fulltext = 0;   /* always disable */
556         put_config();
557         lprintf(CTDL_INFO, "Imported config file\n");
558 }
559
560
561 void artv_import_control(void) {
562         char buf[SIZ];
563
564         lprintf(CTDL_DEBUG, "Importing control file\n");
565         client_getln(buf, sizeof buf);  CitControl.MMhighest = atol(buf);
566         client_getln(buf, sizeof buf);  CitControl.MMflags = atoi(buf);
567         client_getln(buf, sizeof buf);  CitControl.MMnextuser = atol(buf);
568         client_getln(buf, sizeof buf);  CitControl.MMnextroom = atol(buf);
569         client_getln(buf, sizeof buf);  CitControl.version = atoi(buf);
570         CitControl.MMfulltext = (-1L);  /* always flush */
571         put_control();
572         lprintf(CTDL_INFO, "Imported control file\n");
573 }
574
575
576 void artv_import_user(void) {
577         char cbuf[SIZ];
578         struct ctdluser usbuf, *buf;
579         buf = &usbuf;
580 /*
581 #include "artv_deserialize.h"
582 #include "dtds/user-defs.h"
583 #include "undef_data.h"
584
585 /*/
586         client_getln(cbuf, sizeof cbuf);        buf->version = atoi(cbuf);
587         client_getln(cbuf, sizeof cbuf);        buf->uid = atoi(cbuf);
588         client_getln(buf->password, sizeof buf->password);
589         client_getln(cbuf, sizeof cbuf);        buf->flags = atoi(cbuf);
590         client_getln(cbuf, sizeof cbuf);        buf->timescalled = atol(cbuf);
591         client_getln(cbuf, sizeof cbuf);        buf->posted = atol(cbuf);
592         client_getln(cbuf, sizeof cbuf);        buf->axlevel = atoi(cbuf);
593         client_getln(cbuf, sizeof cbuf);        buf->usernum = atol(cbuf);
594         client_getln(cbuf, sizeof cbuf);        buf->lastcall = atol(cbuf);
595         client_getln(cbuf, sizeof cbuf);        buf->USuserpurge = atoi(cbuf);
596         client_getln(buf->fullname, sizeof buf->fullname);
597         client_getln(cbuf, sizeof cbuf);        buf->USscreenwidth = atoi(cbuf);
598         client_getln(cbuf, sizeof cbuf);        buf->USscreenheight = atoi(cbuf);
599 //*/
600         putuser(buf);
601 }
602
603
604 void artv_import_room(void) {
605         char cbuf[SIZ];
606         struct ctdlroom qrbuf, *buf;
607         long msgnum;
608         int msgcount = 0;
609
610         buf = &qrbuf;
611 /*
612 #include "artv_deserialize.h"
613 #include "dtds/room-defs.h"
614 #include "undef_data.h"
615
616 /*/
617         client_getln(buf->QRname, sizeof buf->QRname);
618         client_getln(buf->QRpasswd, sizeof buf->QRpasswd);
619         client_getln(cbuf, sizeof cbuf);        buf->QRroomaide = atol(cbuf);
620         client_getln(cbuf, sizeof cbuf);        buf->QRhighest = atol(cbuf);
621         client_getln(cbuf, sizeof cbuf);        buf->QRgen = atol(cbuf);
622         client_getln(cbuf, sizeof cbuf);        buf->QRflags = atoi(cbuf);
623         client_getln(buf->QRdirname, sizeof buf->QRdirname);
624         client_getln(cbuf, sizeof cbuf);        buf->QRinfo = atol(cbuf);
625         client_getln(cbuf, sizeof cbuf);        buf->QRfloor = atoi(cbuf);
626         client_getln(cbuf, sizeof cbuf);        buf->QRmtime = atol(cbuf);
627         client_getln(cbuf, sizeof cbuf);        buf->QRep.expire_mode = atoi(cbuf);
628         client_getln(cbuf, sizeof cbuf);        buf->QRep.expire_value = atoi(cbuf);
629         client_getln(cbuf, sizeof cbuf);        buf->QRnumber = atol(cbuf);
630         client_getln(cbuf, sizeof cbuf);        buf->QRorder = atoi(cbuf);
631         client_getln(cbuf, sizeof cbuf);        buf->QRflags2 = atoi(cbuf);
632         client_getln(cbuf, sizeof cbuf);        buf->QRdefaultview = atoi(cbuf);
633 //*/
634         putroom(buf);
635         lprintf(CTDL_INFO, "Imported room <%s>\n", qrbuf.QRname);
636         /* format of message list export is all message numbers output
637          * one per line terminated by a 0.
638          */
639         while (client_getln(cbuf, sizeof cbuf), msgnum = atol(cbuf), msgnum > 0) {
640                 CtdlSaveMsgPointerInRoom(qrbuf.QRname, msgnum, 0, NULL);
641                 ++msgcount;
642         }
643         lprintf(CTDL_INFO, "(%d messages)\n", msgcount);
644 }
645
646
647 void artv_import_floor(void) {
648         struct floor flbuf, *buf;
649         int i;
650         char cbuf[SIZ];
651
652         buf = & flbuf;
653         memset(buf, 0, sizeof(buf));
654         client_getln(cbuf, sizeof cbuf);        i = atoi(cbuf);
655 /*
656 #include "artv_deserialize.h"
657 #include "dtds/floor-defs.h"
658 #include "undef_data.h"
659 /*/
660         client_getln(cbuf, sizeof cbuf);        buf->f_flags = atoi(cbuf);
661         client_getln(buf->f_name, sizeof buf->f_name);
662         client_getln(cbuf, sizeof cbuf);        buf->f_ref_count = atoi(cbuf);
663         client_getln(cbuf, sizeof cbuf);        buf->f_ep.expire_mode = atoi(cbuf);
664         client_getln(cbuf, sizeof cbuf);        buf->f_ep.expire_value = atoi(cbuf);
665 //*/
666         putfloor(buf, i);
667         lprintf(CTDL_INFO, "Imported floor #%d (%s)\n", i, flbuf.f_name);
668 }
669
670
671 /* 
672  */
673 void artv_import_visit(void) {
674         struct visit vbuf;
675         char buf[SIZ];
676         int i;
677         int is_textual_seen = 0;
678
679         client_getln(buf, sizeof buf);  vbuf.v_roomnum = atol(buf);
680         client_getln(buf, sizeof buf);  vbuf.v_roomgen = atol(buf);
681         client_getln(buf, sizeof buf);  vbuf.v_usernum = atol(buf);
682
683         client_getln(buf, sizeof buf);
684         vbuf.v_lastseen = atol(buf);
685         for (i=0; buf[i]; ++i) if (!isdigit(buf[i])) is_textual_seen = 1;
686         if (is_textual_seen)    strcpy(vbuf.v_seen, buf);
687
688         client_getln(vbuf.v_answered, sizeof vbuf.v_answered);
689         client_getln(buf, sizeof buf);  vbuf.v_flags = atoi(buf);
690         client_getln(buf, sizeof buf);  vbuf.v_view = atoi(buf);
691         put_visit(&vbuf);
692         lprintf(CTDL_INFO, "Imported visit %ld/%ld/%ld\n",
693                 vbuf.v_roomnum, vbuf.v_roomgen, vbuf.v_usernum);
694 }
695
696
697
698 void artv_import_message(void) {
699         struct MetaData smi;
700         long msgnum;
701         long msglen;
702         FILE *fp;
703         char buf[SIZ];
704         char tempfile[PATH_MAX];
705         char *mbuf;
706
707         memset(&smi, 0, sizeof(struct MetaData));
708         client_getln(buf, sizeof buf);  msgnum = atol(buf);
709                                 smi.meta_msgnum = msgnum;
710         client_getln(buf, sizeof buf);  smi.meta_refcount = atoi(buf);
711         client_getln(smi.meta_content_type, sizeof smi.meta_content_type);
712
713         lprintf(CTDL_INFO, "message #%ld\n", msgnum);
714
715         /* decode base64 message text */
716         CtdlMakeTempFileName(tempfile, sizeof tempfile);
717         snprintf(buf, sizeof buf, "%s -d >%s", file_base64, tempfile);
718         fp = popen(buf, "w");
719         while (client_getln(buf, sizeof buf), strcasecmp(buf, END_OF_MESSAGE)) {
720                 fprintf(fp, "%s\n", buf);
721         }
722         pclose(fp);
723         fp = fopen(tempfile, "rb");
724         fseek(fp, 0L, SEEK_END);
725         msglen = ftell(fp);
726         fclose(fp);
727         lprintf(CTDL_DEBUG, "msglen = %ld\n", msglen);
728
729         mbuf = malloc(msglen);
730         fp = fopen(tempfile, "rb");
731         fread(mbuf, msglen, 1, fp);
732         fclose(fp);
733
734         cdb_store(CDB_MSGMAIN, &msgnum, sizeof(long), mbuf, msglen);
735
736         free(mbuf);
737         unlink(tempfile);
738
739         PutMetaData(&smi);
740         lprintf(CTDL_INFO, "Imported message %ld\n", msgnum);
741 }
742
743
744
745
746 void artv_do_import(void) {
747         char buf[SIZ];
748         char abuf[SIZ];
749         char s_version[SIZ];
750         int version;
751         long iterations;
752
753         unbuffer_output();
754
755         cprintf("%d sock it to me\n", SEND_LISTING);
756         abuf[0] = '\0';
757         unbuffer_output();
758         iterations = 0;
759         while (client_getln(buf, sizeof buf), strcmp(buf, "000")) {
760
761                 lprintf(CTDL_DEBUG, "import keyword: <%s>\n", buf);
762                 if ((abuf[0] == '\0') || (strcasecmp(buf, abuf))) {
763                         cprintf ("\n\nImporting datatype %s\n", buf);
764                         strncpy (abuf, buf, SIZ);       
765                         iterations = 0;
766                 }
767                 else {
768                         cprintf(".");
769                         if (iterations % 64 == 0)
770                                 cprintf("\n");
771                         
772                 }
773                 
774                 if (!strcasecmp(buf, "version")) {
775                         client_getln(s_version, sizeof s_version);
776                         version = atoi(s_version);
777                         if ((version<EXPORT_REV_MIN) || (version>REV_LEVEL)) {
778                                 lprintf(CTDL_ERR, "Version mismatch in ARTV import; aborting\n");
779                                 break;
780                         }
781                 }
782                 else if (!strcasecmp(buf, "config")) artv_import_config();
783                 else if (!strcasecmp(buf, "control")) artv_import_control();
784                 else if (!strcasecmp(buf, "user")) artv_import_user();
785                 else if (!strcasecmp(buf, "room")) artv_import_room();
786                 else if (!strcasecmp(buf, "floor")) artv_import_floor();
787                 else if (!strcasecmp(buf, "visit")) artv_import_visit();
788                 else if (!strcasecmp(buf, "message")) artv_import_message();
789                 else break;
790                 iterations ++;
791         }
792         lprintf(CTDL_INFO, "Invalid keyword <%s>.  Flushing input.\n", buf);
793         while (client_getln(buf, sizeof buf), strcmp(buf, "000"))  ;;
794         rebuild_euid_index();
795 }
796
797
798
799 void cmd_artv(char *cmdbuf) {
800         char cmd[32];
801         static int is_running = 0;
802
803         if (CtdlAccessCheck(ac_internal)) return;
804         if (is_running) {
805                 cprintf("%d The importer/exporter is already running.\n",
806                         ERROR + RESOURCE_BUSY);
807                 return;
808         }
809         is_running = 1;
810
811         CtdlMakeTempFileName(artv_tempfilename1, sizeof artv_tempfilename1);
812         CtdlMakeTempFileName(artv_tempfilename2, sizeof artv_tempfilename2);
813
814         extract_token(cmd, cmdbuf, 0, '|', sizeof cmd);
815         if (!strcasecmp(cmd, "export")) artv_do_export();
816         else if (!strcasecmp(cmd, "import")) artv_do_import();
817         else if (!strcasecmp(cmd, "dump")) artv_do_dump();
818         else cprintf("%d illegal command\n", ERROR + ILLEGAL_VALUE);
819
820         unlink(artv_tempfilename1);
821         unlink(artv_tempfilename2);
822
823         is_running = 0;
824 }
825
826
827
828
829 CTDL_MODULE_INIT(vandelay)
830 {
831         CtdlRegisterProtoHook(cmd_artv, "ARTV", "import/export data store");
832
833         /* return our Subversion id for the Log */
834         return "$Id$";
835 }