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