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