don't use a tempfile to store the config use a strbuf. libc will decide when to do...
[citadel.git] / webcit / roomops.c
1 /*
2  * Lots of different room-related operations.
3  *
4  * Copyright (c) 1996-2011 by the citadel.org team
5  *
6  * This program is open source software.  You can redistribute it and/or
7  * modify it under the terms of the GNU General Public License as
8  * published by the Free Software Foundation; either version 3 of the
9  * License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19  */
20
21 #include "webcit.h"
22 #include "webserver.h"
23
24 ConstStr QRFlagList[] = {
25         {HKEY(strof(QR_PERMANENT))},
26         {HKEY(strof(QR_INUSE))},
27         {HKEY(strof(QR_PRIVATE))},
28         {HKEY(strof(QR_PASSWORDED))},
29         {HKEY(strof(QR_GUESSNAME))},
30         {HKEY(strof(QR_DIRECTORY))},
31         {HKEY(strof(QR_UPLOAD))},
32         {HKEY(strof(QR_DOWNLOAD))},
33         {HKEY(strof(QR_VISDIR))},
34         {HKEY(strof(QR_ANONONLY))},
35         {HKEY(strof(QR_ANONOPT))},
36         {HKEY(strof(QR_NETWORK))},
37         {HKEY(strof(QR_PREFONLY))},
38         {HKEY(strof(QR_READONLY))},
39         {HKEY(strof(QR_MAILBOX))}
40 };
41 ConstStr QR2FlagList[] = {
42         {HKEY(strof(QR2_SYSTEM))},
43         {HKEY(strof(QR2_SELFLIST))},
44         {HKEY(strof(QR2_COLLABDEL))},
45         {HKEY(strof(QR2_SUBJECTREQ))},
46         {HKEY(strof(QR2_SMTP_PUBLIC))},
47         {HKEY(strof(QR2_MODERATED))},
48         {HKEY("")}, 
49         {HKEY("")}, 
50         {HKEY("")}, 
51         {HKEY("")}, 
52         {HKEY("")}, 
53         {HKEY("")}, 
54         {HKEY("")}, 
55         {HKEY("")}, 
56         {HKEY("")}
57 };
58
59 void _DBG_QR(long QR)
60 {
61         int i = 1;
62         int j=0;
63         StrBuf *QRVec;
64
65         QRVec = NewStrBufPlain(NULL, 256);
66         while (i != 0)
67         {
68                 if ((QR & i) != 0) {
69                         if (StrLength(QRVec) > 0)
70                                 StrBufAppendBufPlain(QRVec, HKEY(" | "), 0);
71                         StrBufAppendBufPlain(QRVec, CKEY(QRFlagList[j]), 0);
72                 }
73                 i = i << 1;
74                 j++;
75         }
76         syslog(9, "DBG: QR-Vec [%ld] [%s]\n", QR, ChrPtr(QRVec));
77         FreeStrBuf(&QRVec);
78 }
79
80
81
82 void _DBG_QR2(long QR2)
83 {
84         int i = 1;
85         int j=0;
86         StrBuf *QR2Vec;
87
88         QR2Vec = NewStrBufPlain(NULL, 256);
89         while (i != 0)
90         {
91                 if ((QR2 & i) != 0) {
92                         if (StrLength(QR2Vec) > 0)
93                                 StrBufAppendBufPlain(QR2Vec, HKEY(" | "), 0);
94                         StrBufAppendBufPlain(QR2Vec, CKEY(QR2FlagList[j]), 0);
95                 }
96                 i = i << 1;
97                 j++;
98         }
99         syslog(9, "DBG: QR2-Vec [%ld] [%s]\n", QR2, ChrPtr(QR2Vec));
100         FreeStrBuf(&QR2Vec);
101 }
102
103
104
105
106
107
108
109
110
111
112
113 /*******************************************************************************
114  ***************************** Goto Commands ***********************************
115  ******************************************************************************/
116
117 void dotskip(void) {
118         smart_goto(sbstr("room"));
119 }
120
121 void dotgoto(void) {
122         if (!havebstr("room")) {
123                 readloop(readnew, eUseDefault);
124                 return;
125         }
126         if (WC->CurRoom.view != VIEW_MAILBOX) { /* dotgoto acts like dotskip when we're in a mailbox view */
127                 slrp_highest();
128         }
129         smart_goto(sbstr("room"));
130 }
131
132 /*
133  * goto next room
134  */
135 void smart_goto(const StrBuf *next_room) {
136         gotoroom(next_room);
137         readloop(readnew, eUseDefault);
138 }
139
140 /*
141  * goto a private room
142  */
143 void goto_private(void)
144 {
145         char hold_rm[SIZ];
146         StrBuf *Buf;
147         const StrBuf *gr_name;
148         long err;
149
150         if (!havebstr("ok_button")) {
151                 display_main_menu();
152                 return;
153         }
154         gr_name = sbstr("gr_name");
155         Buf = NewStrBuf();
156         strcpy(hold_rm, ChrPtr(WC->CurRoom.name));
157         serv_printf("GOTO %s|%s",
158                     ChrPtr(gr_name),
159                     bstr("gr_pass"));
160         StrBuf_ServGetln(Buf);
161         if  (GetServerStatus(Buf, &err) == 2) {
162                 FlushRoomlist();
163                 smart_goto(gr_name);
164                 FreeStrBuf(&Buf);
165                 return;
166         }
167         if (err == 540) {
168                 DoTemplate(HKEY("room_display_private"), NULL, &NoCtx);
169                 FreeStrBuf(&Buf);
170                 return;
171         }
172         StrBufCutLeft(Buf, 4);
173         AppendImportantMessage (SKEY(Buf));
174         Buf = NewStrBufPlain(HKEY("_BASEROOM_"));
175         smart_goto(Buf);
176         FreeStrBuf(&Buf);
177         return;
178 }
179
180 /*
181  * back end routine to take the session to a new room
182  */
183 long gotoroom(const StrBuf *gname)
184 {
185         wcsession *WCC = WC;
186         StrBuf *Buf;
187         static long ls = (-1L);
188         long err = 0;
189         int room_name_supplied = 0;
190         int is_baseroom = 0;
191
192         /* store ungoto information */
193         if (StrLength(gname) > 0) {
194                 room_name_supplied = 1;
195         }
196         if (room_name_supplied) {
197                 strcpy(WCC->ugname, ChrPtr(WCC->CurRoom.name));
198                 if (!strcasecmp(ChrPtr(gname), "_BASEROOM_")) {
199                         is_baseroom = 1;
200                 }
201         }
202         WCC->uglsn = ls;
203         Buf = NewStrBuf();
204
205         /* move to the new room */
206         if (room_name_supplied) {
207                 serv_printf("GOTO %s", ChrPtr(gname));
208         }
209         else {
210                 /* or just refresh the current state... */
211                 serv_printf("GOTO 00000000000000000000");
212         }
213         StrBuf_ServGetln(Buf);
214         if  (GetServerStatus(Buf, &err) != 2) {
215                 serv_puts("GOTO _BASEROOM_");
216                 StrBuf_ServGetln(Buf);
217                 /* 
218                  * well, we know that this is the fallback case, 
219                  * but we're interested that the first command 
220                  * didn't work out in first place.
221                  */
222                 if (GetServerStatus(Buf, NULL) != 2) {
223                         FreeStrBuf(&Buf);
224                         return err;
225                 }
226         }
227         FlushFolder(&WCC->CurRoom);
228         ParseGoto(&WCC->CurRoom, Buf);
229
230         if (room_name_supplied) {
231                 remove_march(WCC->CurRoom.name);
232                 if (is_baseroom) {
233                         remove_march(gname);
234                 }
235         }
236         FreeStrBuf(&Buf);
237
238         return err;
239 }
240
241
242
243 void ParseGoto(folder *room, StrBuf *Line)
244 {
245         wcsession *WCC = WC;
246         const char *Pos;
247         int flag;
248         void *vFloor = NULL;
249         StrBuf *pBuf;
250
251         if (StrLength(Line) < 4) {
252                 return;
253         }
254         
255         /* ignore the commandstate... */
256         Pos = ChrPtr(Line) + 4;
257
258         if (room->RoomNameParts != NULL)
259         {
260                 int i;
261                 for (i=0; i < room->nRoomNameParts; i++)
262                         FreeStrBuf(&room->RoomNameParts[i]);
263                 free(room->RoomNameParts);
264                 room->RoomNameParts = NULL;
265         }
266
267         pBuf = room->name;  
268         if (pBuf == NULL)
269                 pBuf = NewStrBufPlain(NULL, StrLength(Line));
270         else
271                 FlushStrBuf(pBuf);
272         memset(room, 0, sizeof(folder));
273         room->name = pBuf;
274
275         StrBufExtract_NextToken(room->name, Line, &Pos, '|');
276
277         room->nNewMessages = StrBufExtractNext_long(Line, &Pos, '|'); 
278         if (room->nNewMessages > 0)
279                 room->RAFlags |= UA_HASNEWMSGS;
280
281         room->nTotalMessages = StrBufExtractNext_long(Line, &Pos, '|');
282
283         room->ShowInfo =  StrBufExtractNext_long(Line, &Pos, '|');
284         
285         room->QRFlags = StrBufExtractNext_long(Line, &Pos, '|');
286
287         DBG_QR(room->QRFlags);
288
289         room->HighestRead = StrBufExtractNext_long(Line, &Pos, '|');
290         room->LastMessageRead = StrBufExtractNext_long(Line, &Pos, '|');
291
292         room->is_inbox = StrBufExtractNext_long(Line, &Pos, '|');
293
294         flag = StrBufExtractNext_long(Line, &Pos, '|');
295         if (WCC->is_aide || flag) {
296                 room->RAFlags |= UA_ADMINALLOWED;
297         }
298
299         room->UsersNewMAilboxMessages = StrBufExtractNext_long(Line, &Pos, '|');
300
301         room->floorid = StrBufExtractNext_int(Line, &Pos, '|');
302
303         room->view = StrBufExtractNext_long(Line, &Pos, '|');
304
305         room->defview = StrBufExtractNext_long(Line, &Pos, '|');
306
307         flag = StrBufExtractNext_long(Line, &Pos, '|');
308         if (flag)
309                 room->RAFlags |= UA_ISTRASH;
310
311         room->QRFlags2 = StrBufExtractNext_long(Line, &Pos, '|');
312         DBG_QR2(room->QRFlags2);
313
314         /* find out, whether we are in a sub-room */
315         room->nRoomNameParts = StrBufNum_tokens(room->name, '\\');
316         if (room->nRoomNameParts > 1)
317         {
318                 int i;
319                 
320                 Pos = NULL;
321                 room->RoomNameParts = malloc(sizeof(StrBuf*) * (room->nRoomNameParts + 1));
322                 memset(room->RoomNameParts, 0, sizeof(StrBuf*) * (room->nRoomNameParts + 1));
323                 for (i=0; i < room->nRoomNameParts; i++)
324                 {
325                         room->RoomNameParts[i] = NewStrBuf();
326                         StrBufExtract_NextToken(room->RoomNameParts[i],
327                                                 room->name, &Pos, '\\');
328                 }
329         }
330
331         /* Private mailboxes on the main floor get remapped to the personal folder */
332         if ((room->QRFlags & QR_MAILBOX) && 
333             (room->floorid == 0))
334         {
335                 room->floorid = VIRTUAL_MY_FLOOR;
336                 if ((room->nRoomNameParts == 1) && 
337                     (StrLength(room->name) == 4) && 
338                     (strcmp(ChrPtr(room->name), "Mail") == 0))
339                 {
340                         room->is_inbox = 1;
341                 }
342                 
343         }
344         /* get a pointer to the floor we're on: */
345         if (WCC->Floors == NULL)
346                 GetFloorListHash(NULL, NULL);
347
348         GetHash(WCC->Floors, IKEY(room->floorid), &vFloor);
349         room->Floor = (const Floor*) vFloor;
350 }
351
352 /*
353  * Delete the current room
354  */
355 void delete_room(void)
356 {
357         StrBuf *Line;
358         
359         serv_puts("KILL 1");
360         StrBuf_ServGetln(Line);
361         if (GetServerStatusMsg(Line, NULL, 1, 2) != 2) {
362                 display_main_menu();
363         } else {
364                 StrBuf *Buf;
365                 
366                 FlushRoomlist ();
367                 Buf = NewStrBufPlain(HKEY("_BASEROOM_"));
368                 smart_goto(Buf);
369                 FreeStrBuf(&Buf);
370         }
371         FreeStrBuf(&Line);
372 }
373
374 /*
375  * zap a room
376  */
377 void zap(void)
378 {
379         char buf[SIZ];
380         StrBuf *final_destination;
381
382         /**
383          * If the forget-room routine fails for any reason, we fall back
384          * to the current room; otherwise, we go to the Lobby
385          */
386         final_destination = NewStrBufDup(WC->CurRoom.name);
387
388         if (havebstr("ok_button")) {
389                 serv_printf("GOTO %s", ChrPtr(WC->CurRoom.name));
390                 serv_getln(buf, sizeof buf);
391                 if (buf[0] == '2') {
392                         serv_puts("FORG");
393                         serv_getln(buf, sizeof buf);
394                         if (buf[0] == '2') {
395                                 FlushStrBuf(final_destination);
396                                 StrBufAppendBufPlain(final_destination, HKEY("_BASEROOM_"), 0);
397                         }
398                 }
399                 FlushRoomlist ();
400         }
401         smart_goto(final_destination);
402         FreeStrBuf(&final_destination);
403 }
404
405
406 /*
407  * mark all messages in current room as having been read
408  */
409 void slrp_highest(void)
410 {
411         char buf[256];
412
413         serv_puts("SLRP HIGHEST");
414         serv_getln(buf, sizeof buf);
415 }
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430 /*******************************************************************************
431  ***************************** Modify Rooms ************************************
432  ******************************************************************************/
433
434
435
436
437
438 void LoadRoomAide(void)
439 {
440         wcsession *WCC = WC;
441         StrBuf *Buf;
442         
443         if (WCC->CurRoom.RoomAideLoaded)
444                 return;
445
446         WCC->CurRoom.RoomAideLoaded = 1;
447         Buf = NewStrBuf();
448         serv_puts("GETA");
449         StrBuf_ServGetln(Buf);
450         if (GetServerStatus(Buf, NULL) != 2) {
451                 FlushStrBuf(WCC->CurRoom.RoomAide);
452                 AppendImportantMessage (ChrPtr(Buf) + 4, 
453                                         StrLength(Buf) - 4);
454         } else {
455                 const char *Pos;
456
457                 Pos = ChrPtr(Buf) + 4;
458
459                 FreeStrBuf(&WCC->CurRoom.RoomAide);
460                 WCC->CurRoom.RoomAide = NewStrBufPlain (NULL, StrLength (Buf));
461
462                 StrBufExtract_NextToken(WCC->CurRoom.RoomAide, Buf, &Pos, '|'); 
463         }
464         FreeStrBuf (&Buf);
465 }
466
467 int SaveRoomAide(folder *Room)
468 {
469         StrBuf *Buf;
470         Buf = NewStrBuf ();
471         serv_printf("SETA %s", ChrPtr(Room->RoomAide));
472         StrBuf_ServGetln(Buf);
473         if (GetServerStatus(Buf, NULL) != 2) {
474                 StrBufCutLeft(Buf, 4);
475                 AppendImportantMessage (SKEY(Buf));
476                 FreeStrBuf(&Buf);
477                 return 0;
478         }
479         FreeStrBuf(&Buf);
480         return 1;
481 }
482
483
484 int GetCurrentRoomFlags(folder *Room)
485 {
486         StrBuf *Buf;
487
488         Buf = NewStrBuf();
489         serv_puts("GETR");
490         StrBuf_ServGetln(Buf);
491         if (GetServerStatus(Buf, NULL) != 2) {
492                 FlushStrBuf(Room->XAPass);
493                 FlushStrBuf(Room->Directory);
494                 StrBufCutLeft(Buf, 4);
495                 AppendImportantMessage (SKEY(Buf));
496                 FreeStrBuf(&Buf);
497                 return 0;
498         } else {
499                 const char *Pos;
500
501                 Pos = ChrPtr(Buf) + 4;
502
503                 FreeStrBuf(&Room->XAPass);
504                 FreeStrBuf(&Room->Directory);
505
506                 Room->XAPass = NewStrBufPlain (NULL, StrLength (Buf));
507                 Room->Directory = NewStrBufPlain (NULL, StrLength (Buf));
508
509                 FreeStrBuf(&Room->name);
510                 Room->name = NewStrBufPlain(NULL, StrLength(Buf));
511                 StrBufExtract_NextToken(Room->name, Buf, &Pos, '|'); 
512                                         
513                 StrBufExtract_NextToken(Room->XAPass, Buf, &Pos, '|'); 
514                 StrBufExtract_NextToken(Room->Directory, Buf, &Pos, '|'); 
515                 
516                 Room->QRFlags = StrBufExtractNext_long(Buf, &Pos, '|');
517                 Room->floorid = StrBufExtractNext_long(Buf, &Pos, '|');
518                 Room->Order = StrBufExtractNext_long(Buf, &Pos, '|');
519                 Room->defview = StrBufExtractNext_long(Buf, &Pos, '|');
520                 Room->QRFlags2 = StrBufExtractNext_long(Buf, &Pos, '|');
521                 FreeStrBuf (&Buf);
522                 Room->XALoaded = 1;
523                 return 1;
524         }
525 }
526
527
528 int SetCurrentRoomFlags(folder *Room)
529 {
530         StrBuf *Buf;
531
532         Buf = NewStrBuf();
533         DBG_QR(Room->QRFlags);
534         DBG_QR2(Room->QRFlags2);
535
536         serv_printf("SETR %s|%s|%s|%ld|%d|%d|%ld|%ld|%ld",
537                     ChrPtr(Room->name),
538                     ChrPtr(Room->XAPass),
539                     ChrPtr(Room->Directory),
540                     Room->QRFlags, 
541                     Room->BumpUsers,
542                     Room->floorid, 
543                     Room->Order,
544                     Room->defview,
545                     Room->QRFlags2);
546
547         StrBuf_ServGetln(Buf);
548         if (GetServerStatus(Buf, NULL) != 2) {
549                 StrBufCutLeft(Buf, 4);
550                 AppendImportantMessage (SKEY(Buf));
551                 FreeStrBuf(&Buf);
552                 return 0;
553         } else {
554                 FreeStrBuf(&Buf);
555                 return 1;
556         }
557 }
558
559 void LoadRoomXA (void)
560 {
561         wcsession *WCC = WC;
562                 
563         if (WCC->CurRoom.XALoaded)
564                 return;
565
566         GetCurrentRoomFlags(&WCC->CurRoom);
567 }
568
569
570 void LoadXRoomPic(void)
571 {
572         wcsession *WCC = WC;
573         StrBuf *Buf;
574         
575         if (WCC->CurRoom.XHaveRoomPicLoaded)
576                 return;
577
578         WCC->CurRoom.XHaveRoomPicLoaded = 1;
579         Buf = NewStrBuf();
580         serv_puts("OIMG _roompic_");
581         StrBuf_ServGetln(Buf);
582         if (GetServerStatus(Buf, NULL) != 2) {
583                 WCC->CurRoom.XHaveRoomPic = 0;
584         } else {
585                 WCC->CurRoom.XHaveRoomPic = 1;
586         }
587         serv_puts("CLOS");
588         StrBuf_ServGetln(Buf);
589         GetServerStatus(Buf, NULL);
590         FreeStrBuf (&Buf);
591 }
592
593
594 void LoadXRoomInfoText(void)
595 {
596         wcsession *WCC = WC;
597         StrBuf *Buf;
598         int Done = 0;
599         
600         if (WCC->CurRoom.XHaveInfoTextLoaded) {
601                 return;
602         }
603
604         WCC->CurRoom.XHaveInfoTextLoaded = 1;
605         Buf = NewStrBuf();
606
607         serv_puts("RINF");
608
609         StrBuf_ServGetln(Buf);
610         if (GetServerStatus(Buf, NULL) == 1) {
611                 WCC->CurRoom.XInfoText = NewStrBuf ();
612                 
613                 while (!Done && StrBuf_ServGetln(Buf)>=0) {
614                         if ( (StrLength(Buf)==3) && 
615                              !strcmp(ChrPtr(Buf), "000")) 
616                                 Done = 1;
617                         else 
618                                 StrBufAppendBuf(WCC->CurRoom.XInfoText, Buf, 0);
619                 }
620         }
621
622         FreeStrBuf(&Buf);
623 }
624
625
626 void LoadXRoomXCountFiles(void)
627 {
628         wcsession *WCC = WC;
629         StrBuf *Buf;
630         int Done = 0;
631         
632         if (WCC->CurRoom.XHaveDownloadCount)
633                 return;
634
635         WCC->CurRoom.XHaveDownloadCount = 1;
636
637         Buf = NewStrBuf();
638         serv_puts("RDIR");
639         StrBuf_ServGetln(Buf);
640         if (GetServerStatus(Buf, NULL) == 1) {
641                 
642                 while (!Done && StrBuf_ServGetln(Buf)>=0) {
643                         if ( (StrLength(Buf)==3) && 
644                              !strcmp(ChrPtr(Buf), "000")) 
645                                 Done = 1;
646                         else 
647                                 WCC->CurRoom.XDownloadCount++;
648                 }
649         }
650
651         FreeStrBuf (&Buf);
652 }
653
654
655 /* 
656  * Toggle self-service list subscription
657  */
658 void toggle_self_service(void) {
659         wcsession *WCC = WC;
660
661         if (GetCurrentRoomFlags (&WCC->CurRoom) == 0)
662                 return;
663
664         if (yesbstr("QR2_SelfList")) 
665                 WCC->CurRoom.QRFlags2 = WCC->CurRoom.QRFlags2 | QR2_SELFLIST;
666         else 
667                 WCC->CurRoom.QRFlags2 = WCC->CurRoom.QRFlags2 & ~QR2_SELFLIST;
668
669         if (yesbstr("QR2_SMTP_PUBLIC")) 
670                 WCC->CurRoom.QRFlags2 = WCC->CurRoom.QRFlags2 | QR2_SMTP_PUBLIC;
671         else
672                 WCC->CurRoom.QRFlags2 = WCC->CurRoom.QRFlags2 & ~QR2_SMTP_PUBLIC;
673
674         if (yesbstr("QR2_Moderated")) 
675                 WCC->CurRoom.QRFlags2 = WCC->CurRoom.QRFlags2 | QR2_MODERATED;
676         else
677                 WCC->CurRoom.QRFlags2 = WCC->CurRoom.QRFlags2 & ~QR2_MODERATED;
678         if (yesbstr("QR2_SubsOnly")) 
679                 WCC->CurRoom.QRFlags2 = WCC->CurRoom.QRFlags2 | QR2_SMTP_PUBLIC;
680         else
681                 WCC->CurRoom.QRFlags2 = WCC->CurRoom.QRFlags2 & ~QR2_SMTP_PUBLIC;
682
683         SetCurrentRoomFlags (&WCC->CurRoom);
684         
685         http_transmit_thing(ChrPtr(do_template("room_edit")), 0);
686 }
687
688
689
690 /*
691  * save new parameters for a room
692  */
693 void editroom(void)
694 {
695         wcsession *WCC = WC;
696         const StrBuf *Ptr;
697         const StrBuf *er_name;
698         const StrBuf *er_password;
699         const StrBuf *er_dirname;
700         const StrBuf *er_roomaide;
701         unsigned er_flags;
702         unsigned er_flags2;
703         int succ1, succ2;
704
705         if (!havebstr("ok_button")) {
706                 AppendImportantMessage(_("Cancelled.  Changes were not saved."), -1);
707                 http_transmit_thing(ChrPtr(do_template("room_edit")), 0);
708                 return;
709         }
710         if (GetCurrentRoomFlags (&WCC->CurRoom) == 0)
711                 return;
712
713         LoadRoomAide();
714
715         er_flags = WCC->CurRoom.QRFlags;
716         er_flags &= !(QR_PRIVATE | QR_PASSWORDED | QR_GUESSNAME);
717
718         er_flags2 = WCC->CurRoom.QRFlags2;
719
720         Ptr = sbstr("type");
721         if (!strcmp(ChrPtr(Ptr), "invonly")) {
722                 er_flags |= (QR_PRIVATE);
723         }
724         if (!strcmp(ChrPtr(Ptr), "hidden")) {
725                 er_flags |= (QR_PRIVATE | QR_GUESSNAME);
726         }
727         if (!strcmp(ChrPtr(Ptr), "passworded")) {
728                 er_flags |= (QR_PRIVATE | QR_PASSWORDED);
729         }
730         if (!strcmp(ChrPtr(Ptr), "personal")) {
731                 er_flags |= QR_MAILBOX;
732         } else {
733                 er_flags &= ~QR_MAILBOX;
734         }
735
736
737         
738         if (yesbstr("prefonly")) {
739                 er_flags |= QR_PREFONLY;
740         } else {
741                 er_flags &= ~QR_PREFONLY;
742         }
743
744         if (yesbstr("readonly")) {
745                 er_flags |= QR_READONLY;
746         } else {
747                 er_flags &= ~QR_READONLY;
748         }
749
750         
751         if (yesbstr("collabdel")) {
752                 er_flags2 |= QR2_COLLABDEL;
753         } else {
754                 er_flags2 &= ~QR2_COLLABDEL;
755         }
756
757         if (yesbstr("permanent")) {
758                 er_flags |= QR_PERMANENT;
759         } else {
760                 er_flags &= ~QR_PERMANENT;
761         }
762
763         if (yesbstr("subjectreq")) {
764                 er_flags2 |= QR2_SUBJECTREQ;
765         } else {
766                 er_flags2 &= ~QR2_SUBJECTREQ;
767         }
768
769         if (yesbstr("network")) {
770                 er_flags |= QR_NETWORK;
771         } else {
772                 er_flags &= ~QR_NETWORK;
773         }
774
775         if (yesbstr("directory")) {
776                 er_flags |= QR_DIRECTORY;
777         } else {
778                 er_flags &= ~QR_DIRECTORY;
779         }
780
781         if (yesbstr("ulallowed")) {
782                 er_flags |= QR_UPLOAD;
783         } else {
784                 er_flags &= ~QR_UPLOAD;
785         }
786
787         if (yesbstr("dlallowed")) {
788                 er_flags |= QR_DOWNLOAD;
789         } else {
790                 er_flags &= ~QR_DOWNLOAD;
791         }
792
793         if (yesbstr("visdir")) {
794                 er_flags |= QR_VISDIR;
795         } else {
796                 er_flags &= ~QR_VISDIR;
797         }
798
799
800         Ptr = sbstr("anon");
801
802         er_flags &= ~(QR_ANONONLY | QR_ANONOPT);
803         if (!strcmp(ChrPtr(Ptr), "anononly"))
804                 er_flags |= QR_ANONONLY;
805         if (!strcmp(ChrPtr(Ptr), "anon2"))
806                 er_flags |= QR_ANONOPT;
807
808         er_name     = sbstr("er_name");
809         er_dirname  = sbstr("er_dirname");
810         er_roomaide = sbstr("er_roomaide");
811         er_password = sbstr("er_password");
812
813         FlushStrBuf(WCC->CurRoom.name);
814         StrBufAppendBuf(WCC->CurRoom.name, er_name, 0);
815
816         FlushStrBuf(WCC->CurRoom.Directory);
817         StrBufAppendBuf(WCC->CurRoom.Directory, er_dirname, 0);
818
819         FlushStrBuf(WCC->CurRoom.RoomAide);
820         StrBufAppendBuf(WCC->CurRoom.RoomAide, er_roomaide, 0);
821
822         FlushStrBuf(WCC->CurRoom.XAPass);
823         StrBufAppendBuf(WCC->CurRoom.XAPass, er_password, 0);
824
825         WCC->CurRoom.BumpUsers = yesbstr("bump");
826
827         WCC->CurRoom.floorid = ibstr("er_floor");
828
829         succ1 = SetCurrentRoomFlags(&WCC->CurRoom);
830
831         succ2 = SaveRoomAide (&WCC->CurRoom);
832         
833         if (succ1 + succ2 == 0)
834                 AppendImportantMessage (_("Your changes have been saved."), -1);
835         http_transmit_thing(ChrPtr(do_template("room_edit")), 0);
836         return;
837 }
838
839
840
841 /*
842  * Display form for Invite, Kick, and show Who Knows a room
843  */
844 void do_invt_kick(void) 
845 {
846         StrBuf *Buf, *User;
847         const StrBuf *UserNames;
848         int Kick, Invite;
849         wcsession *WCC = WC;
850
851
852         if (GetCurrentRoomFlags(&WCC->CurRoom) == 1)
853         {
854                 const char *Pos;
855                 UserNames = sbstr("username");
856                 Kick = havebstr("kick_button");
857                 Invite = havebstr("invite_button");
858
859                 User = NewStrBufPlain(NULL, StrLength(UserNames));
860                 Buf = NewStrBuf();
861                 
862                 Pos = ChrPtr(UserNames);
863                 while (Pos != StrBufNOTNULL)
864                 {
865                         StrBufExtract_NextToken(User, UserNames, &Pos, ',');
866                         StrBufTrim(User);
867                         if ((StrLength(User) > 0) && (Kick))
868                         {
869                                 serv_printf("KICK %s", ChrPtr(User));
870                                 if (StrBuf_ServGetln(Buf) < 0)
871                                         break;
872                                 if (GetServerStatus(Buf, NULL) != 2) {
873                                         StrBufCutLeft(Buf, 4);
874                                         AppendImportantMessage(SKEY(Buf));
875                                 } else {
876                                         StrBufPrintf(Buf, 
877                                                      _("User '%s' kicked out of room '%s'."), 
878                                                      ChrPtr(User), 
879                                                      ChrPtr(WCC->CurRoom.name)
880                                                 );
881                                         AppendImportantMessage(SKEY(Buf));
882                                 }
883                         }
884                         else if ((StrLength(User) > 0) && (Invite))
885                         {
886                                 serv_printf("INVT %s", ChrPtr(User));
887                                 if (StrBuf_ServGetln(Buf) < 0)
888                                         break;
889                                 if (GetServerStatus(Buf, NULL) != 2) {
890                                         StrBufCutLeft(Buf, 4);
891                                         AppendImportantMessage(SKEY(Buf));
892                                 } else {
893                                         StrBufPrintf(Buf, 
894                                                      _("User '%s' invited to room '%s'."), 
895                                                      ChrPtr(User), 
896                                                      ChrPtr(WCC->CurRoom.name)
897                                                 );
898                                         AppendImportantMessage(SKEY(Buf));
899                                 }
900                         }
901                 }
902         }
903
904         http_transmit_thing(ChrPtr(do_template("room_edit")), 0);
905 }
906
907
908 /*
909  * Create a new room
910  */
911 void entroom(void)
912 {
913         StrBuf *Line;
914         const StrBuf *er_name;
915         const StrBuf *er_type;
916         const StrBuf *er_password;
917         int er_floor;
918         int er_num_type;
919         int er_view;
920         wcsession *WCC = WC;
921
922         if (!havebstr("ok_button")) {
923                 AppendImportantMessage(_("Cancelled.  No new room was created."), -1);
924                 display_main_menu();
925                 return;
926         }
927         er_name = sbstr("er_name");
928         er_type = sbstr("type");
929         er_password = sbstr("er_password");
930         er_floor = ibstr("er_floor");
931         er_view = ibstr("er_view");
932
933         er_num_type = 0;
934         if (!strcmp(ChrPtr(er_type), "hidden"))
935                 er_num_type = 1;
936         else if (!strcmp(ChrPtr(er_type), "passworded"))
937                 er_num_type = 2;
938         else if (!strcmp(ChrPtr(er_type), "invonly"))
939                 er_num_type = 3;
940         else if (!strcmp(ChrPtr(er_type), "personal"))
941                 er_num_type = 4;
942
943         serv_printf("CRE8 1|%s|%d|%s|%d|%d|%d", 
944                     ChrPtr(er_name), 
945                     er_num_type, 
946                     ChrPtr(er_password), 
947                     er_floor, 
948                     0, 
949                     er_view);
950
951         Line = NewStrBuf();
952         StrBuf_ServGetln(Line);
953         if (GetServerStatusMsg(Line, NULL, 1, 2) != 2) {
954                 FreeStrBuf(&Line);
955                 display_main_menu();
956                 return;
957         }
958         /** TODO: Room created, now update the left hand icon bar for this user */
959         gotoroom(er_name);
960
961         serv_printf("VIEW %d", er_view);
962         StrBuf_ServGetln(Line);
963         FreeStrBuf(&Line); /* TODO: should we care about errors? */
964         WCC->CurRoom.view = er_view;
965
966         if ( (WCC != NULL) && ( (WCC->CurRoom.RAFlags & UA_ADMINALLOWED) != 0) )  {
967                 http_transmit_thing(ChrPtr(do_template("room_edit")), 0);
968         } else {
969                 smart_goto(WCC->CurRoom.name);
970         }
971         FreeStrBuf(&Line);
972 }
973
974
975
976
977
978 /*
979  * Change the view for this room
980  */
981 void change_view(void) {
982         int newview;
983         char buf[SIZ];
984
985         newview = lbstr("view");
986         serv_printf("VIEW %d", newview);
987         serv_getln(buf, sizeof buf);
988         WC->CurRoom.view = newview;
989         smart_goto(WC->CurRoom.name);
990 }
991
992
993
994 /*
995  * Set the message expire policy for this room and/or floor
996  */
997 void set_room_policy(void) {
998         StrBuf *Line;
999
1000         if (!havebstr("ok_button")) {
1001                 AppendImportantMessage(_("Cancelled.  Changes were not saved."), -1);
1002                 http_transmit_thing(ChrPtr(do_template("room_edit")), 0);
1003                 return;
1004         }
1005         Line = NewStrBuf();
1006
1007         serv_printf("SPEX roompolicy|%d|%d", ibstr("roompolicy"), ibstr("roomvalue"));
1008         StrBuf_ServGetln(Line);
1009         GetServerStatusMsg(Line, NULL, 1, 0);
1010         if (WC->axlevel >= 6) {
1011                 serv_printf("SPEX floorpolicy|%d|%d", ibstr("floorpolicy"), ibstr("floorvalue"));
1012                 StrBuf_ServGetln(Line);
1013                 GetServerStatusMsg(Line, NULL, 1, 0);
1014         }
1015         FreeStrBuf(&Line);
1016         ReloadCurrentRoom();
1017         http_transmit_thing(ChrPtr(do_template("room_edit")), 0);
1018 }
1019
1020
1021
1022 /*
1023  * Perform changes to a room's network configuration
1024  */
1025 void netedit(void) {
1026         char buf[SIZ];
1027         char line[SIZ];
1028         char cmpa0[SIZ];
1029         char cmpa1[SIZ];
1030         char cmpb0[SIZ];
1031         char cmpb1[SIZ];
1032         int i, num_addrs;
1033         StrBuf *Line;
1034         StrBuf *TmpBuf;
1035         int Done;
1036
1037         /*/ TODO: do line dynamic! */
1038         if (havebstr("line_pop3host")) {
1039                 strcpy(line, bstr("prefix"));
1040                 strcat(line, bstr("line_pop3host"));
1041                 strcat(line, "|");
1042                 strcat(line, bstr("line_pop3user"));
1043                 strcat(line, "|");
1044                 strcat(line, bstr("line_pop3pass"));
1045                 strcat(line, "|");
1046                 strcat(line, ibstr("line_pop3keep") ? "1" : "0" );
1047                 strcat(line, "|");
1048                 sprintf(&line[strlen(line)],"%ld", lbstr("line_pop3int"));
1049                 strcat(line, bstr("suffix"));
1050         }
1051         else if (havebstr("line")) {
1052                 strcpy(line, bstr("prefix"));
1053                 strcat(line, bstr("line"));
1054                 strcat(line, bstr("suffix"));
1055         }
1056         else {
1057                 http_transmit_thing(ChrPtr(do_template("room_edit")), 0);
1058                 return;
1059         }
1060
1061         Line = NewStrBuf();
1062         TmpBuf = NewStrBuf();
1063         serv_puts("GNET");
1064         StrBuf_ServGetln(Line);
1065         if  (GetServerStatus(Line, NULL) != 1) {
1066                 AppendImportantMessage(SRV_STATUS_MSG(Line));   
1067                 FreeStrBuf(&Line);
1068                 http_transmit_thing(ChrPtr(do_template("room_edit")), 0);
1069                 return;
1070         }
1071
1072         /** This loop works for add *or* remove.  Spiffy, eh? */
1073         Done = 0;
1074         extract_token(cmpb0, line, 0, '|', sizeof cmpb0);
1075         extract_token(cmpb1, line, 1, '|', sizeof cmpb1);
1076         while (!Done && StrBuf_ServGetln(Line)>=0) {
1077                 if ( (StrLength(Line)==3) && 
1078                      !strcmp(ChrPtr(Line), "000")) 
1079                 {
1080                         Done = 1;
1081                 }
1082                 else
1083                 {
1084                         extract_token(cmpa0, ChrPtr(Line), 0, '|', sizeof cmpa0);
1085                         extract_token(cmpa1, ChrPtr(Line), 1, '|', sizeof cmpa1);
1086                         if ( (strcasecmp(cmpa0, cmpb0)) 
1087                              || (strcasecmp(cmpa1, cmpb1)) ) {
1088                                 StrBufAppendBufPlain(Line, HKEY("\n"), 0);
1089                                 StrBufAppendBuf(TmpBuf, Line, 0);
1090                         }
1091                 }
1092         }
1093
1094         serv_puts("SNET");
1095         StrBuf_ServGetln(Line);
1096         if  (GetServerStatus(Line, NULL) != 4) {
1097
1098                 AppendImportantMessage(SRV_STATUS_MSG(Line));   
1099                 http_transmit_thing(ChrPtr(do_template("room_edit")), 0);
1100                 FreeStrBuf(&Line);
1101                 FreeStrBuf(&TmpBuf);
1102                 return;
1103         }
1104
1105         serv_putbuf(TmpBuf);
1106         FreeStrBuf(&TmpBuf);
1107
1108         if (havebstr("add_button")) {
1109                 num_addrs = num_tokens(bstr("line"), ',');
1110                 if (num_addrs < 2) {
1111                         /* just adding one node or address */
1112                         serv_puts(line);
1113                 }
1114                 else {
1115                         /* adding multiple addresses separated by commas */
1116                         for (i=0; i<num_addrs; ++i) {
1117                                 strcpy(line, bstr("prefix"));
1118                                 extract_token(buf, bstr("line"), i, ',', sizeof buf);
1119                                 striplt(buf);
1120                                 strcat(line, buf);
1121                                 strcat(line, bstr("suffix"));
1122                                 serv_puts(line);
1123                         }
1124                 }
1125         }
1126
1127         serv_puts("000");
1128         FlushIgnetCfgs(&WC->CurRoom);
1129         FreeStrBuf(&Line);
1130
1131         http_transmit_thing(ChrPtr(do_template("room_edit")), 0);
1132 }
1133
1134 /*
1135  * Known rooms list (box style)
1136  */
1137 void knrooms(void)
1138 {
1139         DeleteHash(&WC->Rooms);
1140         output_headers(1, 1, 1, 0, 0, 0); 
1141         do_template("knrooms");
1142         wDumpContent(1);
1143 }
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162 /*******************************************************************************
1163  ********************** FLOOR Coomands *****************************************
1164  ******************************************************************************/
1165
1166
1167
1168 /*
1169  * delete the actual floor
1170  */
1171 void delete_floor(void) {
1172         int floornum;
1173         StrBuf *Buf;
1174         const char *Err;
1175                 
1176         floornum = ibstr("floornum");
1177         Buf = NewStrBuf();
1178         serv_printf("KFLR %d|1", floornum);
1179         
1180         StrBufTCP_read_line(Buf, &WC->serv_sock, 0, &Err);
1181
1182         if (GetServerStatus(Buf, NULL) == 2) {
1183                 StrBufPlain(Buf, _("Floor has been deleted."),-1);
1184         }
1185         else {
1186                 StrBufCutLeft(Buf, 4);
1187         }
1188         AppendImportantMessage (SKEY(Buf));
1189
1190         FlushRoomlist();
1191         http_transmit_thing(ChrPtr(do_template("floors")), 0);
1192         FreeStrBuf(&Buf);
1193 }
1194
1195 /*
1196  * start creating a new floor
1197  */
1198 void create_floor(void) {
1199         StrBuf *Buf;
1200         const char *Err;
1201
1202         Buf = NewStrBuf();
1203         serv_printf("CFLR %s|1", bstr("floorname"));
1204         StrBufTCP_read_line(Buf, &WC->serv_sock, 0, &Err);
1205
1206         if (GetServerStatus(Buf, NULL) == 2) {
1207                 StrBufPlain(Buf, _("New floor has been created."),-1);
1208         }
1209         else {
1210                 StrBufCutLeft(Buf, 4);
1211         }
1212         AppendImportantMessage (SKEY(Buf));
1213         FlushRoomlist();
1214         http_transmit_thing(ChrPtr(do_template("floors")), 0);
1215         FreeStrBuf(&Buf);
1216 }
1217
1218
1219 /*
1220  * rename this floor
1221  */
1222 void rename_floor(void) {
1223         StrBuf *Buf;
1224
1225         Buf = NewStrBuf();
1226         FlushRoomlist();
1227
1228         serv_printf("EFLR %d|%s", ibstr("floornum"), bstr("floorname"));
1229         StrBuf_ServGetln(Buf);
1230
1231         StrBufCutLeft(Buf, 4);
1232         AppendImportantMessage (SKEY(Buf));
1233
1234         http_transmit_thing(ChrPtr(do_template("floors")), 0);
1235         FreeStrBuf(&Buf);
1236 }
1237
1238
1239
1240 void jsonRoomFlr(void) 
1241 {
1242         /* Send as our own (application/json) content type */
1243         hprintf("HTTP/1.1 200 OK\r\n");
1244         hprintf("Content-type: application/json; charset=utf-8\r\n");
1245         hprintf("Server: %s / %s\r\n", PACKAGE_STRING, ChrPtr(WC->serv_info->serv_software));
1246         hprintf("Connection: close\r\n");
1247         hprintf("Pragma: no-cache\r\nCache-Control: no-store\r\nExpires:-1\r\n");
1248         begin_burst();
1249         DoTemplate(HKEY("json_roomflr"),NULL,&NoCtx);
1250         end_burst(); 
1251 }
1252
1253 void _FlushRoomList(wcsession *WCC)
1254 {
1255         free_march_list(WCC);
1256         DeleteHash(&WCC->Floors);
1257         DeleteHash(&WCC->Rooms);
1258         DeleteHash(&WCC->FloorsByName);
1259         FlushFolder(&WCC->CurRoom);
1260 }
1261
1262 void ReloadCurrentRoom(void)
1263 {
1264         wcsession *WCC = WC;
1265         StrBuf *CurRoom;
1266
1267         CurRoom = WCC->CurRoom.name;
1268         WCC->CurRoom.name = NULL;
1269         _FlushRoomList(WCC);
1270         gotoroom(CurRoom);
1271         FreeStrBuf(&CurRoom);
1272 }
1273
1274 void FlushRoomlist(void)
1275 {
1276         wcsession *WCC = WC;
1277         _FlushRoomList(WCC);
1278 }
1279
1280
1281 void 
1282 InitModule_ROOMOPS
1283 (void)
1284 {
1285         RegisterPreference("roomlistview",
1286                            _("Room list view"),
1287                            PRF_STRING,
1288                            NULL);
1289         RegisterPreference("emptyfloors", _("Show empty floors"), PRF_YESNO, NULL);
1290
1291         
1292         WebcitAddUrlHandler(HKEY("json_roomflr"), "", 0, jsonRoomFlr, 0);
1293
1294         WebcitAddUrlHandler(HKEY("delete_floor"), "", 0, delete_floor, 0);
1295         WebcitAddUrlHandler(HKEY("rename_floor"), "", 0, rename_floor, 0);
1296         WebcitAddUrlHandler(HKEY("create_floor"), "", 0, create_floor, 0);
1297
1298         WebcitAddUrlHandler(HKEY("knrooms"), "", 0, knrooms, ANONYMOUS);
1299         WebcitAddUrlHandler(HKEY("dotgoto"), "", 0, dotgoto, NEED_URL);
1300         WebcitAddUrlHandler(HKEY("dotskip"), "", 0, dotskip, NEED_URL);
1301
1302         WebcitAddUrlHandler(HKEY("goto_private"), "", 0, goto_private, NEED_URL);
1303         WebcitAddUrlHandler(HKEY("zap"), "", 0, zap, 0);
1304         WebcitAddUrlHandler(HKEY("entroom"), "", 0, entroom, 0);
1305         WebcitAddUrlHandler(HKEY("do_invt_kick"), "", 0, do_invt_kick, 0);
1306         
1307         WebcitAddUrlHandler(HKEY("netedit"), "", 0, netedit, 0);
1308         WebcitAddUrlHandler(HKEY("editroom"), "", 0, editroom, 0);
1309         WebcitAddUrlHandler(HKEY("delete_room"), "", 0, delete_room, 0);
1310         WebcitAddUrlHandler(HKEY("set_room_policy"), "", 0, set_room_policy, 0);
1311         WebcitAddUrlHandler(HKEY("changeview"), "", 0, change_view, 0);
1312         WebcitAddUrlHandler(HKEY("toggle_self_service"), "", 0, toggle_self_service, 0);
1313
1314
1315         REGISTERTokenParamDefine(QR_PERMANENT);
1316         REGISTERTokenParamDefine(QR_INUSE);
1317         REGISTERTokenParamDefine(QR_PRIVATE);
1318         REGISTERTokenParamDefine(QR_PASSWORDED);
1319         REGISTERTokenParamDefine(QR_GUESSNAME);
1320         REGISTERTokenParamDefine(QR_DIRECTORY);
1321         REGISTERTokenParamDefine(QR_UPLOAD);
1322         REGISTERTokenParamDefine(QR_DOWNLOAD);
1323         REGISTERTokenParamDefine(QR_VISDIR);
1324         REGISTERTokenParamDefine(QR_ANONONLY);
1325         REGISTERTokenParamDefine(QR_ANONOPT);
1326         REGISTERTokenParamDefine(QR_NETWORK);
1327         REGISTERTokenParamDefine(QR_PREFONLY);
1328         REGISTERTokenParamDefine(QR_READONLY);
1329         REGISTERTokenParamDefine(QR_MAILBOX);
1330         REGISTERTokenParamDefine(QR2_SYSTEM);
1331         REGISTERTokenParamDefine(QR2_SELFLIST);
1332         REGISTERTokenParamDefine(QR2_COLLABDEL);
1333         REGISTERTokenParamDefine(QR2_SUBJECTREQ);
1334         REGISTERTokenParamDefine(QR2_SMTP_PUBLIC);
1335         REGISTERTokenParamDefine(QR2_MODERATED);
1336
1337         REGISTERTokenParamDefine(UA_KNOWN);
1338         REGISTERTokenParamDefine(UA_GOTOALLOWED);
1339         REGISTERTokenParamDefine(UA_HASNEWMSGS);
1340         REGISTERTokenParamDefine(UA_ZAPPED);
1341         REGISTERTokenParamDefine(UA_POSTALLOWED);
1342         REGISTERTokenParamDefine(UA_ADMINALLOWED);
1343         REGISTERTokenParamDefine(UA_DELETEALLOWED);
1344         REGISTERTokenParamDefine(UA_ISTRASH);
1345
1346         REGISTERTokenParamDefine(US_NEEDVALID);
1347         REGISTERTokenParamDefine(US_PERM);
1348         REGISTERTokenParamDefine(US_LASTOLD);
1349         REGISTERTokenParamDefine(US_EXPERT);
1350         REGISTERTokenParamDefine(US_UNLISTED);
1351         REGISTERTokenParamDefine(US_NOPROMPT);
1352         REGISTERTokenParamDefine(US_PROMPTCTL);
1353         REGISTERTokenParamDefine(US_DISAPPEAR);
1354         REGISTERTokenParamDefine(US_REGIS);
1355         REGISTERTokenParamDefine(US_PAGINATOR);
1356         REGISTERTokenParamDefine(US_INTERNET);
1357         REGISTERTokenParamDefine(US_FLOORS);
1358         REGISTERTokenParamDefine(US_COLOR);
1359         REGISTERTokenParamDefine(US_USER_SET);
1360
1361         REGISTERTokenParamDefine(VIEW_BBS);
1362         REGISTERTokenParamDefine(VIEW_MAILBOX); 
1363         REGISTERTokenParamDefine(VIEW_ADDRESSBOOK);
1364         REGISTERTokenParamDefine(VIEW_CALENDAR);        
1365         REGISTERTokenParamDefine(VIEW_TASKS);   
1366         REGISTERTokenParamDefine(VIEW_NOTES);           
1367         REGISTERTokenParamDefine(VIEW_WIKI);            
1368         REGISTERTokenParamDefine(VIEW_CALBRIEF);
1369         REGISTERTokenParamDefine(VIEW_JOURNAL);
1370         REGISTERTokenParamDefine(VIEW_BLOG);
1371
1372         /* GNET types: */
1373         /* server internal, we need to know but ignore them. */
1374         REGISTERTokenParamDefine(subpending);
1375         REGISTERTokenParamDefine(unsubpending);
1376         REGISTERTokenParamDefine(lastsent);
1377
1378         REGISTERTokenParamDefine(ignet_push_share);
1379         { /* these are the parts of an IGNET push config */
1380                 REGISTERTokenParamDefine(GNET_IGNET_NODE);
1381                 REGISTERTokenParamDefine(GNET_IGNET_ROOM);
1382         }
1383         REGISTERTokenParamDefine(listrecp);
1384         REGISTERTokenParamDefine(digestrecp);
1385         REGISTERTokenParamDefine(pop3client);
1386         { /* These are the parts of a pop3 client line... */
1387                 REGISTERTokenParamDefine(GNET_POP3_HOST);
1388                 REGISTERTokenParamDefine(GNET_POP3_USER);
1389                 REGISTERTokenParamDefine(GNET_POP3_DONT_DELETE_REMOTE);
1390                 REGISTERTokenParamDefine(GNET_POP3_INTERVAL);
1391         }
1392         REGISTERTokenParamDefine(rssclient);
1393         REGISTERTokenParamDefine(participate);
1394
1395
1396
1397 }
1398
1399
1400 void 
1401 SessionDestroyModule_ROOMOPS
1402 (wcsession *sess)
1403 {
1404         _FlushRoomList (sess);
1405 }
1406