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