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 */
177 wc_printf("<div id=\"navbar\"><ul>");
180 "<li class=\"ungoto\">"
181 "<a href=\"ungoto\">"
182 "<img src=\"static/ungoto2_24x.gif\" alt=\"\" width=\"24\" height=\"24\">"
183 "<span class=\"navbar_link\">%s</span></A>"
184 "</li>\n", _("Ungoto")
187 if (WC->CurRoom.view == VIEW_BBS) {
189 "<li class=\"newmess\">"
190 "<a href=\"readnew\">"
191 "<img src=\"static/newmess2_24x.gif\" alt=\"\" width=\"24\" height=\"24\">"
192 "<span class=\"navbar_link\">%s</span></A>"
193 "</li>\n", _("Read new messages")
197 switch(WC->CurRoom.view) {
198 case VIEW_ADDRESSBOOK:
200 "<li class=\"viewcontacts\">"
201 "<a href=\"readfwd\">"
202 "<img src=\"static/viewcontacts_24x.gif\" "
203 "alt=\"\" width=\"24\" height=\"24\">"
204 "<span class=\"navbar_link\">"
206 "</span></a></li>\n", _("View contacts")
209 "<li class=\"addnewcontact\">"
210 "<a href=\"display_enter\">"
211 "<img src=\"static/addnewcontact_24x.gif\" "
212 "alt=\"\" width=\"24\" height=\"24\">"
213 "<span class=\"navbar_link\">"
215 "</span></a></li>\n", _("Add new contact")
220 "<li class=\"staskday\">"
221 "<a href=\"readfwd?calview=day\">"
222 "<img src=\"static/taskday2_24x.gif\" "
223 "alt=\"\" width=\"24\" height=\"24\">"
224 "<span class=\"navbar_link\">"
226 "</span></a></li>\n", _("Day view")
229 "<li class=\"monthview\">"
230 "<a href=\"readfwd?calview=month\">"
231 "<img src=\"static/monthview2_24x.gif\" "
232 "alt=\"\" width=\"24\" height=\"24\">"
233 "<span class=\"navbar_link\">"
235 "</span></a></li>\n", _("Month view")
237 wc_printf("<li class=\"addevent\"><a href=\"display_enter");
238 if (havebstr("year" )) wc_printf("?year=%s", bstr("year"));
239 if (havebstr("month")) wc_printf("?month=%s", bstr("month"));
240 if (havebstr("day" )) wc_printf("?day=%s", bstr("day"));
242 "<img src=\"static/addevent_24x.gif\" "
243 "alt=\"\" width=\"24\" height=\"24\">"
244 "<span class=\"navbar_link\">"
246 "</span></a></li>\n", _("Add new event")
251 "<li class=\"monthview\">"
252 "<a href=\"readfwd?calview=month\">"
253 "<img src=\"static/monthview2_24x.gif\" "
254 "alt=\"\" width=\"24\" height=\"24\">"
255 "<span class=\"navbar_link\">"
257 "</span></a></li>\n", _("Calendar list")
262 "<li class=\"taskmanag\">"
263 "<a href=\"readfwd\">"
264 "<img src=\"static/taskmanag_24x.gif\" "
265 "alt=\"\" width=\"24\" height=\"24\">"
266 "<span class=\"navbar_link\">"
268 "</span></a></li>\n", _("View tasks")
271 "<li class=\"newmess\">"
272 "<a href=\"display_enter\">"
273 "<img src=\"static/newmess3_24x.gif\" "
274 "alt=\"\" width=\"24\" height=\"24\">"
275 "<span class=\"navbar_link\">"
277 "</span></a></li>\n", _("Add new task")
282 "<li class=\"viewnotes\">"
283 "<a href=\"readfwd\">"
284 "<img src=\"static/viewnotes_24x.gif\" "
285 "alt=\"\" width=\"24\" height=\"24\">"
286 "<span class=\"navbar_link\">"
288 "</span></a></li>\n", _("View notes")
291 "<li class=\"enternewnote\">"
292 "<a href=\"add_new_note\">"
293 "<img src=\"static/enternewnote_24x.gif\" "
294 "alt=\"\" width=\"24\" height=\"24\">"
295 "<span class=\"navbar_link\">"
297 "</span></a></li>\n", _("Add new note")
302 "<li class=\"readallmess\">"
303 "<a id=\"m_refresh\" href=\"readfwd\">"
304 "<img src=\"static/readallmess3_24x.gif\" "
305 "alt=\"\" width=\"24\" height=\"24\">"
306 "<span class=\"navbar_link\">"
308 "</span></a></li>\n", _("Refresh message list")
311 "<li class=\"readallmess\">"
312 "<a href=\"readfwd\">"
313 "<img src=\"static/readallmess3_24x.gif\" "
314 "alt=\"\" width=\"24\" height=\"24\">"
315 "<span class=\"navbar_link\">"
317 "</span></a></li>\n", _("Read all messages")
320 "<li class=\"newmess\">"
321 "<a href=\"display_enter\">"
322 "<img src=\"static/newmess3_24x.gif\" "
323 "alt=\"\" width=\"24\" height=\"24\">"
324 "<span class=\"navbar_link\">"
326 "</span></a></li>\n", _("Write mail")
331 "<li class=\"readallmess\">"
332 "<a href=\"wiki?page=home\">"
333 "<img src=\"static/readallmess3_24x.gif\" "
334 "alt=\"\" width=\"24\" height=\"24\">"
335 "<span class=\"navbar_link\">"
337 "</span></a></li>\n", _("Wiki home")
339 safestrncpy(buf, bstr("page"), sizeof buf);
340 if (IsEmptyStr(buf)) {
341 safestrncpy(buf, "home", sizeof buf);
345 "<li class=\"newmess\">"
346 "<a href=\"display_enter?page=%s\">"
347 "<img src=\"static/newmess3_24x.gif\" "
348 "alt=\"\" width=\"24\" height=\"24\">"
349 "<span class=\"navbar_link\">"
351 "</span></a></li>\n", buf, _("Edit this page")
354 if (bmstrcasestr((char *)ChrPtr(WCC->Hdr->HR.ReqLine), "wiki_history")) {
355 /* already viewing history; display a link to the current page */
357 "<li class=\"newmess\">"
358 "<a href=\"wiki?page=%s\">"
359 "<img src=\"static/newmess3_24x.gif\" "
360 "alt=\"\" width=\"24\" height=\"24\">"
361 "<span class=\"navbar_link\">"
363 "</span></a></li>\n", buf, _("Current version")
367 /* display a link to the history */
369 "<li class=\"newmess\">"
370 "<a href=\"wiki_history?page=%s\">"
371 "<img src=\"static/newmess3_24x.gif\" "
372 "alt=\"\" width=\"24\" height=\"24\">"
373 "<span class=\"navbar_link\">"
375 "</span></a></li>\n", buf, _("History")
382 "<li class=\"readallmess\">"
383 "<a href=\"readfwd\">"
384 "<img src=\"static/readallmess3_24x.gif\" "
385 "alt=\"\" width=\"24\" height=\"24\">"
386 "<span class=\"navbar_link\">"
388 "</span></a></li>\n", _("Read all messages")
391 "<li class=\"newmess\">"
392 "<a href=\"display_enter\">"
393 "<img src=\"static/newmess3_24x.gif\" "
394 "alt=\"\" width=\"24\" height=\"24\">"
395 "<span class=\"navbar_link\">"
397 "</span></a></li>\n", _("Enter a message")
403 "<li class=\"skipthisroom\">"
406 "<img src=\"static/skipthisroom_24x.gif\" alt=\"\" "
407 "width=\"24\" height=\"24\">"
408 "<span class=\"navbar_link\">%s</span></a>"
410 _("Leave all messages marked as unread, go to next room with unread messages"),
415 "<li class=\"markngo\">"
416 "<a href=\"gotonext\" "
418 "<img src=\"static/markngo_24x.gif\" alt=\"\" "
419 "width=\"24\" height=\"24\">"
420 "<span class=\"navbar_link\">%s</span></a>"
422 _("Mark all messages as read, go to next room with unread messages"),
426 wc_printf("</ul></div>\n");
431 * back end routine to take the session to a new room
433 long gotoroom(const StrBuf *gname)
437 static long ls = (-1L);
440 /* store ungoto information */
441 if (StrLength(gname) > 0)
442 strcpy(WCC->ugname, ChrPtr(WCC->CurRoom.name));
446 /* move to the new room */
447 if (StrLength(gname) > 0)
448 serv_printf("GOTO %s", ChrPtr(gname));
449 else /* or just refresh the current state... */
450 serv_printf("GOTO 00000000000000000000");
451 StrBuf_ServGetln(Buf);
452 if (GetServerStatus(Buf, &err) != 2) {
453 serv_puts("GOTO _BASEROOM_");
454 StrBuf_ServGetln(Buf);
456 * well, we know that this is the fallback case,
457 * but we're interested that the first command
458 * didn't work out in first place.
460 if (GetServerStatus(Buf, NULL) != 2) {
465 FlushFolder(&WCC->CurRoom);
466 ParseGoto(&WCC->CurRoom, Buf);
468 if (StrLength(gname) > 0)
470 remove_march(WCC->CurRoom.name);
471 if (!strcasecmp(ChrPtr(gname), "_BASEROOM_"))
481 void ParseGoto(folder *room, StrBuf *Line)
489 if (StrLength(Line) < 4) {
493 /* ignore the commandstate... */
494 Pos = ChrPtr(Line) + 4;
496 if (room->RoomNameParts != NULL)
499 for (i=0; i < room->nRoomNameParts; i++)
500 FreeStrBuf(&room->RoomNameParts[i]);
501 free(room->RoomNameParts);
502 room->RoomNameParts = NULL;
507 pBuf = NewStrBufPlain(NULL, StrLength(Line));
510 memset(room, 0, sizeof(folder));
513 StrBufExtract_NextToken(room->name, Line, &Pos, '|'); // WC->CurRoom->name
515 room->nNewMessages = StrBufExtractNext_long(Line, &Pos, '|');
516 if (room->nNewMessages > 0)
517 room->RAFlags |= UA_HASNEWMSGS;
519 room->nTotalMessages = StrBufExtractNext_long(Line, &Pos, '|');
521 room->ShowInfo = StrBufExtractNext_long(Line, &Pos, '|');
523 room->QRFlags = StrBufExtractNext_long(Line, &Pos, '|'); //CurRoom->QRFlags
525 DBG_QR(room->QRFlags);
527 room->HighestRead = StrBufExtractNext_long(Line, &Pos, '|');
528 room->LastMessageRead = StrBufExtractNext_long(Line, &Pos, '|');
530 room->is_inbox = StrBufExtractNext_long(Line, &Pos, '|'); // is_mailbox
532 flag = StrBufExtractNext_long(Line, &Pos, '|');
533 if (WCC->is_aide || flag) {
534 room->RAFlags |= UA_ADMINALLOWED;
537 room->UsersNewMAilboxMessages = StrBufExtractNext_long(Line, &Pos, '|');
539 room->floorid = StrBufExtractNext_int(Line, &Pos, '|'); // wc_floor
541 room->view = StrBufExtractNext_long(Line, &Pos, '|'); // CurRoom->view
543 room->defview = StrBufExtractNext_long(Line, &Pos, '|'); // CurRoom->defview
545 flag = StrBufExtractNext_long(Line, &Pos, '|');
547 room->RAFlags |= UA_ISTRASH; // wc_is_trash
549 room->QRFlags2 = StrBufExtractNext_long(Line, &Pos, '|'); // CurRoom->QRFlags2
550 DBG_QR2(room->QRFlags2);
552 /* find out, whether we are in a sub-room */
553 room->nRoomNameParts = StrBufNum_tokens(room->name, '\\');
554 if (room->nRoomNameParts > 1)
559 room->RoomNameParts = malloc(sizeof(StrBuf*) * (room->nRoomNameParts + 1));
560 memset(room->RoomNameParts, 0, sizeof(StrBuf*) * (room->nRoomNameParts + 1));
561 for (i=0; i < room->nRoomNameParts; i++)
563 room->RoomNameParts[i] = NewStrBuf();
564 StrBufExtract_NextToken(room->RoomNameParts[i],
565 room->name, &Pos, '\\');
569 /* Private mailboxes on the main floor get remapped to the personal folder */
570 if ((room->QRFlags & QR_MAILBOX) &&
571 (room->floorid == 0))
573 room->floorid = VIRTUAL_MY_FLOOR;
574 if ((room->nRoomNameParts == 1) &&
575 (StrLength(room->name) == 4) &&
576 (strcmp(ChrPtr(room->name), "Mail") == 0))
582 /* get a pointer to the floor we're on: */
583 if (WCC->Floors == NULL)
584 GetFloorListHash(NULL, NULL);
586 GetHash(WCC->Floors, IKEY(room->floorid), &vFloor);
587 room->Floor = (const Floor*) vFloor;
590 void LoadRoomAide(void)
595 if (WCC->CurRoom.RoomAideLoaded)
598 WCC->CurRoom.RoomAideLoaded = 1;
601 StrBuf_ServGetln(Buf);
602 if (GetServerStatus(Buf, NULL) != 2) {
603 FlushStrBuf(WCC->CurRoom.RoomAide);
604 AppendImportantMessage (ChrPtr(Buf) + 4,
609 Pos = ChrPtr(Buf) + 4;
611 FreeStrBuf(&WCC->CurRoom.RoomAide);
612 WCC->CurRoom.RoomAide = NewStrBufPlain (NULL, StrLength (Buf));
614 StrBufExtract_NextToken(WCC->CurRoom.RoomAide, Buf, &Pos, '|');
619 int SaveRoomAide(folder *Room)
623 serv_printf("SETA %s", ChrPtr(Room->RoomAide));
624 StrBuf_ServGetln(Buf);
625 if (GetServerStatus(Buf, NULL) != 2) {
626 StrBufCutLeft(Buf, 4);
627 AppendImportantMessage (SKEY(Buf));
635 void tmplput_CurrentRoomFloorName(StrBuf *Target, WCTemplputParams *TP)
638 folder *Folder = &WCC->CurRoom;
644 pFloor = Folder->Floor;
648 StrBufAppendTemplate(Target, TP, pFloor->Name, 0);
651 void tmplput_CurrentRoomAide(StrBuf *Target, WCTemplputParams *TP)
657 StrBufAppendTemplate(Target, TP, WCC->CurRoom.RoomAide, 0);
660 int GetCurrentRoomFlags(folder *Room)
666 StrBuf_ServGetln(Buf);
667 if (GetServerStatus(Buf, NULL) != 2) {
668 FlushStrBuf(Room->XAPass);
669 FlushStrBuf(Room->Directory);
670 StrBufCutLeft(Buf, 4);
671 AppendImportantMessage (SKEY(Buf));
677 Pos = ChrPtr(Buf) + 4;
679 FreeStrBuf(&Room->XAPass);
680 FreeStrBuf(&Room->Directory);
682 Room->XAPass = NewStrBufPlain (NULL, StrLength (Buf));
683 Room->Directory = NewStrBufPlain (NULL, StrLength (Buf));
685 FreeStrBuf(&Room->name);
686 Room->name = NewStrBufPlain(NULL, StrLength(Buf));
687 StrBufExtract_NextToken(Room->name, Buf, &Pos, '|');
689 StrBufExtract_NextToken(Room->XAPass, Buf, &Pos, '|');
690 StrBufExtract_NextToken(Room->Directory, Buf, &Pos, '|');
692 Room->QRFlags = StrBufExtractNext_long(Buf, &Pos, '|');
693 Room->floorid = StrBufExtractNext_long(Buf, &Pos, '|');
694 Room->Order = StrBufExtractNext_long(Buf, &Pos, '|');
695 Room->defview = StrBufExtractNext_long(Buf, &Pos, '|');
696 Room->QRFlags2 = StrBufExtractNext_long(Buf, &Pos, '|');
704 int SetCurrentRoomFlags(folder *Room)
709 DBG_QR(Room->QRFlags);
710 DBG_QR2(Room->QRFlags2);
712 serv_printf("SETR %s|%s|%s|%ld|%d|%d|%ld|%ld|%ld",
714 ChrPtr(Room->XAPass),
715 ChrPtr(Room->Directory),
723 StrBuf_ServGetln(Buf);
724 if (GetServerStatus(Buf, NULL) != 2) {
725 StrBufCutLeft(Buf, 4);
726 AppendImportantMessage (SKEY(Buf));
735 void LoadRoomXA (void)
739 if (WCC->CurRoom.XALoaded)
742 GetCurrentRoomFlags(&WCC->CurRoom);
746 void LoadXRoomPic(void)
751 if (WCC->CurRoom.XHaveRoomPicLoaded)
754 WCC->CurRoom.XHaveRoomPicLoaded = 1;
756 serv_puts("OIMG _roompic_");
757 StrBuf_ServGetln(Buf);
758 if (GetServerStatus(Buf, NULL) != 2) {
759 WCC->CurRoom.XHaveRoomPic = 0;
761 WCC->CurRoom.XHaveRoomPic = 1;
764 StrBuf_ServGetln(Buf);
765 GetServerStatus(Buf, NULL);
769 int ConditionalThisRoomXHavePic(StrBuf *Target, WCTemplputParams *TP)
777 return WCC->CurRoom.XHaveRoomPic == 1;
780 void LoadXRoomInfoText(void)
786 if (WCC->CurRoom.XHaveInfoTextLoaded)
789 WCC->CurRoom.XHaveInfoTextLoaded = 1;
794 StrBuf_ServGetln(Buf);
795 if (GetServerStatus(Buf, NULL) == 1) {
796 WCC->CurRoom.XInfoText = NewStrBuf ();
798 while (!Done && StrBuf_ServGetln(Buf)>=0) {
799 if ( (StrLength(Buf)==3) &&
800 !strcmp(ChrPtr(Buf), "000"))
803 StrBufAppendBuf(WCC->CurRoom.XInfoText, Buf, 0);
810 int ConditionalThisRoomXHaveInfoText(StrBuf *Target, WCTemplputParams *TP)
818 return (StrLength(WCC->CurRoom.XInfoText)>0);
821 void tmplput_CurrentRoomInfoText(StrBuf *Target, WCTemplputParams *TP)
827 StrBufAppendTemplate(Target, TP, WCC->CurRoom.XAPass, 1);
830 void LoadXRoomXCountFiles(void)
836 if (WCC->CurRoom.XHaveDownloadCount)
839 WCC->CurRoom.XHaveDownloadCount = 1;
843 StrBuf_ServGetln(Buf);
844 if (GetServerStatus(Buf, NULL) == 1) {
846 while (!Done && StrBuf_ServGetln(Buf)>=0) {
847 if ( (StrLength(Buf)==3) &&
848 !strcmp(ChrPtr(Buf), "000"))
851 WCC->CurRoom.XDownloadCount++;
858 void tmplput_CurrentRoomXNFiles(StrBuf *Target, WCTemplputParams *TP)
862 LoadXRoomXCountFiles();
864 StrBufAppendPrintf(Target, "%d", WCC->CurRoom.XDownloadCount);
867 void tmplput_CurrentRoomX_FileString(StrBuf *Target, WCTemplputParams *TP)
871 LoadXRoomXCountFiles();
873 if (WCC->CurRoom.XDownloadCount == 1)
874 StrBufAppendBufPlain(Target, _("file"), -1, 0);
876 StrBufAppendBufPlain(Target, _("files"), -1, 0);
879 void tmplput_CurrentRoomPass(StrBuf *Target, WCTemplputParams *TP)
885 StrBufAppendTemplate(Target, TP, WCC->CurRoom.XAPass, 0);
887 void tmplput_CurrentRoomDirectory(StrBuf *Target, WCTemplputParams *TP)
893 StrBufAppendTemplate(Target, TP, WCC->CurRoom.Directory, 0);
895 void tmplput_CurrentRoomOrder(StrBuf *Target, WCTemplputParams *TP)
901 StrBufAppendPrintf(Target, "%d", WCC->CurRoom.Order);
903 void tmplput_CurrentRoomDefView(StrBuf *Target, WCTemplputParams *TP)
907 StrBufAppendPrintf(Target, "%d", WCC->CurRoom.defview);
910 void tmplput_CurrentRoom_nNewMessages(StrBuf *Target, WCTemplputParams *TP)
916 StrBufAppendPrintf(Target, "%d", WCC->CurRoom.nNewMessages);
919 void tmplput_CurrentRoom_nTotalMessages(StrBuf *Target, WCTemplputParams *TP)
925 StrBufAppendPrintf(Target, "%d", WCC->CurRoom.nTotalMessages);
928 int ConditionalThisRoomOrder(StrBuf *Target, WCTemplputParams *TP)
938 CheckThis = GetTemplateTokenNumber(Target, TP, 2, 0);
939 return CheckThis == WCC->CurRoom.Order;
942 int ConditionalThisRoomDefView(StrBuf *Target, WCTemplputParams *TP)
950 CheckThis = GetTemplateTokenNumber(Target, TP, 2, 0);
951 return CheckThis == WCC->CurRoom.defview;
954 int ConditionalThisRoomCurrView(StrBuf *Target, WCTemplputParams *TP)
962 CheckThis = GetTemplateTokenNumber(Target, TP, 2, 0);
963 return CheckThis == WCC->CurRoom.view;
966 int ConditionalThisRoomHaveView(StrBuf *Target, WCTemplputParams *TP)
974 CheckThis = GetTemplateTokenNumber(Target, TP, 2, 0);
975 if ((CheckThis >= VIEW_MAX) || (CheckThis < VIEW_BBS))
977 LogTemplateError(Target, "Conditional", ERR_PARM2, TP,
978 "Roomview [%ld] not valid\n",
983 return exchangeable_views [WCC->CurRoom.defview][CheckThis] != VIEW_MAX;
986 void tmplput_CurrentRoomViewString(StrBuf *Target, WCTemplputParams *TP)
992 (WCC->CurRoom.defview >= VIEW_MAX) ||
993 (WCC->CurRoom.defview < VIEW_BBS))
995 LogTemplateError(Target, "Token", ERR_PARM2, TP,
996 "Roomview [%ld] not valid\n",
998 WCC->CurRoom.defview : -1);
1002 Buf = NewStrBufPlain(_(viewdefs[WCC->CurRoom.defview]), -1);
1003 StrBufAppendTemplate(Target, TP, Buf, 0);
1007 void tmplput_RoomViewString(StrBuf *Target, WCTemplputParams *TP)
1012 CheckThis = GetTemplateTokenNumber(Target, TP, 0, 0);
1013 if ((CheckThis >= VIEW_MAX) || (CheckThis < VIEW_BBS))
1015 LogTemplateError(Target, "Token", ERR_PARM2, TP,
1016 "Roomview [%ld] not valid\n",
1021 Buf = NewStrBufPlain(_(viewdefs[CheckThis]), -1);
1022 StrBufAppendTemplate(Target, TP, Buf, 0);
1027 int ConditionalIsAllowedDefaultView(StrBuf *Target, WCTemplputParams *TP)
1029 wcsession *WCC = WC;
1035 CheckThis = GetTemplateTokenNumber(Target, TP, 2, 0);
1036 if ((CheckThis >= VIEW_MAX) || (CheckThis < VIEW_BBS))
1038 LogTemplateError(Target, "Conditional", ERR_PARM2, TP,
1039 "Roomview [%ld] not valid\n",
1044 return allowed_default_views[CheckThis] != 0;
1050 void smart_goto(const StrBuf *next_room) {
1051 gotoroom(next_room);
1052 readloop(readnew, eUseDefault);
1058 * mark all messages in current room as having been read
1060 void slrp_highest(void)
1064 serv_puts("SLRP HIGHEST");
1065 serv_getln(buf, sizeof buf);
1071 * Set/clear/read the "self-service list subscribe" flag for a room
1073 * set newval to 0 to clear, 1 to set, any other value to leave unchanged.
1074 * returns the new value.
1077 int self_service(int newval) {
1078 int current_value = 0;
1079 wcsession *WCC = WC;
1081 if (GetCurrentRoomFlags (&WCC->CurRoom) == 0)
1086 if ((WCC->CurRoom.QRFlags2 & QR2_SELFLIST) != 0) {
1094 WCC->CurRoom.QRFlags2 = WCC->CurRoom.QRFlags2 | QR2_SELFLIST;
1096 else if (newval == 0) {
1097 WCC->CurRoom.QRFlags2 = WCC->CurRoom.QRFlags2 & ~QR2_SELFLIST;
1100 return(current_value);
1103 if (newval != current_value) {
1104 SetCurrentRoomFlags(&WCC->CurRoom);
1114 * Toggle self-service list subscription
1116 void toggle_self_service(void) {
1117 wcsession *WCC = WC;
1119 if (GetCurrentRoomFlags (&WCC->CurRoom) == 0)
1122 if (yesbstr("QR2_SelfList"))
1123 WCC->CurRoom.QRFlags2 = WCC->CurRoom.QRFlags2 | QR2_SELFLIST;
1125 WCC->CurRoom.QRFlags2 = WCC->CurRoom.QRFlags2 & ~QR2_SELFLIST;
1127 if (yesbstr("QR2_SMTP_PUBLIC"))
1128 WCC->CurRoom.QRFlags2 = WCC->CurRoom.QRFlags2 | QR2_SMTP_PUBLIC;
1130 WCC->CurRoom.QRFlags2 = WCC->CurRoom.QRFlags2 & ~QR2_SMTP_PUBLIC;
1132 if (yesbstr("QR2_Moderated"))
1133 WCC->CurRoom.QRFlags2 = WCC->CurRoom.QRFlags2 | QR2_MODERATED;
1135 WCC->CurRoom.QRFlags2 = WCC->CurRoom.QRFlags2 & ~QR2_MODERATED;
1136 if (yesbstr("QR2_SubsOnly"))
1137 WCC->CurRoom.QRFlags2 = WCC->CurRoom.QRFlags2 | QR2_SMTP_PUBLIC;
1139 WCC->CurRoom.QRFlags2 = WCC->CurRoom.QRFlags2 & ~QR2_SMTP_PUBLIC;
1141 SetCurrentRoomFlags (&WCC->CurRoom);
1143 http_transmit_thing(ChrPtr(do_template("room_edit", NULL)), 0);
1149 * save new parameters for a room
1153 wcsession *WCC = WC;
1155 const StrBuf *er_name;
1156 const StrBuf *er_password;
1157 const StrBuf *er_dirname;
1158 const StrBuf *er_roomaide;
1163 if (!havebstr("ok_button")) {
1164 strcpy(WC->ImportantMessage,
1165 _("Cancelled. Changes were not saved."));
1166 http_transmit_thing(ChrPtr(do_template("room_edit", NULL)), 0);
1169 if (GetCurrentRoomFlags (&WCC->CurRoom) == 0)
1174 er_flags = WCC->CurRoom.QRFlags;
1175 er_flags &= !(QR_PRIVATE | QR_PASSWORDED | QR_GUESSNAME);
1177 er_flags2 = WCC->CurRoom.QRFlags2;
1179 Ptr = sbstr("type");
1180 if (!strcmp(ChrPtr(Ptr), "invonly")) {
1181 er_flags |= (QR_PRIVATE);
1183 if (!strcmp(ChrPtr(Ptr), "hidden")) {
1184 er_flags |= (QR_PRIVATE | QR_GUESSNAME);
1186 if (!strcmp(ChrPtr(Ptr), "passworded")) {
1187 er_flags |= (QR_PRIVATE | QR_PASSWORDED);
1189 if (!strcmp(ChrPtr(Ptr), "personal")) {
1190 er_flags |= QR_MAILBOX;
1192 er_flags &= ~QR_MAILBOX;
1197 if (yesbstr("prefonly")) {
1198 er_flags |= QR_PREFONLY;
1200 er_flags &= ~QR_PREFONLY;
1203 if (yesbstr("readonly")) {
1204 er_flags |= QR_READONLY;
1206 er_flags &= ~QR_READONLY;
1210 if (yesbstr("collabdel")) {
1211 er_flags2 |= QR2_COLLABDEL;
1213 er_flags2 &= ~QR2_COLLABDEL;
1216 if (yesbstr("permanent")) {
1217 er_flags |= QR_PERMANENT;
1219 er_flags &= ~QR_PERMANENT;
1222 if (yesbstr("subjectreq")) {
1223 er_flags2 |= QR2_SUBJECTREQ;
1225 er_flags2 &= ~QR2_SUBJECTREQ;
1228 if (yesbstr("network")) {
1229 er_flags |= QR_NETWORK;
1231 er_flags &= ~QR_NETWORK;
1234 if (yesbstr("directory")) {
1235 er_flags |= QR_DIRECTORY;
1237 er_flags &= ~QR_DIRECTORY;
1240 if (yesbstr("ulallowed")) {
1241 er_flags |= QR_UPLOAD;
1243 er_flags &= ~QR_UPLOAD;
1246 if (yesbstr("dlallowed")) {
1247 er_flags |= QR_DOWNLOAD;
1249 er_flags &= ~QR_DOWNLOAD;
1252 if (yesbstr("visdir")) {
1253 er_flags |= QR_VISDIR;
1255 er_flags &= ~QR_VISDIR;
1259 Ptr = sbstr("anon");
1261 er_flags &= ~(QR_ANONONLY | QR_ANONOPT);
1262 if (!strcmp(ChrPtr(Ptr), "anononly"))
1263 er_flags |= QR_ANONONLY;
1264 if (!strcmp(ChrPtr(Ptr), "anon2"))
1265 er_flags |= QR_ANONOPT;
1267 er_name = sbstr("er_name");
1268 er_dirname = sbstr("er_dirname");
1269 er_roomaide = sbstr("er_roomaide");
1270 er_password = sbstr("er_password");
1272 FlushStrBuf(WCC->CurRoom.name);
1273 StrBufAppendBuf(WCC->CurRoom.name, er_name, 0);
1275 FlushStrBuf(WCC->CurRoom.Directory);
1276 StrBufAppendBuf(WCC->CurRoom.Directory, er_dirname, 0);
1278 FlushStrBuf(WCC->CurRoom.RoomAide);
1279 StrBufAppendBuf(WCC->CurRoom.RoomAide, er_roomaide, 0);
1281 FlushStrBuf(WCC->CurRoom.XAPass);
1282 StrBufAppendBuf(WCC->CurRoom.XAPass, er_password, 0);
1284 WCC->CurRoom.BumpUsers = yesbstr("bump");
1286 WCC->CurRoom.floorid = ibstr("er_floor");
1288 succ1 = SetCurrentRoomFlags(&WCC->CurRoom);
1290 succ2 = SaveRoomAide (&WCC->CurRoom);
1292 if (succ1 + succ2 == 0)
1293 AppendImportantMessage (_("Your changes have been saved."), -1);
1294 http_transmit_thing(ChrPtr(do_template("room_edit", NULL)), 0);
1300 * Display form for Invite, Kick, and show Who Knows a room
1302 void do_invt_kick(void)
1305 const StrBuf *UserNames;
1307 wcsession *WCC = WC;
1310 if (GetCurrentRoomFlags(&WCC->CurRoom) == 1)
1313 UserNames = sbstr("username");
1314 Kick = havebstr("kick_button");
1315 Invite = havebstr("invite_button");
1317 User = NewStrBufPlain(NULL, StrLength(UserNames));
1320 Pos = ChrPtr(UserNames);
1321 while (Pos != StrBufNOTNULL)
1323 StrBufExtract_NextToken(User, UserNames, &Pos, ',');
1325 if ((StrLength(User) > 0) && (Kick))
1327 serv_printf("KICK %s", ChrPtr(User));
1328 StrBuf_ServGetln(Buf);
1329 if (GetServerStatus(Buf, NULL) != 2) {
1330 StrBufCutLeft(Buf, 4);
1331 AppendImportantMessage(SKEY(Buf));
1334 _("User '%s' kicked out of room '%s'."),
1336 ChrPtr(WCC->CurRoom.name)
1338 AppendImportantMessage(SKEY(Buf));
1341 else if ((StrLength(User) > 0) && (Invite))
1343 serv_printf("INVT %s", ChrPtr(User));
1344 StrBuf_ServGetln(Buf);
1345 if (GetServerStatus(Buf, NULL) != 2) {
1346 StrBufCutLeft(Buf, 4);
1347 AppendImportantMessage(SKEY(Buf));
1350 _("User '%s' invited to room '%s'."),
1352 ChrPtr(WCC->CurRoom.name)
1354 AppendImportantMessage(SKEY(Buf));
1360 http_transmit_thing(ChrPtr(do_template("room_edit", NULL)), 0);
1364 * support function for entroom() -- sets the default view
1366 void er_set_default_view(int newview) {
1379 serv_getln(buf, sizeof buf);
1380 if (buf[0] != '2') return;
1382 extract_token(rm_name, &buf[4], 0, '|', sizeof rm_name);
1383 extract_token(rm_pass, &buf[4], 1, '|', sizeof rm_pass);
1384 extract_token(rm_dir, &buf[4], 2, '|', sizeof rm_dir);
1385 rm_bits1 = extract_int(&buf[4], 3);
1386 rm_floor = extract_int(&buf[4], 4);
1387 rm_listorder = extract_int(&buf[4], 5);
1388 rm_bits2 = extract_int(&buf[4], 7);
1390 serv_printf("SETR %s|%s|%s|%d|0|%d|%d|%d|%d",
1391 rm_name, rm_pass, rm_dir, rm_bits1, rm_floor,
1392 rm_listorder, newview, rm_bits2
1394 serv_getln(buf, sizeof buf);
1405 const StrBuf *er_name;
1406 const StrBuf *er_type;
1407 const StrBuf *er_password;
1411 wcsession *WCC = WC;
1413 if (!havebstr("ok_button")) {
1414 strcpy(WC->ImportantMessage,
1415 _("Cancelled. No new room was created."));
1416 display_main_menu();
1419 er_name = sbstr("er_name");
1420 er_type = sbstr("type");
1421 er_password = sbstr("er_password");
1422 er_floor = ibstr("er_floor");
1423 er_view = ibstr("er_view");
1426 if (!strcmp(ChrPtr(er_type), "hidden"))
1428 else if (!strcmp(ChrPtr(er_type), "passworded"))
1430 else if (!strcmp(ChrPtr(er_type), "invonly"))
1432 else if (!strcmp(ChrPtr(er_type), "personal"))
1435 serv_printf("CRE8 1|%s|%d|%s|%d|%d|%d",
1438 ChrPtr(er_password),
1443 serv_getln(buf, sizeof buf);
1444 if (buf[0] != '2') {
1445 strcpy(WCC->ImportantMessage, &buf[4]);
1446 display_main_menu();
1449 /** TODO: Room created, now update the left hand icon bar for this user */
1452 serv_printf("VIEW %d", er_view);
1453 serv_getln(buf, sizeof buf);
1454 WCC->CurRoom.view = er_view;
1456 if ( (WCC != NULL) && ( (WCC->CurRoom.RAFlags & UA_ADMINALLOWED) != 0) ) {
1457 http_transmit_thing(ChrPtr(do_template("room_edit", NULL)), 0);
1459 do_change_view(er_view); /* Now go there */
1466 * \brief goto a private room
1468 void goto_private(void)
1472 const StrBuf *gr_name;
1475 if (!havebstr("ok_button")) {
1476 display_main_menu();
1479 gr_name = sbstr("gr_name");
1481 strcpy(hold_rm, ChrPtr(WC->CurRoom.name));
1482 serv_printf("GOTO %s|%s",
1485 StrBuf_ServGetln(Buf);
1486 if (GetServerStatus(Buf, &err) == 2) {
1488 smart_goto(gr_name);
1493 DoTemplate(HKEY("room_display_private"), NULL, &NoCtx);
1497 StrBufCutLeft(Buf, 4);
1498 AppendImportantMessage (SKEY(Buf));
1499 Buf = NewStrBufPlain(HKEY("_BASEROOM_"));
1513 StrBuf *final_destination;
1516 * If the forget-room routine fails for any reason, we fall back
1517 * to the current room; otherwise, we go to the Lobby
1519 final_destination = NewStrBufDup(WC->CurRoom.name);
1521 if (havebstr("ok_button")) {
1522 serv_printf("GOTO %s", ChrPtr(WC->CurRoom.name));
1523 serv_getln(buf, sizeof buf);
1524 if (buf[0] == '2') {
1526 serv_getln(buf, sizeof buf);
1527 if (buf[0] == '2') {
1528 FlushStrBuf(final_destination);
1529 StrBufAppendBufPlain(final_destination, HKEY("_BASEROOM_"), 0);
1534 smart_goto(final_destination);
1535 FreeStrBuf(&final_destination);
1541 * \brief Delete the current room
1543 void delete_room(void)
1548 serv_puts("KILL 1");
1549 serv_getln(buf, sizeof buf);
1551 if (buf[0] != '2') {
1552 strcpy(WC->ImportantMessage, &buf[4]);
1553 display_main_menu();
1559 Buf = NewStrBufPlain(HKEY("_BASEROOM_"));
1568 * \brief Perform changes to a room's network configuration
1570 void netedit(void) {
1579 /*/ TODO: do line dynamic! */
1580 if (havebstr("line_pop3host")) {
1581 strcpy(line, bstr("prefix"));
1582 strcat(line, bstr("line_pop3host"));
1584 strcat(line, bstr("line_pop3user"));
1586 strcat(line, bstr("line_pop3pass"));
1588 strcat(line, ibstr("line_pop3keep") ? "1" : "0" );
1590 sprintf(&line[strlen(line)],"%ld", lbstr("line_pop3int"));
1591 strcat(line, bstr("suffix"));
1593 else if (havebstr("line")) {
1594 strcpy(line, bstr("prefix"));
1595 strcat(line, bstr("line"));
1596 strcat(line, bstr("suffix"));
1599 http_transmit_thing(ChrPtr(do_template("room_edit", NULL)), 0);
1606 http_transmit_thing(ChrPtr(do_template("room_edit", NULL)), 0);
1611 serv_getln(buf, sizeof buf);
1612 if (buf[0] != '1') {
1614 http_transmit_thing(ChrPtr(do_template("room_edit", NULL)), 0);
1618 /** This loop works for add *or* remove. Spiffy, eh? */
1619 while (serv_getln(buf, sizeof buf), strcmp(buf, "000")) {
1620 extract_token(cmpa0, buf, 0, '|', sizeof cmpa0);
1621 extract_token(cmpa1, buf, 1, '|', sizeof cmpa1);
1622 extract_token(cmpb0, line, 0, '|', sizeof cmpb0);
1623 extract_token(cmpb1, line, 1, '|', sizeof cmpb1);
1624 if ( (strcasecmp(cmpa0, cmpb0))
1625 || (strcasecmp(cmpa1, cmpb1)) ) {
1626 fprintf(fp, "%s\n", buf);
1632 serv_getln(buf, sizeof buf);
1633 if (buf[0] != '4') {
1635 http_transmit_thing(ChrPtr(do_template("room_edit", NULL)), 0);
1639 while (fgets(buf, sizeof buf, fp) != NULL) {
1640 buf[strlen(buf)-1] = 0;
1644 if (havebstr("add_button")) {
1645 num_addrs = num_tokens(bstr("line"), ',');
1646 if (num_addrs < 2) {
1647 /* just adding one node or address */
1651 /* adding multiple addresses separated by commas */
1652 for (i=0; i<num_addrs; ++i) {
1653 strcpy(line, bstr("prefix"));
1654 extract_token(buf, bstr("line"), i, ',', sizeof buf);
1657 strcat(line, bstr("suffix"));
1665 http_transmit_thing(ChrPtr(do_template("room_edit", NULL)), 0);
1670 * \brief Back end for change_view()
1671 * \param newview set newview???
1673 void do_change_view(int newview) {
1676 serv_printf("VIEW %d", newview);
1677 serv_getln(buf, sizeof buf);
1678 WC->CurRoom.view = newview;
1679 smart_goto(WC->CurRoom.name);
1685 * \brief Change the view for this room
1687 void change_view(void) {
1690 view = lbstr("view");
1691 do_change_view(view);
1695 * \brief Do either a known rooms list or a folders list, depending on the
1700 StrBuf *ListView = NULL;
1702 /** Determine whether the user is trying to change views */
1703 if (havebstr("view")) {
1704 ListView = NewStrBufDup(SBSTR("view"));
1705 set_preference("roomlistview", ListView, 1);
1707 /** Sanitize the input so its safe */
1708 if((get_preference("roomlistview", &ListView) != 0)||
1709 ((strcasecmp(ChrPtr(ListView), "folders") != 0) &&
1710 (strcasecmp(ChrPtr(ListView), "table") != 0)))
1712 if (ListView == NULL) {
1713 ListView = NewStrBufPlain(HKEY("rooms"));
1714 set_preference("roomlistview", ListView, 0);
1718 ListView = NewStrBufPlain(HKEY("rooms"));
1719 set_preference("roomlistview", ListView, 0);
1723 FreeStrBuf(&ListView);
1730 * \brief Set the message expire policy for this room and/or floor
1732 void set_room_policy(void) {
1735 if (!havebstr("ok_button")) {
1736 strcpy(WC->ImportantMessage,
1737 _("Cancelled. Changes were not saved."));
1738 http_transmit_thing(ChrPtr(do_template("room_edit", NULL)), 0);
1742 serv_printf("SPEX roompolicy|%d|%d", ibstr("roompolicy"), ibstr("roomvalue"));
1743 serv_getln(buf, sizeof buf);
1744 strcpy(WC->ImportantMessage, &buf[4]);
1746 if (WC->axlevel >= 6) {
1747 strcat(WC->ImportantMessage, "<br />\n");
1748 serv_printf("SPEX floorpolicy|%d|%d", ibstr("floorpolicy"), ibstr("floorvalue"));
1749 serv_getln(buf, sizeof buf);
1750 strcat(WC->ImportantMessage, &buf[4]);
1752 ReloadCurrentRoom();
1753 http_transmit_thing(ChrPtr(do_template("room_edit", NULL)), 0);
1756 void tmplput_RoomName(StrBuf *Target, WCTemplputParams *TP)
1758 StrBufAppendTemplate(Target, TP, WC->CurRoom.name, 0);
1761 void dotgoto(void) {
1762 if (!havebstr("room")) {
1763 readloop(readnew, eUseDefault);
1766 if (WC->CurRoom.view != VIEW_MAILBOX) { /* dotgoto acts like dotskip when we're in a mailbox view */
1769 smart_goto(sbstr("room"));
1774 void tmplput_current_room(StrBuf *Target, WCTemplputParams *TP)
1776 wcsession *WCC = WC;
1779 StrBufAppendTemplate(Target, TP,
1784 void tmplput_roombanner(StrBuf *Target, WCTemplputParams *TP)
1786 wc_printf("<div id=\"banner\">\n");
1787 embed_room_banner();
1788 wc_printf("</div>\n");
1792 void tmplput_ungoto(StrBuf *Target, WCTemplputParams *TP)
1794 wcsession *WCC = WC;
1797 (!IsEmptyStr(WCC->ugname)))
1798 StrBufAppendBufPlain(Target, WCC->ugname, -1, 0);
1801 int ConditionalRoomAide(StrBuf *Target, WCTemplputParams *TP)
1803 wcsession *WCC = WC;
1804 return (WCC != NULL)?
1805 ((WCC->CurRoom.RAFlags & UA_ADMINALLOWED) != 0) : 0;
1808 int ConditionalRoomAcessDelete(StrBuf *Target, WCTemplputParams *TP)
1810 wcsession *WCC = WC;
1811 return (WCC == NULL)? 0 :
1812 ( ((WCC->CurRoom.RAFlags & UA_ADMINALLOWED) != 0) ||
1813 (WCC->CurRoom.is_inbox) ||
1814 (WCC->CurRoom.QRFlags2 & QR2_COLLABDEL) );
1817 int ConditionalHaveUngoto(StrBuf *Target, WCTemplputParams *TP)
1819 wcsession *WCC = WC;
1821 return ((WCC!=NULL) &&
1822 (!IsEmptyStr(WCC->ugname)) &&
1823 (strcasecmp(WCC->ugname, ChrPtr(WCC->CurRoom.name)) == 0));
1827 int ConditionalRoomHas_UAFlag(StrBuf *Target, WCTemplputParams *TP)
1829 folder *Folder = (folder *)(TP->Context);
1832 UA_CheckFlag = GetTemplateTokenNumber(Target, TP, 2, 0);
1833 if (UA_CheckFlag == 0)
1834 LogTemplateError(Target, "Conditional", ERR_PARM1, TP,
1835 "requires one of the #\"UA_*\"- defines or an integer flag 0 is invalid!");
1837 return ((Folder->RAFlags & UA_CheckFlag) != 0);
1842 int ConditionalCurrentRoomHas_QRFlag(StrBuf *Target, WCTemplputParams *TP)
1845 wcsession *WCC = WC;
1847 QR_CheckFlag = GetTemplateTokenNumber(Target, TP, 2, 0);
1848 if (QR_CheckFlag == 0)
1849 LogTemplateError(Target, "Conditional", ERR_PARM1, TP,
1850 "requires one of the #\"QR*\"- defines or an integer flag 0 is invalid!");
1855 if ((TP->Tokens->Params[2]->MaskBy == eOR) ||
1856 (TP->Tokens->Params[2]->MaskBy == eNO))
1857 return (WCC->CurRoom.QRFlags & QR_CheckFlag) != 0;
1859 return (WCC->CurRoom.QRFlags & QR_CheckFlag) == QR_CheckFlag;
1862 int ConditionalRoomHas_QRFlag(StrBuf *Target, WCTemplputParams *TP)
1865 folder *Folder = (folder *)(TP->Context);
1867 QR_CheckFlag = GetTemplateTokenNumber(Target, TP, 2, 0);
1868 if (QR_CheckFlag == 0)
1869 LogTemplateError(Target, "Conditional", ERR_PARM1, TP,
1870 "requires one of the #\"QR*\"- defines or an integer flag 0 is invalid!");
1872 if ((TP->Tokens->Params[2]->MaskBy == eOR) ||
1873 (TP->Tokens->Params[2]->MaskBy == eNO))
1874 return (Folder->QRFlags & QR_CheckFlag) != 0;
1876 return (Folder->QRFlags & QR_CheckFlag) == QR_CheckFlag;
1880 int ConditionalCurrentRoomHas_QRFlag2(StrBuf *Target, WCTemplputParams *TP)
1883 wcsession *WCC = WC;
1885 QR2_CheckFlag = GetTemplateTokenNumber(Target, TP, 2, 0);
1886 if (QR2_CheckFlag == 0)
1887 LogTemplateError(Target, "Conditional", ERR_PARM1, TP,
1888 "requires one of the #\"QR2*\"- defines or an integer flag 0 is invalid!");
1894 if ((TP->Tokens->Params[2]->MaskBy == eOR) ||
1895 (TP->Tokens->Params[2]->MaskBy == eNO))
1896 return (WCC->CurRoom.QRFlags2 & QR2_CheckFlag) != 0;
1898 return (WCC->CurRoom.QRFlags2 & QR2_CheckFlag) == QR2_CheckFlag;
1901 int ConditionalRoomHas_QRFlag2(StrBuf *Target, WCTemplputParams *TP)
1904 folder *Folder = (folder *)(TP->Context);
1906 QR2_CheckFlag = GetTemplateTokenNumber(Target, TP, 2, 0);
1907 if (QR2_CheckFlag == 0)
1908 LogTemplateError(Target, "Conditional", ERR_PARM1, TP,
1909 "requires one of the #\"QR2*\"- defines or an integer flag 0 is invalid!");
1910 return ((Folder->QRFlags2 & QR2_CheckFlag) != 0);
1914 int ConditionalHaveRoomeditRights(StrBuf *Target, WCTemplputParams *TP)
1916 wcsession *WCC = WC;
1918 return ( (WCC!= NULL) &&
1919 ((WCC->axlevel >= 6) ||
1920 ((WCC->CurRoom.RAFlags & UA_ADMINALLOWED) != 0) ||
1921 (WCC->CurRoom.is_inbox) ));
1924 int ConditionalIsRoomtype(StrBuf *Target, WCTemplputParams *TP)
1926 wcsession *WCC = WC;
1928 if ((WCC == NULL) ||
1929 (TP->Tokens->nParameters < 3))
1931 return ((WCC->CurRoom.view < VIEW_BBS) ||
1932 (WCC->CurRoom.view > VIEW_MAX));
1935 return WCC->CurRoom.view == GetTemplateTokenNumber(Target, TP, 2, VIEW_BBS);
1939 HashList *GetWhoKnowsHash(StrBuf *Target, WCTemplputParams *TP)
1941 wcsession *WCC = WC;
1945 HashList *Whok = NULL;
1951 StrBuf_ServGetln(Line);
1952 if (GetServerStatus(Line, &State) == 1)
1954 Whok = NewHash(1, Flathash);
1955 while(!Done && StrBuf_ServGetln(Line))
1956 if ( (StrLength(Line)==3) &&
1957 !strcmp(ChrPtr(Line), "000"))
1964 const char *Pos = NULL;
1965 Token = NewStrBufPlain (NULL, StrLength(Line));
1966 StrBufExtract_NextToken(Token, Line, &Pos, '|');
1975 else if (State == 550)
1976 StrBufAppendBufPlain(WCC->ImportantMsg,
1977 _("Higher access is required to access this function."), -1, 0);
1986 void _FlushRoomList(wcsession *WCC)
1988 free_march_list(WCC);
1989 DeleteHash(&WCC->Floors);
1990 DeleteHash(&WCC->Rooms);
1991 DeleteHash(&WCC->FloorsByName);
1992 FlushFolder(&WCC->CurRoom);
1995 void ReloadCurrentRoom(void)
1997 wcsession *WCC = WC;
2000 CurRoom = WCC->CurRoom.name;
2001 WCC->CurRoom.name = NULL;
2002 _FlushRoomList(WCC);
2004 FreeStrBuf(&CurRoom);
2007 void FlushRoomlist(void)
2009 wcsession *WCC = WC;
2010 _FlushRoomList(WCC);
2018 initialize_viewdefs();
2019 RegisterPreference("roomlistview",
2020 _("Room list view"),
2023 RegisterPreference("emptyfloors", _("Show empty floors"), PRF_YESNO, NULL);
2025 RegisterNamespace("ROOMNAME", 0, 1, tmplput_RoomName, NULL, CTX_NONE);
2028 WebcitAddUrlHandler(HKEY("knrooms"), "", 0, knrooms, 0);
2029 WebcitAddUrlHandler(HKEY("dotgoto"), "", 0, dotgoto, NEED_URL);
2030 WebcitAddUrlHandler(HKEY("dotskip"), "", 0, dotskip, NEED_URL);
2032 WebcitAddUrlHandler(HKEY("goto_private"), "", 0, goto_private, NEED_URL);
2033 WebcitAddUrlHandler(HKEY("zap"), "", 0, zap, 0);
2034 WebcitAddUrlHandler(HKEY("entroom"), "", 0, entroom, 0);
2035 WebcitAddUrlHandler(HKEY("do_invt_kick"), "", 0, do_invt_kick, 0);
2037 WebcitAddUrlHandler(HKEY("netedit"), "", 0, netedit, 0);
2038 WebcitAddUrlHandler(HKEY("editroom"), "", 0, editroom, 0);
2039 WebcitAddUrlHandler(HKEY("delete_room"), "", 0, delete_room, 0);
2040 WebcitAddUrlHandler(HKEY("set_room_policy"), "", 0, set_room_policy, 0);
2041 WebcitAddUrlHandler(HKEY("changeview"), "", 0, change_view, 0);
2042 WebcitAddUrlHandler(HKEY("toggle_self_service"), "", 0, toggle_self_service, 0);
2043 RegisterNamespace("ROOMBANNER", 0, 1, tmplput_roombanner, NULL, CTX_NONE);
2045 RegisterConditional(HKEY("COND:ROOM:TYPE_IS"), 0, ConditionalIsRoomtype, CTX_NONE);
2046 RegisterConditional(HKEY("COND:THISROOM:FLAG:QR"), 0, ConditionalCurrentRoomHas_QRFlag, CTX_NONE);
2047 RegisterConditional(HKEY("COND:ROOM:FLAG:QR"), 0, ConditionalRoomHas_QRFlag, CTX_ROOMS);
2049 RegisterConditional(HKEY("COND:THISROOM:FLAG:QR2"), 0, ConditionalCurrentRoomHas_QRFlag2, CTX_NONE);
2050 RegisterConditional(HKEY("COND:ROOM:FLAG:QR2"), 0, ConditionalRoomHas_QRFlag2, CTX_ROOMS);
2051 RegisterConditional(HKEY("COND:ROOM:FLAG:UA"), 0, ConditionalRoomHas_UAFlag, CTX_ROOMS);
2053 RegisterIterator("ITERATE:THISROOM:WHO_KNOWS", 0, NULL, GetWhoKnowsHash, NULL, DeleteHash, CTX_STRBUF, CTX_NONE, IT_NOFLAG);
2054 RegisterNamespace("THISROOM:MSGS:NEW", 0, 0, tmplput_CurrentRoom_nNewMessages, NULL, CTX_NONE);
2055 RegisterNamespace("THISROOM:MSGS:TOTAL", 0, 0, tmplput_CurrentRoom_nTotalMessages, NULL, CTX_NONE);
2057 RegisterNamespace("THISROOM:FLOOR:NAME", 0, 1, tmplput_CurrentRoomFloorName, NULL, CTX_NONE);
2058 RegisterNamespace("THISROOM:AIDE", 0, 1, tmplput_CurrentRoomAide, NULL, CTX_NONE);
2059 RegisterNamespace("THISROOM:PASS", 0, 1, tmplput_CurrentRoomPass, NULL, CTX_NONE);
2060 RegisterNamespace("THISROOM:DIRECTORY", 0, 1, tmplput_CurrentRoomDirectory, NULL, CTX_NONE);
2061 RegisterNamespace("THISROOM:ORDER", 0, 0, tmplput_CurrentRoomOrder, NULL, CTX_NONE);
2062 RegisterNamespace("THISROOM:DEFAULT_VIEW", 0, 0, tmplput_CurrentRoomDefView, NULL, CTX_NONE);
2063 RegisterConditional(HKEY("COND:THISROOM:HAVE_VIEW"), 0, ConditionalThisRoomHaveView, CTX_NONE);
2064 RegisterConditional(HKEY("COND:ALLOWED_DEFAULT_VIEW"), 0, ConditionalIsAllowedDefaultView, CTX_NONE);
2066 RegisterNamespace("THISROOM:VIEW_STRING", 0, 1, tmplput_CurrentRoomViewString, NULL, CTX_NONE);
2067 RegisterNamespace("ROOM:VIEW_STRING", 1, 2, tmplput_RoomViewString, NULL, CTX_NONE);
2069 RegisterNamespace("THISROOM:INFOTEXT", 1, 2, tmplput_CurrentRoomInfoText, NULL, CTX_NONE);
2070 RegisterConditional(HKEY("COND:THISROOM:ORDER"), 0, ConditionalThisRoomOrder, CTX_NONE);
2071 RegisterConditional(HKEY("COND:THISROOM:DEFAULT_VIEW"), 0, ConditionalThisRoomDefView, CTX_NONE);
2072 RegisterConditional(HKEY("COND:THISROOM:CURR_VIEW"), 0, ConditionalThisRoomCurrView, CTX_NONE);
2073 RegisterConditional(HKEY("COND:THISROOM:HAVE_PIC"), 0, ConditionalThisRoomXHavePic, CTX_NONE);
2074 RegisterConditional(HKEY("COND:THISROOM:HAVE_INFOTEXT"), 0, ConditionalThisRoomXHaveInfoText, CTX_NONE);
2075 RegisterNamespace("THISROOM:FILES:N", 0, 1, tmplput_CurrentRoomXNFiles, NULL, CTX_NONE);
2076 RegisterNamespace("THISROOM:FILES:STR", 0, 1, tmplput_CurrentRoomX_FileString, NULL, CTX_NONE);
2078 REGISTERTokenParamDefine(QR_PERMANENT);
2079 REGISTERTokenParamDefine(QR_INUSE);
2080 REGISTERTokenParamDefine(QR_PRIVATE);
2081 REGISTERTokenParamDefine(QR_PASSWORDED);
2082 REGISTERTokenParamDefine(QR_GUESSNAME);
2083 REGISTERTokenParamDefine(QR_DIRECTORY);
2084 REGISTERTokenParamDefine(QR_UPLOAD);
2085 REGISTERTokenParamDefine(QR_DOWNLOAD);
2086 REGISTERTokenParamDefine(QR_VISDIR);
2087 REGISTERTokenParamDefine(QR_ANONONLY);
2088 REGISTERTokenParamDefine(QR_ANONOPT);
2089 REGISTERTokenParamDefine(QR_NETWORK);
2090 REGISTERTokenParamDefine(QR_PREFONLY);
2091 REGISTERTokenParamDefine(QR_READONLY);
2092 REGISTERTokenParamDefine(QR_MAILBOX);
2093 REGISTERTokenParamDefine(QR2_SYSTEM);
2094 REGISTERTokenParamDefine(QR2_SELFLIST);
2095 REGISTERTokenParamDefine(QR2_COLLABDEL);
2096 REGISTERTokenParamDefine(QR2_SUBJECTREQ);
2097 REGISTERTokenParamDefine(QR2_SMTP_PUBLIC);
2098 REGISTERTokenParamDefine(QR2_MODERATED);
2100 REGISTERTokenParamDefine(UA_KNOWN);
2101 REGISTERTokenParamDefine(UA_GOTOALLOWED);
2102 REGISTERTokenParamDefine(UA_HASNEWMSGS);
2103 REGISTERTokenParamDefine(UA_ZAPPED);
2104 REGISTERTokenParamDefine(UA_POSTALLOWED);
2105 REGISTERTokenParamDefine(UA_ADMINALLOWED);
2106 REGISTERTokenParamDefine(UA_DELETEALLOWED);
2107 REGISTERTokenParamDefine(UA_ISTRASH);
2109 REGISTERTokenParamDefine(US_NEEDVALID);
2110 REGISTERTokenParamDefine(US_PERM);
2111 REGISTERTokenParamDefine(US_LASTOLD);
2112 REGISTERTokenParamDefine(US_EXPERT);
2113 REGISTERTokenParamDefine(US_UNLISTED);
2114 REGISTERTokenParamDefine(US_NOPROMPT);
2115 REGISTERTokenParamDefine(US_PROMPTCTL);
2116 REGISTERTokenParamDefine(US_DISAPPEAR);
2117 REGISTERTokenParamDefine(US_REGIS);
2118 REGISTERTokenParamDefine(US_PAGINATOR);
2119 REGISTERTokenParamDefine(US_INTERNET);
2120 REGISTERTokenParamDefine(US_FLOORS);
2121 REGISTERTokenParamDefine(US_COLOR);
2122 REGISTERTokenParamDefine(US_USER_SET);
2124 REGISTERTokenParamDefine(VIEW_BBS);
2125 REGISTERTokenParamDefine(VIEW_MAILBOX);
2126 REGISTERTokenParamDefine(VIEW_ADDRESSBOOK);
2127 REGISTERTokenParamDefine(VIEW_CALENDAR);
2128 REGISTERTokenParamDefine(VIEW_TASKS);
2129 REGISTERTokenParamDefine(VIEW_NOTES);
2130 REGISTERTokenParamDefine(VIEW_WIKI);
2131 REGISTERTokenParamDefine(VIEW_CALBRIEF);
2132 REGISTERTokenParamDefine(VIEW_JOURNAL);
2133 REGISTERTokenParamDefine(VIEW_BLOG);
2136 REGISTERTokenParamDefine(ignet_push_share);
2137 { /* these are the parts of an IGNET push config */
2138 REGISTERTokenParamDefine(GNET_IGNET_NODE);
2139 REGISTERTokenParamDefine(GNET_IGNET_ROOM);
2141 REGISTERTokenParamDefine(listrecp);
2142 REGISTERTokenParamDefine(digestrecp);
2143 REGISTERTokenParamDefine(pop3client);
2144 { /* These are the parts of a pop3 client line... */
2145 REGISTERTokenParamDefine(GNET_POP3_HOST);
2146 REGISTERTokenParamDefine(GNET_POP3_USER);
2147 REGISTERTokenParamDefine(GNET_POP3_DONT_DELETE_REMOTE);
2148 REGISTERTokenParamDefine(GNET_POP3_INTERVAL);
2150 REGISTERTokenParamDefine(rssclient);
2151 REGISTERTokenParamDefine(participate);
2153 RegisterConditional(HKEY("COND:ROOMAIDE"), 2, ConditionalRoomAide, CTX_NONE);
2154 RegisterConditional(HKEY("COND:ACCESS:DELETE"), 2, ConditionalRoomAcessDelete, CTX_NONE);
2156 RegisterConditional(HKEY("COND:UNGOTO"), 0, ConditionalHaveUngoto, CTX_NONE);
2157 RegisterConditional(HKEY("COND:ROOM:EDITACCESS"), 0, ConditionalHaveRoomeditRights, CTX_NONE);
2159 RegisterNamespace("CURRENT_ROOM", 0, 1, tmplput_current_room, NULL, CTX_NONE);
2160 RegisterNamespace("ROOM:UNGOTO", 0, 0, tmplput_ungoto, NULL, CTX_NONE);
2161 RegisterIterator("FLOORS", 0, NULL, GetFloorListHash, NULL, NULL, CTX_FLOORS, CTX_NONE, IT_NOFLAG);
2168 SessionDestroyModule_ROOMOPS
2171 _FlushRoomList (sess);