07dd5358c2d0b5ce350aedbc3bfad44323828120
[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
81 void artv_export_users(void) {
82         ForEachUser(artv_export_users_backend, NULL);
83 }
84
85
86 void artv_export_room_msg(long msgnum, void *userdata) {
87         cprintf("%ld\n", msgnum);
88         fprintf(artv_global_message_list, "%ld\n", msgnum);
89 }
90
91
92 void artv_export_rooms_backend(struct ctdlroom *buf, void *data) {
93         cprintf("room\n");
94 /*
95 #include "artv_serialize.h"
96 #include "dtds/room-defs.h"
97 #include "undef_data.h"
98 */
99         cprintf("%s\n", buf->QRname);
100         cprintf("%s\n", buf->QRpasswd);
101         cprintf("%ld\n", buf->QRroomaide);
102         cprintf("%ld\n", buf->QRhighest);
103         cprintf("%ld\n", (long)buf->QRgen);
104         cprintf("%u\n", buf->QRflags);
105         cprintf("%s\n", buf->QRdirname);
106         cprintf("%ld\n", buf->QRinfo);
107         cprintf("%d\n", buf->QRfloor);
108         cprintf("%ld\n", (long)buf->QRmtime);
109         cprintf("%d\n", buf->QRep.expire_mode);
110         cprintf("%d\n", buf->QRep.expire_value);
111         cprintf("%ld\n", buf->QRnumber);
112         cprintf("%d\n", buf->QRorder);
113         cprintf("%u\n", buf->QRflags2);
114         cprintf("%d\n", buf->QRdefaultview);
115
116         getroom(&CC->room, buf->QRname);
117         /* format of message list export is all message numbers output
118          * one per line terminated by a 0.
119          */
120 //*/
121         getroom(&CC->room, buf->QRname);
122         /* format of message list export is all message numbers output
123          * one per line terminated by a 0.
124          */
125         CtdlForEachMessage(MSGS_ALL, 0L, NULL, NULL, NULL,
126                 artv_export_room_msg, NULL);
127         cprintf("0\n");
128
129 }
130
131
132
133 void artv_export_rooms(void) {
134         char cmd[SIZ];
135         artv_global_message_list = fopen(artv_tempfilename1, "w");
136         if (artv_global_message_list != NULL) {
137                 ForEachRoom(artv_export_rooms_backend, NULL);
138                 fclose(artv_global_message_list);
139         }
140
141         /*
142          * Process the 'global' message list.  (Sort it and remove dups.
143          * Dups are ok because a message may be in more than one room, but
144          * this will be handled by exporting the reference count, not by
145          * exporting the message multiple times.)
146          */
147         snprintf(cmd, sizeof cmd, "sort <%s >%s", artv_tempfilename1, artv_tempfilename2);
148         system(cmd);
149         snprintf(cmd, sizeof cmd, "uniq <%s >%s", artv_tempfilename2, artv_tempfilename1);
150         system(cmd);
151 }
152
153
154 void artv_export_floors(void) {
155         struct floor qfbuf, *buf;
156         int i;
157
158         for (i=0; i < MAXFLOORS; ++i) {
159                 cprintf("floor\n");
160                 cprintf("%d\n", i);
161                 getfloor(&qfbuf, i);
162                 buf = &qfbuf;
163 /*
164 #include "artv_serialize.h"
165 #include "dtds/floor-defs.h"
166 #include "undef_data.h"
167 /*/
168                 cprintf("%u\n", buf->f_flags);
169                 cprintf("%s\n", buf->f_name);
170                 cprintf("%d\n", buf->f_ref_count);
171                 cprintf("%d\n", buf->f_ep.expire_mode);
172                 cprintf("%d\n", buf->f_ep.expire_value);
173 //*/
174         }
175 }
176
177
178
179
180
181 /* 
182  *  Traverse the visits file...
183  */
184 void artv_export_visits(void) {
185         struct visit vbuf;
186         struct cdbdata *cdbv;
187
188         cdb_rewind(CDB_VISIT);
189
190         while (cdbv = cdb_next_item(CDB_VISIT), cdbv != NULL) {
191                 memset(&vbuf, 0, sizeof(struct visit));
192                 memcpy(&vbuf, cdbv->ptr,
193                        ((cdbv->len > sizeof(struct visit)) ?
194                         sizeof(struct visit) : cdbv->len));
195                 cdb_free(cdbv);
196
197                 cprintf("visit\n");
198                 cprintf("%ld\n", vbuf.v_roomnum);
199                 cprintf("%ld\n", vbuf.v_roomgen);
200                 cprintf("%ld\n", vbuf.v_usernum);
201
202                 if (!IsEmptyStr(vbuf.v_seen)) {
203                         cprintf("%s\n", vbuf.v_seen);
204                 }
205                 else {
206                         cprintf("%ld\n", vbuf.v_lastseen);
207                 }
208
209                 cprintf("%s\n", vbuf.v_answered);
210                 cprintf("%u\n", vbuf.v_flags);
211                 cprintf("%d\n", vbuf.v_view);
212         }
213 }
214
215
216 void artv_export_message(long msgnum) {
217         struct MetaData smi;
218         struct CtdlMessage *msg;
219         struct ser_ret smr;
220         FILE *fp;
221         char buf[SIZ];
222         char tempfile[PATH_MAX];
223
224         msg = CtdlFetchMessage(msgnum, 1);
225         if (msg == NULL) return;        /* fail silently */
226
227         cprintf("message\n");
228         GetMetaData(&smi, msgnum);
229         cprintf("%ld\n", msgnum);
230         cprintf("%d\n", smi.meta_refcount);
231         cprintf("%s\n", smi.meta_content_type);
232
233         serialize_message(&smr, msg);
234         CtdlFreeMessage(msg);
235
236         /* write it in base64 */
237         CtdlMakeTempFileName(tempfile, sizeof tempfile);
238         snprintf(buf, sizeof buf, "%s -e >%s", file_base64, tempfile);
239         fp = popen(buf, "w");
240         fwrite(smr.ser, smr.len, 1, fp);
241         pclose(fp);
242
243         free(smr.ser);
244
245         fp = fopen(tempfile, "r");
246         unlink(tempfile);
247         if (fp != NULL) {
248                 while (fgets(buf, sizeof(buf), fp) != NULL) {
249                         buf[strlen(buf)-1] = 0;
250                         cprintf("%s\n", buf);
251                 }
252                 fclose(fp);
253         }
254         cprintf("%s\n", END_OF_MESSAGE);
255 }
256
257
258
259 void artv_export_messages(void) {
260         char buf[SIZ];
261         long msgnum;
262         int count = 0;
263
264         artv_global_message_list = fopen(artv_tempfilename1, "r");
265         if (artv_global_message_list != NULL) {
266                 lprintf(CTDL_INFO, "Opened %s\n", artv_tempfilename1);
267                 while (fgets(buf, sizeof(buf),
268                       artv_global_message_list) != NULL) {
269                         msgnum = atol(buf);
270                         if (msgnum > 0L) {
271                                 artv_export_message(msgnum);
272                                 ++count;
273                         }
274                 }
275                 fclose(artv_global_message_list);
276         }
277         lprintf(CTDL_INFO, "Exported %d messages.\n", count);
278 }
279
280
281
282
283 void artv_do_export(void) {
284         struct config *buf;
285         buf = &config;
286         cprintf("%d Exporting all Citadel databases.\n", LISTING_FOLLOWS);
287
288         cprintf("version\n%d\n", REV_LEVEL);
289
290         /* export the config file */
291         cprintf("config\n");
292
293 #include "artv_serialize.h"
294 #include "dtds/config-defs.h"
295 #include "undef_data.h"
296
297 /*
298         cprintf("%s\n", config.c_nodename);
299         cprintf("%s\n", config.c_fqdn);
300         cprintf("%s\n", config.c_humannode);
301         cprintf("%s\n", config.c_phonenum);
302         cprintf("%ld\n", (long)config.c_ctdluid);
303         cprintf("%d\n", config.c_creataide);
304         cprintf("%d\n", config.c_sleeping);
305         cprintf("%d\n", config.c_initax);
306         cprintf("%d\n", config.c_regiscall);
307         cprintf("%d\n", config.c_twitdetect);
308         cprintf("%s\n", config.c_twitroom);
309         cprintf("%s\n", config.c_moreprompt);
310         cprintf("%d\n", config.c_restrict);
311         cprintf("%s\n", config.c_site_location);
312         cprintf("%s\n", config.c_sysadm);
313         cprintf("%d\n", config.c_setup_level);
314         cprintf("%d\n", config.c_maxsessions);
315         cprintf("%d\n", config.c_port_number);
316         cprintf("%d\n", config.c_ep.expire_mode);
317         cprintf("%d\n", config.c_ep.expire_value);
318         cprintf("%d\n", config.c_userpurge);
319         cprintf("%d\n", config.c_roompurge);
320         cprintf("%s\n", config.c_logpages);
321         cprintf("%d\n", config.c_createax);
322         cprintf("%ld\n", config.c_maxmsglen);
323         cprintf("%d\n", config.c_min_workers);
324         cprintf("%d\n", config.c_max_workers);
325         cprintf("%d\n", config.c_pop3_port);
326         cprintf("%d\n", config.c_smtp_port);
327         cprintf("%d\n", config.c_purge_hour);
328         cprintf("%d\n", config.c_mbxep.expire_mode);
329         cprintf("%d\n", config.c_mbxep.expire_value);
330         cprintf("%s\n", config.c_ldap_host);
331         cprintf("%d\n", config.c_ldap_port);
332         cprintf("%s\n", config.c_ldap_base_dn);
333         cprintf("%s\n", config.c_ldap_bind_dn);
334         cprintf("%s\n", config.c_ldap_bind_pw);
335         cprintf("%s\n", config.c_ip_addr);
336         cprintf("%d\n", config.c_msa_port);
337         cprintf("%d\n", config.c_imaps_port);
338         cprintf("%d\n", config.c_pop3s_port);
339         cprintf("%d\n", config.c_smtps_port);
340         cprintf("%d\n", config.c_rfc822_strict_from);
341         cprintf("%d\n", config.c_aide_zap);
342         cprintf("%d\n", config.c_imap_port);
343         cprintf("%ld\n", config.c_net_freq);
344         cprintf("%d\n", config.c_disable_newu);
345         cprintf("%s\n", config.c_baseroom);
346         cprintf("%s\n", config.c_aideroom);
347         cprintf("%d\n", config.c_auto_cull);
348         cprintf("%d\n", config.c_instant_expunge);
349         cprintf("%d\n", config.c_allow_spoofing);
350         cprintf("%d\n", config.c_journal_email);
351         cprintf("%d\n", config.c_journal_pubmsgs);
352         cprintf("%s\n", config.c_journal_dest);
353         cprintf("%s\n", config.c_default_cal_zone);
354         cprintf("%d\n", config.c_pftcpdict_port);
355         cprintf("%d\n", config.c_managesieve_port);
356         cprintf("%d\n", config.c_auth_mode);
357         cprintf("%s\n", config.c_funambol_host);
358         cprintf("%d\n", config.c_funambol_port);
359         cprintf("%s\n", config.c_funambol_source);
360         cprintf("%s\n", config.c_funambol_auth);
361         cprintf("%d\n", config.c_rbl_at_greeting);
362 */
363         /* Export the control file */
364         get_control();
365         cprintf("control\n");
366         cprintf("%ld\n", CitControl.MMhighest);
367         cprintf("%u\n", CitControl.MMflags);
368         cprintf("%ld\n", CitControl.MMnextuser);
369         cprintf("%ld\n", CitControl.MMnextroom);
370         cprintf("%d\n", CitControl.version);
371
372         artv_export_users();
373         artv_export_rooms();
374         artv_export_floors();
375         artv_export_visits();
376         artv_export_messages();
377
378         cprintf("000\n");
379 }
380
381
382
383 void artv_import_config(void) {
384         char cbuf[SIZ];
385         struct config *buf;
386         buf = &config;
387
388         lprintf(CTDL_DEBUG, "Importing config file\n");
389
390 #include "artv_deserialize.h"
391 #include "dtds/config-defs.h"
392 #include "undef_data.h"
393
394 /*
395         client_getln(config.c_nodename, sizeof config.c_nodename);
396         client_getln(config.c_fqdn, sizeof config.c_fqdn);
397         client_getln(config.c_humannode, sizeof config.c_humannode);
398         client_getln(config.c_phonenum, sizeof config.c_phonenum);
399         client_getln(buf, sizeof buf);  config.c_ctdluid = atoi(buf);
400         client_getln(buf, sizeof buf);  config.c_creataide = atoi(buf);
401         client_getln(buf, sizeof buf);  config.c_sleeping = atoi(buf);
402         client_getln(buf, sizeof buf);  config.c_initax = atoi(buf);
403         client_getln(buf, sizeof buf);  config.c_regiscall = atoi(buf);
404         client_getln(buf, sizeof buf);  config.c_twitdetect = atoi(buf);
405         client_getln(config.c_twitroom, sizeof config.c_twitroom);
406         client_getln(config.c_moreprompt, sizeof config.c_moreprompt);
407         client_getln(buf, sizeof buf);  config.c_restrict = atoi(buf);
408         client_getln(config.c_site_location, sizeof config.c_site_location);
409         client_getln(config.c_sysadm, sizeof config.c_sysadm);
410         client_getln(buf, sizeof buf);  config.c_setup_level = atoi(buf);
411         client_getln(buf, sizeof buf);  config.c_maxsessions = atoi(buf);
412         client_getln(buf, sizeof buf);  config.c_port_number = atoi(buf);
413         client_getln(buf, sizeof buf);  config.c_ep.expire_mode = atoi(buf);
414         client_getln(buf, sizeof buf);  config.c_ep.expire_value = atoi(buf);
415         client_getln(buf, sizeof buf);  config.c_userpurge = atoi(buf);
416         client_getln(buf, sizeof buf);  config.c_roompurge = atoi(buf);
417         client_getln(config.c_logpages, sizeof config.c_logpages);
418         client_getln(buf, sizeof buf);  config.c_createax = atoi(buf);
419         client_getln(buf, sizeof buf);  config.c_maxmsglen = atol(buf);
420         client_getln(buf, sizeof buf);  config.c_min_workers = atoi(buf);
421         client_getln(buf, sizeof buf);  config.c_max_workers = atoi(buf);
422         client_getln(buf, sizeof buf);  config.c_pop3_port = atoi(buf);
423         client_getln(buf, sizeof buf);  config.c_smtp_port = atoi(buf);
424         client_getln(buf, sizeof buf);  config.c_purge_hour = atoi(buf);
425         client_getln(buf, sizeof buf);  config.c_mbxep.expire_mode = atoi(buf);
426         client_getln(buf, sizeof buf);  config.c_mbxep.expire_value = atoi(buf);
427         client_getln(config.c_ldap_host, sizeof config.c_ldap_host);
428         client_getln(buf, sizeof buf);  config.c_ldap_port = atoi(buf);
429         client_getln(config.c_ldap_base_dn, sizeof config.c_ldap_base_dn);
430         client_getln(config.c_ldap_bind_dn, sizeof config.c_ldap_bind_dn);
431         client_getln(config.c_ldap_bind_pw, sizeof config.c_ldap_bind_pw);
432         client_getln(config.c_ip_addr, sizeof config.c_ip_addr);
433         client_getln(buf, sizeof buf);  config.c_msa_port = atoi(buf);
434         client_getln(buf, sizeof buf);  config.c_imaps_port = atoi(buf);
435         client_getln(buf, sizeof buf);  config.c_pop3s_port = atoi(buf);
436         client_getln(buf, sizeof buf);  config.c_smtps_port = atoi(buf);
437         client_getln(buf, sizeof buf);  config.c_rfc822_strict_from = atoi(buf);
438         client_getln(buf, sizeof buf);  config.c_aide_zap = atoi(buf);
439         client_getln(buf, sizeof buf);  config.c_imap_port = atoi(buf);
440         client_getln(buf, sizeof buf);  config.c_net_freq = atol(buf);
441         client_getln(buf, sizeof buf);  config.c_disable_newu = atoi(buf);
442         client_getln(config.c_baseroom, sizeof config.c_baseroom);
443         client_getln(config.c_aideroom, sizeof config.c_aideroom);
444         client_getln(buf, sizeof buf);  config.c_auto_cull = atoi(buf);
445         client_getln(buf, sizeof buf);  config.c_instant_expunge = atoi(buf);
446         client_getln(buf, sizeof buf);  config.c_allow_spoofing = atoi(buf);
447         client_getln(buf, sizeof buf);  config.c_journal_email = atoi(buf);
448         client_getln(buf, sizeof buf);  config.c_journal_pubmsgs = atoi(buf);
449         client_getln(config.c_journal_dest, sizeof config.c_journal_dest);
450         client_getln(config.c_default_cal_zone, sizeof config.c_default_cal_zone);
451         client_getln(buf, sizeof buf);  config.c_pftcpdict_port = atoi(buf);
452         client_getln(buf, sizeof buf);  config.c_managesieve_port = atoi(buf);
453         client_getln(buf, sizeof buf);  config.c_auth_mode = atoi(buf);
454         client_getln(config.c_funambol_host, sizeof config.c_funambol_host);
455         client_getln(buf, sizeof buf); config.c_funambol_port = atoi(buf);
456         client_getln(config.c_funambol_source, sizeof config.c_funambol_source);
457         client_getln(config.c_funambol_auth, sizeof config.c_funambol_auth);
458         client_getln(buf, sizeof buf);  config.c_rbl_at_greeting = atoi(buf);
459 */
460         config.c_enable_fulltext = 0;   /* always disable */
461         put_config();
462         lprintf(CTDL_INFO, "Imported config file\n");
463 }
464
465
466 void artv_import_control(void) {
467         char buf[SIZ];
468
469         lprintf(CTDL_DEBUG, "Importing control file\n");
470         client_getln(buf, sizeof buf);  CitControl.MMhighest = atol(buf);
471         client_getln(buf, sizeof buf);  CitControl.MMflags = atoi(buf);
472         client_getln(buf, sizeof buf);  CitControl.MMnextuser = atol(buf);
473         client_getln(buf, sizeof buf);  CitControl.MMnextroom = atol(buf);
474         client_getln(buf, sizeof buf);  CitControl.version = atoi(buf);
475         CitControl.MMfulltext = (-1L);  /* always flush */
476         put_control();
477         lprintf(CTDL_INFO, "Imported control file\n");
478 }
479
480
481 void artv_import_user(void) {
482         char cbuf[SIZ];
483         struct ctdluser usbuf, *buf;
484         buf = &usbuf;
485 /*
486 #include "artv_deserialize.h"
487 #include "dtds/user-defs.h"
488 #include "undef_data.h"
489
490 /*/
491         client_getln(cbuf, sizeof cbuf);        buf->version = atoi(cbuf);
492         client_getln(cbuf, sizeof cbuf);        buf->uid = atoi(cbuf);
493         client_getln(buf->password, sizeof buf->password);
494         client_getln(cbuf, sizeof cbuf);        buf->flags = atoi(cbuf);
495         client_getln(cbuf, sizeof cbuf);        buf->timescalled = atol(cbuf);
496         client_getln(cbuf, sizeof cbuf);        buf->posted = atol(cbuf);
497         client_getln(cbuf, sizeof cbuf);        buf->axlevel = atoi(cbuf);
498         client_getln(cbuf, sizeof cbuf);        buf->usernum = atol(cbuf);
499         client_getln(cbuf, sizeof cbuf);        buf->lastcall = atol(cbuf);
500         client_getln(cbuf, sizeof cbuf);        buf->USuserpurge = atoi(cbuf);
501         client_getln(buf->fullname, sizeof buf->fullname);
502         client_getln(cbuf, sizeof cbuf);        buf->USscreenwidth = atoi(cbuf);
503         client_getln(cbuf, sizeof cbuf);        buf->USscreenheight = atoi(cbuf);
504 //*/
505         putuser(buf);
506 }
507
508
509 void artv_import_room(void) {
510         char cbuf[SIZ];
511         struct ctdlroom qrbuf, *buf;
512         long msgnum;
513         int msgcount = 0;
514
515         buf = &qrbuf;
516 /*
517 #include "artv_deserialize.h"
518 #include "dtds/room-defs.h"
519 #include "undef_data.h"
520
521 /*/
522         client_getln(buf->QRname, sizeof buf->QRname);
523         client_getln(buf->QRpasswd, sizeof buf->QRpasswd);
524         client_getln(cbuf, sizeof cbuf);        buf->QRroomaide = atol(cbuf);
525         client_getln(cbuf, sizeof cbuf);        buf->QRhighest = atol(cbuf);
526         client_getln(cbuf, sizeof cbuf);        buf->QRgen = atol(cbuf);
527         client_getln(cbuf, sizeof cbuf);        buf->QRflags = atoi(cbuf);
528         client_getln(buf->QRdirname, sizeof buf->QRdirname);
529         client_getln(cbuf, sizeof cbuf);        buf->QRinfo = atol(cbuf);
530         client_getln(cbuf, sizeof cbuf);        buf->QRfloor = atoi(cbuf);
531         client_getln(cbuf, sizeof cbuf);        buf->QRmtime = atol(cbuf);
532         client_getln(cbuf, sizeof cbuf);        buf->QRep.expire_mode = atoi(cbuf);
533         client_getln(cbuf, sizeof cbuf);        buf->QRep.expire_value = atoi(cbuf);
534         client_getln(cbuf, sizeof cbuf);        buf->QRnumber = atol(cbuf);
535         client_getln(cbuf, sizeof cbuf);        buf->QRorder = atoi(cbuf);
536         client_getln(cbuf, sizeof cbuf);        buf->QRflags2 = atoi(cbuf);
537         client_getln(cbuf, sizeof cbuf);        buf->QRdefaultview = atoi(cbuf);
538 //*/
539         putroom(buf);
540         lprintf(CTDL_INFO, "Imported room <%s>\n", qrbuf.QRname);
541         /* format of message list export is all message numbers output
542          * one per line terminated by a 0.
543          */
544         while (client_getln(cbuf, sizeof cbuf), msgnum = atol(cbuf), msgnum > 0) {
545                 CtdlSaveMsgPointerInRoom(qrbuf.QRname, msgnum, 0, NULL);
546                 ++msgcount;
547         }
548         lprintf(CTDL_INFO, "(%d messages)\n", msgcount);
549 }
550
551
552 void artv_import_floor(void) {
553         struct floor flbuf, *buf;
554         int i;
555         char cbuf[SIZ];
556
557         buf = & flbuf;
558         memset(buf, 0, sizeof(buf));
559         client_getln(cbuf, sizeof cbuf);        i = atoi(cbuf);
560 /*
561 #include "artv_deserialize.h"
562 #include "dtds/floor-defs.h"
563 #include "undef_data.h"
564 /*/
565         client_getln(cbuf, sizeof cbuf);        buf->f_flags = atoi(cbuf);
566         client_getln(buf->f_name, sizeof buf->f_name);
567         client_getln(cbuf, sizeof cbuf);        buf->f_ref_count = atoi(cbuf);
568         client_getln(cbuf, sizeof cbuf);        buf->f_ep.expire_mode = atoi(cbuf);
569         client_getln(cbuf, sizeof cbuf);        buf->f_ep.expire_value = atoi(cbuf);
570 //*/
571         putfloor(buf, i);
572         lprintf(CTDL_INFO, "Imported floor #%d (%s)\n", i, flbuf.f_name);
573 }
574
575
576 /* 
577  */
578 void artv_import_visit(void) {
579         struct visit vbuf;
580         char buf[SIZ];
581         int i;
582         int is_textual_seen = 0;
583
584         client_getln(buf, sizeof buf);  vbuf.v_roomnum = atol(buf);
585         client_getln(buf, sizeof buf);  vbuf.v_roomgen = atol(buf);
586         client_getln(buf, sizeof buf);  vbuf.v_usernum = atol(buf);
587
588         client_getln(buf, sizeof buf);
589         vbuf.v_lastseen = atol(buf);
590         for (i=0; buf[i]; ++i) if (!isdigit(buf[i])) is_textual_seen = 1;
591         if (is_textual_seen)    strcpy(vbuf.v_seen, buf);
592
593         client_getln(vbuf.v_answered, sizeof vbuf.v_answered);
594         client_getln(buf, sizeof buf);  vbuf.v_flags = atoi(buf);
595         client_getln(buf, sizeof buf);  vbuf.v_view = atoi(buf);
596         put_visit(&vbuf);
597         lprintf(CTDL_INFO, "Imported visit %ld/%ld/%ld\n",
598                 vbuf.v_roomnum, vbuf.v_roomgen, vbuf.v_usernum);
599 }
600
601
602
603 void artv_import_message(void) {
604         struct MetaData smi;
605         long msgnum;
606         long msglen;
607         FILE *fp;
608         char buf[SIZ];
609         char tempfile[PATH_MAX];
610         char *mbuf;
611
612         memset(&smi, 0, sizeof(struct MetaData));
613         client_getln(buf, sizeof buf);  msgnum = atol(buf);
614                                 smi.meta_msgnum = msgnum;
615         client_getln(buf, sizeof buf);  smi.meta_refcount = atoi(buf);
616         client_getln(smi.meta_content_type, sizeof smi.meta_content_type);
617
618         lprintf(CTDL_INFO, "message #%ld\n", msgnum);
619
620         /* decode base64 message text */
621         CtdlMakeTempFileName(tempfile, sizeof tempfile);
622         snprintf(buf, sizeof buf, "%s -d >%s", file_base64, tempfile);
623         fp = popen(buf, "w");
624         while (client_getln(buf, sizeof buf), strcasecmp(buf, END_OF_MESSAGE)) {
625                 fprintf(fp, "%s\n", buf);
626         }
627         pclose(fp);
628         fp = fopen(tempfile, "rb");
629         fseek(fp, 0L, SEEK_END);
630         msglen = ftell(fp);
631         fclose(fp);
632         lprintf(CTDL_DEBUG, "msglen = %ld\n", msglen);
633
634         mbuf = malloc(msglen);
635         fp = fopen(tempfile, "rb");
636         fread(mbuf, msglen, 1, fp);
637         fclose(fp);
638
639         cdb_store(CDB_MSGMAIN, &msgnum, sizeof(long), mbuf, msglen);
640
641         free(mbuf);
642         unlink(tempfile);
643
644         PutMetaData(&smi);
645         lprintf(CTDL_INFO, "Imported message %ld\n", msgnum);
646 }
647
648
649
650
651 void artv_do_import(void) {
652         char buf[SIZ];
653         char abuf[SIZ];
654         char s_version[SIZ];
655         int version;
656         long iterations;
657
658         unbuffer_output();
659
660         cprintf("%d sock it to me\n", SEND_LISTING);
661         abuf[0] = '\0';
662         unbuffer_output();
663         iterations = 0;
664         while (client_getln(buf, sizeof buf), strcmp(buf, "000")) {
665
666                 lprintf(CTDL_DEBUG, "import keyword: <%s>\n", buf);
667                 if ((abuf[0] == '\0') || (strcasecmp(buf, abuf))) {
668                         cprintf ("\n\nImporting datatype %s\n", buf);
669                         strncpy (abuf, buf, SIZ);       
670                         iterations = 0;
671                 }
672                 else {
673                         cprintf(".");
674                         if (iterations % 64 == 0)
675                                 cprintf("\n");
676                         
677                 }
678                 
679                 if (!strcasecmp(buf, "version")) {
680                         client_getln(s_version, sizeof s_version);
681                         version = atoi(s_version);
682                         if ((version<EXPORT_REV_MIN) || (version>REV_LEVEL)) {
683                                 lprintf(CTDL_ERR, "Version mismatch in ARTV import; aborting\n");
684                                 break;
685                         }
686                 }
687                 else if (!strcasecmp(buf, "config")) artv_import_config();
688                 else if (!strcasecmp(buf, "control")) artv_import_control();
689                 else if (!strcasecmp(buf, "user")) artv_import_user();
690                 else if (!strcasecmp(buf, "room")) artv_import_room();
691                 else if (!strcasecmp(buf, "floor")) artv_import_floor();
692                 else if (!strcasecmp(buf, "visit")) artv_import_visit();
693                 else if (!strcasecmp(buf, "message")) artv_import_message();
694                 else break;
695                 iterations ++;
696         }
697         lprintf(CTDL_INFO, "Invalid keyword <%s>.  Flushing input.\n", buf);
698         while (client_getln(buf, sizeof buf), strcmp(buf, "000"))  ;;
699         rebuild_euid_index();
700 }
701
702
703
704 void cmd_artv(char *cmdbuf) {
705         char cmd[32];
706         static int is_running = 0;
707
708         if (CtdlAccessCheck(ac_internal)) return;
709         if (is_running) {
710                 cprintf("%d The importer/exporter is already running.\n",
711                         ERROR + RESOURCE_BUSY);
712                 return;
713         }
714         is_running = 1;
715
716         CtdlMakeTempFileName(artv_tempfilename1, sizeof artv_tempfilename1);
717         CtdlMakeTempFileName(artv_tempfilename2, sizeof artv_tempfilename2);
718
719         extract_token(cmd, cmdbuf, 0, '|', sizeof cmd);
720         if (!strcasecmp(cmd, "export")) artv_do_export();
721         else if (!strcasecmp(cmd, "import")) artv_do_import();
722         else cprintf("%d illegal command\n", ERROR + ILLEGAL_VALUE);
723
724         unlink(artv_tempfilename1);
725         unlink(artv_tempfilename2);
726
727         is_running = 0;
728 }
729
730
731
732
733 CTDL_MODULE_INIT(vandelay)
734 {
735         CtdlRegisterProtoHook(cmd_artv, "ARTV", "import/export data store");
736
737         /* return our Subversion id for the Log */
738         return "$Id$";
739 }