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 serv_printf("SETR %s|%s|%s|%ld|%d|%d|%ld|%ld|%ld",
711 ChrPtr(Room->XAPass),
712 ChrPtr(Room->Directory),
720 StrBuf_ServGetln(Buf);
721 if (GetServerStatus(Buf, NULL) != 2) {
722 StrBufCutLeft(Buf, 4);
723 AppendImportantMessage (SKEY(Buf));
732 void LoadRoomXA (void)
736 if (WCC->CurRoom.XALoaded)
739 GetCurrentRoomFlags(&WCC->CurRoom);
743 void LoadXRoomPic(void)
748 if (WCC->CurRoom.XHaveRoomPicLoaded)
751 WCC->CurRoom.XHaveRoomPicLoaded = 1;
753 serv_puts("OIMG _roompic_");
754 StrBuf_ServGetln(Buf);
755 if (GetServerStatus(Buf, NULL) != 2) {
756 WCC->CurRoom.XHaveRoomPic = 0;
758 WCC->CurRoom.XHaveRoomPic = 1;
761 StrBuf_ServGetln(Buf);
762 GetServerStatus(Buf, NULL);
766 int ConditionalThisRoomXHavePic(StrBuf *Target, WCTemplputParams *TP)
774 return WCC->CurRoom.XHaveRoomPic == 1;
777 void LoadXRoomInfoText(void)
783 if (WCC->CurRoom.XHaveInfoTextLoaded)
786 WCC->CurRoom.XHaveInfoTextLoaded = 1;
791 StrBuf_ServGetln(Buf);
792 if (GetServerStatus(Buf, NULL) == 1) {
793 WCC->CurRoom.XInfoText = NewStrBuf ();
795 while (!Done && StrBuf_ServGetln(Buf)>=0) {
796 if ( (StrLength(Buf)==3) &&
797 !strcmp(ChrPtr(Buf), "000"))
800 StrBufAppendBuf(WCC->CurRoom.XInfoText, Buf, 0);
807 int ConditionalThisRoomXHaveInfoText(StrBuf *Target, WCTemplputParams *TP)
815 return (StrLength(WCC->CurRoom.XInfoText)>0);
818 void tmplput_CurrentRoomInfoText(StrBuf *Target, WCTemplputParams *TP)
824 StrBufAppendTemplate(Target, TP, WCC->CurRoom.XAPass, 1);
827 void LoadXRoomXCountFiles(void)
833 if (WCC->CurRoom.XHaveDownloadCount)
836 WCC->CurRoom.XHaveDownloadCount = 1;
840 StrBuf_ServGetln(Buf);
841 if (GetServerStatus(Buf, NULL) == 1) {
843 while (!Done && StrBuf_ServGetln(Buf)>=0) {
844 if ( (StrLength(Buf)==3) &&
845 !strcmp(ChrPtr(Buf), "000"))
848 WCC->CurRoom.XDownloadCount++;
855 void tmplput_CurrentRoomXNFiles(StrBuf *Target, WCTemplputParams *TP)
859 LoadXRoomXCountFiles();
861 StrBufAppendPrintf(Target, "%d", WCC->CurRoom.XDownloadCount);
864 void tmplput_CurrentRoomX_FileString(StrBuf *Target, WCTemplputParams *TP)
868 LoadXRoomXCountFiles();
870 if (WCC->CurRoom.XDownloadCount == 1)
871 StrBufAppendBufPlain(Target, _("file"), -1, 0);
873 StrBufAppendBufPlain(Target, _("files"), -1, 0);
876 void tmplput_CurrentRoomPass(StrBuf *Target, WCTemplputParams *TP)
882 StrBufAppendTemplate(Target, TP, WCC->CurRoom.XAPass, 0);
884 void tmplput_CurrentRoomDirectory(StrBuf *Target, WCTemplputParams *TP)
890 StrBufAppendTemplate(Target, TP, WCC->CurRoom.Directory, 0);
892 void tmplput_CurrentRoomOrder(StrBuf *Target, WCTemplputParams *TP)
898 StrBufAppendPrintf(Target, "%d", WCC->CurRoom.Order);
900 void tmplput_CurrentRoomDefView(StrBuf *Target, WCTemplputParams *TP)
904 StrBufAppendPrintf(Target, "%d", WCC->CurRoom.defview);
907 void tmplput_CurrentRoom_nNewMessages(StrBuf *Target, WCTemplputParams *TP)
913 StrBufAppendPrintf(Target, "%d", WCC->CurRoom.nNewMessages);
916 void tmplput_CurrentRoom_nTotalMessages(StrBuf *Target, WCTemplputParams *TP)
922 StrBufAppendPrintf(Target, "%d", WCC->CurRoom.nTotalMessages);
925 int ConditionalThisRoomOrder(StrBuf *Target, WCTemplputParams *TP)
935 CheckThis = GetTemplateTokenNumber(Target, TP, 2, 0);
936 return CheckThis == WCC->CurRoom.Order;
939 int ConditionalThisRoomDefView(StrBuf *Target, WCTemplputParams *TP)
947 CheckThis = GetTemplateTokenNumber(Target, TP, 2, 0);
948 return CheckThis == WCC->CurRoom.defview;
951 int ConditionalThisRoomCurrView(StrBuf *Target, WCTemplputParams *TP)
959 CheckThis = GetTemplateTokenNumber(Target, TP, 2, 0);
960 return CheckThis == WCC->CurRoom.view;
963 int ConditionalThisRoomHaveView(StrBuf *Target, WCTemplputParams *TP)
971 CheckThis = GetTemplateTokenNumber(Target, TP, 2, 0);
972 if ((CheckThis >= VIEW_MAX) || (CheckThis < VIEW_BBS))
974 LogTemplateError(Target, "Conditional", ERR_PARM2, TP,
975 "Roomview [%ld] not valid\n",
980 return exchangeable_views [WCC->CurRoom.defview][CheckThis] != VIEW_MAX;
983 void tmplput_CurrentRoomViewString(StrBuf *Target, WCTemplputParams *TP)
989 (WCC->CurRoom.defview >= VIEW_MAX) ||
990 (WCC->CurRoom.defview < VIEW_BBS))
992 LogTemplateError(Target, "Token", ERR_PARM2, TP,
993 "Roomview [%ld] not valid\n",
995 WCC->CurRoom.defview : -1);
999 Buf = NewStrBufPlain(_(viewdefs[WCC->CurRoom.defview]), -1);
1000 StrBufAppendTemplate(Target, TP, Buf, 0);
1004 void tmplput_RoomViewString(StrBuf *Target, WCTemplputParams *TP)
1009 CheckThis = GetTemplateTokenNumber(Target, TP, 0, 0);
1010 if ((CheckThis >= VIEW_MAX) || (CheckThis < VIEW_BBS))
1012 LogTemplateError(Target, "Token", ERR_PARM2, TP,
1013 "Roomview [%ld] not valid\n",
1018 Buf = NewStrBufPlain(_(viewdefs[CheckThis]), -1);
1019 StrBufAppendTemplate(Target, TP, Buf, 0);
1024 int ConditionalIsAllowedDefaultView(StrBuf *Target, WCTemplputParams *TP)
1026 wcsession *WCC = WC;
1032 CheckThis = GetTemplateTokenNumber(Target, TP, 2, 0);
1033 if ((CheckThis >= VIEW_MAX) || (CheckThis < VIEW_BBS))
1035 LogTemplateError(Target, "Conditional", ERR_PARM2, TP,
1036 "Roomview [%ld] not valid\n",
1041 return allowed_default_views[CheckThis] != 0;
1047 void smart_goto(const StrBuf *next_room) {
1048 gotoroom(next_room);
1049 readloop(readnew, eUseDefault);
1055 * mark all messages in current room as having been read
1057 void slrp_highest(void)
1061 serv_puts("SLRP HIGHEST");
1062 serv_getln(buf, sizeof buf);
1068 * Set/clear/read the "self-service list subscribe" flag for a room
1070 * set newval to 0 to clear, 1 to set, any other value to leave unchanged.
1071 * returns the new value.
1074 int self_service(int newval) {
1075 int current_value = 0;
1076 wcsession *WCC = WC;
1078 if (GetCurrentRoomFlags (&WCC->CurRoom) == 0)
1083 if ((WCC->CurRoom.QRFlags2 & QR2_SELFLIST) != 0) {
1091 WCC->CurRoom.QRFlags2 = WCC->CurRoom.QRFlags2 | QR2_SELFLIST;
1093 else if (newval == 0) {
1094 WCC->CurRoom.QRFlags2 = WCC->CurRoom.QRFlags2 & ~QR2_SELFLIST;
1097 return(current_value);
1100 if (newval != current_value) {
1101 SetCurrentRoomFlags(&WCC->CurRoom);
1111 * Toggle self-service list subscription
1113 void toggle_self_service(void) {
1114 wcsession *WCC = WC;
1116 if (GetCurrentRoomFlags (&WCC->CurRoom) == 0)
1119 if (yesbstr("QR2_SelfList"))
1120 WCC->CurRoom.QRFlags2 = WCC->CurRoom.QRFlags2 | QR2_SELFLIST;
1122 WCC->CurRoom.QRFlags2 = WCC->CurRoom.QRFlags2 & ~QR2_SELFLIST;
1124 if (yesbstr("QR2_SMTP_PUBLIC"))
1125 WCC->CurRoom.QRFlags2 = WCC->CurRoom.QRFlags2 | QR2_SMTP_PUBLIC;
1127 WCC->CurRoom.QRFlags2 = WCC->CurRoom.QRFlags2 & ~QR2_SMTP_PUBLIC;
1129 if (yesbstr("QR2_Moderated"))
1130 WCC->CurRoom.QRFlags2 = WCC->CurRoom.QRFlags2 | QR2_MODERATED;
1132 WCC->CurRoom.QRFlags2 = WCC->CurRoom.QRFlags2 & ~QR2_MODERATED;
1133 if (yesbstr("QR2_SubsOnly"))
1134 WCC->CurRoom.QRFlags2 = WCC->CurRoom.QRFlags2 | QR2_SMTP_PUBLIC;
1136 WCC->CurRoom.QRFlags2 = WCC->CurRoom.QRFlags2 & ~QR2_SMTP_PUBLIC;
1138 SetCurrentRoomFlags (&WCC->CurRoom);
1140 http_transmit_thing(ChrPtr(do_template("room_edit", NULL)), 0);
1146 * save new parameters for a room
1150 wcsession *WCC = WC;
1152 const StrBuf *er_name;
1153 const StrBuf *er_password;
1154 const StrBuf *er_dirname;
1155 const StrBuf *er_roomaide;
1160 if (!havebstr("ok_button")) {
1161 strcpy(WC->ImportantMessage,
1162 _("Cancelled. Changes were not saved."));
1163 http_transmit_thing(ChrPtr(do_template("room_edit", NULL)), 0);
1166 if (GetCurrentRoomFlags (&WCC->CurRoom) == 0)
1171 er_flags = WCC->CurRoom.QRFlags;
1172 er_flags &= !(QR_PRIVATE | QR_PASSWORDED | QR_GUESSNAME);
1174 er_flags2 = WCC->CurRoom.QRFlags2;
1176 Ptr = sbstr("type");
1177 if (!strcmp(ChrPtr(Ptr), "invonly")) {
1178 er_flags |= (QR_PRIVATE);
1180 if (!strcmp(ChrPtr(Ptr), "hidden")) {
1181 er_flags |= (QR_PRIVATE | QR_GUESSNAME);
1183 if (!strcmp(ChrPtr(Ptr), "passworded")) {
1184 er_flags |= (QR_PRIVATE | QR_PASSWORDED);
1186 if (!strcmp(ChrPtr(Ptr), "personal")) {
1187 er_flags |= QR_MAILBOX;
1189 er_flags &= ~QR_MAILBOX;
1194 if (yesbstr("prefonly")) {
1195 er_flags |= QR_PREFONLY;
1197 er_flags &= ~QR_PREFONLY;
1200 if (yesbstr("readonly")) {
1201 er_flags |= QR_READONLY;
1203 er_flags &= ~QR_READONLY;
1207 if (yesbstr("collabdel")) {
1208 er_flags2 |= QR2_COLLABDEL;
1210 er_flags2 &= ~QR2_COLLABDEL;
1213 if (yesbstr("permanent")) {
1214 er_flags |= QR_PERMANENT;
1216 er_flags &= ~QR_PERMANENT;
1219 if (yesbstr("subjectreq")) {
1220 er_flags2 |= QR2_SUBJECTREQ;
1222 er_flags2 &= ~QR2_SUBJECTREQ;
1225 if (yesbstr("network")) {
1226 er_flags |= QR_NETWORK;
1228 er_flags &= ~QR_NETWORK;
1231 if (yesbstr("directory")) {
1232 er_flags |= QR_DIRECTORY;
1234 er_flags &= ~QR_DIRECTORY;
1237 if (yesbstr("ulallowed")) {
1238 er_flags |= QR_UPLOAD;
1240 er_flags &= ~QR_UPLOAD;
1243 if (yesbstr("dlallowed")) {
1244 er_flags |= QR_DOWNLOAD;
1246 er_flags &= ~QR_DOWNLOAD;
1249 if (yesbstr("visdir")) {
1250 er_flags |= QR_VISDIR;
1252 er_flags &= ~QR_VISDIR;
1256 Ptr = sbstr("anon");
1258 er_flags &= ~(QR_ANONONLY | QR_ANONOPT);
1259 if (!strcmp(ChrPtr(Ptr), "anononly"))
1260 er_flags |= QR_ANONONLY;
1261 if (!strcmp(ChrPtr(Ptr), "anon2"))
1262 er_flags |= QR_ANONOPT;
1264 er_name = sbstr("er_name");
1265 er_dirname = sbstr("er_dirname");
1266 er_roomaide = sbstr("er_roomaide");
1267 er_password = sbstr("er_password");
1269 FlushStrBuf(WCC->CurRoom.name);
1270 StrBufAppendBuf(WCC->CurRoom.name, er_name, 0);
1272 FlushStrBuf(WCC->CurRoom.Directory);
1273 StrBufAppendBuf(WCC->CurRoom.Directory, er_dirname, 0);
1275 FlushStrBuf(WCC->CurRoom.RoomAide);
1276 StrBufAppendBuf(WCC->CurRoom.RoomAide, er_roomaide, 0);
1278 FlushStrBuf(WCC->CurRoom.XAPass);
1279 StrBufAppendBuf(WCC->CurRoom.XAPass, er_password, 0);
1281 WCC->CurRoom.BumpUsers = yesbstr("bump");
1283 WCC->CurRoom.floorid = ibstr("er_floor");
1285 succ1 = SetCurrentRoomFlags(&WCC->CurRoom);
1287 succ2 = SaveRoomAide (&WCC->CurRoom);
1289 if (succ1 + succ2 == 0)
1290 AppendImportantMessage (_("Your changes have been saved."), -1);
1291 http_transmit_thing(ChrPtr(do_template("room_edit", NULL)), 0);
1297 * Display form for Invite, Kick, and show Who Knows a room
1299 void do_invt_kick(void) {
1300 char buf[SIZ], room[SIZ], username[SIZ];
1303 serv_getln(buf, sizeof buf);
1305 if (buf[0] != '2') {
1309 extract_token(room, &buf[4], 0, '|', sizeof room);
1311 strcpy(username, bstr("username"));
1313 if (havebstr("kick_button")) {
1314 sprintf(buf, "KICK %s", username);
1316 serv_getln(buf, sizeof buf);
1318 if (buf[0] != '2') {
1319 strcpy(WC->ImportantMessage, &buf[4]);
1321 sprintf(WC->ImportantMessage,
1322 _("<B><I>User %s kicked out of room %s.</I></B>\n"),
1327 if (havebstr("invite_button")) {
1328 sprintf(buf, "INVT %s", username);
1330 serv_getln(buf, sizeof buf);
1332 if (buf[0] != '2') {
1333 strcpy(WC->ImportantMessage, &buf[4]);
1335 sprintf(WC->ImportantMessage,
1336 _("<B><I>User %s invited to room %s.</I></B>\n"),
1341 http_transmit_thing(ChrPtr(do_template("room_edit", NULL)), 0);
1345 * support function for entroom() -- sets the default view
1347 void er_set_default_view(int newview) {
1360 serv_getln(buf, sizeof buf);
1361 if (buf[0] != '2') return;
1363 extract_token(rm_name, &buf[4], 0, '|', sizeof rm_name);
1364 extract_token(rm_pass, &buf[4], 1, '|', sizeof rm_pass);
1365 extract_token(rm_dir, &buf[4], 2, '|', sizeof rm_dir);
1366 rm_bits1 = extract_int(&buf[4], 3);
1367 rm_floor = extract_int(&buf[4], 4);
1368 rm_listorder = extract_int(&buf[4], 5);
1369 rm_bits2 = extract_int(&buf[4], 7);
1371 serv_printf("SETR %s|%s|%s|%d|0|%d|%d|%d|%d",
1372 rm_name, rm_pass, rm_dir, rm_bits1, rm_floor,
1373 rm_listorder, newview, rm_bits2
1375 serv_getln(buf, sizeof buf);
1386 const StrBuf *er_name;
1387 const StrBuf *er_type;
1388 const StrBuf *er_password;
1392 wcsession *WCC = WC;
1394 if (!havebstr("ok_button")) {
1395 strcpy(WC->ImportantMessage,
1396 _("Cancelled. No new room was created."));
1397 display_main_menu();
1400 er_name = sbstr("er_name");
1401 er_type = sbstr("type");
1402 er_password = sbstr("er_password");
1403 er_floor = ibstr("er_floor");
1404 er_view = ibstr("er_view");
1407 if (!strcmp(ChrPtr(er_type), "hidden"))
1409 else if (!strcmp(ChrPtr(er_type), "passworded"))
1411 else if (!strcmp(ChrPtr(er_type), "invonly"))
1413 else if (!strcmp(ChrPtr(er_type), "personal"))
1416 serv_printf("CRE8 1|%s|%d|%s|%d|%d|%d",
1419 ChrPtr(er_password),
1424 serv_getln(buf, sizeof buf);
1425 if (buf[0] != '2') {
1426 strcpy(WCC->ImportantMessage, &buf[4]);
1427 display_main_menu();
1430 /** TODO: Room created, now update the left hand icon bar for this user */
1433 serv_printf("VIEW %d", er_view);
1434 serv_getln(buf, sizeof buf);
1435 WCC->CurRoom.view = er_view;
1437 if ( (WCC != NULL) && ( (WCC->CurRoom.RAFlags & UA_ADMINALLOWED) != 0) ) {
1438 http_transmit_thing(ChrPtr(do_template("room_edit", NULL)), 0);
1440 do_change_view(er_view); /* Now go there */
1447 * \brief goto a private room
1449 void goto_private(void)
1453 const StrBuf *gr_name;
1456 if (!havebstr("ok_button")) {
1457 display_main_menu();
1460 gr_name = sbstr("gr_name");
1462 strcpy(hold_rm, ChrPtr(WC->CurRoom.name));
1463 serv_printf("GOTO %s|%s",
1466 StrBuf_ServGetln(Buf);
1467 if (GetServerStatus(Buf, &err) == 2) {
1469 smart_goto(gr_name);
1474 DoTemplate(HKEY("room_display_private"), NULL, &NoCtx);
1478 StrBufCutLeft(Buf, 4);
1479 AppendImportantMessage (SKEY(Buf));
1480 Buf = NewStrBufPlain(HKEY("_BASEROOM_"));
1494 StrBuf *final_destination;
1497 * If the forget-room routine fails for any reason, we fall back
1498 * to the current room; otherwise, we go to the Lobby
1500 final_destination = NewStrBufDup(WC->CurRoom.name);
1502 if (havebstr("ok_button")) {
1503 serv_printf("GOTO %s", ChrPtr(WC->CurRoom.name));
1504 serv_getln(buf, sizeof buf);
1505 if (buf[0] == '2') {
1507 serv_getln(buf, sizeof buf);
1508 if (buf[0] == '2') {
1509 FlushStrBuf(final_destination);
1510 StrBufAppendBufPlain(final_destination, HKEY("_BASEROOM_"), 0);
1515 smart_goto(final_destination);
1516 FreeStrBuf(&final_destination);
1522 * \brief Delete the current room
1524 void delete_room(void)
1529 serv_puts("KILL 1");
1530 serv_getln(buf, sizeof buf);
1532 if (buf[0] != '2') {
1533 strcpy(WC->ImportantMessage, &buf[4]);
1534 display_main_menu();
1540 Buf = NewStrBufPlain(HKEY("_BASEROOM_"));
1549 * \brief Perform changes to a room's network configuration
1551 void netedit(void) {
1560 /*/ TODO: do line dynamic! */
1561 if (havebstr("line_pop3host")) {
1562 strcpy(line, bstr("prefix"));
1563 strcat(line, bstr("line_pop3host"));
1565 strcat(line, bstr("line_pop3user"));
1567 strcat(line, bstr("line_pop3pass"));
1569 strcat(line, ibstr("line_pop3keep") ? "1" : "0" );
1571 sprintf(&line[strlen(line)],"%ld", lbstr("line_pop3int"));
1572 strcat(line, bstr("suffix"));
1574 else if (havebstr("line")) {
1575 strcpy(line, bstr("prefix"));
1576 strcat(line, bstr("line"));
1577 strcat(line, bstr("suffix"));
1580 http_transmit_thing(ChrPtr(do_template("room_edit", NULL)), 0);
1587 http_transmit_thing(ChrPtr(do_template("room_edit", NULL)), 0);
1592 serv_getln(buf, sizeof buf);
1593 if (buf[0] != '1') {
1595 http_transmit_thing(ChrPtr(do_template("room_edit", NULL)), 0);
1599 /** This loop works for add *or* remove. Spiffy, eh? */
1600 while (serv_getln(buf, sizeof buf), strcmp(buf, "000")) {
1601 extract_token(cmpa0, buf, 0, '|', sizeof cmpa0);
1602 extract_token(cmpa1, buf, 1, '|', sizeof cmpa1);
1603 extract_token(cmpb0, line, 0, '|', sizeof cmpb0);
1604 extract_token(cmpb1, line, 1, '|', sizeof cmpb1);
1605 if ( (strcasecmp(cmpa0, cmpb0))
1606 || (strcasecmp(cmpa1, cmpb1)) ) {
1607 fprintf(fp, "%s\n", buf);
1613 serv_getln(buf, sizeof buf);
1614 if (buf[0] != '4') {
1616 http_transmit_thing(ChrPtr(do_template("room_edit", NULL)), 0);
1620 while (fgets(buf, sizeof buf, fp) != NULL) {
1621 buf[strlen(buf)-1] = 0;
1625 if (havebstr("add_button")) {
1626 num_addrs = num_tokens(bstr("line"), ',');
1627 if (num_addrs < 2) {
1628 /* just adding one node or address */
1632 /* adding multiple addresses separated by commas */
1633 for (i=0; i<num_addrs; ++i) {
1634 strcpy(line, bstr("prefix"));
1635 extract_token(buf, bstr("line"), i, ',', sizeof buf);
1638 strcat(line, bstr("suffix"));
1646 http_transmit_thing(ChrPtr(do_template("room_edit", NULL)), 0);
1651 * \brief Back end for change_view()
1652 * \param newview set newview???
1654 void do_change_view(int newview) {
1657 serv_printf("VIEW %d", newview);
1658 serv_getln(buf, sizeof buf);
1659 WC->CurRoom.view = newview;
1660 smart_goto(WC->CurRoom.name);
1666 * \brief Change the view for this room
1668 void change_view(void) {
1671 view = lbstr("view");
1672 do_change_view(view);
1676 * \brief Do either a known rooms list or a folders list, depending on the
1681 StrBuf *ListView = NULL;
1683 /** Determine whether the user is trying to change views */
1684 if (havebstr("view")) {
1685 ListView = NewStrBufDup(SBSTR("view"));
1686 set_preference("roomlistview", ListView, 1);
1688 /** Sanitize the input so its safe */
1689 if((get_preference("roomlistview", &ListView) != 0)||
1690 ((strcasecmp(ChrPtr(ListView), "folders") != 0) &&
1691 (strcasecmp(ChrPtr(ListView), "table") != 0)))
1693 if (ListView == NULL) {
1694 ListView = NewStrBufPlain(HKEY("rooms"));
1695 set_preference("roomlistview", ListView, 0);
1699 ListView = NewStrBufPlain(HKEY("rooms"));
1700 set_preference("roomlistview", ListView, 0);
1704 FreeStrBuf(&ListView);
1711 * \brief Set the message expire policy for this room and/or floor
1713 void set_room_policy(void) {
1716 if (!havebstr("ok_button")) {
1717 strcpy(WC->ImportantMessage,
1718 _("Cancelled. Changes were not saved."));
1719 http_transmit_thing(ChrPtr(do_template("room_edit", NULL)), 0);
1723 serv_printf("SPEX roompolicy|%d|%d", ibstr("roompolicy"), ibstr("roomvalue"));
1724 serv_getln(buf, sizeof buf);
1725 strcpy(WC->ImportantMessage, &buf[4]);
1727 if (WC->axlevel >= 6) {
1728 strcat(WC->ImportantMessage, "<br />\n");
1729 serv_printf("SPEX floorpolicy|%d|%d", ibstr("floorpolicy"), ibstr("floorvalue"));
1730 serv_getln(buf, sizeof buf);
1731 strcat(WC->ImportantMessage, &buf[4]);
1733 ReloadCurrentRoom();
1734 http_transmit_thing(ChrPtr(do_template("room_edit", NULL)), 0);
1737 void tmplput_RoomName(StrBuf *Target, WCTemplputParams *TP)
1739 StrBufAppendTemplate(Target, TP, WC->CurRoom.name, 0);
1742 void dotgoto(void) {
1743 if (!havebstr("room")) {
1744 readloop(readnew, eUseDefault);
1747 if (WC->CurRoom.view != VIEW_MAILBOX) { /* dotgoto acts like dotskip when we're in a mailbox view */
1750 smart_goto(sbstr("room"));
1755 void tmplput_current_room(StrBuf *Target, WCTemplputParams *TP)
1757 wcsession *WCC = WC;
1760 StrBufAppendTemplate(Target, TP,
1765 void tmplput_roombanner(StrBuf *Target, WCTemplputParams *TP)
1767 wc_printf("<div id=\"banner\">\n");
1768 embed_room_banner();
1769 wc_printf("</div>\n");
1773 void tmplput_ungoto(StrBuf *Target, WCTemplputParams *TP)
1775 wcsession *WCC = WC;
1778 (!IsEmptyStr(WCC->ugname)))
1779 StrBufAppendBufPlain(Target, WCC->ugname, -1, 0);
1782 int ConditionalRoomAide(StrBuf *Target, WCTemplputParams *TP)
1784 wcsession *WCC = WC;
1785 return (WCC != NULL)?
1786 ((WCC->CurRoom.RAFlags & UA_ADMINALLOWED) != 0) : 0;
1789 int ConditionalRoomAcessDelete(StrBuf *Target, WCTemplputParams *TP)
1791 wcsession *WCC = WC;
1792 return (WCC == NULL)? 0 :
1793 ( ((WCC->CurRoom.RAFlags & UA_ADMINALLOWED) != 0) ||
1794 (WCC->CurRoom.is_inbox) ||
1795 (WCC->CurRoom.QRFlags2 & QR2_COLLABDEL) );
1798 int ConditionalHaveUngoto(StrBuf *Target, WCTemplputParams *TP)
1800 wcsession *WCC = WC;
1802 return ((WCC!=NULL) &&
1803 (!IsEmptyStr(WCC->ugname)) &&
1804 (strcasecmp(WCC->ugname, ChrPtr(WCC->CurRoom.name)) == 0));
1808 int ConditionalRoomHas_UAFlag(StrBuf *Target, WCTemplputParams *TP)
1810 folder *Folder = (folder *)(TP->Context);
1813 UA_CheckFlag = GetTemplateTokenNumber(Target, TP, 2, 0);
1814 if (UA_CheckFlag == 0)
1815 LogTemplateError(Target, "Conditional", ERR_PARM1, TP,
1816 "requires one of the #\"UA_*\"- defines or an integer flag 0 is invalid!");
1818 return ((Folder->RAFlags & UA_CheckFlag) != 0);
1823 int ConditionalCurrentRoomHas_QRFlag(StrBuf *Target, WCTemplputParams *TP)
1826 wcsession *WCC = WC;
1828 QR_CheckFlag = GetTemplateTokenNumber(Target, TP, 2, 0);
1829 if (QR_CheckFlag == 0)
1830 LogTemplateError(Target, "Conditional", ERR_PARM1, TP,
1831 "requires one of the #\"QR*\"- defines or an integer flag 0 is invalid!");
1836 if ((TP->Tokens->Params[2]->MaskBy == eOR) ||
1837 (TP->Tokens->Params[2]->MaskBy == eNO))
1838 return (WCC->CurRoom.QRFlags & QR_CheckFlag) != 0;
1840 return (WCC->CurRoom.QRFlags & QR_CheckFlag) == QR_CheckFlag;
1843 int ConditionalRoomHas_QRFlag(StrBuf *Target, WCTemplputParams *TP)
1846 folder *Folder = (folder *)(TP->Context);
1848 QR_CheckFlag = GetTemplateTokenNumber(Target, TP, 2, 0);
1849 if (QR_CheckFlag == 0)
1850 LogTemplateError(Target, "Conditional", ERR_PARM1, TP,
1851 "requires one of the #\"QR*\"- defines or an integer flag 0 is invalid!");
1853 if ((TP->Tokens->Params[2]->MaskBy == eOR) ||
1854 (TP->Tokens->Params[2]->MaskBy == eNO))
1855 return (Folder->QRFlags & QR_CheckFlag) != 0;
1857 return (Folder->QRFlags & QR_CheckFlag) == QR_CheckFlag;
1861 int ConditionalCurrentRoomHas_QRFlag2(StrBuf *Target, WCTemplputParams *TP)
1864 wcsession *WCC = WC;
1866 QR2_CheckFlag = GetTemplateTokenNumber(Target, TP, 2, 0);
1867 if (QR2_CheckFlag == 0)
1868 LogTemplateError(Target, "Conditional", ERR_PARM1, TP,
1869 "requires one of the #\"QR2*\"- defines or an integer flag 0 is invalid!");
1875 if ((TP->Tokens->Params[2]->MaskBy == eOR) ||
1876 (TP->Tokens->Params[2]->MaskBy == eNO))
1877 return (WCC->CurRoom.QRFlags2 & QR2_CheckFlag) != 0;
1879 return (WCC->CurRoom.QRFlags2 & QR2_CheckFlag) == QR2_CheckFlag;
1882 int ConditionalRoomHas_QRFlag2(StrBuf *Target, WCTemplputParams *TP)
1885 folder *Folder = (folder *)(TP->Context);
1887 QR2_CheckFlag = GetTemplateTokenNumber(Target, TP, 2, 0);
1888 if (QR2_CheckFlag == 0)
1889 LogTemplateError(Target, "Conditional", ERR_PARM1, TP,
1890 "requires one of the #\"QR2*\"- defines or an integer flag 0 is invalid!");
1891 return ((Folder->QRFlags2 & QR2_CheckFlag) != 0);
1895 int ConditionalHaveRoomeditRights(StrBuf *Target, WCTemplputParams *TP)
1897 wcsession *WCC = WC;
1899 return ( (WCC!= NULL) &&
1900 ((WCC->axlevel >= 6) ||
1901 ((WCC->CurRoom.RAFlags & UA_ADMINALLOWED) != 0) ||
1902 (WCC->CurRoom.is_inbox) ));
1905 int ConditionalIsRoomtype(StrBuf *Target, WCTemplputParams *TP)
1907 wcsession *WCC = WC;
1909 if ((WCC == NULL) ||
1910 (TP->Tokens->nParameters < 3))
1912 return ((WCC->CurRoom.view < VIEW_BBS) ||
1913 (WCC->CurRoom.view > VIEW_MAX));
1916 return WCC->CurRoom.view == GetTemplateTokenNumber(Target, TP, 2, VIEW_BBS);
1920 HashList *GetWhoKnowsHash(StrBuf *Target, WCTemplputParams *TP)
1922 wcsession *WCC = WC;
1926 HashList *Whok = NULL;
1932 StrBuf_ServGetln(Line);
1933 if (GetServerStatus(Line, &State) == 1)
1935 Whok = NewHash(1, Flathash);
1936 while(!Done && StrBuf_ServGetln(Line))
1937 if ( (StrLength(Line)==3) &&
1938 !strcmp(ChrPtr(Line), "000"))
1945 const char *Pos = NULL;
1946 Token = NewStrBufPlain (NULL, StrLength(Line));
1947 StrBufExtract_NextToken(Token, Line, &Pos, '|');
1955 else if (State == 550)
1956 StrBufAppendBufPlain(WCC->ImportantMsg,
1957 _("Higher access is required to access this function."), -1, 0);
1966 void _FlushRoomList(wcsession *WCC)
1968 free_march_list(WCC);
1969 DeleteHash(&WCC->Floors);
1970 DeleteHash(&WCC->Rooms);
1971 DeleteHash(&WCC->FloorsByName);
1972 FlushFolder(&WCC->CurRoom);
1975 void ReloadCurrentRoom(void)
1977 wcsession *WCC = WC;
1980 CurRoom = WCC->CurRoom.name;
1981 WCC->CurRoom.name = NULL;
1982 _FlushRoomList(WCC);
1984 FreeStrBuf(&CurRoom);
1987 void FlushRoomlist(void)
1989 wcsession *WCC = WC;
1990 _FlushRoomList(WCC);
1998 initialize_viewdefs();
1999 RegisterPreference("roomlistview",
2000 _("Room list view"),
2003 RegisterPreference("emptyfloors", _("Show empty floors"), PRF_YESNO, NULL);
2005 RegisterNamespace("ROOMNAME", 0, 1, tmplput_RoomName, NULL, CTX_NONE);
2008 WebcitAddUrlHandler(HKEY("knrooms"), "", 0, knrooms, 0);
2009 WebcitAddUrlHandler(HKEY("dotgoto"), "", 0, dotgoto, NEED_URL);
2010 WebcitAddUrlHandler(HKEY("dotskip"), "", 0, dotskip, NEED_URL);
2012 WebcitAddUrlHandler(HKEY("goto_private"), "", 0, goto_private, NEED_URL);
2013 WebcitAddUrlHandler(HKEY("zap"), "", 0, zap, 0);
2014 WebcitAddUrlHandler(HKEY("entroom"), "", 0, entroom, 0);
2015 WebcitAddUrlHandler(HKEY("do_invt_kick"), "", 0, do_invt_kick, 0);
2017 WebcitAddUrlHandler(HKEY("netedit"), "", 0, netedit, 0);
2018 WebcitAddUrlHandler(HKEY("editroom"), "", 0, editroom, 0);
2019 WebcitAddUrlHandler(HKEY("delete_room"), "", 0, delete_room, 0);
2020 WebcitAddUrlHandler(HKEY("set_room_policy"), "", 0, set_room_policy, 0);
2021 WebcitAddUrlHandler(HKEY("changeview"), "", 0, change_view, 0);
2022 WebcitAddUrlHandler(HKEY("toggle_self_service"), "", 0, toggle_self_service, 0);
2023 RegisterNamespace("ROOMBANNER", 0, 1, tmplput_roombanner, NULL, CTX_NONE);
2025 RegisterConditional(HKEY("COND:ROOM:TYPE_IS"), 0, ConditionalIsRoomtype, CTX_NONE);
2026 RegisterConditional(HKEY("COND:THISROOM:FLAG:QR"), 0, ConditionalCurrentRoomHas_QRFlag, CTX_NONE);
2027 RegisterConditional(HKEY("COND:ROOM:FLAG:QR"), 0, ConditionalRoomHas_QRFlag, CTX_ROOMS);
2029 RegisterConditional(HKEY("COND:THISROOM:FLAG:QR2"), 0, ConditionalCurrentRoomHas_QRFlag2, CTX_NONE);
2030 RegisterConditional(HKEY("COND:ROOM:FLAG:QR2"), 0, ConditionalRoomHas_QRFlag2, CTX_ROOMS);
2031 RegisterConditional(HKEY("COND:ROOM:FLAG:UA"), 0, ConditionalRoomHas_UAFlag, CTX_ROOMS);
2033 RegisterIterator("ITERATE:THISROOM:WHO_KNOWS", 0, NULL, GetWhoKnowsHash, NULL, DeleteHash, CTX_STRBUF, CTX_NONE, IT_NOFLAG);
2034 RegisterNamespace("THISROOM:MSGS:NEW", 0, 0, tmplput_CurrentRoom_nNewMessages, NULL, CTX_NONE);
2035 RegisterNamespace("THISROOM:MSGS:TOTAL", 0, 0, tmplput_CurrentRoom_nTotalMessages, NULL, CTX_NONE);
2037 RegisterNamespace("THISROOM:FLOOR:NAME", 0, 1, tmplput_CurrentRoomFloorName, NULL, CTX_NONE);
2038 RegisterNamespace("THISROOM:AIDE", 0, 1, tmplput_CurrentRoomAide, NULL, CTX_NONE);
2039 RegisterNamespace("THISROOM:PASS", 0, 1, tmplput_CurrentRoomPass, NULL, CTX_NONE);
2040 RegisterNamespace("THISROOM:DIRECTORY", 0, 1, tmplput_CurrentRoomDirectory, NULL, CTX_NONE);
2041 RegisterNamespace("THISROOM:ORDER", 0, 0, tmplput_CurrentRoomOrder, NULL, CTX_NONE);
2042 RegisterNamespace("THISROOM:DEFAULT_VIEW", 0, 0, tmplput_CurrentRoomDefView, NULL, CTX_NONE);
2043 RegisterConditional(HKEY("COND:THISROOM:HAVE_VIEW"), 0, ConditionalThisRoomHaveView, CTX_NONE);
2044 RegisterConditional(HKEY("COND:ALLOWED_DEFAULT_VIEW"), 0, ConditionalIsAllowedDefaultView, CTX_NONE);
2046 RegisterNamespace("THISROOM:VIEW_STRING", 0, 1, tmplput_CurrentRoomViewString, NULL, CTX_NONE);
2047 RegisterNamespace("ROOM:VIEW_STRING", 1, 2, tmplput_RoomViewString, NULL, CTX_NONE);
2049 RegisterNamespace("THISROOM:INFOTEXT", 1, 2, tmplput_CurrentRoomInfoText, NULL, CTX_NONE);
2050 RegisterConditional(HKEY("COND:THISROOM:ORDER"), 0, ConditionalThisRoomOrder, CTX_NONE);
2051 RegisterConditional(HKEY("COND:THISROOM:DEFAULT_VIEW"), 0, ConditionalThisRoomDefView, CTX_NONE);
2052 RegisterConditional(HKEY("COND:THISROOM:CURR_VIEW"), 0, ConditionalThisRoomCurrView, CTX_NONE);
2053 RegisterConditional(HKEY("COND:THISROOM:HAVE_PIC"), 0, ConditionalThisRoomXHavePic, CTX_NONE);
2054 RegisterConditional(HKEY("COND:THISROOM:HAVE_INFOTEXT"), 0, ConditionalThisRoomXHaveInfoText, CTX_NONE);
2055 RegisterNamespace("THISROOM:FILES:N", 0, 1, tmplput_CurrentRoomXNFiles, NULL, CTX_NONE);
2056 RegisterNamespace("THISROOM:FILES:STR", 0, 1, tmplput_CurrentRoomX_FileString, NULL, CTX_NONE);
2058 REGISTERTokenParamDefine(QR_PERMANENT);
2059 REGISTERTokenParamDefine(QR_INUSE);
2060 REGISTERTokenParamDefine(QR_PRIVATE);
2061 REGISTERTokenParamDefine(QR_PASSWORDED);
2062 REGISTERTokenParamDefine(QR_GUESSNAME);
2063 REGISTERTokenParamDefine(QR_DIRECTORY);
2064 REGISTERTokenParamDefine(QR_UPLOAD);
2065 REGISTERTokenParamDefine(QR_DOWNLOAD);
2066 REGISTERTokenParamDefine(QR_VISDIR);
2067 REGISTERTokenParamDefine(QR_ANONONLY);
2068 REGISTERTokenParamDefine(QR_ANONOPT);
2069 REGISTERTokenParamDefine(QR_NETWORK);
2070 REGISTERTokenParamDefine(QR_PREFONLY);
2071 REGISTERTokenParamDefine(QR_READONLY);
2072 REGISTERTokenParamDefine(QR_MAILBOX);
2073 REGISTERTokenParamDefine(QR2_SYSTEM);
2074 REGISTERTokenParamDefine(QR2_SELFLIST);
2075 REGISTERTokenParamDefine(QR2_COLLABDEL);
2076 REGISTERTokenParamDefine(QR2_SUBJECTREQ);
2077 REGISTERTokenParamDefine(QR2_SMTP_PUBLIC);
2078 REGISTERTokenParamDefine(QR2_MODERATED);
2080 REGISTERTokenParamDefine(UA_KNOWN);
2081 REGISTERTokenParamDefine(UA_GOTOALLOWED);
2082 REGISTERTokenParamDefine(UA_HASNEWMSGS);
2083 REGISTERTokenParamDefine(UA_ZAPPED);
2084 REGISTERTokenParamDefine(UA_POSTALLOWED);
2085 REGISTERTokenParamDefine(UA_ADMINALLOWED);
2086 REGISTERTokenParamDefine(UA_DELETEALLOWED);
2087 REGISTERTokenParamDefine(UA_ISTRASH);
2089 REGISTERTokenParamDefine(US_NEEDVALID);
2090 REGISTERTokenParamDefine(US_PERM);
2091 REGISTERTokenParamDefine(US_LASTOLD);
2092 REGISTERTokenParamDefine(US_EXPERT);
2093 REGISTERTokenParamDefine(US_UNLISTED);
2094 REGISTERTokenParamDefine(US_NOPROMPT);
2095 REGISTERTokenParamDefine(US_PROMPTCTL);
2096 REGISTERTokenParamDefine(US_DISAPPEAR);
2097 REGISTERTokenParamDefine(US_REGIS);
2098 REGISTERTokenParamDefine(US_PAGINATOR);
2099 REGISTERTokenParamDefine(US_INTERNET);
2100 REGISTERTokenParamDefine(US_FLOORS);
2101 REGISTERTokenParamDefine(US_COLOR);
2102 REGISTERTokenParamDefine(US_USER_SET);
2104 REGISTERTokenParamDefine(VIEW_BBS);
2105 REGISTERTokenParamDefine(VIEW_MAILBOX);
2106 REGISTERTokenParamDefine(VIEW_ADDRESSBOOK);
2107 REGISTERTokenParamDefine(VIEW_CALENDAR);
2108 REGISTERTokenParamDefine(VIEW_TASKS);
2109 REGISTERTokenParamDefine(VIEW_NOTES);
2110 REGISTERTokenParamDefine(VIEW_WIKI);
2111 REGISTERTokenParamDefine(VIEW_CALBRIEF);
2112 REGISTERTokenParamDefine(VIEW_JOURNAL);
2113 REGISTERTokenParamDefine(VIEW_BLOG);
2116 REGISTERTokenParamDefine(ignet_push_share);
2117 { /* these are the parts of an IGNET push config */
2118 REGISTERTokenParamDefine(GNET_IGNET_NODE);
2119 REGISTERTokenParamDefine(GNET_IGNET_ROOM);
2121 REGISTERTokenParamDefine(listrecp);
2122 REGISTERTokenParamDefine(digestrecp);
2123 REGISTERTokenParamDefine(pop3client);
2124 { /* These are the parts of a pop3 client line... */
2125 REGISTERTokenParamDefine(GNET_POP3_HOST);
2126 REGISTERTokenParamDefine(GNET_POP3_USER);
2127 REGISTERTokenParamDefine(GNET_POP3_DONT_DELETE_REMOTE);
2128 REGISTERTokenParamDefine(GNET_POP3_INTERVAL);
2130 REGISTERTokenParamDefine(rssclient);
2131 REGISTERTokenParamDefine(participate);
2133 RegisterConditional(HKEY("COND:ROOMAIDE"), 2, ConditionalRoomAide, CTX_NONE);
2134 RegisterConditional(HKEY("COND:ACCESS:DELETE"), 2, ConditionalRoomAcessDelete, CTX_NONE);
2136 RegisterConditional(HKEY("COND:UNGOTO"), 0, ConditionalHaveUngoto, CTX_NONE);
2137 RegisterConditional(HKEY("COND:ROOM:EDITACCESS"), 0, ConditionalHaveRoomeditRights, CTX_NONE);
2139 RegisterNamespace("CURRENT_ROOM", 0, 1, tmplput_current_room, NULL, CTX_NONE);
2140 RegisterNamespace("ROOM:UNGOTO", 0, 0, tmplput_ungoto, NULL, CTX_NONE);
2141 RegisterIterator("FLOORS", 0, NULL, GetFloorListHash, NULL, NULL, CTX_FLOORS, CTX_NONE, IT_NOFLAG);
2148 SessionDestroyModule_ROOMOPS
2151 _FlushRoomList (sess);