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