3 * Lots of different room-related operations.
9 char *viewdefs[VIEW_MAX]; /* the different kinds of available views */
11 ROOM_VIEWS exchangeable_views[VIEW_MAX][VIEW_MAX] = { /* the different kinds of available views for a view */
12 {VIEW_BBS, VIEW_MAILBOX, VIEW_MAX, VIEW_MAX, VIEW_MAX, VIEW_MAX, VIEW_MAX, VIEW_MAX, VIEW_MAX, VIEW_MAX },
13 {VIEW_BBS, VIEW_MAILBOX, VIEW_MAX, VIEW_MAX, VIEW_MAX, VIEW_MAX, VIEW_MAX, VIEW_MAX, VIEW_MAX, VIEW_MAX },
14 {VIEW_MAX, VIEW_MAX, VIEW_ADDRESSBOOK, VIEW_CALENDAR, VIEW_MAX, VIEW_MAX, VIEW_MAX, VIEW_MAX, VIEW_MAX, VIEW_MAX },
15 {VIEW_MAX, VIEW_MAX, VIEW_MAX, VIEW_CALENDAR, VIEW_MAX, VIEW_MAX, VIEW_MAX, VIEW_MAX /*VIEW_CALBRIEF*/, VIEW_MAX, VIEW_MAX },
16 {VIEW_MAX, VIEW_MAX, VIEW_MAX, VIEW_MAX, VIEW_TASKS, VIEW_MAX, VIEW_MAX, VIEW_MAX, VIEW_MAX, VIEW_MAX, },
17 {VIEW_MAX, VIEW_MAX, VIEW_MAX, VIEW_MAX, VIEW_MAX, VIEW_NOTES, VIEW_MAX, VIEW_MAX, VIEW_MAX, VIEW_MAX, },
18 {VIEW_MAX, VIEW_MAX, VIEW_MAX, VIEW_MAX, VIEW_MAX, VIEW_MAX, VIEW_WIKI, VIEW_MAX, VIEW_MAX, VIEW_MAX},
19 {VIEW_MAX, VIEW_MAX, VIEW_MAX, VIEW_CALENDAR, VIEW_MAX, VIEW_MAX, VIEW_MAX, VIEW_MAX/*VIEW_CALBRIEF*/, VIEW_MAX, VIEW_MAX},
20 {VIEW_MAX, VIEW_MAX, VIEW_MAX, VIEW_MAX, VIEW_MAX, VIEW_MAX, VIEW_MAX, VIEW_MAX, VIEW_JOURNAL, VIEW_MAX },
21 {VIEW_MAX, VIEW_MAX, VIEW_MAX, VIEW_MAX, VIEW_MAX, VIEW_MAX, VIEW_MAX, VIEW_MAX, VIEW_MAX, VIEW_BLOG },
23 /* the brief calendar view is disabled: VIEW_CALBRIEF */
25 ROOM_VIEWS allowed_default_views[VIEW_MAX] = {
26 1, /* VIEW_BBS Bulletin board view */
27 1, /* VIEW_MAILBOX Mailbox summary */
28 1, /* VIEW_ADDRESSBOOK Address book view */
29 1, /* VIEW_CALENDAR Calendar view */
30 1, /* VIEW_TASKS Tasks view */
31 1, /* VIEW_NOTES Notes view */
32 1, /* VIEW_WIKI Wiki view */
33 0, /* VIEW_CALBRIEF Brief Calendar view */
34 0, /* VIEW_JOURNAL Journal view */
35 0 /* VIEW_BLOG Blog view (not yet implemented) */
40 * Initialize the viewdefs with localized strings
42 void initialize_viewdefs(void) {
43 viewdefs[VIEW_BBS] = _("Bulletin Board");
44 viewdefs[VIEW_MAILBOX] = _("Mail Folder");
45 viewdefs[VIEW_ADDRESSBOOK] = _("Address Book");
46 viewdefs[VIEW_CALENDAR] = _("Calendar");
47 viewdefs[VIEW_TASKS] = _("Task List");
48 viewdefs[VIEW_NOTES] = _("Notes List");
49 viewdefs[VIEW_WIKI] = _("Wiki");
50 viewdefs[VIEW_CALBRIEF] = _("Calendar List");
51 viewdefs[VIEW_JOURNAL] = _("Journal");
52 viewdefs[VIEW_BLOG] = _("Blog");
55 ConstStr QRFlagList[] = {
56 {HKEY(strof(QR_PERMANENT))},
57 {HKEY(strof(QR_INUSE))},
58 {HKEY(strof(QR_PRIVATE))},
59 {HKEY(strof(QR_PASSWORDED))},
60 {HKEY(strof(QR_GUESSNAME))},
61 {HKEY(strof(QR_DIRECTORY))},
62 {HKEY(strof(QR_UPLOAD))},
63 {HKEY(strof(QR_DOWNLOAD))},
64 {HKEY(strof(QR_VISDIR))},
65 {HKEY(strof(QR_ANONONLY))},
66 {HKEY(strof(QR_ANONOPT))},
67 {HKEY(strof(QR_NETWORK))},
68 {HKEY(strof(QR_PREFONLY))},
69 {HKEY(strof(QR_READONLY))},
70 {HKEY(strof(QR_MAILBOX))}
72 ConstStr QR2FlagList[] = {
73 {HKEY(strof(QR2_SYSTEM))},
74 {HKEY(strof(QR2_SELFLIST))},
75 {HKEY(strof(QR2_COLLABDEL))},
76 {HKEY(strof(QR2_SUBJECTREQ))},
77 {HKEY(strof(QR2_SMTP_PUBLIC))},
78 {HKEY(strof(QR2_MODERATED))},
96 QRVec = NewStrBufPlain(NULL, 256);
100 if (StrLength(QRVec) > 0)
101 StrBufAppendBufPlain(QRVec, HKEY(" | "), 0);
102 StrBufAppendBufPlain(QRVec, CKEY(QRFlagList[j]), 0);
107 lprintf(9, "DBG: QR-Vec [%ld] [%s]\n", QR, ChrPtr(QRVec));
113 void DBG_QR2(long QR2)
119 QR2Vec = NewStrBufPlain(NULL, 256);
122 if ((QR2 & i) != 0) {
123 if (StrLength(QR2Vec) > 0)
124 StrBufAppendBufPlain(QR2Vec, HKEY(" | "), 0);
125 StrBufAppendBufPlain(QR2Vec, CKEY(QR2FlagList[j]), 0);
130 lprintf(9, "DBG: QR2-Vec [%ld] [%s]\n", QR2, ChrPtr(QR2Vec));
136 * Embed the room banner
138 * got The information returned from a GOTO server command
139 * navbar_style Determines which navigation buttons to display
143 void embed_room_banner(void)
148 /* refresh current room states... */
149 /* dosen't work??? gotoroom(NULL); */
151 /* The browser needs some information for its own use */
152 wc_printf("<script type=\"text/javascript\"> \n"
153 " room_is_trash = %d; \n"
155 ((WC->CurRoom.RAFlags & UA_ISTRASH) != 0)
159 * If the user happens to select the "make this my start page" link,
160 * we want it to remember the URL as a "/dotskip" one instead of
161 * a "skip" or "gotonext" or something like that.
163 if (WCC->Hdr->this_page == NULL) {
164 WCC->Hdr->this_page = NewStrBuf();
166 StrBufPrintf(WCC->Hdr->this_page,
168 ChrPtr(WC->CurRoom.name)
171 do_template("roombanner", NULL);
172 /* roombanner contains this for mobile */
176 do_template("navbar", NULL);
180 "<li class=\"readallmess\">"
181 "<a href=\"wiki?page=home\">"
182 "<img src=\"static/readallmess3_24x.gif\" "
183 "alt=\"\" width=\"24\" height=\"24\">"
184 "<span class=\"navbar_link\">"
186 "</span></a></li>\n", _("Wiki home")
188 safestrncpy(buf, bstr("page"), sizeof buf);
189 if (IsEmptyStr(buf)) {
190 safestrncpy(buf, "home", sizeof buf);
194 "<li class=\"newmess\">"
195 "<a href=\"display_enter?page=%s\">"
196 "<img src=\"static/newmess3_24x.gif\" "
197 "alt=\"\" width=\"24\" height=\"24\">"
198 "<span class=\"navbar_link\">"
200 "</span></a></li>\n", buf, _("Edit this page")
203 if (bmstrcasestr((char *)ChrPtr(WCC->Hdr->HR.ReqLine), "wiki_history")) {
204 / * already viewing history; display a link to the current page * /
206 "<li class=\"newmess\">"
207 "<a href=\"wiki?page=%s\">"
208 "<img src=\"static/newmess3_24x.gif\" "
209 "alt=\"\" width=\"24\" height=\"24\">"
210 "<span class=\"navbar_link\">"
212 "</span></a></li>\n", buf, _("Current version")
216 / * display a link to the history * /
218 "<li class=\"newmess\">"
219 "<a href=\"wiki_history?page=%s\">"
220 "<img src=\"static/newmess3_24x.gif\" "
221 "alt=\"\" width=\"24\" height=\"24\">"
222 "<span class=\"navbar_link\">"
224 "</span></a></li>\n", buf, _("History")
233 * back end routine to take the session to a new room
235 long gotoroom(const StrBuf *gname)
239 static long ls = (-1L);
242 /* store ungoto information */
243 if (StrLength(gname) > 0)
244 strcpy(WCC->ugname, ChrPtr(WCC->CurRoom.name));
248 /* move to the new room */
249 if (StrLength(gname) > 0)
250 serv_printf("GOTO %s", ChrPtr(gname));
251 else /* or just refresh the current state... */
252 serv_printf("GOTO 00000000000000000000");
253 StrBuf_ServGetln(Buf);
254 if (GetServerStatus(Buf, &err) != 2) {
255 serv_puts("GOTO _BASEROOM_");
256 StrBuf_ServGetln(Buf);
258 * well, we know that this is the fallback case,
259 * but we're interested that the first command
260 * didn't work out in first place.
262 if (GetServerStatus(Buf, NULL) != 2) {
267 FlushFolder(&WCC->CurRoom);
268 ParseGoto(&WCC->CurRoom, Buf);
270 if (StrLength(gname) > 0)
272 remove_march(WCC->CurRoom.name);
273 if (!strcasecmp(ChrPtr(gname), "_BASEROOM_"))
283 void ParseGoto(folder *room, StrBuf *Line)
291 if (StrLength(Line) < 4) {
295 /* ignore the commandstate... */
296 Pos = ChrPtr(Line) + 4;
298 if (room->RoomNameParts != NULL)
301 for (i=0; i < room->nRoomNameParts; i++)
302 FreeStrBuf(&room->RoomNameParts[i]);
303 free(room->RoomNameParts);
304 room->RoomNameParts = NULL;
309 pBuf = NewStrBufPlain(NULL, StrLength(Line));
312 memset(room, 0, sizeof(folder));
315 StrBufExtract_NextToken(room->name, Line, &Pos, '|'); // WC->CurRoom->name
317 room->nNewMessages = StrBufExtractNext_long(Line, &Pos, '|');
318 if (room->nNewMessages > 0)
319 room->RAFlags |= UA_HASNEWMSGS;
321 room->nTotalMessages = StrBufExtractNext_long(Line, &Pos, '|');
323 room->ShowInfo = StrBufExtractNext_long(Line, &Pos, '|');
325 room->QRFlags = StrBufExtractNext_long(Line, &Pos, '|'); //CurRoom->QRFlags
327 DBG_QR(room->QRFlags);
329 room->HighestRead = StrBufExtractNext_long(Line, &Pos, '|');
330 room->LastMessageRead = StrBufExtractNext_long(Line, &Pos, '|');
332 room->is_inbox = StrBufExtractNext_long(Line, &Pos, '|'); // is_mailbox
334 flag = StrBufExtractNext_long(Line, &Pos, '|');
335 if (WCC->is_aide || flag) {
336 room->RAFlags |= UA_ADMINALLOWED;
339 room->UsersNewMAilboxMessages = StrBufExtractNext_long(Line, &Pos, '|');
341 room->floorid = StrBufExtractNext_int(Line, &Pos, '|'); // wc_floor
343 room->view = StrBufExtractNext_long(Line, &Pos, '|'); // CurRoom->view
345 room->defview = StrBufExtractNext_long(Line, &Pos, '|'); // CurRoom->defview
347 flag = StrBufExtractNext_long(Line, &Pos, '|');
349 room->RAFlags |= UA_ISTRASH; // wc_is_trash
351 room->QRFlags2 = StrBufExtractNext_long(Line, &Pos, '|'); // CurRoom->QRFlags2
352 DBG_QR2(room->QRFlags2);
354 /* find out, whether we are in a sub-room */
355 room->nRoomNameParts = StrBufNum_tokens(room->name, '\\');
356 if (room->nRoomNameParts > 1)
361 room->RoomNameParts = malloc(sizeof(StrBuf*) * (room->nRoomNameParts + 1));
362 memset(room->RoomNameParts, 0, sizeof(StrBuf*) * (room->nRoomNameParts + 1));
363 for (i=0; i < room->nRoomNameParts; i++)
365 room->RoomNameParts[i] = NewStrBuf();
366 StrBufExtract_NextToken(room->RoomNameParts[i],
367 room->name, &Pos, '\\');
371 /* Private mailboxes on the main floor get remapped to the personal folder */
372 if ((room->QRFlags & QR_MAILBOX) &&
373 (room->floorid == 0))
375 room->floorid = VIRTUAL_MY_FLOOR;
376 if ((room->nRoomNameParts == 1) &&
377 (StrLength(room->name) == 4) &&
378 (strcmp(ChrPtr(room->name), "Mail") == 0))
384 /* get a pointer to the floor we're on: */
385 if (WCC->Floors == NULL)
386 GetFloorListHash(NULL, NULL);
388 GetHash(WCC->Floors, IKEY(room->floorid), &vFloor);
389 room->Floor = (const Floor*) vFloor;
392 void LoadRoomAide(void)
397 if (WCC->CurRoom.RoomAideLoaded)
400 WCC->CurRoom.RoomAideLoaded = 1;
403 StrBuf_ServGetln(Buf);
404 if (GetServerStatus(Buf, NULL) != 2) {
405 FlushStrBuf(WCC->CurRoom.RoomAide);
406 AppendImportantMessage (ChrPtr(Buf) + 4,
411 Pos = ChrPtr(Buf) + 4;
413 FreeStrBuf(&WCC->CurRoom.RoomAide);
414 WCC->CurRoom.RoomAide = NewStrBufPlain (NULL, StrLength (Buf));
416 StrBufExtract_NextToken(WCC->CurRoom.RoomAide, Buf, &Pos, '|');
421 int SaveRoomAide(folder *Room)
425 serv_printf("SETA %s", ChrPtr(Room->RoomAide));
426 StrBuf_ServGetln(Buf);
427 if (GetServerStatus(Buf, NULL) != 2) {
428 StrBufCutLeft(Buf, 4);
429 AppendImportantMessage (SKEY(Buf));
437 void tmplput_CurrentRoomFloorName(StrBuf *Target, WCTemplputParams *TP)
440 folder *Folder = &WCC->CurRoom;
446 pFloor = Folder->Floor;
450 StrBufAppendTemplate(Target, TP, pFloor->Name, 0);
453 void tmplput_CurrentRoomAide(StrBuf *Target, WCTemplputParams *TP)
459 StrBufAppendTemplate(Target, TP, WCC->CurRoom.RoomAide, 0);
462 int GetCurrentRoomFlags(folder *Room)
468 StrBuf_ServGetln(Buf);
469 if (GetServerStatus(Buf, NULL) != 2) {
470 FlushStrBuf(Room->XAPass);
471 FlushStrBuf(Room->Directory);
472 StrBufCutLeft(Buf, 4);
473 AppendImportantMessage (SKEY(Buf));
479 Pos = ChrPtr(Buf) + 4;
481 FreeStrBuf(&Room->XAPass);
482 FreeStrBuf(&Room->Directory);
484 Room->XAPass = NewStrBufPlain (NULL, StrLength (Buf));
485 Room->Directory = NewStrBufPlain (NULL, StrLength (Buf));
487 FreeStrBuf(&Room->name);
488 Room->name = NewStrBufPlain(NULL, StrLength(Buf));
489 StrBufExtract_NextToken(Room->name, Buf, &Pos, '|');
491 StrBufExtract_NextToken(Room->XAPass, Buf, &Pos, '|');
492 StrBufExtract_NextToken(Room->Directory, Buf, &Pos, '|');
494 Room->QRFlags = StrBufExtractNext_long(Buf, &Pos, '|');
495 Room->floorid = StrBufExtractNext_long(Buf, &Pos, '|');
496 Room->Order = StrBufExtractNext_long(Buf, &Pos, '|');
497 Room->defview = StrBufExtractNext_long(Buf, &Pos, '|');
498 Room->QRFlags2 = StrBufExtractNext_long(Buf, &Pos, '|');
506 int SetCurrentRoomFlags(folder *Room)
511 DBG_QR(Room->QRFlags);
512 DBG_QR2(Room->QRFlags2);
514 serv_printf("SETR %s|%s|%s|%ld|%d|%d|%ld|%ld|%ld",
516 ChrPtr(Room->XAPass),
517 ChrPtr(Room->Directory),
525 StrBuf_ServGetln(Buf);
526 if (GetServerStatus(Buf, NULL) != 2) {
527 StrBufCutLeft(Buf, 4);
528 AppendImportantMessage (SKEY(Buf));
537 void LoadRoomXA (void)
541 if (WCC->CurRoom.XALoaded)
544 GetCurrentRoomFlags(&WCC->CurRoom);
548 void LoadXRoomPic(void)
553 if (WCC->CurRoom.XHaveRoomPicLoaded)
556 WCC->CurRoom.XHaveRoomPicLoaded = 1;
558 serv_puts("OIMG _roompic_");
559 StrBuf_ServGetln(Buf);
560 if (GetServerStatus(Buf, NULL) != 2) {
561 WCC->CurRoom.XHaveRoomPic = 0;
563 WCC->CurRoom.XHaveRoomPic = 1;
566 StrBuf_ServGetln(Buf);
567 GetServerStatus(Buf, NULL);
571 int ConditionalThisRoomXHavePic(StrBuf *Target, WCTemplputParams *TP)
579 return WCC->CurRoom.XHaveRoomPic == 1;
582 void LoadXRoomInfoText(void)
588 if (WCC->CurRoom.XHaveInfoTextLoaded)
591 WCC->CurRoom.XHaveInfoTextLoaded = 1;
596 StrBuf_ServGetln(Buf);
597 if (GetServerStatus(Buf, NULL) == 1) {
598 WCC->CurRoom.XInfoText = NewStrBuf ();
600 while (!Done && StrBuf_ServGetln(Buf)>=0) {
601 if ( (StrLength(Buf)==3) &&
602 !strcmp(ChrPtr(Buf), "000"))
605 StrBufAppendBuf(WCC->CurRoom.XInfoText, Buf, 0);
612 int ConditionalThisRoomXHaveInfoText(StrBuf *Target, WCTemplputParams *TP)
620 return (StrLength(WCC->CurRoom.XInfoText)>0);
623 void tmplput_CurrentRoomInfoText(StrBuf *Target, WCTemplputParams *TP)
629 StrBufAppendTemplate(Target, TP, WCC->CurRoom.XAPass, 1);
632 void LoadXRoomXCountFiles(void)
638 if (WCC->CurRoom.XHaveDownloadCount)
641 WCC->CurRoom.XHaveDownloadCount = 1;
645 StrBuf_ServGetln(Buf);
646 if (GetServerStatus(Buf, NULL) == 1) {
648 while (!Done && StrBuf_ServGetln(Buf)>=0) {
649 if ( (StrLength(Buf)==3) &&
650 !strcmp(ChrPtr(Buf), "000"))
653 WCC->CurRoom.XDownloadCount++;
660 void tmplput_CurrentRoomXNFiles(StrBuf *Target, WCTemplputParams *TP)
664 LoadXRoomXCountFiles();
666 StrBufAppendPrintf(Target, "%d", WCC->CurRoom.XDownloadCount);
669 void tmplput_CurrentRoomX_FileString(StrBuf *Target, WCTemplputParams *TP)
673 LoadXRoomXCountFiles();
675 if (WCC->CurRoom.XDownloadCount == 1)
676 StrBufAppendBufPlain(Target, _("file"), -1, 0);
678 StrBufAppendBufPlain(Target, _("files"), -1, 0);
681 void tmplput_CurrentRoomPass(StrBuf *Target, WCTemplputParams *TP)
687 StrBufAppendTemplate(Target, TP, WCC->CurRoom.XAPass, 0);
689 void tmplput_CurrentRoomDirectory(StrBuf *Target, WCTemplputParams *TP)
695 StrBufAppendTemplate(Target, TP, WCC->CurRoom.Directory, 0);
697 void tmplput_CurrentRoomOrder(StrBuf *Target, WCTemplputParams *TP)
703 StrBufAppendPrintf(Target, "%d", WCC->CurRoom.Order);
705 void tmplput_CurrentRoomDefView(StrBuf *Target, WCTemplputParams *TP)
709 StrBufAppendPrintf(Target, "%d", WCC->CurRoom.defview);
712 void tmplput_CurrentRoom_nNewMessages(StrBuf *Target, WCTemplputParams *TP)
718 StrBufAppendPrintf(Target, "%d", WCC->CurRoom.nNewMessages);
721 void tmplput_CurrentRoom_nTotalMessages(StrBuf *Target, WCTemplputParams *TP)
727 StrBufAppendPrintf(Target, "%d", WCC->CurRoom.nTotalMessages);
730 int ConditionalThisRoomOrder(StrBuf *Target, WCTemplputParams *TP)
740 CheckThis = GetTemplateTokenNumber(Target, TP, 2, 0);
741 return CheckThis == WCC->CurRoom.Order;
744 int ConditionalThisRoomDefView(StrBuf *Target, WCTemplputParams *TP)
752 CheckThis = GetTemplateTokenNumber(Target, TP, 2, 0);
753 return CheckThis == WCC->CurRoom.defview;
756 int ConditionalThisRoomCurrView(StrBuf *Target, WCTemplputParams *TP)
764 CheckThis = GetTemplateTokenNumber(Target, TP, 2, 0);
765 return CheckThis == WCC->CurRoom.view;
768 int ConditionalThisRoomHaveView(StrBuf *Target, WCTemplputParams *TP)
776 CheckThis = GetTemplateTokenNumber(Target, TP, 2, 0);
777 if ((CheckThis >= VIEW_MAX) || (CheckThis < VIEW_BBS))
779 LogTemplateError(Target, "Conditional", ERR_PARM2, TP,
780 "Roomview [%ld] not valid\n",
785 return exchangeable_views [WCC->CurRoom.defview][CheckThis] != VIEW_MAX;
788 void tmplput_CurrentRoomViewString(StrBuf *Target, WCTemplputParams *TP)
794 (WCC->CurRoom.defview >= VIEW_MAX) ||
795 (WCC->CurRoom.defview < VIEW_BBS))
797 LogTemplateError(Target, "Token", ERR_PARM2, TP,
798 "Roomview [%ld] not valid\n",
800 WCC->CurRoom.defview : -1);
804 Buf = NewStrBufPlain(_(viewdefs[WCC->CurRoom.defview]), -1);
805 StrBufAppendTemplate(Target, TP, Buf, 0);
809 void tmplput_RoomViewString(StrBuf *Target, WCTemplputParams *TP)
814 CheckThis = GetTemplateTokenNumber(Target, TP, 0, 0);
815 if ((CheckThis >= VIEW_MAX) || (CheckThis < VIEW_BBS))
817 LogTemplateError(Target, "Token", ERR_PARM2, TP,
818 "Roomview [%ld] not valid\n",
823 Buf = NewStrBufPlain(_(viewdefs[CheckThis]), -1);
824 StrBufAppendTemplate(Target, TP, Buf, 0);
829 int ConditionalIsAllowedDefaultView(StrBuf *Target, WCTemplputParams *TP)
837 CheckThis = GetTemplateTokenNumber(Target, TP, 2, 0);
838 if ((CheckThis >= VIEW_MAX) || (CheckThis < VIEW_BBS))
840 LogTemplateError(Target, "Conditional", ERR_PARM2, TP,
841 "Roomview [%ld] not valid\n",
846 return allowed_default_views[CheckThis] != 0;
852 void smart_goto(const StrBuf *next_room) {
854 readloop(readnew, eUseDefault);
860 * mark all messages in current room as having been read
862 void slrp_highest(void)
866 serv_puts("SLRP HIGHEST");
867 serv_getln(buf, sizeof buf);
873 * Set/clear/read the "self-service list subscribe" flag for a room
875 * set newval to 0 to clear, 1 to set, any other value to leave unchanged.
876 * returns the new value.
879 int self_service(int newval) {
880 int current_value = 0;
883 if (GetCurrentRoomFlags (&WCC->CurRoom) == 0)
888 if ((WCC->CurRoom.QRFlags2 & QR2_SELFLIST) != 0) {
896 WCC->CurRoom.QRFlags2 = WCC->CurRoom.QRFlags2 | QR2_SELFLIST;
898 else if (newval == 0) {
899 WCC->CurRoom.QRFlags2 = WCC->CurRoom.QRFlags2 & ~QR2_SELFLIST;
902 return(current_value);
905 if (newval != current_value) {
906 SetCurrentRoomFlags(&WCC->CurRoom);
916 * Toggle self-service list subscription
918 void toggle_self_service(void) {
921 if (GetCurrentRoomFlags (&WCC->CurRoom) == 0)
924 if (yesbstr("QR2_SelfList"))
925 WCC->CurRoom.QRFlags2 = WCC->CurRoom.QRFlags2 | QR2_SELFLIST;
927 WCC->CurRoom.QRFlags2 = WCC->CurRoom.QRFlags2 & ~QR2_SELFLIST;
929 if (yesbstr("QR2_SMTP_PUBLIC"))
930 WCC->CurRoom.QRFlags2 = WCC->CurRoom.QRFlags2 | QR2_SMTP_PUBLIC;
932 WCC->CurRoom.QRFlags2 = WCC->CurRoom.QRFlags2 & ~QR2_SMTP_PUBLIC;
934 if (yesbstr("QR2_Moderated"))
935 WCC->CurRoom.QRFlags2 = WCC->CurRoom.QRFlags2 | QR2_MODERATED;
937 WCC->CurRoom.QRFlags2 = WCC->CurRoom.QRFlags2 & ~QR2_MODERATED;
938 if (yesbstr("QR2_SubsOnly"))
939 WCC->CurRoom.QRFlags2 = WCC->CurRoom.QRFlags2 | QR2_SMTP_PUBLIC;
941 WCC->CurRoom.QRFlags2 = WCC->CurRoom.QRFlags2 & ~QR2_SMTP_PUBLIC;
943 SetCurrentRoomFlags (&WCC->CurRoom);
945 http_transmit_thing(ChrPtr(do_template("room_edit", NULL)), 0);
951 * save new parameters for a room
957 const StrBuf *er_name;
958 const StrBuf *er_password;
959 const StrBuf *er_dirname;
960 const StrBuf *er_roomaide;
965 if (!havebstr("ok_button")) {
966 strcpy(WC->ImportantMessage,
967 _("Cancelled. Changes were not saved."));
968 http_transmit_thing(ChrPtr(do_template("room_edit", NULL)), 0);
971 if (GetCurrentRoomFlags (&WCC->CurRoom) == 0)
976 er_flags = WCC->CurRoom.QRFlags;
977 er_flags &= !(QR_PRIVATE | QR_PASSWORDED | QR_GUESSNAME);
979 er_flags2 = WCC->CurRoom.QRFlags2;
982 if (!strcmp(ChrPtr(Ptr), "invonly")) {
983 er_flags |= (QR_PRIVATE);
985 if (!strcmp(ChrPtr(Ptr), "hidden")) {
986 er_flags |= (QR_PRIVATE | QR_GUESSNAME);
988 if (!strcmp(ChrPtr(Ptr), "passworded")) {
989 er_flags |= (QR_PRIVATE | QR_PASSWORDED);
991 if (!strcmp(ChrPtr(Ptr), "personal")) {
992 er_flags |= QR_MAILBOX;
994 er_flags &= ~QR_MAILBOX;
999 if (yesbstr("prefonly")) {
1000 er_flags |= QR_PREFONLY;
1002 er_flags &= ~QR_PREFONLY;
1005 if (yesbstr("readonly")) {
1006 er_flags |= QR_READONLY;
1008 er_flags &= ~QR_READONLY;
1012 if (yesbstr("collabdel")) {
1013 er_flags2 |= QR2_COLLABDEL;
1015 er_flags2 &= ~QR2_COLLABDEL;
1018 if (yesbstr("permanent")) {
1019 er_flags |= QR_PERMANENT;
1021 er_flags &= ~QR_PERMANENT;
1024 if (yesbstr("subjectreq")) {
1025 er_flags2 |= QR2_SUBJECTREQ;
1027 er_flags2 &= ~QR2_SUBJECTREQ;
1030 if (yesbstr("network")) {
1031 er_flags |= QR_NETWORK;
1033 er_flags &= ~QR_NETWORK;
1036 if (yesbstr("directory")) {
1037 er_flags |= QR_DIRECTORY;
1039 er_flags &= ~QR_DIRECTORY;
1042 if (yesbstr("ulallowed")) {
1043 er_flags |= QR_UPLOAD;
1045 er_flags &= ~QR_UPLOAD;
1048 if (yesbstr("dlallowed")) {
1049 er_flags |= QR_DOWNLOAD;
1051 er_flags &= ~QR_DOWNLOAD;
1054 if (yesbstr("visdir")) {
1055 er_flags |= QR_VISDIR;
1057 er_flags &= ~QR_VISDIR;
1061 Ptr = sbstr("anon");
1063 er_flags &= ~(QR_ANONONLY | QR_ANONOPT);
1064 if (!strcmp(ChrPtr(Ptr), "anononly"))
1065 er_flags |= QR_ANONONLY;
1066 if (!strcmp(ChrPtr(Ptr), "anon2"))
1067 er_flags |= QR_ANONOPT;
1069 er_name = sbstr("er_name");
1070 er_dirname = sbstr("er_dirname");
1071 er_roomaide = sbstr("er_roomaide");
1072 er_password = sbstr("er_password");
1074 FlushStrBuf(WCC->CurRoom.name);
1075 StrBufAppendBuf(WCC->CurRoom.name, er_name, 0);
1077 FlushStrBuf(WCC->CurRoom.Directory);
1078 StrBufAppendBuf(WCC->CurRoom.Directory, er_dirname, 0);
1080 FlushStrBuf(WCC->CurRoom.RoomAide);
1081 StrBufAppendBuf(WCC->CurRoom.RoomAide, er_roomaide, 0);
1083 FlushStrBuf(WCC->CurRoom.XAPass);
1084 StrBufAppendBuf(WCC->CurRoom.XAPass, er_password, 0);
1086 WCC->CurRoom.BumpUsers = yesbstr("bump");
1088 WCC->CurRoom.floorid = ibstr("er_floor");
1090 succ1 = SetCurrentRoomFlags(&WCC->CurRoom);
1092 succ2 = SaveRoomAide (&WCC->CurRoom);
1094 if (succ1 + succ2 == 0)
1095 AppendImportantMessage (_("Your changes have been saved."), -1);
1096 http_transmit_thing(ChrPtr(do_template("room_edit", NULL)), 0);
1102 * Display form for Invite, Kick, and show Who Knows a room
1104 void do_invt_kick(void)
1107 const StrBuf *UserNames;
1109 wcsession *WCC = WC;
1112 if (GetCurrentRoomFlags(&WCC->CurRoom) == 1)
1115 UserNames = sbstr("username");
1116 Kick = havebstr("kick_button");
1117 Invite = havebstr("invite_button");
1119 User = NewStrBufPlain(NULL, StrLength(UserNames));
1122 Pos = ChrPtr(UserNames);
1123 while (Pos != StrBufNOTNULL)
1125 StrBufExtract_NextToken(User, UserNames, &Pos, ',');
1127 if ((StrLength(User) > 0) && (Kick))
1129 serv_printf("KICK %s", ChrPtr(User));
1130 StrBuf_ServGetln(Buf);
1131 if (GetServerStatus(Buf, NULL) != 2) {
1132 StrBufCutLeft(Buf, 4);
1133 AppendImportantMessage(SKEY(Buf));
1136 _("User '%s' kicked out of room '%s'."),
1138 ChrPtr(WCC->CurRoom.name)
1140 AppendImportantMessage(SKEY(Buf));
1143 else if ((StrLength(User) > 0) && (Invite))
1145 serv_printf("INVT %s", ChrPtr(User));
1146 StrBuf_ServGetln(Buf);
1147 if (GetServerStatus(Buf, NULL) != 2) {
1148 StrBufCutLeft(Buf, 4);
1149 AppendImportantMessage(SKEY(Buf));
1152 _("User '%s' invited to room '%s'."),
1154 ChrPtr(WCC->CurRoom.name)
1156 AppendImportantMessage(SKEY(Buf));
1162 http_transmit_thing(ChrPtr(do_template("room_edit", NULL)), 0);
1166 * support function for entroom() -- sets the default view
1168 void er_set_default_view(int newview) {
1181 serv_getln(buf, sizeof buf);
1182 if (buf[0] != '2') return;
1184 extract_token(rm_name, &buf[4], 0, '|', sizeof rm_name);
1185 extract_token(rm_pass, &buf[4], 1, '|', sizeof rm_pass);
1186 extract_token(rm_dir, &buf[4], 2, '|', sizeof rm_dir);
1187 rm_bits1 = extract_int(&buf[4], 3);
1188 rm_floor = extract_int(&buf[4], 4);
1189 rm_listorder = extract_int(&buf[4], 5);
1190 rm_bits2 = extract_int(&buf[4], 7);
1192 serv_printf("SETR %s|%s|%s|%d|0|%d|%d|%d|%d",
1193 rm_name, rm_pass, rm_dir, rm_bits1, rm_floor,
1194 rm_listorder, newview, rm_bits2
1196 serv_getln(buf, sizeof buf);
1207 const StrBuf *er_name;
1208 const StrBuf *er_type;
1209 const StrBuf *er_password;
1213 wcsession *WCC = WC;
1215 if (!havebstr("ok_button")) {
1216 strcpy(WC->ImportantMessage,
1217 _("Cancelled. No new room was created."));
1218 display_main_menu();
1221 er_name = sbstr("er_name");
1222 er_type = sbstr("type");
1223 er_password = sbstr("er_password");
1224 er_floor = ibstr("er_floor");
1225 er_view = ibstr("er_view");
1228 if (!strcmp(ChrPtr(er_type), "hidden"))
1230 else if (!strcmp(ChrPtr(er_type), "passworded"))
1232 else if (!strcmp(ChrPtr(er_type), "invonly"))
1234 else if (!strcmp(ChrPtr(er_type), "personal"))
1237 serv_printf("CRE8 1|%s|%d|%s|%d|%d|%d",
1240 ChrPtr(er_password),
1245 serv_getln(buf, sizeof buf);
1246 if (buf[0] != '2') {
1247 strcpy(WCC->ImportantMessage, &buf[4]);
1248 display_main_menu();
1251 /** TODO: Room created, now update the left hand icon bar for this user */
1254 serv_printf("VIEW %d", er_view);
1255 serv_getln(buf, sizeof buf);
1256 WCC->CurRoom.view = er_view;
1258 if ( (WCC != NULL) && ( (WCC->CurRoom.RAFlags & UA_ADMINALLOWED) != 0) ) {
1259 http_transmit_thing(ChrPtr(do_template("room_edit", NULL)), 0);
1261 do_change_view(er_view); /* Now go there */
1268 * \brief goto a private room
1270 void goto_private(void)
1274 const StrBuf *gr_name;
1277 if (!havebstr("ok_button")) {
1278 display_main_menu();
1281 gr_name = sbstr("gr_name");
1283 strcpy(hold_rm, ChrPtr(WC->CurRoom.name));
1284 serv_printf("GOTO %s|%s",
1287 StrBuf_ServGetln(Buf);
1288 if (GetServerStatus(Buf, &err) == 2) {
1290 smart_goto(gr_name);
1295 DoTemplate(HKEY("room_display_private"), NULL, &NoCtx);
1299 StrBufCutLeft(Buf, 4);
1300 AppendImportantMessage (SKEY(Buf));
1301 Buf = NewStrBufPlain(HKEY("_BASEROOM_"));
1315 StrBuf *final_destination;
1318 * If the forget-room routine fails for any reason, we fall back
1319 * to the current room; otherwise, we go to the Lobby
1321 final_destination = NewStrBufDup(WC->CurRoom.name);
1323 if (havebstr("ok_button")) {
1324 serv_printf("GOTO %s", ChrPtr(WC->CurRoom.name));
1325 serv_getln(buf, sizeof buf);
1326 if (buf[0] == '2') {
1328 serv_getln(buf, sizeof buf);
1329 if (buf[0] == '2') {
1330 FlushStrBuf(final_destination);
1331 StrBufAppendBufPlain(final_destination, HKEY("_BASEROOM_"), 0);
1336 smart_goto(final_destination);
1337 FreeStrBuf(&final_destination);
1343 * \brief Delete the current room
1345 void delete_room(void)
1350 serv_puts("KILL 1");
1351 serv_getln(buf, sizeof buf);
1353 if (buf[0] != '2') {
1354 strcpy(WC->ImportantMessage, &buf[4]);
1355 display_main_menu();
1361 Buf = NewStrBufPlain(HKEY("_BASEROOM_"));
1370 * \brief Perform changes to a room's network configuration
1372 void netedit(void) {
1381 /*/ TODO: do line dynamic! */
1382 if (havebstr("line_pop3host")) {
1383 strcpy(line, bstr("prefix"));
1384 strcat(line, bstr("line_pop3host"));
1386 strcat(line, bstr("line_pop3user"));
1388 strcat(line, bstr("line_pop3pass"));
1390 strcat(line, ibstr("line_pop3keep") ? "1" : "0" );
1392 sprintf(&line[strlen(line)],"%ld", lbstr("line_pop3int"));
1393 strcat(line, bstr("suffix"));
1395 else if (havebstr("line")) {
1396 strcpy(line, bstr("prefix"));
1397 strcat(line, bstr("line"));
1398 strcat(line, bstr("suffix"));
1401 http_transmit_thing(ChrPtr(do_template("room_edit", NULL)), 0);
1408 http_transmit_thing(ChrPtr(do_template("room_edit", NULL)), 0);
1413 serv_getln(buf, sizeof buf);
1414 if (buf[0] != '1') {
1416 http_transmit_thing(ChrPtr(do_template("room_edit", NULL)), 0);
1420 /** This loop works for add *or* remove. Spiffy, eh? */
1421 while (serv_getln(buf, sizeof buf), strcmp(buf, "000")) {
1422 extract_token(cmpa0, buf, 0, '|', sizeof cmpa0);
1423 extract_token(cmpa1, buf, 1, '|', sizeof cmpa1);
1424 extract_token(cmpb0, line, 0, '|', sizeof cmpb0);
1425 extract_token(cmpb1, line, 1, '|', sizeof cmpb1);
1426 if ( (strcasecmp(cmpa0, cmpb0))
1427 || (strcasecmp(cmpa1, cmpb1)) ) {
1428 fprintf(fp, "%s\n", buf);
1434 serv_getln(buf, sizeof buf);
1435 if (buf[0] != '4') {
1437 http_transmit_thing(ChrPtr(do_template("room_edit", NULL)), 0);
1441 while (fgets(buf, sizeof buf, fp) != NULL) {
1442 buf[strlen(buf)-1] = 0;
1446 if (havebstr("add_button")) {
1447 num_addrs = num_tokens(bstr("line"), ',');
1448 if (num_addrs < 2) {
1449 /* just adding one node or address */
1453 /* adding multiple addresses separated by commas */
1454 for (i=0; i<num_addrs; ++i) {
1455 strcpy(line, bstr("prefix"));
1456 extract_token(buf, bstr("line"), i, ',', sizeof buf);
1459 strcat(line, bstr("suffix"));
1467 FlushIgnetCfgs(&WC->CurRoom);
1469 http_transmit_thing(ChrPtr(do_template("room_edit", NULL)), 0);
1473 * delete the actual floor
1475 void delete_floor(void) {
1480 floornum = ibstr("floornum");
1482 serv_printf("KFLR %d|1", floornum);
1484 StrBufTCP_read_line(Buf, &WC->serv_sock, 0, &Err);
1486 if (GetServerStatus(Buf, NULL) == 2) {
1487 StrBufPlain(Buf, _("Floor has been deleted."),-1);
1490 StrBufCutLeft(Buf, 4);
1492 AppendImportantMessage (SKEY(Buf));
1495 http_transmit_thing(ChrPtr(do_template("floors", NULL)), 0);
1500 * start creating a new floor
1502 void create_floor(void) {
1507 serv_printf("CFLR %s|1", bstr("floorname"));
1508 StrBufTCP_read_line(Buf, &WC->serv_sock, 0, &Err);
1510 if (GetServerStatus(Buf, NULL) == 2) {
1511 StrBufPlain(Buf, _("New floor has been created."),-1);
1514 StrBufCutLeft(Buf, 4);
1516 AppendImportantMessage (SKEY(Buf));
1518 http_transmit_thing(ChrPtr(do_template("floors", NULL)), 0);
1526 void rename_floor(void) {
1532 serv_printf("EFLR %d|%s", ibstr("floornum"), bstr("floorname"));
1533 StrBuf_ServGetln(Buf);
1535 StrBufCutLeft(Buf, 4);
1536 AppendImportantMessage (SKEY(Buf));
1538 http_transmit_thing(ChrPtr(do_template("floors", NULL)), 0);
1545 * \brief Back end for change_view()
1546 * \param newview set newview???
1548 void do_change_view(int newview) {
1551 serv_printf("VIEW %d", newview);
1552 serv_getln(buf, sizeof buf);
1553 WC->CurRoom.view = newview;
1554 smart_goto(WC->CurRoom.name);
1560 * \brief Change the view for this room
1562 void change_view(void) {
1565 view = lbstr("view");
1566 do_change_view(view);
1570 * \brief Do either a known rooms list or a folders list, depending on the
1575 StrBuf *ListView = NULL;
1577 /** Determine whether the user is trying to change views */
1578 if (havebstr("view")) {
1579 ListView = NewStrBufDup(SBSTR("view"));
1580 set_preference("roomlistview", ListView, 1);
1582 /** Sanitize the input so its safe */
1583 if((get_preference("roomlistview", &ListView) != 0)||
1584 ((strcasecmp(ChrPtr(ListView), "folders") != 0) &&
1585 (strcasecmp(ChrPtr(ListView), "table") != 0)))
1587 if (ListView == NULL) {
1588 ListView = NewStrBufPlain(HKEY("rooms"));
1589 set_preference("roomlistview", ListView, 0);
1593 ListView = NewStrBufPlain(HKEY("rooms"));
1594 set_preference("roomlistview", ListView, 0);
1598 FreeStrBuf(&ListView);
1605 * \brief Set the message expire policy for this room and/or floor
1607 void set_room_policy(void) {
1610 if (!havebstr("ok_button")) {
1611 strcpy(WC->ImportantMessage,
1612 _("Cancelled. Changes were not saved."));
1613 http_transmit_thing(ChrPtr(do_template("room_edit", NULL)), 0);
1617 serv_printf("SPEX roompolicy|%d|%d", ibstr("roompolicy"), ibstr("roomvalue"));
1618 serv_getln(buf, sizeof buf);
1619 strcpy(WC->ImportantMessage, &buf[4]);
1621 if (WC->axlevel >= 6) {
1622 strcat(WC->ImportantMessage, "<br />\n");
1623 serv_printf("SPEX floorpolicy|%d|%d", ibstr("floorpolicy"), ibstr("floorvalue"));
1624 serv_getln(buf, sizeof buf);
1625 strcat(WC->ImportantMessage, &buf[4]);
1627 ReloadCurrentRoom();
1628 http_transmit_thing(ChrPtr(do_template("room_edit", NULL)), 0);
1631 void tmplput_RoomName(StrBuf *Target, WCTemplputParams *TP)
1633 StrBufAppendTemplate(Target, TP, WC->CurRoom.name, 0);
1636 void dotgoto(void) {
1637 if (!havebstr("room")) {
1638 readloop(readnew, eUseDefault);
1641 if (WC->CurRoom.view != VIEW_MAILBOX) { /* dotgoto acts like dotskip when we're in a mailbox view */
1644 smart_goto(sbstr("room"));
1649 void tmplput_current_room(StrBuf *Target, WCTemplputParams *TP)
1651 wcsession *WCC = WC;
1654 StrBufAppendTemplate(Target, TP,
1659 void tmplput_roombanner(StrBuf *Target, WCTemplputParams *TP)
1661 wc_printf("<div id=\"banner\">\n");
1662 embed_room_banner();
1663 wc_printf("</div>\n");
1667 void tmplput_ungoto(StrBuf *Target, WCTemplputParams *TP)
1669 wcsession *WCC = WC;
1672 (!IsEmptyStr(WCC->ugname)))
1673 StrBufAppendBufPlain(Target, WCC->ugname, -1, 0);
1676 int ConditionalRoomAide(StrBuf *Target, WCTemplputParams *TP)
1678 wcsession *WCC = WC;
1679 return (WCC != NULL)?
1680 ((WCC->CurRoom.RAFlags & UA_ADMINALLOWED) != 0) : 0;
1683 int ConditionalRoomAcessDelete(StrBuf *Target, WCTemplputParams *TP)
1685 wcsession *WCC = WC;
1686 return (WCC == NULL)? 0 :
1687 ( ((WCC->CurRoom.RAFlags & UA_ADMINALLOWED) != 0) ||
1688 (WCC->CurRoom.is_inbox) ||
1689 (WCC->CurRoom.QRFlags2 & QR2_COLLABDEL) );
1692 int ConditionalHaveUngoto(StrBuf *Target, WCTemplputParams *TP)
1694 wcsession *WCC = WC;
1696 return ((WCC!=NULL) &&
1697 (!IsEmptyStr(WCC->ugname)) &&
1698 (strcasecmp(WCC->ugname, ChrPtr(WCC->CurRoom.name)) == 0));
1702 int ConditionalRoomHas_UAFlag(StrBuf *Target, WCTemplputParams *TP)
1704 folder *Folder = (folder *)(TP->Context);
1707 UA_CheckFlag = GetTemplateTokenNumber(Target, TP, 2, 0);
1708 if (UA_CheckFlag == 0)
1709 LogTemplateError(Target, "Conditional", ERR_PARM1, TP,
1710 "requires one of the #\"UA_*\"- defines or an integer flag 0 is invalid!");
1712 return ((Folder->RAFlags & UA_CheckFlag) != 0);
1717 int ConditionalCurrentRoomHas_QRFlag(StrBuf *Target, WCTemplputParams *TP)
1720 wcsession *WCC = WC;
1722 QR_CheckFlag = GetTemplateTokenNumber(Target, TP, 2, 0);
1723 if (QR_CheckFlag == 0)
1724 LogTemplateError(Target, "Conditional", ERR_PARM1, TP,
1725 "requires one of the #\"QR*\"- defines or an integer flag 0 is invalid!");
1730 if ((TP->Tokens->Params[2]->MaskBy == eOR) ||
1731 (TP->Tokens->Params[2]->MaskBy == eNO))
1732 return (WCC->CurRoom.QRFlags & QR_CheckFlag) != 0;
1734 return (WCC->CurRoom.QRFlags & QR_CheckFlag) == QR_CheckFlag;
1737 int ConditionalRoomHas_QRFlag(StrBuf *Target, WCTemplputParams *TP)
1740 folder *Folder = (folder *)(TP->Context);
1742 QR_CheckFlag = GetTemplateTokenNumber(Target, TP, 2, 0);
1743 if (QR_CheckFlag == 0)
1744 LogTemplateError(Target, "Conditional", ERR_PARM1, TP,
1745 "requires one of the #\"QR*\"- defines or an integer flag 0 is invalid!");
1747 if ((TP->Tokens->Params[2]->MaskBy == eOR) ||
1748 (TP->Tokens->Params[2]->MaskBy == eNO))
1749 return (Folder->QRFlags & QR_CheckFlag) != 0;
1751 return (Folder->QRFlags & QR_CheckFlag) == QR_CheckFlag;
1755 int ConditionalCurrentRoomHas_QRFlag2(StrBuf *Target, WCTemplputParams *TP)
1758 wcsession *WCC = WC;
1760 QR2_CheckFlag = GetTemplateTokenNumber(Target, TP, 2, 0);
1761 if (QR2_CheckFlag == 0)
1762 LogTemplateError(Target, "Conditional", ERR_PARM1, TP,
1763 "requires one of the #\"QR2*\"- defines or an integer flag 0 is invalid!");
1769 if ((TP->Tokens->Params[2]->MaskBy == eOR) ||
1770 (TP->Tokens->Params[2]->MaskBy == eNO))
1771 return (WCC->CurRoom.QRFlags2 & QR2_CheckFlag) != 0;
1773 return (WCC->CurRoom.QRFlags2 & QR2_CheckFlag) == QR2_CheckFlag;
1776 int ConditionalRoomHas_QRFlag2(StrBuf *Target, WCTemplputParams *TP)
1779 folder *Folder = (folder *)(TP->Context);
1781 QR2_CheckFlag = GetTemplateTokenNumber(Target, TP, 2, 0);
1782 if (QR2_CheckFlag == 0)
1783 LogTemplateError(Target, "Conditional", ERR_PARM1, TP,
1784 "requires one of the #\"QR2*\"- defines or an integer flag 0 is invalid!");
1785 return ((Folder->QRFlags2 & QR2_CheckFlag) != 0);
1789 int ConditionalHaveRoomeditRights(StrBuf *Target, WCTemplputParams *TP)
1791 wcsession *WCC = WC;
1793 return ( (WCC!= NULL) &&
1794 ((WCC->axlevel >= 6) ||
1795 ((WCC->CurRoom.RAFlags & UA_ADMINALLOWED) != 0) ||
1796 (WCC->CurRoom.is_inbox) ));
1799 int ConditionalIsRoomtype(StrBuf *Target, WCTemplputParams *TP)
1801 wcsession *WCC = WC;
1803 if ((WCC == NULL) ||
1804 (TP->Tokens->nParameters < 3))
1806 return ((WCC->CurRoom.view < VIEW_BBS) ||
1807 (WCC->CurRoom.view > VIEW_MAX));
1810 return WCC->CurRoom.view == GetTemplateTokenNumber(Target, TP, 2, VIEW_BBS);
1814 HashList *GetWhoKnowsHash(StrBuf *Target, WCTemplputParams *TP)
1816 wcsession *WCC = WC;
1820 HashList *Whok = NULL;
1826 StrBuf_ServGetln(Line);
1827 if (GetServerStatus(Line, &State) == 1)
1829 Whok = NewHash(1, Flathash);
1830 while(!Done && StrBuf_ServGetln(Line))
1831 if ( (StrLength(Line)==3) &&
1832 !strcmp(ChrPtr(Line), "000"))
1839 const char *Pos = NULL;
1840 Token = NewStrBufPlain (NULL, StrLength(Line));
1841 StrBufExtract_NextToken(Token, Line, &Pos, '|');
1850 else if (State == 550)
1851 StrBufAppendBufPlain(WCC->ImportantMsg,
1852 _("Higher access is required to access this function."), -1, 0);
1861 void _FlushRoomList(wcsession *WCC)
1863 free_march_list(WCC);
1864 DeleteHash(&WCC->Floors);
1865 DeleteHash(&WCC->Rooms);
1866 DeleteHash(&WCC->FloorsByName);
1867 FlushFolder(&WCC->CurRoom);
1870 void ReloadCurrentRoom(void)
1872 wcsession *WCC = WC;
1875 CurRoom = WCC->CurRoom.name;
1876 WCC->CurRoom.name = NULL;
1877 _FlushRoomList(WCC);
1879 FreeStrBuf(&CurRoom);
1882 void FlushRoomlist(void)
1884 wcsession *WCC = WC;
1885 _FlushRoomList(WCC);
1893 initialize_viewdefs();
1894 RegisterPreference("roomlistview",
1895 _("Room list view"),
1898 RegisterPreference("emptyfloors", _("Show empty floors"), PRF_YESNO, NULL);
1900 RegisterNamespace("ROOMNAME", 0, 1, tmplput_RoomName, NULL, CTX_NONE);
1903 WebcitAddUrlHandler(HKEY("delete_floor"), "", 0, delete_floor, 0);
1904 WebcitAddUrlHandler(HKEY("rename_floor"), "", 0, rename_floor, 0);
1905 WebcitAddUrlHandler(HKEY("create_floor"), "", 0, create_floor, 0);
1907 WebcitAddUrlHandler(HKEY("knrooms"), "", 0, knrooms, 0);
1908 WebcitAddUrlHandler(HKEY("dotgoto"), "", 0, dotgoto, NEED_URL);
1909 WebcitAddUrlHandler(HKEY("dotskip"), "", 0, dotskip, NEED_URL);
1911 WebcitAddUrlHandler(HKEY("goto_private"), "", 0, goto_private, NEED_URL);
1912 WebcitAddUrlHandler(HKEY("zap"), "", 0, zap, 0);
1913 WebcitAddUrlHandler(HKEY("entroom"), "", 0, entroom, 0);
1914 WebcitAddUrlHandler(HKEY("do_invt_kick"), "", 0, do_invt_kick, 0);
1916 WebcitAddUrlHandler(HKEY("netedit"), "", 0, netedit, 0);
1917 WebcitAddUrlHandler(HKEY("editroom"), "", 0, editroom, 0);
1918 WebcitAddUrlHandler(HKEY("delete_room"), "", 0, delete_room, 0);
1919 WebcitAddUrlHandler(HKEY("set_room_policy"), "", 0, set_room_policy, 0);
1920 WebcitAddUrlHandler(HKEY("changeview"), "", 0, change_view, 0);
1921 WebcitAddUrlHandler(HKEY("toggle_self_service"), "", 0, toggle_self_service, 0);
1922 RegisterNamespace("ROOMBANNER", 0, 1, tmplput_roombanner, NULL, CTX_NONE);
1924 RegisterConditional(HKEY("COND:ROOM:TYPE_IS"), 0, ConditionalIsRoomtype, CTX_NONE);
1925 RegisterConditional(HKEY("COND:THISROOM:FLAG:QR"), 0, ConditionalCurrentRoomHas_QRFlag, CTX_NONE);
1926 RegisterConditional(HKEY("COND:ROOM:FLAG:QR"), 0, ConditionalRoomHas_QRFlag, CTX_ROOMS);
1928 RegisterConditional(HKEY("COND:THISROOM:FLAG:QR2"), 0, ConditionalCurrentRoomHas_QRFlag2, CTX_NONE);
1929 RegisterConditional(HKEY("COND:ROOM:FLAG:QR2"), 0, ConditionalRoomHas_QRFlag2, CTX_ROOMS);
1930 RegisterConditional(HKEY("COND:ROOM:FLAG:UA"), 0, ConditionalRoomHas_UAFlag, CTX_ROOMS);
1932 RegisterIterator("ITERATE:THISROOM:WHO_KNOWS", 0, NULL, GetWhoKnowsHash, NULL, DeleteHash, CTX_STRBUF, CTX_NONE, IT_NOFLAG);
1933 RegisterNamespace("THISROOM:MSGS:NEW", 0, 0, tmplput_CurrentRoom_nNewMessages, NULL, CTX_NONE);
1934 RegisterNamespace("THISROOM:MSGS:TOTAL", 0, 0, tmplput_CurrentRoom_nTotalMessages, NULL, CTX_NONE);
1936 RegisterNamespace("THISROOM:FLOOR:NAME", 0, 1, tmplput_CurrentRoomFloorName, NULL, CTX_NONE);
1937 RegisterNamespace("THISROOM:AIDE", 0, 1, tmplput_CurrentRoomAide, NULL, CTX_NONE);
1938 RegisterNamespace("THISROOM:PASS", 0, 1, tmplput_CurrentRoomPass, NULL, CTX_NONE);
1939 RegisterNamespace("THISROOM:DIRECTORY", 0, 1, tmplput_CurrentRoomDirectory, NULL, CTX_NONE);
1940 RegisterNamespace("THISROOM:ORDER", 0, 0, tmplput_CurrentRoomOrder, NULL, CTX_NONE);
1941 RegisterNamespace("THISROOM:DEFAULT_VIEW", 0, 0, tmplput_CurrentRoomDefView, NULL, CTX_NONE);
1942 RegisterConditional(HKEY("COND:THISROOM:HAVE_VIEW"), 0, ConditionalThisRoomHaveView, CTX_NONE);
1943 RegisterConditional(HKEY("COND:ALLOWED_DEFAULT_VIEW"), 0, ConditionalIsAllowedDefaultView, CTX_NONE);
1945 RegisterNamespace("THISROOM:VIEW_STRING", 0, 1, tmplput_CurrentRoomViewString, NULL, CTX_NONE);
1946 RegisterNamespace("ROOM:VIEW_STRING", 1, 2, tmplput_RoomViewString, NULL, CTX_NONE);
1948 RegisterNamespace("THISROOM:INFOTEXT", 1, 2, tmplput_CurrentRoomInfoText, NULL, CTX_NONE);
1949 RegisterConditional(HKEY("COND:THISROOM:ORDER"), 0, ConditionalThisRoomOrder, CTX_NONE);
1950 RegisterConditional(HKEY("COND:THISROOM:DEFAULT_VIEW"), 0, ConditionalThisRoomDefView, CTX_NONE);
1951 RegisterConditional(HKEY("COND:THISROOM:CURR_VIEW"), 0, ConditionalThisRoomCurrView, CTX_NONE);
1952 RegisterConditional(HKEY("COND:THISROOM:HAVE_PIC"), 0, ConditionalThisRoomXHavePic, CTX_NONE);
1953 RegisterConditional(HKEY("COND:THISROOM:HAVE_INFOTEXT"), 0, ConditionalThisRoomXHaveInfoText, CTX_NONE);
1954 RegisterNamespace("THISROOM:FILES:N", 0, 1, tmplput_CurrentRoomXNFiles, NULL, CTX_NONE);
1955 RegisterNamespace("THISROOM:FILES:STR", 0, 1, tmplput_CurrentRoomX_FileString, NULL, CTX_NONE);
1957 REGISTERTokenParamDefine(QR_PERMANENT);
1958 REGISTERTokenParamDefine(QR_INUSE);
1959 REGISTERTokenParamDefine(QR_PRIVATE);
1960 REGISTERTokenParamDefine(QR_PASSWORDED);
1961 REGISTERTokenParamDefine(QR_GUESSNAME);
1962 REGISTERTokenParamDefine(QR_DIRECTORY);
1963 REGISTERTokenParamDefine(QR_UPLOAD);
1964 REGISTERTokenParamDefine(QR_DOWNLOAD);
1965 REGISTERTokenParamDefine(QR_VISDIR);
1966 REGISTERTokenParamDefine(QR_ANONONLY);
1967 REGISTERTokenParamDefine(QR_ANONOPT);
1968 REGISTERTokenParamDefine(QR_NETWORK);
1969 REGISTERTokenParamDefine(QR_PREFONLY);
1970 REGISTERTokenParamDefine(QR_READONLY);
1971 REGISTERTokenParamDefine(QR_MAILBOX);
1972 REGISTERTokenParamDefine(QR2_SYSTEM);
1973 REGISTERTokenParamDefine(QR2_SELFLIST);
1974 REGISTERTokenParamDefine(QR2_COLLABDEL);
1975 REGISTERTokenParamDefine(QR2_SUBJECTREQ);
1976 REGISTERTokenParamDefine(QR2_SMTP_PUBLIC);
1977 REGISTERTokenParamDefine(QR2_MODERATED);
1979 REGISTERTokenParamDefine(UA_KNOWN);
1980 REGISTERTokenParamDefine(UA_GOTOALLOWED);
1981 REGISTERTokenParamDefine(UA_HASNEWMSGS);
1982 REGISTERTokenParamDefine(UA_ZAPPED);
1983 REGISTERTokenParamDefine(UA_POSTALLOWED);
1984 REGISTERTokenParamDefine(UA_ADMINALLOWED);
1985 REGISTERTokenParamDefine(UA_DELETEALLOWED);
1986 REGISTERTokenParamDefine(UA_ISTRASH);
1988 REGISTERTokenParamDefine(US_NEEDVALID);
1989 REGISTERTokenParamDefine(US_PERM);
1990 REGISTERTokenParamDefine(US_LASTOLD);
1991 REGISTERTokenParamDefine(US_EXPERT);
1992 REGISTERTokenParamDefine(US_UNLISTED);
1993 REGISTERTokenParamDefine(US_NOPROMPT);
1994 REGISTERTokenParamDefine(US_PROMPTCTL);
1995 REGISTERTokenParamDefine(US_DISAPPEAR);
1996 REGISTERTokenParamDefine(US_REGIS);
1997 REGISTERTokenParamDefine(US_PAGINATOR);
1998 REGISTERTokenParamDefine(US_INTERNET);
1999 REGISTERTokenParamDefine(US_FLOORS);
2000 REGISTERTokenParamDefine(US_COLOR);
2001 REGISTERTokenParamDefine(US_USER_SET);
2003 REGISTERTokenParamDefine(VIEW_BBS);
2004 REGISTERTokenParamDefine(VIEW_MAILBOX);
2005 REGISTERTokenParamDefine(VIEW_ADDRESSBOOK);
2006 REGISTERTokenParamDefine(VIEW_CALENDAR);
2007 REGISTERTokenParamDefine(VIEW_TASKS);
2008 REGISTERTokenParamDefine(VIEW_NOTES);
2009 REGISTERTokenParamDefine(VIEW_WIKI);
2010 REGISTERTokenParamDefine(VIEW_CALBRIEF);
2011 REGISTERTokenParamDefine(VIEW_JOURNAL);
2012 REGISTERTokenParamDefine(VIEW_BLOG);
2015 /* server internal, we need to know but ignore them. */
2016 REGISTERTokenParamDefine(subpending);
2017 REGISTERTokenParamDefine(unsubpending);
2018 REGISTERTokenParamDefine(lastsent);
2020 REGISTERTokenParamDefine(ignet_push_share);
2021 { /* these are the parts of an IGNET push config */
2022 REGISTERTokenParamDefine(GNET_IGNET_NODE);
2023 REGISTERTokenParamDefine(GNET_IGNET_ROOM);
2025 REGISTERTokenParamDefine(listrecp);
2026 REGISTERTokenParamDefine(digestrecp);
2027 REGISTERTokenParamDefine(pop3client);
2028 { /* These are the parts of a pop3 client line... */
2029 REGISTERTokenParamDefine(GNET_POP3_HOST);
2030 REGISTERTokenParamDefine(GNET_POP3_USER);
2031 REGISTERTokenParamDefine(GNET_POP3_DONT_DELETE_REMOTE);
2032 REGISTERTokenParamDefine(GNET_POP3_INTERVAL);
2034 REGISTERTokenParamDefine(rssclient);
2035 REGISTERTokenParamDefine(participate);
2037 RegisterConditional(HKEY("COND:ROOMAIDE"), 2, ConditionalRoomAide, CTX_NONE);
2038 RegisterConditional(HKEY("COND:ACCESS:DELETE"), 2, ConditionalRoomAcessDelete, CTX_NONE);
2040 RegisterConditional(HKEY("COND:UNGOTO"), 0, ConditionalHaveUngoto, CTX_NONE);
2041 RegisterConditional(HKEY("COND:ROOM:EDITACCESS"), 0, ConditionalHaveRoomeditRights, CTX_NONE);
2043 RegisterNamespace("CURRENT_ROOM", 0, 1, tmplput_current_room, NULL, CTX_NONE);
2044 RegisterNamespace("ROOM:UNGOTO", 0, 0, tmplput_ungoto, NULL, CTX_NONE);
2045 RegisterIterator("FLOORS", 0, NULL, GetFloorListHash, NULL, NULL, CTX_FLOORS, CTX_NONE, IT_NOFLAG);
2052 SessionDestroyModule_ROOMOPS
2055 _FlushRoomList (sess);