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