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