2 * Lots of different room-related operations.
4 * Copyright (c) 1996-2016 by the citadel.org team
6 * This program is open source software. You can redistribute it and/or
7 * modify it under the terms of the GNU General Public License, version 3.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
16 #include "webserver.h"
18 ConstStr QRFlagList[] = {
19 {HKEY(strof(QR_PERMANENT))},
20 {HKEY(strof(QR_INUSE))},
21 {HKEY(strof(QR_PRIVATE))},
22 {HKEY(strof(QR_PASSWORDED))},
23 {HKEY(strof(QR_GUESSNAME))},
24 {HKEY(strof(QR_DIRECTORY))},
25 {HKEY(strof(QR_UPLOAD))},
26 {HKEY(strof(QR_DOWNLOAD))},
27 {HKEY(strof(QR_VISDIR))},
28 {HKEY(strof(QR_ANONONLY))},
29 {HKEY(strof(QR_ANONOPT))},
30 {HKEY(strof(QR_NETWORK))},
31 {HKEY(strof(QR_PREFONLY))},
32 {HKEY(strof(QR_READONLY))},
33 {HKEY(strof(QR_MAILBOX))}
35 ConstStr QR2FlagList[] = {
36 {HKEY(strof(QR2_SYSTEM))},
37 {HKEY(strof(QR2_SELFLIST))},
38 {HKEY(strof(QR2_COLLABDEL))},
39 {HKEY(strof(QR2_SUBJECTREQ))},
40 {HKEY(strof(QR2_SMTP_PUBLIC))},
41 {HKEY(strof(QR2_MODERATED))},
42 {HKEY(strof(QR2_NOUPLMSG))},
59 QRVec = NewStrBufPlain(NULL, 256);
63 if (StrLength(QRVec) > 0)
64 StrBufAppendBufPlain(QRVec, HKEY(" | "), 0);
65 StrBufAppendBufPlain(QRVec, CKEY(QRFlagList[j]), 0);
70 syslog(LOG_DEBUG, "DBG: QR-Vec [%ld] [%s]\n", QR, ChrPtr(QRVec));
76 void _DBG_QR2(long QR2)
82 QR2Vec = NewStrBufPlain(NULL, 256);
86 if (StrLength(QR2Vec) > 0)
87 StrBufAppendBufPlain(QR2Vec, HKEY(" | "), 0);
88 StrBufAppendBufPlain(QR2Vec, CKEY(QR2FlagList[j]), 0);
93 syslog(LOG_DEBUG, "DBG: QR2-Vec [%ld] [%s]\n", QR2, ChrPtr(QR2Vec));
107 /*******************************************************************************
108 ***************************** Goto Commands ***********************************
109 ******************************************************************************/
112 smart_goto(sbstr("room"));
117 if (!havebstr("room")) {
118 readloop(readnew, eUseDefault);
121 if ((WCC->CurRoom.view != VIEW_MAILBOX) &&
122 (WCC->CurRoom.view != WCC->CurRoom.view)) {
123 /* dotgoto acts like dotskip when we're in a mailbox view */
126 smart_goto(sbstr("room"));
132 void smart_goto(const StrBuf *next_room) {
133 if (gotoroom(next_room) / 100 == 2)
134 readloop(readnew, eUseDefault);
140 * goto a private room
142 void goto_private(void)
146 const StrBuf *gr_name;
149 if (!havebstr("ok_button")) {
153 gr_name = sbstr("gr_name");
155 strcpy(hold_rm, ChrPtr(WC->CurRoom.name));
156 serv_printf("GOTO %s|%s",
159 StrBuf_ServGetln(Buf);
160 if (GetServerStatus(Buf, &err) == 2) {
167 DoTemplate(HKEY("room_display_private"), NULL, &NoCtx);
171 StrBufCutLeft(Buf, 4);
172 AppendImportantMessage (SKEY(Buf));
173 Buf = NewStrBufPlain(HKEY("_BASEROOM_"));
180 * back end routine to take the session to a new room
182 long gotoroom(const StrBuf *gname)
186 static long ls = (-1L);
188 int room_name_supplied = 0;
192 /* on fail, should we fallback to _BASEROOM_? */
193 failvisibly = ibstr("failvisibly");
195 /* store ungoto information */
196 if (StrLength(gname) > 0) {
197 room_name_supplied = 1;
199 if (room_name_supplied) {
200 strcpy(WCC->ugname, ChrPtr(WCC->CurRoom.name));
201 if (!strcasecmp(ChrPtr(gname), "_BASEROOM_")) {
208 /* move to the new room */
209 if (room_name_supplied) {
210 serv_printf("GOTO %s", ChrPtr(gname));
213 /* or just refresh the current state... */
214 serv_printf("GOTO 00000000000000000000");
216 StrBuf_ServGetln(Buf);
217 if (GetServerStatus(Buf, &err) != 2) {
222 serv_puts("GOTO _BASEROOM_");
223 StrBuf_ServGetln(Buf);
225 * well, we know that this is the fallback case,
226 * but we're interested that the first command
227 * didn't work out in first place.
229 if (GetServerStatus(Buf, NULL) != 2) {
234 FlushFolder(&WCC->CurRoom);
235 ParseGoto(&WCC->CurRoom, Buf);
237 if (room_name_supplied) {
238 remove_march(WCC->CurRoom.name);
250 void ParseGoto(folder *room, StrBuf *Line)
258 if (StrLength(Line) < 4) {
262 /* ignore the commandstate... */
263 Pos = ChrPtr(Line) + 4;
265 if (room->RoomNameParts != NULL)
268 for (i=0; i < room->nRoomNameParts; i++)
269 FreeStrBuf(&room->RoomNameParts[i]);
270 free(room->RoomNameParts);
271 room->RoomNameParts = NULL;
276 pBuf = NewStrBufPlain(NULL, StrLength(Line));
279 memset(room, 0, sizeof(folder));
282 StrBufExtract_NextToken(room->name, Line, &Pos, '|');
284 room->nNewMessages = StrBufExtractNext_long(Line, &Pos, '|');
285 if (room->nNewMessages > 0)
286 room->RAFlags |= UA_HASNEWMSGS;
288 room->nTotalMessages = StrBufExtractNext_long(Line, &Pos, '|');
290 room->ShowInfo = StrBufExtractNext_long(Line, &Pos, '|');
292 room->QRFlags = StrBufExtractNext_long(Line, &Pos, '|');
294 DBG_QR(room->QRFlags);
296 room->HighestRead = StrBufExtractNext_long(Line, &Pos, '|');
297 room->LastMessageRead = StrBufExtractNext_long(Line, &Pos, '|');
299 room->is_inbox = StrBufExtractNext_long(Line, &Pos, '|');
301 flag = StrBufExtractNext_long(Line, &Pos, '|');
302 if (WCC->is_aide || flag) {
303 room->RAFlags |= UA_ADMINALLOWED;
306 room->UsersNewMAilboxMessages = StrBufExtractNext_long(Line, &Pos, '|');
308 room->floorid = StrBufExtractNext_int(Line, &Pos, '|');
310 room->view = StrBufExtractNext_long(Line, &Pos, '|');
312 room->defview = StrBufExtractNext_long(Line, &Pos, '|');
314 flag = StrBufExtractNext_long(Line, &Pos, '|');
316 room->RAFlags |= UA_ISTRASH;
318 room->QRFlags2 = StrBufExtractNext_long(Line, &Pos, '|');
319 DBG_QR2(room->QRFlags2);
321 /* find out, whether we are in a sub-room */
322 room->nRoomNameParts = StrBufNum_tokens(room->name, '\\');
323 if (room->nRoomNameParts > 1)
328 room->RoomNameParts = malloc(sizeof(StrBuf*) * (room->nRoomNameParts + 1));
329 memset(room->RoomNameParts, 0, sizeof(StrBuf*) * (room->nRoomNameParts + 1));
330 for (i=0; i < room->nRoomNameParts; i++)
332 room->RoomNameParts[i] = NewStrBuf();
333 StrBufExtract_NextToken(room->RoomNameParts[i],
334 room->name, &Pos, '\\');
338 /* Private mailboxes on the main floor get remapped to the personal folder */
339 if ((room->QRFlags & QR_MAILBOX) &&
340 (room->floorid == 0))
342 room->floorid = VIRTUAL_MY_FLOOR;
343 if ((room->nRoomNameParts == 1) &&
344 (StrLength(room->name) == 4) &&
345 (strcmp(ChrPtr(room->name), "Mail") == 0))
351 /* get a pointer to the floor we're on: */
352 if (WCC->Floors == NULL)
353 GetFloorListHash(NULL, NULL);
355 GetHash(WCC->Floors, IKEY(room->floorid), &vFloor);
356 room->Floor = (const Floor*) vFloor;
360 * Delete the current room
362 void delete_room(void)
364 StrBuf *Line = NewStrBuf();
365 const StrBuf *GoBstr;
367 GoBstr = sbstr("go");
371 if (gotoroom(GoBstr) == 200)
374 StrBuf_ServGetln(Line);
375 if (GetServerStatusMsg(Line, NULL, 1, 2) == 2) {
379 Buf = NewStrBufPlain(HKEY("_BASEROOM_"));
397 StrBuf *final_destination;
400 * If the forget-room routine fails for any reason, we fall back
401 * to the current room; otherwise, we go to the Lobby
403 final_destination = NewStrBufDup(WC->CurRoom.name);
405 if (havebstr("ok_button")) {
406 serv_printf("GOTO %s", ChrPtr(WC->CurRoom.name));
407 serv_getln(buf, sizeof buf);
410 serv_getln(buf, sizeof buf);
412 FlushStrBuf(final_destination);
413 StrBufAppendBufPlain(final_destination, HKEY("_BASEROOM_"), 0);
418 smart_goto(final_destination);
419 FreeStrBuf(&final_destination);
424 * mark all messages in current room as having been read
426 void slrp_highest(void)
430 serv_puts("SLRP HIGHEST");
431 serv_getln(buf, sizeof buf);
447 /*******************************************************************************
448 ***************************** Modify Rooms ************************************
449 ******************************************************************************/
455 void LoadRoomAide(void)
460 if (WCC->CurRoom.RoomAideLoaded)
463 WCC->CurRoom.RoomAideLoaded = 1;
466 StrBuf_ServGetln(Buf);
467 if (GetServerStatus(Buf, NULL) != 2) {
468 FlushStrBuf(WCC->CurRoom.RoomAide);
469 AppendImportantMessage (ChrPtr(Buf) + 4,
474 Pos = ChrPtr(Buf) + 4;
476 FreeStrBuf(&WCC->CurRoom.RoomAide);
477 WCC->CurRoom.RoomAide = NewStrBufPlain (NULL, StrLength (Buf));
479 StrBufExtract_NextToken(WCC->CurRoom.RoomAide, Buf, &Pos, '|');
484 int SaveRoomAide(folder *Room)
488 serv_printf("SETA %s", ChrPtr(Room->RoomAide));
489 StrBuf_ServGetln(Buf);
490 if (GetServerStatus(Buf, NULL) != 2) {
491 StrBufCutLeft(Buf, 4);
492 AppendImportantMessage (SKEY(Buf));
501 int GetCurrentRoomFlags(folder *Room, int CareForStatusMessage)
507 StrBuf_ServGetln(Buf);
508 if (GetServerStatus(Buf, NULL) != 2) {
509 FlushStrBuf(Room->XAPass);
510 FlushStrBuf(Room->Directory);
511 StrBufCutLeft(Buf, 4);
512 if (CareForStatusMessage)
513 AppendImportantMessage (SKEY(Buf));
520 Pos = ChrPtr(Buf) + 4;
522 FreeStrBuf(&Room->XAPass);
523 FreeStrBuf(&Room->Directory);
525 Room->XAPass = NewStrBufPlain (NULL, StrLength (Buf));
526 Room->Directory = NewStrBufPlain (NULL, StrLength (Buf));
528 FreeStrBuf(&Room->name);
529 Room->name = NewStrBufPlain(NULL, StrLength(Buf));
530 StrBufExtract_NextToken(Room->name, Buf, &Pos, '|');
532 StrBufExtract_NextToken(Room->XAPass, Buf, &Pos, '|');
533 StrBufExtract_NextToken(Room->Directory, Buf, &Pos, '|');
535 Room->QRFlags = StrBufExtractNext_long(Buf, &Pos, '|');
536 Room->floorid = StrBufExtractNext_long(Buf, &Pos, '|');
537 Room->Order = StrBufExtractNext_long(Buf, &Pos, '|');
538 Room->defview = StrBufExtractNext_long(Buf, &Pos, '|');
539 Room->QRFlags2 = StrBufExtractNext_long(Buf, &Pos, '|');
547 int SetCurrentRoomFlags(folder *Room)
552 DBG_QR(Room->QRFlags);
553 DBG_QR2(Room->QRFlags2);
555 serv_printf("SETR %s|%s|%s|%ld|%d|%d|%ld|%ld|%ld",
557 ChrPtr(Room->XAPass),
558 ChrPtr(Room->Directory),
566 StrBuf_ServGetln(Buf);
567 if (GetServerStatus(Buf, NULL) != 2) {
568 StrBufCutLeft(Buf, 4);
569 AppendImportantMessage (SKEY(Buf));
578 void LoadRoomXA (void)
582 if (WCC->CurRoom.XALoaded > 0)
585 GetCurrentRoomFlags(&WCC->CurRoom, 0);
589 void LoadXRoomPic(void)
595 if (WCC->CurRoom.XHaveRoomPicLoaded) {
599 WCC->CurRoom.XHaveRoomPicLoaded = 1;
602 StrBuf_ServGetln(Buf);
603 if (GetServerStatus(Buf, NULL) == 6) {
604 StrBufCutLeft(Buf, 4);
605 bytes = StrBufExtract_long(Buf, 0, '|');
606 WCC->CurRoom.XHaveRoomPic = 1;
607 StrBuf_ServGetBLOBBuffered(Buf, bytes); // discard the data
609 WCC->CurRoom.XHaveRoomPic = 0;
615 void LoadXRoomInfoText(void)
621 if (WCC->CurRoom.XHaveInfoTextLoaded) {
625 WCC->CurRoom.XHaveInfoTextLoaded = 1;
630 StrBuf_ServGetln(Buf);
631 if (GetServerStatus(Buf, NULL) == 1) {
632 WCC->CurRoom.XInfoText = NewStrBuf ();
634 while (!Done && StrBuf_ServGetln(Buf)>=0) {
635 if ( (StrLength(Buf)==3) &&
636 !strcmp(ChrPtr(Buf), "000"))
639 StrBufAppendBuf(WCC->CurRoom.XInfoText, Buf, 0);
647 void LoadXRoomXCountFiles(void)
653 if (WCC->CurRoom.XHaveDownloadCount)
656 WCC->CurRoom.XHaveDownloadCount = 1;
660 StrBuf_ServGetln(Buf);
661 if (GetServerStatus(Buf, NULL) == 1) {
663 while (!Done && StrBuf_ServGetln(Buf)>=0) {
664 if ( (StrLength(Buf)==3) &&
665 !strcmp(ChrPtr(Buf), "000"))
668 WCC->CurRoom.XDownloadCount++;
677 * Toggle self-service list subscription
679 void toggle_self_service(void) {
682 if (GetCurrentRoomFlags (&WCC->CurRoom, 1) == 0)
685 if (yesbstr("QR2_SelfList"))
686 WCC->CurRoom.QRFlags2 = WCC->CurRoom.QRFlags2 | QR2_SELFLIST;
688 WCC->CurRoom.QRFlags2 = WCC->CurRoom.QRFlags2 & ~QR2_SELFLIST;
690 if (yesbstr("QR2_SMTP_PUBLIC"))
691 WCC->CurRoom.QRFlags2 = WCC->CurRoom.QRFlags2 | QR2_SMTP_PUBLIC;
693 WCC->CurRoom.QRFlags2 = WCC->CurRoom.QRFlags2 & ~QR2_SMTP_PUBLIC;
695 if (yesbstr("QR2_Moderated"))
696 WCC->CurRoom.QRFlags2 = WCC->CurRoom.QRFlags2 | QR2_MODERATED;
698 WCC->CurRoom.QRFlags2 = WCC->CurRoom.QRFlags2 & ~QR2_MODERATED;
699 if (yesbstr("QR2_SubsOnly"))
700 WCC->CurRoom.QRFlags2 = WCC->CurRoom.QRFlags2 | QR2_SMTP_PUBLIC;
702 WCC->CurRoom.QRFlags2 = WCC->CurRoom.QRFlags2 & ~QR2_SMTP_PUBLIC;
704 SetCurrentRoomFlags (&WCC->CurRoom);
706 output_headers(1, 1, 1, 0, 0, 0);
707 do_template("room_edit");
714 * save new parameters for a room
720 const StrBuf *er_name;
721 const StrBuf *er_password;
722 const StrBuf *er_dirname;
723 const StrBuf *er_roomaide;
727 templ = sbstr("template");
728 if (!havebstr("ok_button")) {
729 putlbstr("success", 0);
730 AppendImportantMessage(_("Cancelled. Changes were not saved."), -1);
732 output_headers(1, 0, 0, 0, 0, 0);
733 DoTemplate(SKEY(templ), NULL, &NoCtx);
737 output_headers(1, 1, 1, 0, 0, 0);
738 do_template("room_edit");
744 if (GetCurrentRoomFlags (&WCC->CurRoom, 1) == 0) {
745 putlbstr("success", 0);
747 output_headers(1, 0, 0, 0, 0, 0);
748 DoTemplate(SKEY(templ), NULL, &NoCtx);
752 output_headers(1, 1, 1, 0, 0, 0);
753 do_template("room_edit");
760 WCC->CurRoom.QRFlags &= !(QR_PRIVATE | QR_PASSWORDED | QR_GUESSNAME);
763 if (!strcmp(ChrPtr(Ptr), "invonly")) {
764 WCC->CurRoom.QRFlags |= (QR_PRIVATE);
766 if (!strcmp(ChrPtr(Ptr), "hidden")) {
767 WCC->CurRoom.QRFlags |= (QR_PRIVATE | QR_GUESSNAME);
769 if (!strcmp(ChrPtr(Ptr), "passworded")) {
770 WCC->CurRoom.QRFlags |= (QR_PRIVATE | QR_PASSWORDED);
772 if (!strcmp(ChrPtr(Ptr), "personal")) {
773 WCC->CurRoom.QRFlags |= QR_MAILBOX;
775 WCC->CurRoom.QRFlags &= ~QR_MAILBOX;
778 if (yesbstr("prefonly")) {
779 WCC->CurRoom.QRFlags |= QR_PREFONLY;
781 WCC->CurRoom.QRFlags &= ~QR_PREFONLY;
784 if (yesbstr("readonly")) {
785 WCC->CurRoom.QRFlags |= QR_READONLY;
787 WCC->CurRoom.QRFlags &= ~QR_READONLY;
790 if (yesbstr("collabdel")) {
791 WCC->CurRoom.QRFlags2 |= QR2_COLLABDEL;
793 WCC->CurRoom.QRFlags2 &= ~QR2_COLLABDEL;
796 if (yesbstr("permanent")) {
797 WCC->CurRoom.QRFlags |= QR_PERMANENT;
799 WCC->CurRoom.QRFlags &= ~QR_PERMANENT;
802 if (yesbstr("subjectreq")) {
803 WCC->CurRoom.QRFlags2 |= QR2_SUBJECTREQ;
805 WCC->CurRoom.QRFlags2 &= ~QR2_SUBJECTREQ;
808 if (yesbstr("network")) {
809 WCC->CurRoom.QRFlags |= QR_NETWORK;
811 WCC->CurRoom.QRFlags &= ~QR_NETWORK;
814 if (yesbstr("directory")) {
815 WCC->CurRoom.QRFlags |= QR_DIRECTORY;
817 WCC->CurRoom.QRFlags &= ~QR_DIRECTORY;
820 if (yesbstr("ulallowed")) {
821 WCC->CurRoom.QRFlags |= QR_UPLOAD;
823 WCC->CurRoom.QRFlags &= ~QR_UPLOAD;
826 if (yesbstr("dlallowed")) {
827 WCC->CurRoom.QRFlags |= QR_DOWNLOAD;
829 WCC->CurRoom.QRFlags &= ~QR_DOWNLOAD;
832 if (yesbstr("ulmsg")) {
833 WCC->CurRoom.QRFlags2 |= QR2_NOUPLMSG;
835 WCC->CurRoom.QRFlags2 &= ~QR2_NOUPLMSG;
838 if (yesbstr("visdir")) {
839 WCC->CurRoom.QRFlags |= QR_VISDIR;
841 WCC->CurRoom.QRFlags &= ~QR_VISDIR;
846 WCC->CurRoom.QRFlags &= ~(QR_ANONONLY | QR_ANONOPT);
847 if (!strcmp(ChrPtr(Ptr), "anononly"))
848 WCC->CurRoom.QRFlags |= QR_ANONONLY;
849 if (!strcmp(ChrPtr(Ptr), "anon2"))
850 WCC->CurRoom.QRFlags |= QR_ANONOPT;
852 er_name = sbstr("er_name");
853 er_dirname = sbstr("er_dirname");
854 er_roomaide = sbstr("er_roomaide");
855 er_password = sbstr("er_password");
857 FlushStrBuf(WCC->CurRoom.name);
858 StrBufAppendBuf(WCC->CurRoom.name, er_name, 0);
860 FlushStrBuf(WCC->CurRoom.Directory);
861 StrBufAppendBuf(WCC->CurRoom.Directory, er_dirname, 0);
863 FlushStrBuf(WCC->CurRoom.RoomAide);
864 StrBufAppendBuf(WCC->CurRoom.RoomAide, er_roomaide, 0);
866 FlushStrBuf(WCC->CurRoom.XAPass);
867 StrBufAppendBuf(WCC->CurRoom.XAPass, er_password, 0);
869 WCC->CurRoom.BumpUsers = yesbstr("bump");
871 WCC->CurRoom.floorid = ibstr("er_floor");
873 succ1 = SetCurrentRoomFlags(&WCC->CurRoom);
875 succ2 = SaveRoomAide (&WCC->CurRoom);
877 if (succ1 + succ2 == 0) {
878 putlbstr("success", 1);
879 AppendImportantMessage (_("Your changes have been saved."), -1);
882 putlbstr("success", 0);
885 output_headers(1, 0, 0, 0, 0, 0);
886 DoTemplate(SKEY(templ), NULL, &NoCtx);
890 output_headers(1, 1, 1, 0, 0, 0);
891 do_template("room_edit");
900 * Display form for Invite, Kick, and show Who Knows a room
902 void do_invt_kick(void)
905 const StrBuf *UserNames;
910 if (GetCurrentRoomFlags(&WCC->CurRoom, 1) == 1)
913 UserNames = sbstr("username");
914 Kick = havebstr("kick_button");
915 Invite = havebstr("invite_button");
917 User = NewStrBufPlain(NULL, StrLength(UserNames));
920 Pos = ChrPtr(UserNames);
921 while (Pos != StrBufNOTNULL)
923 StrBufExtract_NextToken(User, UserNames, &Pos, ',');
925 if ((StrLength(User) > 0) && (Kick))
927 serv_printf("KICK %s", ChrPtr(User));
928 if (StrBuf_ServGetln(Buf) < 0)
930 if (GetServerStatus(Buf, NULL) != 2) {
931 StrBufCutLeft(Buf, 4);
932 AppendImportantMessage(SKEY(Buf));
935 _("User '%s' kicked out of room '%s'."),
937 ChrPtr(WCC->CurRoom.name)
939 AppendImportantMessage(SKEY(Buf));
942 else if ((StrLength(User) > 0) && (Invite))
944 serv_printf("INVT %s", ChrPtr(User));
945 if (StrBuf_ServGetln(Buf) < 0)
947 if (GetServerStatus(Buf, NULL) != 2) {
948 StrBufCutLeft(Buf, 4);
949 AppendImportantMessage(SKEY(Buf));
952 _("User '%s' invited to room '%s'."),
954 ChrPtr(WCC->CurRoom.name)
956 AppendImportantMessage(SKEY(Buf));
962 output_headers(1, 1, 1, 0, 0, 0);
963 do_template("room_edit");
974 const StrBuf *er_name;
975 const StrBuf *er_type;
976 const StrBuf *er_password;
977 const StrBuf *template;
983 template = sbstr("template");
984 if ((WCC == NULL) || !havebstr("ok_button")) {
985 putlbstr("success", 0);
986 AppendImportantMessage(_("Cancelled. No new room was created."), -1);
987 if (template != NULL) {
988 output_headers(1, 0, 0, 0, 0, 0);
989 DoTemplate(SKEY(template), NULL, &NoCtx);
997 er_name = sbstr("er_name");
998 er_type = sbstr("type");
999 er_password = sbstr("er_password");
1000 er_floor = ibstr("er_floor");
1001 er_view = ibstr("er_view");
1004 if (!strcmp(ChrPtr(er_type), "hidden"))
1006 else if (!strcmp(ChrPtr(er_type), "passworded"))
1008 else if (!strcmp(ChrPtr(er_type), "invonly"))
1010 else if (!strcmp(ChrPtr(er_type), "personal"))
1013 serv_printf("CRE8 1|%s|%d|%s|%d|%d|%d",
1016 ChrPtr(er_password),
1022 StrBuf_ServGetln(Line);
1023 if (GetServerStatusMsg(Line, NULL, 1, 2) != 2) {
1024 putlbstr("success", 0);
1026 if (template != NULL) {
1027 output_headers(1, 0, 0, 0, 0, 0);
1028 DoTemplate(SKEY(template), NULL, &NoCtx);
1032 display_main_menu();
1036 /** TODO: Room created, now update the left hand icon bar for this user */
1039 serv_printf("VIEW %d", er_view);
1040 StrBuf_ServGetln(Line);
1041 FreeStrBuf(&Line); /* TODO: should we care about errors? */
1042 WCC->CurRoom.view = er_view;
1044 putlbstr("success", 1);
1045 if (template != NULL) {
1046 output_headers(1, 0, 0, 0, 0, 0);
1047 DoTemplate(SKEY(template), NULL, &NoCtx);
1050 else if ( (WCC->CurRoom.RAFlags & UA_ADMINALLOWED) != 0) {
1051 output_headers(1, 1, 1, 0, 0, 0);
1052 do_template("room_edit");
1055 smart_goto(WCC->CurRoom.name);
1065 * Change the view for this room
1067 void change_view(void) {
1071 newview = lbstr("view");
1072 serv_printf("VIEW %d", newview);
1073 serv_getln(buf, sizeof buf);
1074 WC->CurRoom.view = newview;
1075 smart_goto(WC->CurRoom.name);
1081 * Set the message expire policy for this room and/or floor
1083 void set_room_policy(void) {
1086 if (!havebstr("ok_button")) {
1087 AppendImportantMessage(_("Cancelled. Changes were not saved."), -1);
1088 output_headers(1, 1, 1, 0, 0, 0);
1089 do_template("room_edit");
1096 serv_printf("SPEX room|%d|%d", ibstr("roompolicy"), ibstr("roomvalue"));
1097 StrBuf_ServGetln(Line);
1098 GetServerStatusMsg(Line, NULL, 1, 0);
1099 if (WC->axlevel >= 6) {
1100 serv_printf("SPEX floor|%d|%d", ibstr("floorpolicy"), ibstr("floorvalue"));
1101 StrBuf_ServGetln(Line);
1102 GetServerStatusMsg(Line, NULL, 1, 0);
1105 ReloadCurrentRoom();
1107 output_headers(1, 1, 1, 0, 0, 0);
1108 do_template("room_edit");
1115 * Perform changes to a room's network configuration
1117 void netedit(void) {
1128 int malias_set_default = 0;
1133 if (havebstr("force_room")) {
1134 gotoroom(sbstr("force_room"));
1136 /*/ TODO: do line dynamic! */
1137 if (havebstr("line_pop3host")) {
1138 strcpy(line, bstr("prefix"));
1139 strcat(line, bstr("line_pop3host"));
1141 strcat(line, bstr("line_pop3user"));
1143 strcat(line, bstr("line_pop3pass"));
1145 strcat(line, ibstr("line_pop3keep") ? "1" : "0" );
1147 sprintf(&line[strlen(line)],"%ld", lbstr("line_pop3int"));
1148 strcat(line, bstr("suffix"));
1150 else if (havebstr("line")) {
1151 strcpy(line, bstr("prefix"));
1152 strcat(line, bstr("line"));
1153 strcat(line, bstr("suffix"));
1155 else if (havebstr("alias")) {
1157 domain = bstr("aliasdomain");
1158 if ((domain == NULL) || IsEmptyStr(domain))
1160 malias_set_default = 1;
1161 strcpy(line, bstr("prefix"));
1162 strcat(line, bstr("default_aliasdomain"));
1168 strcat(line, bstr("prefix"));
1169 if (!IsEmptyStr(domain))
1172 strcat(line, domain);
1175 strcat(line, "room_");
1176 strcat(line, ChrPtr(WC->CurRoom.name));
1180 output_headers(1, 1, 1, 0, 0, 0);
1181 do_template("room_edit");
1187 TmpBuf = NewStrBuf();
1189 serv_puts("GNET "FILE_MAILALIAS);
1192 StrBuf_ServGetln(Line);
1193 if (GetServerStatus(Line, NULL) != 1) {
1194 AppendImportantMessage(SRV_STATUS_MSG(Line));
1196 output_headers(1, 1, 1, 0, 0, 0);
1197 do_template("room_edit");
1202 /** This loop works for add *or* remove. Spiffy, eh? */
1204 extract_token(cmpb0, line, 0, sepchar, sizeof cmpb0);
1205 extract_token(cmpb1, line, 1, sepchar, sizeof cmpb1);
1206 while (!Done && StrBuf_ServGetln(Line)>=0) {
1207 if ( (StrLength(Line)==3) &&
1208 !strcmp(ChrPtr(Line), "000"))
1214 if (StrLength(Line) == 0)
1217 if (malias_set_default)
1219 if (strncasecmp(ChrPtr(Line), HKEY("roommailalias|")) != 0)
1221 StrBufAppendBufPlain(Line, HKEY("\n"), 0);
1222 StrBufAppendBuf(TmpBuf, Line, 0);
1227 extract_token(cmpa0, ChrPtr(Line), 0, sepchar, sizeof cmpa0);
1228 extract_token(cmpa1, ChrPtr(Line), 1, sepchar, sizeof cmpa1);
1229 if ( (strcasecmp(cmpa0, cmpb0)) || (strcasecmp(cmpa1, cmpb1)) )
1231 StrBufAppendBufPlain(Line, HKEY("\n"), 0);
1232 StrBufAppendBuf(TmpBuf, Line, 0);
1239 serv_puts("SNET "FILE_MAILALIAS);
1242 StrBuf_ServGetln(Line);
1243 if (GetServerStatus(Line, NULL) != 4) {
1245 AppendImportantMessage(SRV_STATUS_MSG(Line));
1246 output_headers(1, 1, 1, 0, 0, 0);
1247 do_template("room_edit");
1250 FreeStrBuf(&TmpBuf);
1254 serv_putbuf(TmpBuf);
1255 FreeStrBuf(&TmpBuf);
1257 if (havebstr("add_button")) {
1258 num_addrs = num_tokens(bstr("line"), ',');
1259 if (num_addrs < 2) {
1260 /* just adding one node or address */
1264 /* adding multiple addresses separated by commas */
1265 for (i=0; i<num_addrs; ++i) {
1266 strcpy(line, bstr("prefix"));
1267 extract_token(buf, bstr("line"), i, ',', sizeof buf);
1270 strcat(line, bstr("suffix"));
1278 StrBuf_ServGetln(Line);
1279 if (GetServerStatus(Line, NULL) != 2) { /* WHOOOPS? ERROR? */
1280 AppendImportantMessage(SRV_STATUS_MSG(Line));
1281 StrBuf_ServGetln(Line); /* resync... */
1285 FlushIgnetCfgs(&WC->CurRoom);
1288 output_headers(1, 1, 1, 0, 0, 0);
1289 do_template("room_edit");
1294 * Known rooms list (box style)
1298 DeleteHash(&WC->Rooms);
1299 output_headers(1, 1, 1, 0, 0, 0);
1300 do_template("knrooms");
1321 /*******************************************************************************
1322 ********************** FLOOR Coomands *****************************************
1323 ******************************************************************************/
1328 * delete the actual floor
1330 void delete_floor(void) {
1335 floornum = ibstr("floornum");
1337 serv_printf("KFLR %d|1", floornum);
1339 StrBufTCP_read_line(Buf, &WC->serv_sock, 0, &Err);
1341 if (GetServerStatus(Buf, NULL) == 2) {
1342 StrBufPlain(Buf, _("Floor has been deleted."),-1);
1345 StrBufCutLeft(Buf, 4);
1347 AppendImportantMessage (SKEY(Buf));
1350 http_transmit_thing(ChrPtr(do_template("floors")), 0);
1355 * start creating a new floor
1357 void create_floor(void) {
1362 serv_printf("CFLR %s|1", bstr("floorname"));
1363 StrBufTCP_read_line(Buf, &WC->serv_sock, 0, &Err);
1365 if (GetServerStatus(Buf, NULL) == 2) {
1366 StrBufPlain(Buf, _("New floor has been created."),-1);
1369 StrBufCutLeft(Buf, 4);
1371 AppendImportantMessage (SKEY(Buf));
1373 http_transmit_thing(ChrPtr(do_template("floors")), 0);
1381 void rename_floor(void) {
1387 serv_printf("EFLR %d|%s", ibstr("floornum"), bstr("floorname"));
1388 StrBuf_ServGetln(Buf);
1390 StrBufCutLeft(Buf, 4);
1391 AppendImportantMessage (SKEY(Buf));
1393 http_transmit_thing(ChrPtr(do_template("floors")), 0);
1399 void jsonRoomFlr(void)
1401 /* Send as our own (application/json) content type */
1402 hprintf("HTTP/1.1 200 OK\r\n");
1403 hprintf("Content-type: application/json; charset=utf-8\r\n");
1404 hprintf("Server: %s / %s\r\n", PACKAGE_STRING, ChrPtr(WC->serv_info->serv_software));
1405 hprintf("Connection: close\r\n");
1406 hprintf("Pragma: no-cache\r\nCache-Control: no-store\r\nExpires:-1\r\n");
1408 DoTemplate(HKEY("json_roomflr"),NULL,&NoCtx);
1412 void _FlushRoomList(wcsession *WCC)
1414 free_march_list(WCC);
1415 DeleteHash(&WCC->Floors);
1416 DeleteHash(&WCC->Rooms);
1417 DeleteHash(&WCC->FloorsByName);
1418 FlushFolder(&WCC->CurRoom);
1421 void ReloadCurrentRoom(void)
1423 wcsession *WCC = WC;
1426 CurRoom = WCC->CurRoom.name;
1427 WCC->CurRoom.name = NULL;
1428 _FlushRoomList(WCC);
1430 FreeStrBuf(&CurRoom);
1433 void FlushRoomlist(void)
1435 wcsession *WCC = WC;
1436 _FlushRoomList(WCC);
1444 RegisterPreference("roomlistview",
1445 _("Room list view"),
1448 RegisterPreference("emptyfloors", _("Show empty floors"), PRF_YESNO, NULL);
1450 WebcitAddUrlHandler(HKEY("json_roomflr"), "", 0, jsonRoomFlr, 0);
1452 WebcitAddUrlHandler(HKEY("delete_floor"), "", 0, delete_floor, 0);
1453 WebcitAddUrlHandler(HKEY("rename_floor"), "", 0, rename_floor, 0);
1454 WebcitAddUrlHandler(HKEY("create_floor"), "", 0, create_floor, 0);
1456 WebcitAddUrlHandler(HKEY("knrooms"), "", 0, knrooms, ANONYMOUS);
1457 WebcitAddUrlHandler(HKEY("dotgoto"), "", 0, dotgoto, NEED_URL);
1458 WebcitAddUrlHandler(HKEY("dotskip"), "", 0, dotskip, NEED_URL);
1460 WebcitAddUrlHandler(HKEY("goto_private"), "", 0, goto_private, NEED_URL);
1461 WebcitAddUrlHandler(HKEY("zap"), "", 0, zap, 0);
1462 WebcitAddUrlHandler(HKEY("entroom"), "", 0, entroom, 0);
1463 WebcitAddUrlHandler(HKEY("do_invt_kick"), "", 0, do_invt_kick, 0);
1465 WebcitAddUrlHandler(HKEY("netedit"), "", 0, netedit, 0);
1466 WebcitAddUrlHandler(HKEY("editroom"), "", 0, editroom, 0);
1467 WebcitAddUrlHandler(HKEY("delete_room"), "", 0, delete_room, 0);
1468 WebcitAddUrlHandler(HKEY("set_room_policy"), "", 0, set_room_policy, 0);
1469 WebcitAddUrlHandler(HKEY("changeview"), "", 0, change_view, 0);
1470 WebcitAddUrlHandler(HKEY("toggle_self_service"), "", 0, toggle_self_service, 0);
1473 REGISTERTokenParamDefine(QR_PERMANENT);
1474 REGISTERTokenParamDefine(QR_INUSE);
1475 REGISTERTokenParamDefine(QR_PRIVATE);
1476 REGISTERTokenParamDefine(QR_PASSWORDED);
1477 REGISTERTokenParamDefine(QR_GUESSNAME);
1478 REGISTERTokenParamDefine(QR_DIRECTORY);
1479 REGISTERTokenParamDefine(QR_UPLOAD);
1480 REGISTERTokenParamDefine(QR_DOWNLOAD);
1481 REGISTERTokenParamDefine(QR_VISDIR);
1482 REGISTERTokenParamDefine(QR_ANONONLY);
1483 REGISTERTokenParamDefine(QR_ANONOPT);
1484 REGISTERTokenParamDefine(QR_NETWORK);
1485 REGISTERTokenParamDefine(QR_PREFONLY);
1486 REGISTERTokenParamDefine(QR_READONLY);
1487 REGISTERTokenParamDefine(QR_MAILBOX);
1488 REGISTERTokenParamDefine(QR2_SYSTEM);
1489 REGISTERTokenParamDefine(QR2_SELFLIST);
1490 REGISTERTokenParamDefine(QR2_COLLABDEL);
1491 REGISTERTokenParamDefine(QR2_SUBJECTREQ);
1492 REGISTERTokenParamDefine(QR2_SMTP_PUBLIC);
1493 REGISTERTokenParamDefine(QR2_MODERATED);
1494 REGISTERTokenParamDefine(QR2_NOUPLMSG);
1496 REGISTERTokenParamDefine(UA_KNOWN);
1497 REGISTERTokenParamDefine(UA_GOTOALLOWED);
1498 REGISTERTokenParamDefine(UA_HASNEWMSGS);
1499 REGISTERTokenParamDefine(UA_ZAPPED);
1500 REGISTERTokenParamDefine(UA_POSTALLOWED);
1501 REGISTERTokenParamDefine(UA_ADMINALLOWED);
1502 REGISTERTokenParamDefine(UA_DELETEALLOWED);
1503 REGISTERTokenParamDefine(UA_REPLYALLOWED);
1504 REGISTERTokenParamDefine(UA_ISTRASH);
1506 REGISTERTokenParamDefine(US_NEEDVALID);
1507 REGISTERTokenParamDefine(US_PERM);
1508 REGISTERTokenParamDefine(US_LASTOLD);
1509 REGISTERTokenParamDefine(US_EXPERT);
1510 REGISTERTokenParamDefine(US_UNLISTED);
1511 REGISTERTokenParamDefine(US_NOPROMPT);
1512 REGISTERTokenParamDefine(US_PROMPTCTL);
1513 REGISTERTokenParamDefine(US_DISAPPEAR);
1514 REGISTERTokenParamDefine(US_REGIS);
1515 REGISTERTokenParamDefine(US_PAGINATOR);
1516 REGISTERTokenParamDefine(US_INTERNET);
1517 REGISTERTokenParamDefine(US_FLOORS);
1518 REGISTERTokenParamDefine(US_COLOR);
1519 REGISTERTokenParamDefine(US_USER_SET);
1521 REGISTERTokenParamDefine(VIEW_BBS);
1522 REGISTERTokenParamDefine(VIEW_MAILBOX);
1523 REGISTERTokenParamDefine(VIEW_ADDRESSBOOK);
1524 REGISTERTokenParamDefine(VIEW_CALENDAR);
1525 REGISTERTokenParamDefine(VIEW_TASKS);
1526 REGISTERTokenParamDefine(VIEW_NOTES);
1527 REGISTERTokenParamDefine(VIEW_WIKI);
1528 REGISTERTokenParamDefine(VIEW_CALBRIEF);
1529 REGISTERTokenParamDefine(VIEW_JOURNAL);
1530 REGISTERTokenParamDefine(VIEW_BLOG);
1531 REGISTERTokenParamDefine(VIEW_QUEUE);
1532 REGISTERTokenParamDefine(VIEW_WIKIMD);
1535 /* server internal, we need to know but ignore them. */
1536 REGISTERTokenParamDefine(subpending);
1537 REGISTERTokenParamDefine(unsubpending);
1538 REGISTERTokenParamDefine(lastsent);
1540 REGISTERTokenParamDefine(ignet_push_share);
1541 { /* these are the parts of an IGNET push config */
1542 REGISTERTokenParamDefine(GNET_IGNET_NODE);
1543 REGISTERTokenParamDefine(GNET_IGNET_ROOM);
1545 REGISTERTokenParamDefine(listrecp);
1546 REGISTERTokenParamDefine(digestrecp);
1547 REGISTERTokenParamDefine(pop3client);
1548 { /* These are the parts of a pop3 client line... */
1549 REGISTERTokenParamDefine(GNET_POP3_HOST);
1550 REGISTERTokenParamDefine(GNET_POP3_USER);
1551 REGISTERTokenParamDefine(GNET_POP3_DONT_DELETE_REMOTE);
1552 REGISTERTokenParamDefine(GNET_POP3_INTERVAL);
1554 REGISTERTokenParamDefine(rssclient);
1555 REGISTERTokenParamDefine(participate);
1556 REGISTERTokenParamDefine(roommailalias);
1564 SessionDestroyModule_ROOMOPS
1567 _FlushRoomList (sess);