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