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