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 FlushIgnetCfgs(&WC->CurRoom);
1667 http_transmit_thing(ChrPtr(do_template("room_edit", NULL)), 0);
1671 * delete the actual floor
1673 void delete_floor(void) {
1678 floornum = ibstr("floornum");
1680 serv_printf("KFLR %d|1", floornum);
1682 StrBufTCP_read_line(Buf, &WC->serv_sock, 0, &Err);
1684 if (GetServerStatus(Buf, NULL) == 2) {
1685 StrBufPlain(Buf, _("Floor has been deleted."),-1);
1688 StrBufCutLeft(Buf, 4);
1690 AppendImportantMessage (SKEY(Buf));
1693 http_transmit_thing(ChrPtr(do_template("floors", NULL)), 0);
1698 * start creating a new floor
1700 void create_floor(void) {
1705 serv_printf("CFLR %s|1", bstr("floorname"));
1706 StrBufTCP_read_line(Buf, &WC->serv_sock, 0, &Err);
1708 if (GetServerStatus(Buf, NULL) == 2) {
1709 StrBufPlain(Buf, _("New floor has been created."),-1);
1712 StrBufCutLeft(Buf, 4);
1714 AppendImportantMessage (SKEY(Buf));
1716 http_transmit_thing(ChrPtr(do_template("floors", NULL)), 0);
1724 void rename_floor(void) {
1730 serv_printf("EFLR %d|%s", ibstr("floornum"), bstr("floorname"));
1731 StrBuf_ServGetln(Buf);
1733 StrBufCutLeft(Buf, 4);
1734 AppendImportantMessage (SKEY(Buf));
1736 http_transmit_thing(ChrPtr(do_template("floors", NULL)), 0);
1743 * \brief Back end for change_view()
1744 * \param newview set newview???
1746 void do_change_view(int newview) {
1749 serv_printf("VIEW %d", newview);
1750 serv_getln(buf, sizeof buf);
1751 WC->CurRoom.view = newview;
1752 smart_goto(WC->CurRoom.name);
1758 * \brief Change the view for this room
1760 void change_view(void) {
1763 view = lbstr("view");
1764 do_change_view(view);
1768 * \brief Do either a known rooms list or a folders list, depending on the
1773 StrBuf *ListView = NULL;
1775 /** Determine whether the user is trying to change views */
1776 if (havebstr("view")) {
1777 ListView = NewStrBufDup(SBSTR("view"));
1778 set_preference("roomlistview", ListView, 1);
1780 /** Sanitize the input so its safe */
1781 if((get_preference("roomlistview", &ListView) != 0)||
1782 ((strcasecmp(ChrPtr(ListView), "folders") != 0) &&
1783 (strcasecmp(ChrPtr(ListView), "table") != 0)))
1785 if (ListView == NULL) {
1786 ListView = NewStrBufPlain(HKEY("rooms"));
1787 set_preference("roomlistview", ListView, 0);
1791 ListView = NewStrBufPlain(HKEY("rooms"));
1792 set_preference("roomlistview", ListView, 0);
1796 FreeStrBuf(&ListView);
1803 * \brief Set the message expire policy for this room and/or floor
1805 void set_room_policy(void) {
1808 if (!havebstr("ok_button")) {
1809 strcpy(WC->ImportantMessage,
1810 _("Cancelled. Changes were not saved."));
1811 http_transmit_thing(ChrPtr(do_template("room_edit", NULL)), 0);
1815 serv_printf("SPEX roompolicy|%d|%d", ibstr("roompolicy"), ibstr("roomvalue"));
1816 serv_getln(buf, sizeof buf);
1817 strcpy(WC->ImportantMessage, &buf[4]);
1819 if (WC->axlevel >= 6) {
1820 strcat(WC->ImportantMessage, "<br />\n");
1821 serv_printf("SPEX floorpolicy|%d|%d", ibstr("floorpolicy"), ibstr("floorvalue"));
1822 serv_getln(buf, sizeof buf);
1823 strcat(WC->ImportantMessage, &buf[4]);
1825 ReloadCurrentRoom();
1826 http_transmit_thing(ChrPtr(do_template("room_edit", NULL)), 0);
1829 void tmplput_RoomName(StrBuf *Target, WCTemplputParams *TP)
1831 StrBufAppendTemplate(Target, TP, WC->CurRoom.name, 0);
1834 void dotgoto(void) {
1835 if (!havebstr("room")) {
1836 readloop(readnew, eUseDefault);
1839 if (WC->CurRoom.view != VIEW_MAILBOX) { /* dotgoto acts like dotskip when we're in a mailbox view */
1842 smart_goto(sbstr("room"));
1847 void tmplput_current_room(StrBuf *Target, WCTemplputParams *TP)
1849 wcsession *WCC = WC;
1852 StrBufAppendTemplate(Target, TP,
1857 void tmplput_roombanner(StrBuf *Target, WCTemplputParams *TP)
1859 wc_printf("<div id=\"banner\">\n");
1860 embed_room_banner();
1861 wc_printf("</div>\n");
1865 void tmplput_ungoto(StrBuf *Target, WCTemplputParams *TP)
1867 wcsession *WCC = WC;
1870 (!IsEmptyStr(WCC->ugname)))
1871 StrBufAppendBufPlain(Target, WCC->ugname, -1, 0);
1874 int ConditionalRoomAide(StrBuf *Target, WCTemplputParams *TP)
1876 wcsession *WCC = WC;
1877 return (WCC != NULL)?
1878 ((WCC->CurRoom.RAFlags & UA_ADMINALLOWED) != 0) : 0;
1881 int ConditionalRoomAcessDelete(StrBuf *Target, WCTemplputParams *TP)
1883 wcsession *WCC = WC;
1884 return (WCC == NULL)? 0 :
1885 ( ((WCC->CurRoom.RAFlags & UA_ADMINALLOWED) != 0) ||
1886 (WCC->CurRoom.is_inbox) ||
1887 (WCC->CurRoom.QRFlags2 & QR2_COLLABDEL) );
1890 int ConditionalHaveUngoto(StrBuf *Target, WCTemplputParams *TP)
1892 wcsession *WCC = WC;
1894 return ((WCC!=NULL) &&
1895 (!IsEmptyStr(WCC->ugname)) &&
1896 (strcasecmp(WCC->ugname, ChrPtr(WCC->CurRoom.name)) == 0));
1900 int ConditionalRoomHas_UAFlag(StrBuf *Target, WCTemplputParams *TP)
1902 folder *Folder = (folder *)(TP->Context);
1905 UA_CheckFlag = GetTemplateTokenNumber(Target, TP, 2, 0);
1906 if (UA_CheckFlag == 0)
1907 LogTemplateError(Target, "Conditional", ERR_PARM1, TP,
1908 "requires one of the #\"UA_*\"- defines or an integer flag 0 is invalid!");
1910 return ((Folder->RAFlags & UA_CheckFlag) != 0);
1915 int ConditionalCurrentRoomHas_QRFlag(StrBuf *Target, WCTemplputParams *TP)
1918 wcsession *WCC = WC;
1920 QR_CheckFlag = GetTemplateTokenNumber(Target, TP, 2, 0);
1921 if (QR_CheckFlag == 0)
1922 LogTemplateError(Target, "Conditional", ERR_PARM1, TP,
1923 "requires one of the #\"QR*\"- defines or an integer flag 0 is invalid!");
1928 if ((TP->Tokens->Params[2]->MaskBy == eOR) ||
1929 (TP->Tokens->Params[2]->MaskBy == eNO))
1930 return (WCC->CurRoom.QRFlags & QR_CheckFlag) != 0;
1932 return (WCC->CurRoom.QRFlags & QR_CheckFlag) == QR_CheckFlag;
1935 int ConditionalRoomHas_QRFlag(StrBuf *Target, WCTemplputParams *TP)
1938 folder *Folder = (folder *)(TP->Context);
1940 QR_CheckFlag = GetTemplateTokenNumber(Target, TP, 2, 0);
1941 if (QR_CheckFlag == 0)
1942 LogTemplateError(Target, "Conditional", ERR_PARM1, TP,
1943 "requires one of the #\"QR*\"- defines or an integer flag 0 is invalid!");
1945 if ((TP->Tokens->Params[2]->MaskBy == eOR) ||
1946 (TP->Tokens->Params[2]->MaskBy == eNO))
1947 return (Folder->QRFlags & QR_CheckFlag) != 0;
1949 return (Folder->QRFlags & QR_CheckFlag) == QR_CheckFlag;
1953 int ConditionalCurrentRoomHas_QRFlag2(StrBuf *Target, WCTemplputParams *TP)
1956 wcsession *WCC = WC;
1958 QR2_CheckFlag = GetTemplateTokenNumber(Target, TP, 2, 0);
1959 if (QR2_CheckFlag == 0)
1960 LogTemplateError(Target, "Conditional", ERR_PARM1, TP,
1961 "requires one of the #\"QR2*\"- defines or an integer flag 0 is invalid!");
1967 if ((TP->Tokens->Params[2]->MaskBy == eOR) ||
1968 (TP->Tokens->Params[2]->MaskBy == eNO))
1969 return (WCC->CurRoom.QRFlags2 & QR2_CheckFlag) != 0;
1971 return (WCC->CurRoom.QRFlags2 & QR2_CheckFlag) == QR2_CheckFlag;
1974 int ConditionalRoomHas_QRFlag2(StrBuf *Target, WCTemplputParams *TP)
1977 folder *Folder = (folder *)(TP->Context);
1979 QR2_CheckFlag = GetTemplateTokenNumber(Target, TP, 2, 0);
1980 if (QR2_CheckFlag == 0)
1981 LogTemplateError(Target, "Conditional", ERR_PARM1, TP,
1982 "requires one of the #\"QR2*\"- defines or an integer flag 0 is invalid!");
1983 return ((Folder->QRFlags2 & QR2_CheckFlag) != 0);
1987 int ConditionalHaveRoomeditRights(StrBuf *Target, WCTemplputParams *TP)
1989 wcsession *WCC = WC;
1991 return ( (WCC!= NULL) &&
1992 ((WCC->axlevel >= 6) ||
1993 ((WCC->CurRoom.RAFlags & UA_ADMINALLOWED) != 0) ||
1994 (WCC->CurRoom.is_inbox) ));
1997 int ConditionalIsRoomtype(StrBuf *Target, WCTemplputParams *TP)
1999 wcsession *WCC = WC;
2001 if ((WCC == NULL) ||
2002 (TP->Tokens->nParameters < 3))
2004 return ((WCC->CurRoom.view < VIEW_BBS) ||
2005 (WCC->CurRoom.view > VIEW_MAX));
2008 return WCC->CurRoom.view == GetTemplateTokenNumber(Target, TP, 2, VIEW_BBS);
2012 HashList *GetWhoKnowsHash(StrBuf *Target, WCTemplputParams *TP)
2014 wcsession *WCC = WC;
2018 HashList *Whok = NULL;
2024 StrBuf_ServGetln(Line);
2025 if (GetServerStatus(Line, &State) == 1)
2027 Whok = NewHash(1, Flathash);
2028 while(!Done && StrBuf_ServGetln(Line))
2029 if ( (StrLength(Line)==3) &&
2030 !strcmp(ChrPtr(Line), "000"))
2037 const char *Pos = NULL;
2038 Token = NewStrBufPlain (NULL, StrLength(Line));
2039 StrBufExtract_NextToken(Token, Line, &Pos, '|');
2048 else if (State == 550)
2049 StrBufAppendBufPlain(WCC->ImportantMsg,
2050 _("Higher access is required to access this function."), -1, 0);
2059 void _FlushRoomList(wcsession *WCC)
2061 free_march_list(WCC);
2062 DeleteHash(&WCC->Floors);
2063 DeleteHash(&WCC->Rooms);
2064 DeleteHash(&WCC->FloorsByName);
2065 FlushFolder(&WCC->CurRoom);
2068 void ReloadCurrentRoom(void)
2070 wcsession *WCC = WC;
2073 CurRoom = WCC->CurRoom.name;
2074 WCC->CurRoom.name = NULL;
2075 _FlushRoomList(WCC);
2077 FreeStrBuf(&CurRoom);
2080 void FlushRoomlist(void)
2082 wcsession *WCC = WC;
2083 _FlushRoomList(WCC);
2091 initialize_viewdefs();
2092 RegisterPreference("roomlistview",
2093 _("Room list view"),
2096 RegisterPreference("emptyfloors", _("Show empty floors"), PRF_YESNO, NULL);
2098 RegisterNamespace("ROOMNAME", 0, 1, tmplput_RoomName, NULL, CTX_NONE);
2101 WebcitAddUrlHandler(HKEY("delete_floor"), "", 0, delete_floor, 0);
2102 WebcitAddUrlHandler(HKEY("rename_floor"), "", 0, rename_floor, 0);
2103 WebcitAddUrlHandler(HKEY("create_floor"), "", 0, create_floor, 0);
2105 WebcitAddUrlHandler(HKEY("knrooms"), "", 0, knrooms, 0);
2106 WebcitAddUrlHandler(HKEY("dotgoto"), "", 0, dotgoto, NEED_URL);
2107 WebcitAddUrlHandler(HKEY("dotskip"), "", 0, dotskip, NEED_URL);
2109 WebcitAddUrlHandler(HKEY("goto_private"), "", 0, goto_private, NEED_URL);
2110 WebcitAddUrlHandler(HKEY("zap"), "", 0, zap, 0);
2111 WebcitAddUrlHandler(HKEY("entroom"), "", 0, entroom, 0);
2112 WebcitAddUrlHandler(HKEY("do_invt_kick"), "", 0, do_invt_kick, 0);
2114 WebcitAddUrlHandler(HKEY("netedit"), "", 0, netedit, 0);
2115 WebcitAddUrlHandler(HKEY("editroom"), "", 0, editroom, 0);
2116 WebcitAddUrlHandler(HKEY("delete_room"), "", 0, delete_room, 0);
2117 WebcitAddUrlHandler(HKEY("set_room_policy"), "", 0, set_room_policy, 0);
2118 WebcitAddUrlHandler(HKEY("changeview"), "", 0, change_view, 0);
2119 WebcitAddUrlHandler(HKEY("toggle_self_service"), "", 0, toggle_self_service, 0);
2120 RegisterNamespace("ROOMBANNER", 0, 1, tmplput_roombanner, NULL, CTX_NONE);
2122 RegisterConditional(HKEY("COND:ROOM:TYPE_IS"), 0, ConditionalIsRoomtype, CTX_NONE);
2123 RegisterConditional(HKEY("COND:THISROOM:FLAG:QR"), 0, ConditionalCurrentRoomHas_QRFlag, CTX_NONE);
2124 RegisterConditional(HKEY("COND:ROOM:FLAG:QR"), 0, ConditionalRoomHas_QRFlag, CTX_ROOMS);
2126 RegisterConditional(HKEY("COND:THISROOM:FLAG:QR2"), 0, ConditionalCurrentRoomHas_QRFlag2, CTX_NONE);
2127 RegisterConditional(HKEY("COND:ROOM:FLAG:QR2"), 0, ConditionalRoomHas_QRFlag2, CTX_ROOMS);
2128 RegisterConditional(HKEY("COND:ROOM:FLAG:UA"), 0, ConditionalRoomHas_UAFlag, CTX_ROOMS);
2130 RegisterIterator("ITERATE:THISROOM:WHO_KNOWS", 0, NULL, GetWhoKnowsHash, NULL, DeleteHash, CTX_STRBUF, CTX_NONE, IT_NOFLAG);
2131 RegisterNamespace("THISROOM:MSGS:NEW", 0, 0, tmplput_CurrentRoom_nNewMessages, NULL, CTX_NONE);
2132 RegisterNamespace("THISROOM:MSGS:TOTAL", 0, 0, tmplput_CurrentRoom_nTotalMessages, NULL, CTX_NONE);
2134 RegisterNamespace("THISROOM:FLOOR:NAME", 0, 1, tmplput_CurrentRoomFloorName, NULL, CTX_NONE);
2135 RegisterNamespace("THISROOM:AIDE", 0, 1, tmplput_CurrentRoomAide, NULL, CTX_NONE);
2136 RegisterNamespace("THISROOM:PASS", 0, 1, tmplput_CurrentRoomPass, NULL, CTX_NONE);
2137 RegisterNamespace("THISROOM:DIRECTORY", 0, 1, tmplput_CurrentRoomDirectory, NULL, CTX_NONE);
2138 RegisterNamespace("THISROOM:ORDER", 0, 0, tmplput_CurrentRoomOrder, NULL, CTX_NONE);
2139 RegisterNamespace("THISROOM:DEFAULT_VIEW", 0, 0, tmplput_CurrentRoomDefView, NULL, CTX_NONE);
2140 RegisterConditional(HKEY("COND:THISROOM:HAVE_VIEW"), 0, ConditionalThisRoomHaveView, CTX_NONE);
2141 RegisterConditional(HKEY("COND:ALLOWED_DEFAULT_VIEW"), 0, ConditionalIsAllowedDefaultView, CTX_NONE);
2143 RegisterNamespace("THISROOM:VIEW_STRING", 0, 1, tmplput_CurrentRoomViewString, NULL, CTX_NONE);
2144 RegisterNamespace("ROOM:VIEW_STRING", 1, 2, tmplput_RoomViewString, NULL, CTX_NONE);
2146 RegisterNamespace("THISROOM:INFOTEXT", 1, 2, tmplput_CurrentRoomInfoText, NULL, CTX_NONE);
2147 RegisterConditional(HKEY("COND:THISROOM:ORDER"), 0, ConditionalThisRoomOrder, CTX_NONE);
2148 RegisterConditional(HKEY("COND:THISROOM:DEFAULT_VIEW"), 0, ConditionalThisRoomDefView, CTX_NONE);
2149 RegisterConditional(HKEY("COND:THISROOM:CURR_VIEW"), 0, ConditionalThisRoomCurrView, CTX_NONE);
2150 RegisterConditional(HKEY("COND:THISROOM:HAVE_PIC"), 0, ConditionalThisRoomXHavePic, CTX_NONE);
2151 RegisterConditional(HKEY("COND:THISROOM:HAVE_INFOTEXT"), 0, ConditionalThisRoomXHaveInfoText, CTX_NONE);
2152 RegisterNamespace("THISROOM:FILES:N", 0, 1, tmplput_CurrentRoomXNFiles, NULL, CTX_NONE);
2153 RegisterNamespace("THISROOM:FILES:STR", 0, 1, tmplput_CurrentRoomX_FileString, NULL, CTX_NONE);
2155 REGISTERTokenParamDefine(QR_PERMANENT);
2156 REGISTERTokenParamDefine(QR_INUSE);
2157 REGISTERTokenParamDefine(QR_PRIVATE);
2158 REGISTERTokenParamDefine(QR_PASSWORDED);
2159 REGISTERTokenParamDefine(QR_GUESSNAME);
2160 REGISTERTokenParamDefine(QR_DIRECTORY);
2161 REGISTERTokenParamDefine(QR_UPLOAD);
2162 REGISTERTokenParamDefine(QR_DOWNLOAD);
2163 REGISTERTokenParamDefine(QR_VISDIR);
2164 REGISTERTokenParamDefine(QR_ANONONLY);
2165 REGISTERTokenParamDefine(QR_ANONOPT);
2166 REGISTERTokenParamDefine(QR_NETWORK);
2167 REGISTERTokenParamDefine(QR_PREFONLY);
2168 REGISTERTokenParamDefine(QR_READONLY);
2169 REGISTERTokenParamDefine(QR_MAILBOX);
2170 REGISTERTokenParamDefine(QR2_SYSTEM);
2171 REGISTERTokenParamDefine(QR2_SELFLIST);
2172 REGISTERTokenParamDefine(QR2_COLLABDEL);
2173 REGISTERTokenParamDefine(QR2_SUBJECTREQ);
2174 REGISTERTokenParamDefine(QR2_SMTP_PUBLIC);
2175 REGISTERTokenParamDefine(QR2_MODERATED);
2177 REGISTERTokenParamDefine(UA_KNOWN);
2178 REGISTERTokenParamDefine(UA_GOTOALLOWED);
2179 REGISTERTokenParamDefine(UA_HASNEWMSGS);
2180 REGISTERTokenParamDefine(UA_ZAPPED);
2181 REGISTERTokenParamDefine(UA_POSTALLOWED);
2182 REGISTERTokenParamDefine(UA_ADMINALLOWED);
2183 REGISTERTokenParamDefine(UA_DELETEALLOWED);
2184 REGISTERTokenParamDefine(UA_ISTRASH);
2186 REGISTERTokenParamDefine(US_NEEDVALID);
2187 REGISTERTokenParamDefine(US_PERM);
2188 REGISTERTokenParamDefine(US_LASTOLD);
2189 REGISTERTokenParamDefine(US_EXPERT);
2190 REGISTERTokenParamDefine(US_UNLISTED);
2191 REGISTERTokenParamDefine(US_NOPROMPT);
2192 REGISTERTokenParamDefine(US_PROMPTCTL);
2193 REGISTERTokenParamDefine(US_DISAPPEAR);
2194 REGISTERTokenParamDefine(US_REGIS);
2195 REGISTERTokenParamDefine(US_PAGINATOR);
2196 REGISTERTokenParamDefine(US_INTERNET);
2197 REGISTERTokenParamDefine(US_FLOORS);
2198 REGISTERTokenParamDefine(US_COLOR);
2199 REGISTERTokenParamDefine(US_USER_SET);
2201 REGISTERTokenParamDefine(VIEW_BBS);
2202 REGISTERTokenParamDefine(VIEW_MAILBOX);
2203 REGISTERTokenParamDefine(VIEW_ADDRESSBOOK);
2204 REGISTERTokenParamDefine(VIEW_CALENDAR);
2205 REGISTERTokenParamDefine(VIEW_TASKS);
2206 REGISTERTokenParamDefine(VIEW_NOTES);
2207 REGISTERTokenParamDefine(VIEW_WIKI);
2208 REGISTERTokenParamDefine(VIEW_CALBRIEF);
2209 REGISTERTokenParamDefine(VIEW_JOURNAL);
2210 REGISTERTokenParamDefine(VIEW_BLOG);
2213 /* server internal, we need to know but ignore them. */
2214 REGISTERTokenParamDefine(subpending);
2215 REGISTERTokenParamDefine(unsubpending);
2216 REGISTERTokenParamDefine(lastsent);
2218 REGISTERTokenParamDefine(ignet_push_share);
2219 { /* these are the parts of an IGNET push config */
2220 REGISTERTokenParamDefine(GNET_IGNET_NODE);
2221 REGISTERTokenParamDefine(GNET_IGNET_ROOM);
2223 REGISTERTokenParamDefine(listrecp);
2224 REGISTERTokenParamDefine(digestrecp);
2225 REGISTERTokenParamDefine(pop3client);
2226 { /* These are the parts of a pop3 client line... */
2227 REGISTERTokenParamDefine(GNET_POP3_HOST);
2228 REGISTERTokenParamDefine(GNET_POP3_USER);
2229 REGISTERTokenParamDefine(GNET_POP3_DONT_DELETE_REMOTE);
2230 REGISTERTokenParamDefine(GNET_POP3_INTERVAL);
2232 REGISTERTokenParamDefine(rssclient);
2233 REGISTERTokenParamDefine(participate);
2235 RegisterConditional(HKEY("COND:ROOMAIDE"), 2, ConditionalRoomAide, CTX_NONE);
2236 RegisterConditional(HKEY("COND:ACCESS:DELETE"), 2, ConditionalRoomAcessDelete, CTX_NONE);
2238 RegisterConditional(HKEY("COND:UNGOTO"), 0, ConditionalHaveUngoto, CTX_NONE);
2239 RegisterConditional(HKEY("COND:ROOM:EDITACCESS"), 0, ConditionalHaveRoomeditRights, CTX_NONE);
2241 RegisterNamespace("CURRENT_ROOM", 0, 1, tmplput_current_room, NULL, CTX_NONE);
2242 RegisterNamespace("ROOM:UNGOTO", 0, 0, tmplput_ungoto, NULL, CTX_NONE);
2243 RegisterIterator("FLOORS", 0, NULL, GetFloorListHash, NULL, NULL, CTX_FLOORS, CTX_NONE, IT_NOFLAG);
2250 SessionDestroyModule_ROOMOPS
2253 _FlushRoomList (sess);