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