Deleting rooms: Invalid pointers; safeguarrds
[citadel.git] / webcit / roomops.c
1 /*
2  * Lots of different room-related operations.
3  *
4  * Copyright (c) 1996-2012 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, version 3.
8  * 
9  * 
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  * 
17  * 
18  * 
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 = NewStrBuf();
358         const StrBuf *GoBstr;
359         
360         GoBstr = sbstr("go");
361
362         if (GoBstr != NULL)
363         {
364                 if (gotoroom(GoBstr) == 200)
365                 {
366                         serv_puts("KILL 1");
367                         StrBuf_ServGetln(Line);
368                         if (GetServerStatusMsg(Line, NULL, 1, 2) == 2) {
369                                 StrBuf *Buf;
370                                 
371                                 FlushRoomlist ();
372                                 Buf = NewStrBufPlain(HKEY("_BASEROOM_"));
373                                 smart_goto(Buf);
374                                 FreeStrBuf(&Buf);
375                                 FreeStrBuf(&Line);
376                                 return;
377                         }
378                 }
379         }
380         display_main_menu();
381         FreeStrBuf(&Line);
382 }
383
384 /*
385  * zap a room
386  */
387 void zap(void)
388 {
389         char buf[SIZ];
390         StrBuf *final_destination;
391
392         /**
393          * If the forget-room routine fails for any reason, we fall back
394          * to the current room; otherwise, we go to the Lobby
395          */
396         final_destination = NewStrBufDup(WC->CurRoom.name);
397
398         if (havebstr("ok_button")) {
399                 serv_printf("GOTO %s", ChrPtr(WC->CurRoom.name));
400                 serv_getln(buf, sizeof buf);
401                 if (buf[0] == '2') {
402                         serv_puts("FORG");
403                         serv_getln(buf, sizeof buf);
404                         if (buf[0] == '2') {
405                                 FlushStrBuf(final_destination);
406                                 StrBufAppendBufPlain(final_destination, HKEY("_BASEROOM_"), 0);
407                         }
408                 }
409                 FlushRoomlist ();
410         }
411         smart_goto(final_destination);
412         FreeStrBuf(&final_destination);
413 }
414
415
416 /*
417  * mark all messages in current room as having been read
418  */
419 void slrp_highest(void)
420 {
421         char buf[256];
422
423         serv_puts("SLRP HIGHEST");
424         serv_getln(buf, sizeof buf);
425 }
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440 /*******************************************************************************
441  ***************************** Modify Rooms ************************************
442  ******************************************************************************/
443
444
445
446
447
448 void LoadRoomAide(void)
449 {
450         wcsession *WCC = WC;
451         StrBuf *Buf;
452         
453         if (WCC->CurRoom.RoomAideLoaded)
454                 return;
455
456         WCC->CurRoom.RoomAideLoaded = 1;
457         Buf = NewStrBuf();
458         serv_puts("GETA");
459         StrBuf_ServGetln(Buf);
460         if (GetServerStatus(Buf, NULL) != 2) {
461                 FlushStrBuf(WCC->CurRoom.RoomAide);
462                 AppendImportantMessage (ChrPtr(Buf) + 4, 
463                                         StrLength(Buf) - 4);
464         } else {
465                 const char *Pos;
466
467                 Pos = ChrPtr(Buf) + 4;
468
469                 FreeStrBuf(&WCC->CurRoom.RoomAide);
470                 WCC->CurRoom.RoomAide = NewStrBufPlain (NULL, StrLength (Buf));
471
472                 StrBufExtract_NextToken(WCC->CurRoom.RoomAide, Buf, &Pos, '|'); 
473         }
474         FreeStrBuf (&Buf);
475 }
476
477 int SaveRoomAide(folder *Room)
478 {
479         StrBuf *Buf;
480         Buf = NewStrBuf ();
481         serv_printf("SETA %s", ChrPtr(Room->RoomAide));
482         StrBuf_ServGetln(Buf);
483         if (GetServerStatus(Buf, NULL) != 2) {
484                 StrBufCutLeft(Buf, 4);
485                 AppendImportantMessage (SKEY(Buf));
486                 FreeStrBuf(&Buf);
487                 return 0;
488         }
489         FreeStrBuf(&Buf);
490         return 1;
491 }
492
493
494 int GetCurrentRoomFlags(folder *Room, int CareForStatusMessage)
495 {
496         StrBuf *Buf;
497
498         Buf = NewStrBuf();
499         serv_puts("GETR");
500         StrBuf_ServGetln(Buf);
501         if (GetServerStatus(Buf, NULL) != 2) {
502                 FlushStrBuf(Room->XAPass);
503                 FlushStrBuf(Room->Directory);
504                 StrBufCutLeft(Buf, 4);
505                 if (CareForStatusMessage)
506                         AppendImportantMessage (SKEY(Buf));
507                 FreeStrBuf(&Buf);
508                 Room->XALoaded = 2;
509                 return 0;
510         } else {
511                 const char *Pos;
512
513                 Pos = ChrPtr(Buf) + 4;
514
515                 FreeStrBuf(&Room->XAPass);
516                 FreeStrBuf(&Room->Directory);
517
518                 Room->XAPass = NewStrBufPlain (NULL, StrLength (Buf));
519                 Room->Directory = NewStrBufPlain (NULL, StrLength (Buf));
520
521                 FreeStrBuf(&Room->name);
522                 Room->name = NewStrBufPlain(NULL, StrLength(Buf));
523                 StrBufExtract_NextToken(Room->name, Buf, &Pos, '|'); 
524                                         
525                 StrBufExtract_NextToken(Room->XAPass, Buf, &Pos, '|'); 
526                 StrBufExtract_NextToken(Room->Directory, Buf, &Pos, '|'); 
527                 
528                 Room->QRFlags = StrBufExtractNext_long(Buf, &Pos, '|');
529                 Room->floorid = StrBufExtractNext_long(Buf, &Pos, '|');
530                 Room->Order = StrBufExtractNext_long(Buf, &Pos, '|');
531                 Room->defview = StrBufExtractNext_long(Buf, &Pos, '|');
532                 Room->QRFlags2 = StrBufExtractNext_long(Buf, &Pos, '|');
533                 FreeStrBuf (&Buf);
534                 Room->XALoaded = 1;
535                 return 1;
536         }
537 }
538
539
540 int SetCurrentRoomFlags(folder *Room)
541 {
542         StrBuf *Buf;
543
544         Buf = NewStrBuf();
545         DBG_QR(Room->QRFlags);
546         DBG_QR2(Room->QRFlags2);
547
548         serv_printf("SETR %s|%s|%s|%ld|%d|%d|%ld|%ld|%ld",
549                     ChrPtr(Room->name),
550                     ChrPtr(Room->XAPass),
551                     ChrPtr(Room->Directory),
552                     Room->QRFlags, 
553                     Room->BumpUsers,
554                     Room->floorid, 
555                     Room->Order,
556                     Room->defview,
557                     Room->QRFlags2);
558
559         StrBuf_ServGetln(Buf);
560         if (GetServerStatus(Buf, NULL) != 2) {
561                 StrBufCutLeft(Buf, 4);
562                 AppendImportantMessage (SKEY(Buf));
563                 FreeStrBuf(&Buf);
564                 return 0;
565         } else {
566                 FreeStrBuf(&Buf);
567                 return 1;
568         }
569 }
570
571 void LoadRoomXA (void)
572 {
573         wcsession *WCC = WC;
574                 
575         if (WCC->CurRoom.XALoaded > 0)
576                 return;
577
578         GetCurrentRoomFlags(&WCC->CurRoom, 0);
579 }
580
581
582 void LoadXRoomPic(void)
583 {
584         wcsession *WCC = WC;
585         StrBuf *Buf;
586         
587         if (WCC->CurRoom.XHaveRoomPicLoaded)
588                 return;
589
590         WCC->CurRoom.XHaveRoomPicLoaded = 1;
591         Buf = NewStrBuf();
592         serv_puts("OIMG _roompic_");
593         StrBuf_ServGetln(Buf);
594         if (GetServerStatus(Buf, NULL) != 2) {
595                 WCC->CurRoom.XHaveRoomPic = 0;
596         } else {
597                 WCC->CurRoom.XHaveRoomPic = 1;
598         }
599         serv_puts("CLOS");
600         StrBuf_ServGetln(Buf);
601         GetServerStatus(Buf, NULL);
602         FreeStrBuf (&Buf);
603 }
604
605
606 void LoadXRoomInfoText(void)
607 {
608         wcsession *WCC = WC;
609         StrBuf *Buf;
610         int Done = 0;
611         
612         if (WCC->CurRoom.XHaveInfoTextLoaded) {
613                 return;
614         }
615
616         WCC->CurRoom.XHaveInfoTextLoaded = 1;
617         Buf = NewStrBuf();
618
619         serv_puts("RINF");
620
621         StrBuf_ServGetln(Buf);
622         if (GetServerStatus(Buf, NULL) == 1) {
623                 WCC->CurRoom.XInfoText = NewStrBuf ();
624                 
625                 while (!Done && StrBuf_ServGetln(Buf)>=0) {
626                         if ( (StrLength(Buf)==3) && 
627                              !strcmp(ChrPtr(Buf), "000")) 
628                                 Done = 1;
629                         else 
630                                 StrBufAppendBuf(WCC->CurRoom.XInfoText, Buf, 0);
631                 }
632         }
633
634         FreeStrBuf(&Buf);
635 }
636
637
638 void LoadXRoomXCountFiles(void)
639 {
640         wcsession *WCC = WC;
641         StrBuf *Buf;
642         int Done = 0;
643         
644         if (WCC->CurRoom.XHaveDownloadCount)
645                 return;
646
647         WCC->CurRoom.XHaveDownloadCount = 1;
648
649         Buf = NewStrBuf();
650         serv_puts("RDIR");
651         StrBuf_ServGetln(Buf);
652         if (GetServerStatus(Buf, NULL) == 1) {
653                 
654                 while (!Done && StrBuf_ServGetln(Buf)>=0) {
655                         if ( (StrLength(Buf)==3) && 
656                              !strcmp(ChrPtr(Buf), "000")) 
657                                 Done = 1;
658                         else 
659                                 WCC->CurRoom.XDownloadCount++;
660                 }
661         }
662
663         FreeStrBuf (&Buf);
664 }
665
666
667 /* 
668  * Toggle self-service list subscription
669  */
670 void toggle_self_service(void) {
671         wcsession *WCC = WC;
672
673         if (GetCurrentRoomFlags (&WCC->CurRoom, 1) == 0)
674                 return;
675
676         if (yesbstr("QR2_SelfList")) 
677                 WCC->CurRoom.QRFlags2 = WCC->CurRoom.QRFlags2 | QR2_SELFLIST;
678         else 
679                 WCC->CurRoom.QRFlags2 = WCC->CurRoom.QRFlags2 & ~QR2_SELFLIST;
680
681         if (yesbstr("QR2_SMTP_PUBLIC")) 
682                 WCC->CurRoom.QRFlags2 = WCC->CurRoom.QRFlags2 | QR2_SMTP_PUBLIC;
683         else
684                 WCC->CurRoom.QRFlags2 = WCC->CurRoom.QRFlags2 & ~QR2_SMTP_PUBLIC;
685
686         if (yesbstr("QR2_Moderated")) 
687                 WCC->CurRoom.QRFlags2 = WCC->CurRoom.QRFlags2 | QR2_MODERATED;
688         else
689                 WCC->CurRoom.QRFlags2 = WCC->CurRoom.QRFlags2 & ~QR2_MODERATED;
690         if (yesbstr("QR2_SubsOnly")) 
691                 WCC->CurRoom.QRFlags2 = WCC->CurRoom.QRFlags2 | QR2_SMTP_PUBLIC;
692         else
693                 WCC->CurRoom.QRFlags2 = WCC->CurRoom.QRFlags2 & ~QR2_SMTP_PUBLIC;
694
695         SetCurrentRoomFlags (&WCC->CurRoom);
696         
697         http_transmit_thing(ChrPtr(do_template("room_edit")), 0);
698 }
699
700
701
702 /*
703  * save new parameters for a room
704  */
705 void editroom(void)
706 {
707         wcsession *WCC = WC;
708         const StrBuf *Ptr;
709         const StrBuf *er_name;
710         const StrBuf *er_password;
711         const StrBuf *er_dirname;
712         const StrBuf *er_roomaide;
713         unsigned er_flags;
714         unsigned er_flags2;
715         int succ1, succ2;
716
717         if (!havebstr("ok_button")) {
718                 AppendImportantMessage(_("Cancelled.  Changes were not saved."), -1);
719                 http_transmit_thing(ChrPtr(do_template("room_edit")), 0);
720                 return;
721         }
722         if (GetCurrentRoomFlags (&WCC->CurRoom, 1) == 0) {
723                 http_transmit_thing(ChrPtr(do_template("room_edit")), 0);
724                 return;
725         }
726
727         LoadRoomAide();
728
729         er_flags = WCC->CurRoom.QRFlags;
730         er_flags &= !(QR_PRIVATE | QR_PASSWORDED | QR_GUESSNAME);
731
732         er_flags2 = WCC->CurRoom.QRFlags2;
733
734         Ptr = sbstr("type");
735         if (!strcmp(ChrPtr(Ptr), "invonly")) {
736                 er_flags |= (QR_PRIVATE);
737         }
738         if (!strcmp(ChrPtr(Ptr), "hidden")) {
739                 er_flags |= (QR_PRIVATE | QR_GUESSNAME);
740         }
741         if (!strcmp(ChrPtr(Ptr), "passworded")) {
742                 er_flags |= (QR_PRIVATE | QR_PASSWORDED);
743         }
744         if (!strcmp(ChrPtr(Ptr), "personal")) {
745                 er_flags |= QR_MAILBOX;
746         } else {
747                 er_flags &= ~QR_MAILBOX;
748         }
749
750
751         
752         if (yesbstr("prefonly")) {
753                 er_flags |= QR_PREFONLY;
754         } else {
755                 er_flags &= ~QR_PREFONLY;
756         }
757
758         if (yesbstr("readonly")) {
759                 er_flags |= QR_READONLY;
760         } else {
761                 er_flags &= ~QR_READONLY;
762         }
763
764         
765         if (yesbstr("collabdel")) {
766                 er_flags2 |= QR2_COLLABDEL;
767         } else {
768                 er_flags2 &= ~QR2_COLLABDEL;
769         }
770
771         if (yesbstr("permanent")) {
772                 er_flags |= QR_PERMANENT;
773         } else {
774                 er_flags &= ~QR_PERMANENT;
775         }
776
777         if (yesbstr("subjectreq")) {
778                 er_flags2 |= QR2_SUBJECTREQ;
779         } else {
780                 er_flags2 &= ~QR2_SUBJECTREQ;
781         }
782
783         if (yesbstr("network")) {
784                 er_flags |= QR_NETWORK;
785         } else {
786                 er_flags &= ~QR_NETWORK;
787         }
788
789         if (yesbstr("directory")) {
790                 er_flags |= QR_DIRECTORY;
791         } else {
792                 er_flags &= ~QR_DIRECTORY;
793         }
794
795         if (yesbstr("ulallowed")) {
796                 er_flags |= QR_UPLOAD;
797         } else {
798                 er_flags &= ~QR_UPLOAD;
799         }
800
801         if (yesbstr("dlallowed")) {
802                 er_flags |= QR_DOWNLOAD;
803         } else {
804                 er_flags &= ~QR_DOWNLOAD;
805         }
806
807         if (yesbstr("visdir")) {
808                 er_flags |= QR_VISDIR;
809         } else {
810                 er_flags &= ~QR_VISDIR;
811         }
812
813
814         Ptr = sbstr("anon");
815
816         er_flags &= ~(QR_ANONONLY | QR_ANONOPT);
817         if (!strcmp(ChrPtr(Ptr), "anononly"))
818                 er_flags |= QR_ANONONLY;
819         if (!strcmp(ChrPtr(Ptr), "anon2"))
820                 er_flags |= QR_ANONOPT;
821
822         er_name     = sbstr("er_name");
823         er_dirname  = sbstr("er_dirname");
824         er_roomaide = sbstr("er_roomaide");
825         er_password = sbstr("er_password");
826
827         FlushStrBuf(WCC->CurRoom.name);
828         StrBufAppendBuf(WCC->CurRoom.name, er_name, 0);
829
830         FlushStrBuf(WCC->CurRoom.Directory);
831         StrBufAppendBuf(WCC->CurRoom.Directory, er_dirname, 0);
832
833         FlushStrBuf(WCC->CurRoom.RoomAide);
834         StrBufAppendBuf(WCC->CurRoom.RoomAide, er_roomaide, 0);
835
836         FlushStrBuf(WCC->CurRoom.XAPass);
837         StrBufAppendBuf(WCC->CurRoom.XAPass, er_password, 0);
838
839         WCC->CurRoom.BumpUsers = yesbstr("bump");
840
841         WCC->CurRoom.floorid = ibstr("er_floor");
842
843         succ1 = SetCurrentRoomFlags(&WCC->CurRoom);
844
845         succ2 = SaveRoomAide (&WCC->CurRoom);
846         
847         if (succ1 + succ2 == 0)
848                 AppendImportantMessage (_("Your changes have been saved."), -1);
849         http_transmit_thing(ChrPtr(do_template("room_edit")), 0);
850         return;
851 }
852
853
854
855 /*
856  * Display form for Invite, Kick, and show Who Knows a room
857  */
858 void do_invt_kick(void) 
859 {
860         StrBuf *Buf, *User;
861         const StrBuf *UserNames;
862         int Kick, Invite;
863         wcsession *WCC = WC;
864
865
866         if (GetCurrentRoomFlags(&WCC->CurRoom, 1) == 1)
867         {
868                 const char *Pos;
869                 UserNames = sbstr("username");
870                 Kick = havebstr("kick_button");
871                 Invite = havebstr("invite_button");
872
873                 User = NewStrBufPlain(NULL, StrLength(UserNames));
874                 Buf = NewStrBuf();
875                 
876                 Pos = ChrPtr(UserNames);
877                 while (Pos != StrBufNOTNULL)
878                 {
879                         StrBufExtract_NextToken(User, UserNames, &Pos, ',');
880                         StrBufTrim(User);
881                         if ((StrLength(User) > 0) && (Kick))
882                         {
883                                 serv_printf("KICK %s", ChrPtr(User));
884                                 if (StrBuf_ServGetln(Buf) < 0)
885                                         break;
886                                 if (GetServerStatus(Buf, NULL) != 2) {
887                                         StrBufCutLeft(Buf, 4);
888                                         AppendImportantMessage(SKEY(Buf));
889                                 } else {
890                                         StrBufPrintf(Buf, 
891                                                      _("User '%s' kicked out of room '%s'."), 
892                                                      ChrPtr(User), 
893                                                      ChrPtr(WCC->CurRoom.name)
894                                                 );
895                                         AppendImportantMessage(SKEY(Buf));
896                                 }
897                         }
898                         else if ((StrLength(User) > 0) && (Invite))
899                         {
900                                 serv_printf("INVT %s", ChrPtr(User));
901                                 if (StrBuf_ServGetln(Buf) < 0)
902                                         break;
903                                 if (GetServerStatus(Buf, NULL) != 2) {
904                                         StrBufCutLeft(Buf, 4);
905                                         AppendImportantMessage(SKEY(Buf));
906                                 } else {
907                                         StrBufPrintf(Buf, 
908                                                      _("User '%s' invited to room '%s'."), 
909                                                      ChrPtr(User), 
910                                                      ChrPtr(WCC->CurRoom.name)
911                                                 );
912                                         AppendImportantMessage(SKEY(Buf));
913                                 }
914                         }
915                 }
916         }
917
918         http_transmit_thing(ChrPtr(do_template("room_edit")), 0);
919 }
920
921
922 /*
923  * Create a new room
924  */
925 void entroom(void)
926 {
927         StrBuf *Line;
928         const StrBuf *er_name;
929         const StrBuf *er_type;
930         const StrBuf *er_password;
931         int er_floor;
932         int er_num_type;
933         int er_view;
934         wcsession *WCC = WC;
935
936         if (!havebstr("ok_button")) {
937                 AppendImportantMessage(_("Cancelled.  No new room was created."), -1);
938                 display_main_menu();
939                 return;
940         }
941         er_name = sbstr("er_name");
942         er_type = sbstr("type");
943         er_password = sbstr("er_password");
944         er_floor = ibstr("er_floor");
945         er_view = ibstr("er_view");
946
947         er_num_type = 0;
948         if (!strcmp(ChrPtr(er_type), "hidden"))
949                 er_num_type = 1;
950         else if (!strcmp(ChrPtr(er_type), "passworded"))
951                 er_num_type = 2;
952         else if (!strcmp(ChrPtr(er_type), "invonly"))
953                 er_num_type = 3;
954         else if (!strcmp(ChrPtr(er_type), "personal"))
955                 er_num_type = 4;
956
957         serv_printf("CRE8 1|%s|%d|%s|%d|%d|%d", 
958                     ChrPtr(er_name), 
959                     er_num_type, 
960                     ChrPtr(er_password), 
961                     er_floor, 
962                     0, 
963                     er_view);
964
965         Line = NewStrBuf();
966         StrBuf_ServGetln(Line);
967         if (GetServerStatusMsg(Line, NULL, 1, 2) != 2) {
968                 FreeStrBuf(&Line);
969                 display_main_menu();
970                 return;
971         }
972         /** TODO: Room created, now update the left hand icon bar for this user */
973         gotoroom(er_name);
974
975         serv_printf("VIEW %d", er_view);
976         StrBuf_ServGetln(Line);
977         FreeStrBuf(&Line); /* TODO: should we care about errors? */
978         WCC->CurRoom.view = er_view;
979
980         if ( (WCC != NULL) && ( (WCC->CurRoom.RAFlags & UA_ADMINALLOWED) != 0) )  {
981                 http_transmit_thing(ChrPtr(do_template("room_edit")), 0);
982         } else {
983                 smart_goto(WCC->CurRoom.name);
984         }
985         FreeStrBuf(&Line);
986 }
987
988
989
990
991
992 /*
993  * Change the view for this room
994  */
995 void change_view(void) {
996         int newview;
997         char buf[SIZ];
998
999         newview = lbstr("view");
1000         serv_printf("VIEW %d", newview);
1001         serv_getln(buf, sizeof buf);
1002         WC->CurRoom.view = newview;
1003         smart_goto(WC->CurRoom.name);
1004 }
1005
1006
1007
1008 /*
1009  * Set the message expire policy for this room and/or floor
1010  */
1011 void set_room_policy(void) {
1012         StrBuf *Line;
1013
1014         if (!havebstr("ok_button")) {
1015                 AppendImportantMessage(_("Cancelled.  Changes were not saved."), -1);
1016                 http_transmit_thing(ChrPtr(do_template("room_edit")), 0);
1017                 return;
1018         }
1019         Line = NewStrBuf();
1020
1021         serv_printf("SPEX roompolicy|%d|%d", ibstr("roompolicy"), ibstr("roomvalue"));
1022         StrBuf_ServGetln(Line);
1023         GetServerStatusMsg(Line, NULL, 1, 0);
1024         if (WC->axlevel >= 6) {
1025                 serv_printf("SPEX floorpolicy|%d|%d", ibstr("floorpolicy"), ibstr("floorvalue"));
1026                 StrBuf_ServGetln(Line);
1027                 GetServerStatusMsg(Line, NULL, 1, 0);
1028         }
1029         FreeStrBuf(&Line);
1030         ReloadCurrentRoom();
1031         http_transmit_thing(ChrPtr(do_template("room_edit")), 0);
1032 }
1033
1034
1035
1036 /*
1037  * Perform changes to a room's network configuration
1038  */
1039 void netedit(void) {
1040         char buf[SIZ];
1041         char line[SIZ];
1042         char cmpa0[SIZ];
1043         char cmpa1[SIZ];
1044         char cmpb0[SIZ];
1045         char cmpb1[SIZ];
1046         int i, num_addrs;
1047         StrBuf *Line;
1048         StrBuf *TmpBuf;
1049         int Done;
1050
1051         if (havebstr("force_room")) {
1052                 gotoroom(sbstr("force_room"));
1053         }
1054         /*/ TODO: do line dynamic! */
1055         if (havebstr("line_pop3host")) {
1056                 strcpy(line, bstr("prefix"));
1057                 strcat(line, bstr("line_pop3host"));
1058                 strcat(line, "|");
1059                 strcat(line, bstr("line_pop3user"));
1060                 strcat(line, "|");
1061                 strcat(line, bstr("line_pop3pass"));
1062                 strcat(line, "|");
1063                 strcat(line, ibstr("line_pop3keep") ? "1" : "0" );
1064                 strcat(line, "|");
1065                 sprintf(&line[strlen(line)],"%ld", lbstr("line_pop3int"));
1066                 strcat(line, bstr("suffix"));
1067         }
1068         else if (havebstr("line")) {
1069                 strcpy(line, bstr("prefix"));
1070                 strcat(line, bstr("line"));
1071                 strcat(line, bstr("suffix"));
1072         }
1073         else {
1074                 http_transmit_thing(ChrPtr(do_template("room_edit")), 0);
1075                 return;
1076         }
1077
1078         Line = NewStrBuf();
1079         TmpBuf = NewStrBuf();
1080         serv_puts("GNET");
1081         StrBuf_ServGetln(Line);
1082         if  (GetServerStatus(Line, NULL) != 1) {
1083                 AppendImportantMessage(SRV_STATUS_MSG(Line));   
1084                 FreeStrBuf(&Line);
1085                 http_transmit_thing(ChrPtr(do_template("room_edit")), 0);
1086                 return;
1087         }
1088
1089         /** This loop works for add *or* remove.  Spiffy, eh? */
1090         Done = 0;
1091         extract_token(cmpb0, line, 0, '|', sizeof cmpb0);
1092         extract_token(cmpb1, line, 1, '|', sizeof cmpb1);
1093         while (!Done && StrBuf_ServGetln(Line)>=0) {
1094                 if ( (StrLength(Line)==3) && 
1095                      !strcmp(ChrPtr(Line), "000")) 
1096                 {
1097                         Done = 1;
1098                 }
1099                 else
1100                 {
1101                         extract_token(cmpa0, ChrPtr(Line), 0, '|', sizeof cmpa0);
1102                         extract_token(cmpa1, ChrPtr(Line), 1, '|', sizeof cmpa1);
1103                         if ( (strcasecmp(cmpa0, cmpb0)) 
1104                              || (strcasecmp(cmpa1, cmpb1)) ) {
1105                                 StrBufAppendBufPlain(Line, HKEY("\n"), 0);
1106                                 StrBufAppendBuf(TmpBuf, Line, 0);
1107                         }
1108                 }
1109         }
1110
1111         serv_puts("SNET");
1112         StrBuf_ServGetln(Line);
1113         if  (GetServerStatus(Line, NULL) != 4) {
1114
1115                 AppendImportantMessage(SRV_STATUS_MSG(Line));   
1116                 http_transmit_thing(ChrPtr(do_template("room_edit")), 0);
1117                 FreeStrBuf(&Line);
1118                 FreeStrBuf(&TmpBuf);
1119                 return;
1120         }
1121
1122         serv_putbuf(TmpBuf);
1123         FreeStrBuf(&TmpBuf);
1124
1125         if (havebstr("add_button")) {
1126                 num_addrs = num_tokens(bstr("line"), ',');
1127                 if (num_addrs < 2) {
1128                         /* just adding one node or address */
1129                         serv_puts(line);
1130                 }
1131                 else {
1132                         /* adding multiple addresses separated by commas */
1133                         for (i=0; i<num_addrs; ++i) {
1134                                 strcpy(line, bstr("prefix"));
1135                                 extract_token(buf, bstr("line"), i, ',', sizeof buf);
1136                                 striplt(buf);
1137                                 strcat(line, buf);
1138                                 strcat(line, bstr("suffix"));
1139                                 serv_puts(line);
1140                         }
1141                 }
1142         }
1143
1144         serv_puts("000");
1145         FlushIgnetCfgs(&WC->CurRoom);
1146         FreeStrBuf(&Line);
1147
1148         http_transmit_thing(ChrPtr(do_template("room_edit")), 0);
1149 }
1150
1151 /*
1152  * Known rooms list (box style)
1153  */
1154 void knrooms(void)
1155 {
1156         DeleteHash(&WC->Rooms);
1157         output_headers(1, 1, 1, 0, 0, 0); 
1158         do_template("knrooms");
1159         wDumpContent(1);
1160 }
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179 /*******************************************************************************
1180  ********************** FLOOR Coomands *****************************************
1181  ******************************************************************************/
1182
1183
1184
1185 /*
1186  * delete the actual floor
1187  */
1188 void delete_floor(void) {
1189         int floornum;
1190         StrBuf *Buf;
1191         const char *Err;
1192                 
1193         floornum = ibstr("floornum");
1194         Buf = NewStrBuf();
1195         serv_printf("KFLR %d|1", floornum);
1196         
1197         StrBufTCP_read_line(Buf, &WC->serv_sock, 0, &Err);
1198
1199         if (GetServerStatus(Buf, NULL) == 2) {
1200                 StrBufPlain(Buf, _("Floor has been deleted."),-1);
1201         }
1202         else {
1203                 StrBufCutLeft(Buf, 4);
1204         }
1205         AppendImportantMessage (SKEY(Buf));
1206
1207         FlushRoomlist();
1208         http_transmit_thing(ChrPtr(do_template("floors")), 0);
1209         FreeStrBuf(&Buf);
1210 }
1211
1212 /*
1213  * start creating a new floor
1214  */
1215 void create_floor(void) {
1216         StrBuf *Buf;
1217         const char *Err;
1218
1219         Buf = NewStrBuf();
1220         serv_printf("CFLR %s|1", bstr("floorname"));
1221         StrBufTCP_read_line(Buf, &WC->serv_sock, 0, &Err);
1222
1223         if (GetServerStatus(Buf, NULL) == 2) {
1224                 StrBufPlain(Buf, _("New floor has been created."),-1);
1225         }
1226         else {
1227                 StrBufCutLeft(Buf, 4);
1228         }
1229         AppendImportantMessage (SKEY(Buf));
1230         FlushRoomlist();
1231         http_transmit_thing(ChrPtr(do_template("floors")), 0);
1232         FreeStrBuf(&Buf);
1233 }
1234
1235
1236 /*
1237  * rename this floor
1238  */
1239 void rename_floor(void) {
1240         StrBuf *Buf;
1241
1242         Buf = NewStrBuf();
1243         FlushRoomlist();
1244
1245         serv_printf("EFLR %d|%s", ibstr("floornum"), bstr("floorname"));
1246         StrBuf_ServGetln(Buf);
1247
1248         StrBufCutLeft(Buf, 4);
1249         AppendImportantMessage (SKEY(Buf));
1250
1251         http_transmit_thing(ChrPtr(do_template("floors")), 0);
1252         FreeStrBuf(&Buf);
1253 }
1254
1255
1256
1257 void jsonRoomFlr(void) 
1258 {
1259         /* Send as our own (application/json) content type */
1260         hprintf("HTTP/1.1 200 OK\r\n");
1261         hprintf("Content-type: application/json; charset=utf-8\r\n");
1262         hprintf("Server: %s / %s\r\n", PACKAGE_STRING, ChrPtr(WC->serv_info->serv_software));
1263         hprintf("Connection: close\r\n");
1264         hprintf("Pragma: no-cache\r\nCache-Control: no-store\r\nExpires:-1\r\n");
1265         begin_burst();
1266         DoTemplate(HKEY("json_roomflr"),NULL,&NoCtx);
1267         end_burst(); 
1268 }
1269
1270 void _FlushRoomList(wcsession *WCC)
1271 {
1272         free_march_list(WCC);
1273         DeleteHash(&WCC->Floors);
1274         DeleteHash(&WCC->Rooms);
1275         DeleteHash(&WCC->FloorsByName);
1276         FlushFolder(&WCC->CurRoom);
1277 }
1278
1279 void ReloadCurrentRoom(void)
1280 {
1281         wcsession *WCC = WC;
1282         StrBuf *CurRoom;
1283
1284         CurRoom = WCC->CurRoom.name;
1285         WCC->CurRoom.name = NULL;
1286         _FlushRoomList(WCC);
1287         gotoroom(CurRoom);
1288         FreeStrBuf(&CurRoom);
1289 }
1290
1291 void FlushRoomlist(void)
1292 {
1293         wcsession *WCC = WC;
1294         _FlushRoomList(WCC);
1295 }
1296
1297
1298 void 
1299 InitModule_ROOMOPS
1300 (void)
1301 {
1302         RegisterPreference("roomlistview",
1303                            _("Room list view"),
1304                            PRF_STRING,
1305                            NULL);
1306         RegisterPreference("emptyfloors", _("Show empty floors"), PRF_YESNO, NULL);
1307
1308         
1309         WebcitAddUrlHandler(HKEY("json_roomflr"), "", 0, jsonRoomFlr, 0);
1310
1311         WebcitAddUrlHandler(HKEY("delete_floor"), "", 0, delete_floor, 0);
1312         WebcitAddUrlHandler(HKEY("rename_floor"), "", 0, rename_floor, 0);
1313         WebcitAddUrlHandler(HKEY("create_floor"), "", 0, create_floor, 0);
1314
1315         WebcitAddUrlHandler(HKEY("knrooms"), "", 0, knrooms, ANONYMOUS);
1316         WebcitAddUrlHandler(HKEY("dotgoto"), "", 0, dotgoto, NEED_URL);
1317         WebcitAddUrlHandler(HKEY("dotskip"), "", 0, dotskip, NEED_URL);
1318
1319         WebcitAddUrlHandler(HKEY("goto_private"), "", 0, goto_private, NEED_URL);
1320         WebcitAddUrlHandler(HKEY("zap"), "", 0, zap, 0);
1321         WebcitAddUrlHandler(HKEY("entroom"), "", 0, entroom, 0);
1322         WebcitAddUrlHandler(HKEY("do_invt_kick"), "", 0, do_invt_kick, 0);
1323         
1324         WebcitAddUrlHandler(HKEY("netedit"), "", 0, netedit, 0);
1325         WebcitAddUrlHandler(HKEY("editroom"), "", 0, editroom, 0);
1326         WebcitAddUrlHandler(HKEY("delete_room"), "", 0, delete_room, 0);
1327         WebcitAddUrlHandler(HKEY("set_room_policy"), "", 0, set_room_policy, 0);
1328         WebcitAddUrlHandler(HKEY("changeview"), "", 0, change_view, 0);
1329         WebcitAddUrlHandler(HKEY("toggle_self_service"), "", 0, toggle_self_service, 0);
1330
1331
1332         REGISTERTokenParamDefine(QR_PERMANENT);
1333         REGISTERTokenParamDefine(QR_INUSE);
1334         REGISTERTokenParamDefine(QR_PRIVATE);
1335         REGISTERTokenParamDefine(QR_PASSWORDED);
1336         REGISTERTokenParamDefine(QR_GUESSNAME);
1337         REGISTERTokenParamDefine(QR_DIRECTORY);
1338         REGISTERTokenParamDefine(QR_UPLOAD);
1339         REGISTERTokenParamDefine(QR_DOWNLOAD);
1340         REGISTERTokenParamDefine(QR_VISDIR);
1341         REGISTERTokenParamDefine(QR_ANONONLY);
1342         REGISTERTokenParamDefine(QR_ANONOPT);
1343         REGISTERTokenParamDefine(QR_NETWORK);
1344         REGISTERTokenParamDefine(QR_PREFONLY);
1345         REGISTERTokenParamDefine(QR_READONLY);
1346         REGISTERTokenParamDefine(QR_MAILBOX);
1347         REGISTERTokenParamDefine(QR2_SYSTEM);
1348         REGISTERTokenParamDefine(QR2_SELFLIST);
1349         REGISTERTokenParamDefine(QR2_COLLABDEL);
1350         REGISTERTokenParamDefine(QR2_SUBJECTREQ);
1351         REGISTERTokenParamDefine(QR2_SMTP_PUBLIC);
1352         REGISTERTokenParamDefine(QR2_MODERATED);
1353
1354         REGISTERTokenParamDefine(UA_KNOWN);
1355         REGISTERTokenParamDefine(UA_GOTOALLOWED);
1356         REGISTERTokenParamDefine(UA_HASNEWMSGS);
1357         REGISTERTokenParamDefine(UA_ZAPPED);
1358         REGISTERTokenParamDefine(UA_POSTALLOWED);
1359         REGISTERTokenParamDefine(UA_ADMINALLOWED);
1360         REGISTERTokenParamDefine(UA_DELETEALLOWED);
1361         REGISTERTokenParamDefine(UA_ISTRASH);
1362
1363         REGISTERTokenParamDefine(US_NEEDVALID);
1364         REGISTERTokenParamDefine(US_PERM);
1365         REGISTERTokenParamDefine(US_LASTOLD);
1366         REGISTERTokenParamDefine(US_EXPERT);
1367         REGISTERTokenParamDefine(US_UNLISTED);
1368         REGISTERTokenParamDefine(US_NOPROMPT);
1369         REGISTERTokenParamDefine(US_PROMPTCTL);
1370         REGISTERTokenParamDefine(US_DISAPPEAR);
1371         REGISTERTokenParamDefine(US_REGIS);
1372         REGISTERTokenParamDefine(US_PAGINATOR);
1373         REGISTERTokenParamDefine(US_INTERNET);
1374         REGISTERTokenParamDefine(US_FLOORS);
1375         REGISTERTokenParamDefine(US_COLOR);
1376         REGISTERTokenParamDefine(US_USER_SET);
1377
1378         REGISTERTokenParamDefine(VIEW_BBS);
1379         REGISTERTokenParamDefine(VIEW_MAILBOX); 
1380         REGISTERTokenParamDefine(VIEW_ADDRESSBOOK);
1381         REGISTERTokenParamDefine(VIEW_CALENDAR);        
1382         REGISTERTokenParamDefine(VIEW_TASKS);   
1383         REGISTERTokenParamDefine(VIEW_NOTES);           
1384         REGISTERTokenParamDefine(VIEW_WIKI);            
1385         REGISTERTokenParamDefine(VIEW_CALBRIEF);
1386         REGISTERTokenParamDefine(VIEW_JOURNAL);
1387         REGISTERTokenParamDefine(VIEW_BLOG);
1388
1389         /* GNET types: */
1390         /* server internal, we need to know but ignore them. */
1391         REGISTERTokenParamDefine(subpending);
1392         REGISTERTokenParamDefine(unsubpending);
1393         REGISTERTokenParamDefine(lastsent);
1394
1395         REGISTERTokenParamDefine(ignet_push_share);
1396         { /* these are the parts of an IGNET push config */
1397                 REGISTERTokenParamDefine(GNET_IGNET_NODE);
1398                 REGISTERTokenParamDefine(GNET_IGNET_ROOM);
1399         }
1400         REGISTERTokenParamDefine(listrecp);
1401         REGISTERTokenParamDefine(digestrecp);
1402         REGISTERTokenParamDefine(pop3client);
1403         { /* These are the parts of a pop3 client line... */
1404                 REGISTERTokenParamDefine(GNET_POP3_HOST);
1405                 REGISTERTokenParamDefine(GNET_POP3_USER);
1406                 REGISTERTokenParamDefine(GNET_POP3_DONT_DELETE_REMOTE);
1407                 REGISTERTokenParamDefine(GNET_POP3_INTERVAL);
1408         }
1409         REGISTERTokenParamDefine(rssclient);
1410         REGISTERTokenParamDefine(participate);
1411
1412
1413
1414 }
1415
1416
1417 void 
1418 SessionDestroyModule_ROOMOPS
1419 (wcsession *sess)
1420 {
1421         _FlushRoomList (sess);
1422 }
1423