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