+/* $Id$ */
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include "msgbase.h"
#include "serv_chat.h"
#include "citserver.h"
+#include "control.h"
/*
* Generic routine for determining user access to rooms
int retval = 0;
struct visit vbuf;
- /* Make sure we're dealing with a real, existing room */
- if (roombuf->QRflags & QR_INUSE) {
- retval = retval | UA_INUSE;
- }
- else {
- return(0);
- }
-
/* for internal programs, always do everything */
if (((CC->internal_pgm))&&(roombuf->QRflags & QR_INUSE)) {
- return(UA_INUSE | UA_KNOWN | UA_GOTOALLOWED);
+ return(UA_KNOWN | UA_GOTOALLOWED);
}
/* For mailbox rooms, only allow access to the owner */
/* Locate any applicable user/room relationships */
CtdlGetRelationship(&vbuf, userbuf, roombuf);
+ /* Force the properties of the Aide room */
+ if (!strcasecmp(roombuf->QRname, AIDEROOM)) {
+ if (userbuf->axlevel >= 6) {
+ retval = UA_KNOWN | UA_GOTOALLOWED;
+ }
+ else {
+ retval=0;
+ }
+ goto NEWMSG;
+ }
+
+ /* For mailboxes, we skip all the access stuff (and we've
+ * already checked by this point that the mailbox belongs
+ * to the user)
+ */
+ if (roombuf->QRflags & QR_MAILBOX) {
+ retval = UA_KNOWN | UA_GOTOALLOWED;
+ goto NEWMSG;
+ }
+
/* If this is a public room, it's accessible... */
if ((roombuf->QRflags & QR_PRIVATE) == 0) {
retval = retval | UA_KNOWN | UA_GOTOALLOWED;
/* Aides get access to everything */
if (userbuf->axlevel >= 6) {
- retval = retval | UA_INUSE | UA_KNOWN | UA_GOTOALLOWED;
+ retval = retval | UA_KNOWN | UA_GOTOALLOWED;
retval = retval & ~UA_ZAPPED;
}
- /* By the way, we also check for the presence of new messages */
+NEWMSG: /* By the way, we also check for the presence of new messages */
if ( (roombuf->QRhighest) > (vbuf.v_lastseen) ) {
retval = retval | UA_HASNEWMSGS;
}
char lowercase_name[ROOMNAMELEN];
int a;
- for (a=0; a<=strlen(room_name); ++a) {
+ for (a=0; room_name[a] && a < sizeof lowercase_name - 1; ++a) {
lowercase_name[a] = tolower(room_name[a]);
}
+ lowercase_name[a] = 0;
memset(qrbuf, 0, sizeof(struct quickroom));
cdbqr = cdb_fetch(CDB_QUICKROOM,
( (cdbqr->len > sizeof(struct quickroom)) ?
sizeof(struct quickroom) : cdbqr->len) );
cdb_free(cdbqr);
+
+ /* Mailbox rooms are always on the lowest floor */
+ if (qrbuf->QRflags & QR_MAILBOX) {
+ qrbuf->QRfloor = 0;
+ }
+
return(0);
}
else {
*/
void get_msglist(struct quickroom *whichroom) {
struct cdbdata *cdbfr;
- char dbkey[256];
- int a;
-
- lprintf(9, "get_msglist() called for <%s>\n", whichroom->QRname);
- sprintf(dbkey, "%s%ld", whichroom->QRname, whichroom->QRgen);
- for (a=0; a<strlen(dbkey); ++a) dbkey[a]=tolower(dbkey[a]);
- lprintf(9, "database key is <%s>\n", dbkey);
-
- lprintf(9, "Freeing existing message list\n");
+
if (CC->msglist != NULL) {
free(CC->msglist);
}
CC->msglist = NULL;
CC->num_msgs = 0;
- lprintf(9, "calling cdb_fetch\n");
- cdbfr = cdb_fetch(CDB_MSGLISTS, dbkey, strlen(dbkey));
- lprintf(9, "done\n");
-
+ cdbfr = cdb_fetch(CDB_MSGLISTS, &whichroom->QRnumber, sizeof(long));
if (cdbfr == NULL) {
return;
}
memcpy(CC->msglist, cdbfr->ptr, cdbfr->len);
CC->num_msgs = cdbfr->len / sizeof(long);
cdb_free(cdbfr);
- lprintf(9, "Leaving get_msglist()\n");
}
* put_msglist() - retrieve room message pointers
*/
void put_msglist(struct quickroom *whichroom) {
- char dbkey[256];
- int a;
- sprintf(dbkey, "%s%ld", whichroom->QRname, whichroom->QRgen);
- for (a=0; a<strlen(dbkey); ++a) dbkey[a]=tolower(dbkey[a]);
-
- cdb_store(CDB_MSGLISTS, dbkey, strlen(dbkey),
+ cdb_store(CDB_MSGLISTS, &whichroom->QRnumber, sizeof(long),
CC->msglist, CC->num_msgs * sizeof(long));
}
/*
* delete_msglist() - delete room message pointers
+ * FIX - this really should check first to make sure there's actually a
+ * msglist to delete. As things stand now, calling this function on
+ * a room which has never been posted in will result in a message
+ * like "gdbm: illegal data" (no big deal, but could use fixing).
*/
void delete_msglist(struct quickroom *whichroom) {
- char dbkey[256];
- int a;
- sprintf(dbkey, "%s%ld", whichroom->QRname, whichroom->QRgen);
- for (a=0; a<strlen(dbkey); ++a) dbkey[a]=tolower(dbkey[a]);
+ cdb_delete(CDB_MSGLISTS, &whichroom->QRnumber, sizeof(long));
+ }
+
+
+/*
+ * Add a message number to a room's message list.
+ * So, why doesn't this function use the get_msglist() and put_msglist() stuff
+ * defined above? Because the room the message number is being written to
+ * may not be the current room (as is the case with cmd_move() for example).
+ */
+void AddMessageToRoom(struct quickroom *whichroom, long newmsgid) {
+ struct cdbdata *cdbfr;
+ int num_msgs;
+ long *msglist;
+
+ cdbfr = cdb_fetch(CDB_MSGLISTS, &whichroom->QRnumber, sizeof(long));
+ if (cdbfr == NULL) {
+ msglist = NULL;
+ num_msgs = 0;
+ }
+ else {
+ msglist = malloc(cdbfr->len);
+ num_msgs = cdbfr->len / sizeof(long);
+ memcpy(msglist, cdbfr->ptr, cdbfr->len);
+ cdb_free(cdbfr);
+ }
+
+ /* Now add the new message */
+ ++num_msgs;
+ msglist = realloc(msglist,
+ (num_msgs * sizeof(long)) );
+
+ if (msglist == NULL) {
+ lprintf(3, "ERROR: can't realloc message list!\n");
+ }
+
+ msglist[num_msgs - 1] = newmsgid;
- cdb_delete(CDB_MSGLISTS, dbkey, strlen(dbkey));
+ /* Write it back to disk. */
+ cdb_store(CDB_MSGLISTS, &whichroom->QRnumber, sizeof(long),
+ msglist, num_msgs * sizeof(long));
+
+ /* And finally, free up the memory we used. */
+ free(msglist);
}
}
-
/*
- * Determine whether a given room is one of the base non-editable rooms
+ * Determine whether a given room is non-editable.
*/
int is_noneditable(struct quickroom *qrbuf) {
+
+ /* Lobby> and Aide> are non-editable */
if (!strcasecmp(qrbuf->QRname, BASEROOM)) return(1);
else if (!strcasecmp(qrbuf->QRname, AIDEROOM)) return(1);
+
+ /* Mailbox rooms are also non-editable */
+ else if (qrbuf->QRflags & QR_MAILBOX) return(1);
+
+ /* Everything else is editable */
else return(0);
}
+
+
+/*
+ * Back-back-end for all room listing commands
+ */
+void list_roomname(struct quickroom *qrbuf) {
+ char truncated_roomname[ROOMNAMELEN];
+
+ /* For mailbox rooms, chop off the owner prefix */
+ if (qrbuf->QRflags & QR_MAILBOX) {
+ strcpy(truncated_roomname, qrbuf->QRname);
+ strcpy(truncated_roomname, &truncated_roomname[11]);
+ cprintf("%s", truncated_roomname);
+ }
+ /* For all other rooms, just display the name in its entirety */
+ else {
+ cprintf("%s", qrbuf->QRname);
+ }
+
+ /* ...and now the other parameters */
+ cprintf("|%u|%d\n",
+ qrbuf->QRflags,qrbuf->QRfloor);
+ }
+
+
/*
* cmd_lrms() - List all accessible rooms, known or forgotten
*/
& (UA_KNOWN | UA_ZAPPED)))
&& ((qrbuf->QRfloor == (CC->FloorBeingSearched))
||((CC->FloorBeingSearched)<0)) )
- cprintf("%s|%u|%d\n",
- qrbuf->QRname,qrbuf->QRflags,qrbuf->QRfloor);
+ list_roomname(qrbuf);
}
void cmd_lrms(char *argbuf)
if ( ((CtdlRoomAccess(qrbuf, &CC->usersupp)
& (UA_KNOWN)))
&& ((qrbuf->QRfloor == (CC->FloorBeingSearched))
- ||((CC->FloorBeingSearched)<0)) )
- cprintf("%s|%u|%d\n",
- qrbuf->QRname,qrbuf->QRflags,qrbuf->QRfloor);
+ ||((CC->FloorBeingSearched)<0)) )
+ list_roomname(qrbuf);
}
void cmd_lkra(char *argbuf)
&& (ra & UA_HASNEWMSGS)
&& ((qrbuf->QRfloor == (CC->FloorBeingSearched))
||((CC->FloorBeingSearched)<0)) )
- cprintf("%s|%u|%d\n",
- qrbuf->QRname,qrbuf->QRflags,qrbuf->QRfloor);
+ list_roomname(qrbuf);
}
void cmd_lkrn(char *argbuf)
&& ((ra & UA_HASNEWMSGS)==0)
&& ((qrbuf->QRfloor == (CC->FloorBeingSearched))
||((CC->FloorBeingSearched)<0)) )
- cprintf("%s|%u|%d\n",
- qrbuf->QRname,qrbuf->QRflags,qrbuf->QRfloor);
+ list_roomname(qrbuf);
}
void cmd_lkro(char *argbuf)
&& (ra & UA_ZAPPED)
&& ((qrbuf->QRfloor == (CC->FloorBeingSearched))
||((CC->FloorBeingSearched)<0)) )
- cprintf("%s|%u|%d\n",
- qrbuf->QRname,qrbuf->QRflags,qrbuf->QRfloor);
+ list_roomname(qrbuf);
}
void cmd_lzrm(char *argbuf)
int raideflag;
int newmailcount = 0;
struct visit vbuf;
+ char truncated_roomname[ROOMNAMELEN];
strcpy(CC->quickroom.QRname, where);
- lprintf(9, "usergoto() fetching room record\n");
getroom(&CC->quickroom, where);
- lprintf(9, "usergoto() fetching user record\n");
lgetuser(&CC->usersupp,CC->curr_user);
- lprintf(9, "usergoto() fetching relationships\n");
CtdlGetRelationship(&vbuf, &CC->usersupp, &CC->quickroom);
vbuf.v_flags = vbuf.v_flags & ~V_FORGET & ~V_LOCKOUT;
CtdlSetRelationship(&vbuf, &CC->usersupp, &CC->quickroom);
lputuser(&CC->usersupp,CC->curr_user);
- lprintf(9, "usergoto() about to check for new mail\n");
/* check for new mail */
newmailcount = NewMailCount();
if (CC->quickroom.QRinfo > vbuf.v_lastseen) info = 1;
get_mm();
- lprintf(9, "Fetching message list for counting...\n");
get_msglist(&CC->quickroom);
for (a=0; a<CC->num_msgs; ++a) {
if (MessageFromList(a)>0L) {
}
}
}
- lprintf(9, "...done counting\n");
if (CC->quickroom.QRflags & QR_MAILBOX) rmailflag = 1;
else rmailflag = 0;
|| (CC->usersupp.axlevel>=6) ) raideflag = 1;
else raideflag = 0;
+ strcpy(truncated_roomname, CC->quickroom.QRname);
+ if (CC->quickroom.QRflags & QR_MAILBOX) {
+ strcpy(truncated_roomname, &truncated_roomname[11]);
+ }
+
if (display_result) cprintf("%d%c%s|%d|%d|%d|%d|%ld|%ld|%d|%d|%d|%d\n",
OK,check_express(),
- CC->quickroom.QRname,
+ truncated_roomname,
new_messages, total_messages,
info,CC->quickroom.QRflags,
CC->quickroom.QRhighest,
vbuf.v_lastseen,
rmailflag,raideflag,newmailcount,CC->quickroom.QRfloor);
- if (CC->quickroom.QRflags & QR_PRIVATE) {
- set_wtmpsupp("<private room>");
- }
- else {
- set_wtmpsupp(CC->quickroom.QRname);
- }
+ set_wtmpsupp_to_current_room();
}
int c;
int ok = 0;
int ra;
- char bbb[ROOMNAMELEN],towhere[32],password[20];
+ char augmented_roomname[256];
+ char towhere[256];
+ char password[256];
if ((!(CC->logged_in)) && (!(CC->internal_pgm))) {
cprintf("%d not logged in\n",ERROR+NOT_LOGGED_IN);
extract(towhere,gargs,0);
extract(password,gargs,1);
- c=0;
- getuser(&CC->usersupp,CC->curr_user);
+ getuser(&CC->usersupp, CC->curr_user);
if (!strcasecmp(towhere, "_BASEROOM_"))
strcpy(towhere, BASEROOM);
strcpy(towhere, config.c_twitroom);
- /* let internal programs go directly to any room */
- if (((CC->internal_pgm))&&(!strcasecmp(bbb,towhere))) {
- usergoto(towhere, 1);
- return;
+ /* First try a regular match */
+ c = getroom(&QRscratch, towhere);
+
+ /* Then try a mailbox name match */
+ if (c != 0) {
+ MailboxName(augmented_roomname, &CC->usersupp, towhere);
+ c = getroom(&QRscratch, augmented_roomname);
+ if (c == 0) strcpy(towhere, augmented_roomname);
}
- if (getroom(&QRscratch, towhere) == 0) {
+ /* And if the room was found... */
+ if (c == 0) {
+
+ /* let internal programs go directly to any room */
+ if (CC->internal_pgm) {
+ usergoto(towhere, 1);
+ return;
+ }
/* See if there is an existing user/room relationship */
ra = CtdlRoomAccess(&QRscratch, &CC->usersupp);
void cmd_setr(char *args) {
char buf[256];
struct floor flbuf;
+ char old_name[ROOMNAMELEN];
int old_floor;
if (!(CC->logged_in)) {
}
lgetroom(&CC->quickroom, CC->quickroom.QRname);
+ strcpy(old_name, CC->quickroom.QRname);
extract(buf,args,0); buf[ROOMNAMELEN]=0;
strncpy(CC->quickroom.QRname,buf,ROOMNAMELEN-1);
extract(buf,args,1); buf[10]=0;
CC->quickroom.QRfloor = extract_int(args,5);
}
+ /* Write the room record back to disk */
lputroom(&CC->quickroom, CC->quickroom.QRname);
+ /* If the room name changed, then there are now two room records,
+ * so we have to delete the old one.
+ */
+ /* FIX - This causes everybody to think it's a new room, because the
+ * visit structs no longer match! Major problem! We have to
+ * assign each room a unique Object ID and index by that.
+ */
+ if (strcasecmp(CC->quickroom.QRname, old_name)) {
+ putroom(NULL, old_name);
+ }
+
/* adjust the floor reference counts */
lgetfloor(&flbuf,old_floor);
--flbuf.f_ref_count;
char aaa[100];
int a;
+ lprintf(9, "Deleting room <%s>\n", qrbuf->QRname);
+
/* Delete the info file */
assoc_file_name(aaa, qrbuf, "info");
unlink(aaa);
qrbuf->QRflags=0;
/* then delete the messages in the room */
- lprintf(9, "calling get_msglist()\n");
get_msglist(qrbuf);
if (CC->num_msgs > 0) for (a=0; a < CC->num_msgs; ++a) {
MsgToDelete = MessageFromList(a);
- lprintf(9, "Deleting message %ld\n", MsgToDelete);
cdb_delete(CDB_MSGMAIN, &MsgToDelete, sizeof(long));
}
- lprintf(9, "calling put_msglist()\n");
put_msglist(qrbuf);
free(CC->msglist);
CC->msglist = NULL;
CC->num_msgs = 0;
- lprintf(9, "calling delete_msglist()\n");
delete_msglist(qrbuf);
lputroom(qrbuf, qrbuf->QRname);
/* Delete the room record from the database! */
putroom(NULL, qrbuf->QRname);
- lprintf(9, "finished with delete_room()\n");
}
if (kill_ok) {
strcpy(deleted_room_name, CC->quickroom.QRname);
delete_room(&CC->quickroom); /* Do the dirty work */
- lprintf(9, "Calling usergoto()\n");
usergoto(BASEROOM, 0); /* Return to the Lobby */
- lprintf(9, "Composing notice\n");
/* tell the world what we did */
sprintf(aaa,"%s> killed by %s",
deleted_room_name, CC->curr_user);
- lprintf(9, "Posting notice\n");
aide_message(aaa);
- lprintf(9, "done posting notice\n");
cprintf("%d '%s' deleted.\n", OK, deleted_room_name);
}
else {
strncpy(qrbuf.QRname,new_room_name,ROOMNAMELEN);
strncpy(qrbuf.QRpasswd,new_room_pass,9);
qrbuf.QRflags = QR_INUSE;
+ qrbuf.QRnumber = get_new_room_number();
if (new_room_type > 0) qrbuf.QRflags=(qrbuf.QRflags|QR_PRIVATE);
if (new_room_type == 1) qrbuf.QRflags=(qrbuf.QRflags|QR_GUESSNAME);
if (new_room_type == 2) qrbuf.QRflags=(qrbuf.QRflags|QR_PASSWORDED);