+/* $Id$ */
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/stat.h>
#include <string.h>
#include <pthread.h>
+#include <time.h>
+#include <limits.h>
#include "citadel.h"
#include "server.h"
#include "database.h"
#include "msgbase.h"
#include "serv_chat.h"
#include "citserver.h"
+#include "control.h"
/*
- * is_known() - returns nonzero if room is in user's known room list
+ * Generic routine for determining user access to rooms
*/
-int is_known(struct quickroom *roombuf, int roomnum, struct usersupp *userbuf)
-{
+int CtdlRoomAccess(struct quickroom *roombuf, struct usersupp *userbuf) {
+ int retval = 0;
+ struct visit vbuf;
- /* for internal programs, always succeed */
- if (((CC->internal_pgm))&&(roombuf->QRflags & QR_INUSE)) return(1);
+ /* for internal programs, always do everything */
+ if (((CC->internal_pgm))&&(roombuf->QRflags & QR_INUSE)) {
+ return(UA_KNOWN | UA_GOTOALLOWED);
+ }
- /* for regular rooms, check the permissions */
- if ((roombuf->QRflags & QR_INUSE)
- && ( (roomnum!=2) || (userbuf->axlevel>=6))
- && (roombuf->QRgen != (userbuf->forget[roomnum]) )
+ /* For mailbox rooms, only allow access to the owner */
+ if (roombuf->QRflags & QR_MAILBOX) {
+ if (userbuf->usernum != atol(roombuf->QRname)) {
+ return(retval);
+ }
+ }
- && ( ((roombuf->QRflags&QR_PREFONLY)==0)
- || ((userbuf->axlevel)>=5)
- )
+ /* Locate any applicable user/room relationships */
+ CtdlGetRelationship(&vbuf, userbuf, roombuf);
- && ( ((roombuf->QRflags&QR_PRIVATE)==0)
- || ((userbuf->axlevel)>=6)
- || (roombuf->QRgen==(userbuf->generation[roomnum]))
- )
+ /* 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;
+ }
- ) return(1);
- else return(0);
- }
+ /* 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;
+ }
-/*
- * has_newmsgs() - returns nonzero if room has new messages
- */
-int has_newmsgs(struct quickroom *roombuf, int roomnum, struct usersupp *userbuf)
-{
- if (roombuf->QRhighest > (userbuf->lastseen[roomnum]) )
- return(1);
- else return(0);
- }
+ /* If this is a preferred users only room, check access level */
+ if (roombuf->QRflags & QR_PREFONLY) {
+ if (userbuf->axlevel < 5) {
+ retval = retval & ~UA_KNOWN & ~UA_GOTOALLOWED;
+ }
+ }
-/*
- * is_zapped() - returns nonzero if room is on forgotten rooms list
- */
-int is_zapped(struct quickroom *roombuf, int roomnum, struct usersupp *userbuf)
-{
- if ((roombuf->QRflags & QR_INUSE)
- && (roombuf->QRgen == (userbuf->forget[roomnum]) )
- && ( (roomnum!=2) || ((userbuf->axlevel)>=6))
- && ( ((roombuf->QRflags&QR_PRIVATE)==0)
- || ((userbuf->axlevel)>=6)
- || (roombuf->QRgen==(userbuf->generation[roomnum]))
- )
- ) return(1);
- else return(0);
+ /* For private rooms, check the generation number matchups */
+ if (roombuf->QRflags & QR_PRIVATE) {
+
+ /* An explicit match means the user belongs in this room */
+ if (vbuf.v_flags & V_ACCESS) {
+ retval = retval | UA_KNOWN | UA_GOTOALLOWED;
+ }
+ /* Otherwise, check if this is a guess-name or passworded
+ * room. If it is, a goto may at least be attempted
+ */
+ else if ((roombuf->QRflags & QR_PRIVATE)
+ ||(roombuf->QRflags & QR_PASSWORDED)) {
+ retval = retval & ~UA_KNOWN;
+ retval = retval | UA_GOTOALLOWED;
+ }
+ }
+
+ /* Check to see if the user has forgotten this room */
+ if (vbuf.v_flags & V_FORGET) {
+ retval = retval & ~UA_KNOWN;
+ retval = retval | UA_ZAPPED;
+ }
+
+ /* If user is explicitly locked out of this room, deny everything */
+ if (vbuf.v_flags & V_LOCKOUT) {
+ retval = retval & ~UA_KNOWN & ~UA_GOTOALLOWED;
+ }
+
+ /* Aides get access to everything */
+ if (userbuf->axlevel >= 6) {
+ retval = retval | UA_KNOWN | UA_GOTOALLOWED;
+ retval = retval & ~UA_ZAPPED;
+ }
+
+NEWMSG: /* By the way, we also check for the presence of new messages */
+ if ( (roombuf->QRhighest) > (vbuf.v_lastseen) ) {
+ retval = retval | UA_HASNEWMSGS;
+ }
+
+ return(retval);
}
/*
* getroom() - retrieve room data from disk
*/
-void getroom(struct quickroom *qrbuf, int room_num)
+int getroom(struct quickroom *qrbuf, char *room_name)
{
struct cdbdata *cdbqr;
+ char lowercase_name[ROOMNAMELEN];
int a;
- bzero(qrbuf, sizeof(struct quickroom));
- cdbqr = cdb_fetch(CDB_QUICKROOM, &room_num, sizeof(int));
+ 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,
+ lowercase_name, strlen(lowercase_name));
if (cdbqr != NULL) {
memcpy(qrbuf, cdbqr->ptr,
( (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 {
- if (room_num < 3) {
- qrbuf->QRflags = QR_INUSE;
- qrbuf->QRgen = 1;
- switch(room_num) {
- case 0: strcpy(qrbuf->QRname, "Lobby");
- break;
- case 1: strcpy(qrbuf->QRname, "Mail");
- break;
- case 2: strcpy(qrbuf->QRname, "Aide");
- break;
- }
- }
+ return(1);
}
-
-
- /** FIX ** VILE SLEAZY HACK ALERT!!
- * This is a temporary fix until we can track down where room names
- * are getting corrupted on some systems.
- */
- for (a=0; a<20; ++a) if (qrbuf->QRname[a] < 32) qrbuf->QRname[a] = 0;
- qrbuf->QRname[19] = 0;
}
/*
* lgetroom() - same as getroom() but locks the record (if supported)
*/
-void lgetroom(struct quickroom *qrbuf, int room_num)
+int lgetroom(struct quickroom *qrbuf, char *room_name)
{
begin_critical_section(S_QUICKROOM);
- getroom(qrbuf,room_num);
+ return(getroom(qrbuf, room_name));
}
/*
* putroom() - store room data on disk
+ * (if the supplied buffer is NULL, delete the room record)
*/
-void putroom(struct quickroom *qrbuf, int room_num)
+void putroom(struct quickroom *qrbuf, char *room_name)
{
- time(&qrbuf->QRmtime);
- cdb_store(CDB_QUICKROOM, &room_num, sizeof(int),
- qrbuf, sizeof(struct quickroom));
+ char lowercase_name[ROOMNAMELEN];
+ int a;
+
+ for (a=0; a<=strlen(room_name); ++a) {
+ lowercase_name[a] = tolower(room_name[a]);
+ }
+
+ if (qrbuf == NULL) {
+ cdb_delete(CDB_QUICKROOM,
+ lowercase_name, strlen(lowercase_name));
+ }
+ else {
+ time(&qrbuf->QRmtime);
+ cdb_store(CDB_QUICKROOM,
+ lowercase_name, strlen(lowercase_name),
+ qrbuf, sizeof(struct quickroom));
+ }
}
/*
* lputroom() - same as putroom() but unlocks the record (if supported)
*/
-void lputroom(struct quickroom *qrbuf, int room_num)
+void lputroom(struct quickroom *qrbuf, char *room_name)
{
- putroom(qrbuf,room_num);
+ putroom(qrbuf, room_name);
end_critical_section(S_QUICKROOM);
}
+/****************************************************************************/
/*
* getfloor() - retrieve floor data from disk
{
struct cdbdata *cdbfl;
- bzero(flbuf, sizeof(struct floor));
+ memset(flbuf, 0, sizeof(struct floor));
cdbfl = cdb_fetch(CDB_FLOORTAB, &floor_num, sizeof(int));
if (cdbfl != NULL) {
memcpy(flbuf, cdbfl->ptr,
}
+/*
+ * Traverse the room file...
+ */
+void ForEachRoom(void (*CallBack)(struct quickroom *EachRoom)) {
+ struct quickroom qrbuf;
+ struct cdbdata *cdbqr;
+
+ cdb_rewind(CDB_QUICKROOM);
+
+ while(cdbqr = cdb_next_item(CDB_QUICKROOM), cdbqr != NULL) {
+ memset(&qrbuf, 0, sizeof(struct quickroom));
+ memcpy(&qrbuf, cdbqr->ptr,
+ ( (cdbqr->len > sizeof(struct quickroom)) ?
+ sizeof(struct quickroom) : cdbqr->len) );
+ cdb_free(cdbqr);
+ if (qrbuf.QRflags & QR_INUSE) (*CallBack)(&qrbuf);
+ }
+ }
+
+
/*
* get_msglist() - retrieve room message pointers
*/
-void get_msglist(int room_num)
-{
+void get_msglist(struct quickroom *whichroom) {
struct cdbdata *cdbfr;
if (CC->msglist != NULL) {
CC->msglist = NULL;
CC->num_msgs = 0;
- if (room_num != 1) {
- cdbfr = cdb_fetch(CDB_MSGLISTS, &room_num, sizeof(int));
- }
- else {
- cdbfr = cdb_fetch(CDB_MAILBOXES, &CC->usersupp.usernum,
- sizeof(long));
- }
-
+ cdbfr = cdb_fetch(CDB_MSGLISTS, &whichroom->QRnumber, sizeof(long));
if (cdbfr == NULL) {
return;
}
/*
* put_msglist() - retrieve room message pointers
*/
-void put_msglist(int room_num)
-{
+void put_msglist(struct quickroom *whichroom) {
+
+ 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) {
+
+ cdb_delete(CDB_MSGLISTS, &whichroom->QRnumber, sizeof(long));
+ }
- if (room_num != 1) {
- cdb_store(CDB_MSGLISTS, &room_num, sizeof(int),
- CC->msglist, (CC->num_msgs * 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 {
- cdb_store(CDB_MAILBOXES, &CC->usersupp.usernum, sizeof(long),
- CC->msglist, (CC->num_msgs * sizeof(long)) );
+ 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;
+
+ /* 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);
}
return(numitems);
}
-
+
+/*
+ * 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
*/
+void cmd_lrms_backend(struct quickroom *qrbuf) {
+ if ( ((CtdlRoomAccess(qrbuf, &CC->usersupp)
+ & (UA_KNOWN | UA_ZAPPED)))
+ && ((qrbuf->QRfloor == (CC->FloorBeingSearched))
+ ||((CC->FloorBeingSearched)<0)) )
+ list_roomname(qrbuf);
+ }
+
void cmd_lrms(char *argbuf)
{
- int a;
- int target_floor = (-1);
- struct quickroom qrbuf;
-
- if (strlen(argbuf)>0) target_floor = extract_int(argbuf,0);
+ CC->FloorBeingSearched = (-1);
+ if (strlen(argbuf)>0) CC->FloorBeingSearched = extract_int(argbuf,0);
if (!(CC->logged_in)) {
cprintf("%d Not logged in.\n",ERROR+NOT_LOGGED_IN);
}
cprintf("%d Accessible rooms:\n",LISTING_FOLLOWS);
-
- for (a=0; a<MAXROOMS; ++a) {
- getroom(&qrbuf,a);
- if ( ( (is_known(&qrbuf,a,&CC->usersupp))
- || (is_zapped(&qrbuf,a,&CC->usersupp)) )
- && ((qrbuf.QRfloor == target_floor)||(target_floor<0)) )
- cprintf("%s|%u|%d\n",
- qrbuf.QRname,qrbuf.QRflags,qrbuf.QRfloor);
- }
+
+ ForEachRoom(cmd_lrms_backend);
cprintf("000\n");
}
+
+
/*
* cmd_lkra() - List all known rooms
*/
+void cmd_lkra_backend(struct quickroom *qrbuf) {
+ if ( ((CtdlRoomAccess(qrbuf, &CC->usersupp)
+ & (UA_KNOWN)))
+ && ((qrbuf->QRfloor == (CC->FloorBeingSearched))
+ ||((CC->FloorBeingSearched)<0)) )
+ list_roomname(qrbuf);
+ }
+
void cmd_lkra(char *argbuf)
{
- int a;
- struct quickroom qrbuf;
- int target_floor = (-1);
+ CC->FloorBeingSearched = (-1);
+ if (strlen(argbuf)>0) CC->FloorBeingSearched = extract_int(argbuf,0);
- if (strlen(argbuf)>0) target_floor = extract_int(argbuf,0);
-
- if ((!(CC->logged_in))&&(!(CC->internal_pgm))) {
+ if (!(CC->logged_in)) {
cprintf("%d Not logged in.\n",ERROR+NOT_LOGGED_IN);
return;
}
- if (!(CC->internal_pgm)) if (getuser(&CC->usersupp,CC->curr_user)) {
+ if (getuser(&CC->usersupp,CC->curr_user)) {
cprintf("%d Can't locate user!\n",ERROR+INTERNAL_ERROR);
return;
}
cprintf("%d Known rooms:\n",LISTING_FOLLOWS);
-
- for (a=0; a<MAXROOMS; ++a) {
- getroom(&qrbuf,a);
- if ((is_known(&qrbuf,a,&CC->usersupp))
- && ((qrbuf.QRfloor == target_floor)||(target_floor<0)) )
- cprintf("%s|%u|%d\n",
- qrbuf.QRname,qrbuf.QRflags,qrbuf.QRfloor);
- }
+
+ ForEachRoom(cmd_lkra_backend);
cprintf("000\n");
}
+
+
/*
- * cmd_lkrn() - List Known Rooms with New messages
+ * cmd_lkrn() - List all known rooms with new messages
*/
+void cmd_lkrn_backend(struct quickroom *qrbuf) {
+ int ra;
+
+ ra = CtdlRoomAccess(qrbuf, &CC->usersupp);
+ if ( (ra & UA_KNOWN)
+ && (ra & UA_HASNEWMSGS)
+ && ((qrbuf->QRfloor == (CC->FloorBeingSearched))
+ ||((CC->FloorBeingSearched)<0)) )
+ list_roomname(qrbuf);
+ }
+
void cmd_lkrn(char *argbuf)
{
- int a;
- struct quickroom qrbuf;
- int target_floor = (-1);
-
- if (strlen(argbuf)>0) target_floor = extract_int(argbuf,0);
+ CC->FloorBeingSearched = (-1);
+ if (strlen(argbuf)>0) CC->FloorBeingSearched = extract_int(argbuf,0);
if (!(CC->logged_in)) {
cprintf("%d Not logged in.\n",ERROR+NOT_LOGGED_IN);
}
if (getuser(&CC->usersupp,CC->curr_user)) {
- cprintf("%d can't locate user\n",ERROR+INTERNAL_ERROR);
+ cprintf("%d Can't locate user!\n",ERROR+INTERNAL_ERROR);
return;
}
- cprintf("%d list of rms w/ new msgs\n",LISTING_FOLLOWS);
-
- for (a=0; a<MAXROOMS; ++a) {
- getroom(&qrbuf,a);
- if ( ( (is_known(&qrbuf,a,&CC->usersupp))
- && (has_newmsgs(&qrbuf,a,&CC->usersupp)) )
- && ((qrbuf.QRfloor == target_floor)||(target_floor<0)) )
- cprintf("%s|%u|%d\n",
- qrbuf.QRname,qrbuf.QRflags,qrbuf.QRfloor);
- }
+ cprintf("%d Rooms w/ new msgs:\n",LISTING_FOLLOWS);
+
+ ForEachRoom(cmd_lkrn_backend);
cprintf("000\n");
}
+
+
/*
- * cmd_lkro() - List Known Rooms with Old (no new) messages
+ * cmd_lkro() - List all known rooms
*/
+void cmd_lkro_backend(struct quickroom *qrbuf) {
+ int ra;
+
+ ra = CtdlRoomAccess(qrbuf, &CC->usersupp);
+ if ( (ra & UA_KNOWN)
+ && ((ra & UA_HASNEWMSGS)==0)
+ && ((qrbuf->QRfloor == (CC->FloorBeingSearched))
+ ||((CC->FloorBeingSearched)<0)) )
+ list_roomname(qrbuf);
+ }
+
void cmd_lkro(char *argbuf)
{
- int a;
- struct quickroom qrbuf;
- int target_floor = (-1);
-
- if (strlen(argbuf)>0) target_floor = extract_int(argbuf,0);
+ CC->FloorBeingSearched = (-1);
+ if (strlen(argbuf)>0) CC->FloorBeingSearched = extract_int(argbuf,0);
if (!(CC->logged_in)) {
- cprintf("%d not logged in\n",ERROR+NOT_LOGGED_IN);
+ cprintf("%d Not logged in.\n",ERROR+NOT_LOGGED_IN);
return;
}
if (getuser(&CC->usersupp,CC->curr_user)) {
- cprintf("%d can't locate user\n",ERROR+INTERNAL_ERROR);
+ cprintf("%d Can't locate user!\n",ERROR+INTERNAL_ERROR);
return;
}
- cprintf("%d list of rms w/o new msgs\n",LISTING_FOLLOWS);
-
- for (a=0; a<MAXROOMS; ++a) {
- getroom(&qrbuf,a);
- if ( ( (is_known(&qrbuf,a,&CC->usersupp))
- && (!has_newmsgs(&qrbuf,a,&CC->usersupp)) )
- && ((qrbuf.QRfloor == target_floor)||(target_floor<0)) ) {
- if (!strcmp(qrbuf.QRname,"000")) cprintf(">");
- cprintf("%s|%u|%d\n",
- qrbuf.QRname,qrbuf.QRflags,qrbuf.QRfloor);
- }
- }
+ cprintf("%d Rooms w/o new msgs:\n",LISTING_FOLLOWS);
+
+ ForEachRoom(cmd_lkro_backend);
cprintf("000\n");
}
+
+
/*
- * cmd_lzrm() - List Zapped RooMs
+ * cmd_lzrm() - List all forgotten rooms
*/
+void cmd_lzrm_backend(struct quickroom *qrbuf) {
+ int ra;
+
+ ra = CtdlRoomAccess(qrbuf, &CC->usersupp);
+ if ( (ra & UA_GOTOALLOWED)
+ && (ra & UA_ZAPPED)
+ && ((qrbuf->QRfloor == (CC->FloorBeingSearched))
+ ||((CC->FloorBeingSearched)<0)) )
+ list_roomname(qrbuf);
+ }
+
void cmd_lzrm(char *argbuf)
{
- int a;
- struct quickroom qrbuf;
- int target_floor = (-1);
-
- if (strlen(argbuf)>0) target_floor = extract_int(argbuf,0);
+ CC->FloorBeingSearched = (-1);
+ if (strlen(argbuf)>0) CC->FloorBeingSearched = extract_int(argbuf,0);
if (!(CC->logged_in)) {
- cprintf("%d not logged in\n",ERROR+NOT_LOGGED_IN);
+ cprintf("%d Not logged in.\n",ERROR+NOT_LOGGED_IN);
return;
}
if (getuser(&CC->usersupp,CC->curr_user)) {
- cprintf("%d can't locate user\n",ERROR+INTERNAL_ERROR);
+ cprintf("%d Can't locate user!\n",ERROR+INTERNAL_ERROR);
return;
}
- cprintf("%d list of forgotten rms\n",LISTING_FOLLOWS);
-
- for (a=0; a<MAXROOMS; ++a) {
- getroom(&qrbuf,a);
- if ( (is_zapped(&qrbuf,a,&CC->usersupp))
- && ((qrbuf.QRfloor == target_floor)||(target_floor<0)) ) {
- if (!strcmp(qrbuf.QRname,"000")) cprintf(">");
- cprintf("%s|%u|%d\n",
- qrbuf.QRname,qrbuf.QRflags,qrbuf.QRfloor);
- }
- }
+ cprintf("%d Zapped rooms:\n",LISTING_FOLLOWS);
+
+ ForEachRoom(cmd_lzrm_backend);
cprintf("000\n");
}
-void usergoto(int where, int display_result)
+void usergoto(char *where, int display_result)
{
- int a,b,c;
+ int a;
+ int new_messages = 0;
+ int total_messages = 0;
int info = 0;
int rmailflag;
int raideflag;
int newmailcount = 0;
- struct cdbdata *cdbmb;
- int num_mails;
- long *mailbox;
+ struct visit vbuf;
+ char truncated_roomname[ROOMNAMELEN];
- CC->curr_rm=where;
- getroom(&CC->quickroom,CC->curr_rm);
+ strcpy(CC->quickroom.QRname, where);
+ getroom(&CC->quickroom, where);
lgetuser(&CC->usersupp,CC->curr_user);
- CC->usersupp.forget[CC->curr_rm]=(-1);
- CC->usersupp.generation[CC->curr_rm]=CC->quickroom.QRgen;
+ CtdlGetRelationship(&vbuf, &CC->usersupp, &CC->quickroom);
+
+ vbuf.v_flags = vbuf.v_flags & ~V_FORGET & ~V_LOCKOUT;
+ vbuf.v_flags = vbuf.v_flags | V_ACCESS;
+
+ CtdlSetRelationship(&vbuf, &CC->usersupp, &CC->quickroom);
lputuser(&CC->usersupp,CC->curr_user);
/* check for new mail */
- newmailcount = 0;
-
- cdbmb = cdb_fetch(CDB_MAILBOXES, &CC->usersupp.usernum, sizeof(long));
- if (cdbmb != NULL) {
- num_mails = cdbmb->len / sizeof(long);
- mailbox = (long *) cdbmb->ptr;
- if (num_mails > 0) for (a=0; a<num_mails; ++a) {
- if (mailbox[a] > (CC->usersupp.lastseen[1]))
- ++newmailcount;
- }
- cdb_free(cdbmb);
- }
+ newmailcount = NewMailCount();
/* set info to 1 if the user needs to read the room's info file */
- if (CC->quickroom.QRinfo > CC->usersupp.lastseen[CC->curr_rm]) info = 1;
+ if (CC->quickroom.QRinfo > vbuf.v_lastseen) info = 1;
- b=0; c=0;
get_mm();
- get_msglist(CC->curr_rm);
+ get_msglist(&CC->quickroom);
for (a=0; a<CC->num_msgs; ++a) {
if (MessageFromList(a)>0L) {
- ++b;
- if (MessageFromList(a)
- > CC->usersupp.lastseen[CC->curr_rm]) ++c;
+ ++total_messages;
+ if (MessageFromList(a) > vbuf.v_lastseen) {
+ ++new_messages;
+ }
}
}
-
- if (CC->curr_rm == 1) rmailflag = 1;
+ if (CC->quickroom.QRflags & QR_MAILBOX) rmailflag = 1;
else rmailflag = 0;
if ( (CC->quickroom.QRroomaide == CC->usersupp.usernum)
|| (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,c,b,info,CC->quickroom.QRflags,
- CC->quickroom.QRhighest,CC->usersupp.lastseen[CC->curr_rm],
+ 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();
}
void cmd_goto(char *gargs)
{
struct quickroom QRscratch;
- int a,c;
- int ok;
- char bbb[20],towhere[32],password[20];
+ int c;
+ int ok = 0;
+ int ra;
+ 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);
- for (a=0; a<MAXROOMS; ++a) {
- getroom(&QRscratch,a);
- if ((a==0)&&(!strcasecmp(towhere,"_BASEROOM_"))) {
- strncpy(towhere,QRscratch.QRname,31);
- }
- if ((a==1)&&(!strcasecmp(towhere,"_MAIL_"))) {
- strncpy(towhere,QRscratch.QRname,31);
- }
- if ((!strcasecmp(QRscratch.QRname,config.c_twitroom))
- &&(!strcasecmp(towhere,"_BITBUCKET_"))) {
- strncpy(towhere,QRscratch.QRname,31);
- }
- strcpy(bbb,QRscratch.QRname);
- ok = 0;
+ getuser(&CC->usersupp, CC->curr_user);
+
+ if (!strcasecmp(towhere, "_BASEROOM_"))
+ strcpy(towhere, BASEROOM);
+
+ if (!strcasecmp(towhere, "_MAIL_"))
+ strcpy(towhere, MAILROOM);
+
+ if (!strcasecmp(towhere, "_BITBUCKET_"))
+ strcpy(towhere, config.c_twitroom);
+
+
+ /* 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);
+ }
+
+ /* And if the room was found... */
+ if (c == 0) {
/* let internal programs go directly to any room */
- if (((CC->internal_pgm))&&(!strcasecmp(bbb,towhere))) {
- usergoto(a,1);
+ if (CC->internal_pgm) {
+ usergoto(towhere, 1);
return;
}
- /* normal clients have to pass through security */
- if (
- (strcasecmp(bbb,towhere)==0)
- && ((QRscratch.QRflags&QR_INUSE)!=0)
-
- && ( ((QRscratch.QRflags&QR_PREFONLY)==0)
- || (CC->usersupp.axlevel>=5)
- )
-
- && ( (a!=2) || (CC->usersupp.axlevel>=6) )
-
- && ( ((QRscratch.QRflags&QR_PRIVATE)==0)
- || (QRscratch.QRflags&QR_GUESSNAME)
- || (CC->usersupp.axlevel>=6)
- || (QRscratch.QRflags&QR_PASSWORDED)
- || (QRscratch.QRgen==CC->usersupp.generation[a])
- )
-
- ) ok = 1;
+ /* See if there is an existing user/room relationship */
+ ra = CtdlRoomAccess(&QRscratch, &CC->usersupp);
+ /* normal clients have to pass through security */
+ if (ra & UA_GOTOALLOWED) ok = 1;
if (ok==1) {
-
if ( (QRscratch.QRflags&QR_PASSWORDED) &&
- (CC->usersupp.axlevel<6) &&
- (QRscratch.QRgen!=CC->usersupp.generation[a]) &&
+ ((ra & UA_KNOWN) == 0) &&
(strcasecmp(QRscratch.QRpasswd,password))
) {
cprintf("%d wrong or missing passwd\n",
ERROR+PASSWORD_REQUIRED);
return;
}
-
- usergoto(a,1);
- return;
+ else {
+ usergoto(towhere, 1);
+ return;
+ }
}
-
}
+
cprintf("%d room '%s' not found\n",ERROR+ROOM_NOT_FOUND,towhere);
}
cprintf("%d Who knows room:\n",LISTING_FOLLOWS);
cdb_rewind(CDB_USERSUPP);
while(cdbus = cdb_next_item(CDB_USERSUPP), cdbus != NULL) {
- bzero(&temp, sizeof(struct usersupp));
+ memset(&temp, 0, sizeof(struct usersupp));
memcpy(&temp, cdbus->ptr, cdbus->len);
cdb_free(cdbus);
- if ((CC->quickroom.QRflags & QR_INUSE)
- && ( (CC->curr_rm!=2) || (temp.axlevel>=6) )
- && (CC->quickroom.QRgen != (temp.forget[CC->curr_rm]) )
-
- && ( ((CC->quickroom.QRflags&QR_PREFONLY)==0)
- || (temp.axlevel>=5)
- )
-
- && ( ((CC->quickroom.QRflags&QR_PRIVATE)==0)
- || (temp.axlevel>=6)
- || (CC->quickroom.QRgen==(temp.generation[CC->curr_rm]))
- )
- && (strncmp(temp.fullname,"000",3))
-
- ) cprintf("%s\n",temp.fullname);
+ if ( (CC->quickroom.QRflags & QR_INUSE)
+ && (CtdlRoomAccess(&CC->quickroom, &temp) & UA_KNOWN)
+ ) cprintf("%s\n",temp.fullname);
}
cprintf("000\n");
}
return;
}
- getroom(&CC->quickroom,CC->curr_rm);
- getuser(&CC->usersupp,CC->curr_user);
+ getroom(&CC->quickroom, CC->quickroom.QRname);
+ getuser(&CC->usersupp, CC->curr_user);
if ((CC->quickroom.QRflags & QR_DIRECTORY) == 0) {
cprintf("%d not here.\n",ERROR+NOT_HERE);
return;
}
- if (CC->curr_rm < 3) {
+ if (is_noneditable(&CC->quickroom)) {
cprintf("%d Can't edit this room.\n",ERROR+NOT_HERE);
return;
}
- getroom(&CC->quickroom,CC->curr_rm);
+ getroom(&CC->quickroom, CC->quickroom.QRname);
cprintf("%d%c%s|%s|%s|%d|%d\n",
OK,check_express(),
CC->quickroom.QRname,
void cmd_setr(char *args) {
char buf[256];
struct floor flbuf;
+ char old_name[ROOMNAMELEN];
int old_floor;
if (!(CC->logged_in)) {
return;
}
- if (CC->curr_rm < 3) {
+ if (is_noneditable(&CC->quickroom)) {
cprintf("%d Can't edit this room.\n",ERROR+NOT_HERE);
return;
}
}
}
- lgetroom(&CC->quickroom,CC->curr_rm);
- extract(buf,args,0); buf[20]=0;
- strncpy(CC->quickroom.QRname,buf,19);
+ 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;
strncpy(CC->quickroom.QRpasswd,buf,9);
extract(buf,args,2); buf[15]=0;
||(CC->quickroom.QRflags & QR_PASSWORDED))
CC->quickroom.QRflags |= QR_PRIVATE;
- /* Kick everyone out if the client requested it */
+ /* Kick everyone out if the client requested it (by changing the
+ * room's generation number)
+ */
if (extract_int(args,4)) {
- ++CC->quickroom.QRgen;
- if (CC->quickroom.QRgen==100) CC->quickroom.QRgen=1;
+ time(&CC->quickroom.QRgen);
}
old_floor = CC->quickroom.QRfloor;
CC->quickroom.QRfloor = extract_int(args,5);
}
- lputroom(&CC->quickroom,CC->curr_rm);
+ /* 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);
return;
}
- if (CC->curr_rm < 0) {
- cprintf("%d No current room.\n",ERROR);
+ if (is_noneditable(&CC->quickroom)) {
+ cprintf("%d Can't edit this room.\n",ERROR+NOT_HERE);
return;
}
return;
}
- if (CC->curr_rm < 3) {
- cprintf("%d Can't edit this room.\n",ERROR+NOT_HERE);
- return;
- }
-
if (getuser(&usbuf,new_ra)!=0) {
newu = (-1L);
}
newu = usbuf.usernum;
}
- lgetroom(&CC->quickroom,CC->curr_rm);
+ lgetroom(&CC->quickroom, CC->quickroom.QRname);
post_notice = 0;
if (CC->quickroom.QRroomaide != newu) {
post_notice = 1;
}
CC->quickroom.QRroomaide = newu;
- lputroom(&CC->quickroom,CC->curr_rm);
+ lputroom(&CC->quickroom, CC->quickroom.QRname);
/*
* We have to post the change notice _after_ writing changes to
cprintf("%d Ok\n",OK);
}
+/*
+ * Generate an associated file name for a room
+ */
+void assoc_file_name(char *buf, struct quickroom *qrbuf, char *prefix) {
+ int a;
+
+ sprintf(buf, "./prefix/%s.%ld", qrbuf->QRname, qrbuf->QRgen);
+ for (a=0; a<strlen(buf); ++a) {
+ if (buf[a]==32) buf[a]='.';
+ }
+ }
/*
* retrieve info file for this room
*/
void cmd_rinf(void) {
- char filename[64];
+ char filename[128];
char buf[256];
FILE *info_fp;
- sprintf(filename,"./info/%d",CC->curr_rm);
+ assoc_file_name(filename, &CC->quickroom, "info");
info_fp = fopen(filename,"r");
if (info_fp==NULL) {
}
/*
- * aide command: kill the current room
+ * Back end processing to delete a room and everything associated with it
*/
-void cmd_kill(char *argbuf)
-{
+void delete_room(struct quickroom *qrbuf) {
+ struct floor flbuf;
+ long MsgToDelete;
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);
+
+ /* Delete the image file */
+ assoc_file_name(aaa, qrbuf, "images");
+ unlink(aaa);
+
+ /* first flag the room record as not in use */
+ lgetroom(qrbuf, qrbuf->QRname);
+ qrbuf->QRflags=0;
+
+ /* then delete the messages in the room */
+ get_msglist(qrbuf);
+ if (CC->num_msgs > 0) for (a=0; a < CC->num_msgs; ++a) {
+ MsgToDelete = MessageFromList(a);
+ cdb_delete(CDB_MSGMAIN, &MsgToDelete, sizeof(long));
+ }
+ put_msglist(qrbuf);
+ free(CC->msglist);
+ CC->msglist = NULL;
+ CC->num_msgs = 0;
+ delete_msglist(qrbuf);
+ lputroom(qrbuf, qrbuf->QRname);
+
+ /* then decrement the reference count for the floor */
+ lgetfloor(&flbuf,(int)(qrbuf->QRfloor));
+ flbuf.f_ref_count = flbuf.f_ref_count - 1;
+ lputfloor(&flbuf,(int)(qrbuf->QRfloor));
+
+ /* Delete the room record from the database! */
+ putroom(NULL, qrbuf->QRname);
+ }
+
+
+/*
+ * aide command: kill the current room
+ */
+void cmd_kill(char *argbuf) {
+ char aaa[100];
+ char deleted_room_name[ROOMNAMELEN];
int kill_ok;
- struct floor flbuf;
- long MsgToDelete;
kill_ok = extract_int(argbuf,0);
return;
}
- if (CC->curr_rm < 3) {
- cprintf("%d Can't kill this room.\n",ERROR+NOT_HERE);
+ if (is_noneditable(&CC->quickroom)) {
+ cprintf("%d Can't edit this room.\n",ERROR+NOT_HERE);
return;
}
if (kill_ok) {
-
- /* first flag the room record as not in use */
- lgetroom(&CC->quickroom,CC->curr_rm);
- CC->quickroom.QRflags=0;
-
- /* then delete the messages in the room */
- get_msglist(CC->curr_rm);
- if (CC->num_msgs > 0) for (a=0; a < CC->num_msgs; ++a) {
- MsgToDelete = MessageFromList(a);
- cdb_delete(CDB_MSGMAIN, &MsgToDelete, sizeof(long));
- }
- put_msglist(CC->curr_rm);
- free(CC->msglist);
- CC->num_msgs = 0;
- cdb_delete(CDB_MSGLISTS, &CC->curr_rm, sizeof(int));
-
- lputroom(&CC->quickroom,CC->curr_rm);
-
-
- /* then decrement the reference count for the floor */
- lgetfloor(&flbuf,(int)CC->quickroom.QRfloor);
- flbuf.f_ref_count = flbuf.f_ref_count - 1;
- lputfloor(&flbuf,(int)CC->quickroom.QRfloor);
+ strcpy(deleted_room_name, CC->quickroom.QRname);
+ delete_room(&CC->quickroom); /* Do the dirty work */
+ usergoto(BASEROOM, 0); /* Return to the Lobby */
/* tell the world what we did */
- sprintf(aaa,"%s> killed by %s",CC->quickroom.QRname,CC->curr_user);
+ sprintf(aaa,"%s> killed by %s",
+ deleted_room_name, CC->curr_user);
aide_message(aaa);
- CC->curr_rm=(-1);
- cprintf("%d '%s' deleted.\n",OK,CC->quickroom.QRname);
+ cprintf("%d '%s' deleted.\n", OK, deleted_room_name);
}
else {
cprintf("%d ok to delete.\n",OK);
/*
- * Find a free slot to create a new room in, or return -1 for error.
- * search_dir is the direction to search in. 1 causes this function to
- * return the first available slot, -1 gets the last available slot.
+ * Internal code to create a new room (returns room flags)
+ *
+ * Room types: 0=public, 1=guessname, 2=passworded, 3=inv-only, 4=mailbox
*/
-int get_free_room_slot(int search_dir)
-{
- int a,st;
- struct quickroom qrbuf;
+unsigned create_room(char *new_room_name,
+ int new_room_type,
+ char *new_room_pass,
+ int new_room_floor) {
- st = ((search_dir>0) ? 3 : (MAXROOMS-1));
-
- for (a=st; ((a<MAXROOMS)&&(a>=3)); a=a+search_dir) {
- getroom(&qrbuf,a);
- if ((qrbuf.QRflags & QR_INUSE)==0) return(a);
- }
- return(-1);
- }
-
-
-/*
- * internal code to create a new room (returns room flags)
- */
-unsigned create_room(int free_slot, char *new_room_name, int new_room_type, char *new_room_pass, int new_room_floor)
-{
struct quickroom qrbuf;
struct floor flbuf;
+ struct visit vbuf;
+
+ if (getroom(&qrbuf, new_room_name)==0) return(0); /* already exists */
- lgetroom(&qrbuf,free_slot);
- strncpy(qrbuf.QRname,new_room_name,19);
+ memset(&qrbuf, 0, sizeof(struct quickroom));
+ 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);
- qrbuf.QRroomaide = (-1L);
- if ((new_room_type > 0)&&(CREATAIDE==1))
+ if (new_room_type == 4) qrbuf.QRflags=(qrbuf.QRflags|QR_MAILBOX);
+
+ /* If the room is private, and the system administrator has elected
+ * to automatically grant room aide privileges, do so now; otherwise,
+ * set the room aide to undefined.
+ */
+ if ( (qrbuf.QRflags & QR_PRIVATE) && (CREATAIDE==1) ) {
qrbuf.QRroomaide=CC->usersupp.usernum;
- qrbuf.QRhighest = 0L;
- ++qrbuf.QRgen; if (qrbuf.QRgen>=126) qrbuf.QRgen=10;
+ }
+ else {
+ qrbuf.QRroomaide = (-1L);
+ }
+
+ qrbuf.QRhighest = 0L; /* No messages in this room yet */
+ time(&qrbuf.QRgen); /* Use a timestamp as the generation number */
qrbuf.QRfloor = new_room_floor;
/* save what we just did... */
- lputroom(&qrbuf,free_slot);
+ putroom(&qrbuf, qrbuf.QRname);
/* bump the reference count on whatever floor the room is on */
lgetfloor(&flbuf,(int)qrbuf.QRfloor);
/* be sure not to kick the creator out of the room! */
lgetuser(&CC->usersupp,CC->curr_user);
- CC->usersupp.generation[free_slot] = qrbuf.QRgen;
- CC->usersupp.forget[free_slot] = (-1);
+ CtdlGetRelationship(&vbuf, &CC->usersupp, &qrbuf);
+ vbuf.v_flags = vbuf.v_flags & ~V_FORGET & ~V_LOCKOUT;
+ vbuf.v_flags = vbuf.v_flags | V_ACCESS;
+ CtdlSetRelationship(&vbuf, &CC->usersupp, &qrbuf);
lputuser(&CC->usersupp,CC->curr_user);
/* resume our happy day */
void cmd_cre8(char *args)
{
int cre8_ok;
- int free_slot;
- int a;
char new_room_name[256];
int new_room_type;
char new_room_pass[256];
cre8_ok = extract_int(args,0);
extract(new_room_name,args,1);
- new_room_name[19] = 0;
+ new_room_name[ROOMNAMELEN-1] = 0;
new_room_type = extract_int(args,2);
extract(new_room_pass,args,3);
new_room_pass[9] = 0;
return;
}
- free_slot = get_free_room_slot(1);
- if (free_slot<0) {
- cprintf("%d There is no space available for a new room.\n",
- ERROR);
+ if ((strlen(new_room_name)==0) && (cre8_ok==0)) {
+ cprintf("%d Ok to create rooms.\n", OK);
return;
}
- if (cre8_ok==0) {
- cprintf("%d ok to create...\n",OK);
+ /* Check to make sure the requested room name doesn't already exist */
+ if (getroom(&qrbuf, new_room_name)==0) {
+ cprintf("%d '%s' already exists.\n",
+ ERROR,qrbuf.QRname);
return;
}
- for (a=0; a<MAXROOMS; ++a) {
- getroom(&qrbuf,a);
- if ( (!strcasecmp(qrbuf.QRname,new_room_name))
- && (qrbuf.QRflags & QR_INUSE) ) {
- cprintf("%d '%s' already exists.\n",
- ERROR,qrbuf.QRname);
- return;
- }
- }
-
if ((new_room_type < 0) || (new_room_type > 3)) {
cprintf("%d Invalid room type.\n",ERROR);
return;
}
- newflags = create_room(free_slot,new_room_name,
+ if (cre8_ok == 0) {
+ cprintf("%d OK to create '%s'\n", OK, new_room_name);
+ return;
+ }
+
+ newflags = create_room(new_room_name,
new_room_type,new_room_pass,new_room_floor);
/* post a message in Aide> describing the new room */
}
aide_message(aaa);
- sprintf(aaa,"./info/%d",free_slot); /* delete old info file */
- unlink(aaa);
- sprintf(aaa,"./images/room.%d.gif",free_slot); /* and picture */
- unlink(aaa);
-
cprintf("%d '%s' has been created.\n",OK,qrbuf.QRname);
}
void cmd_einf(char *ok)
{ /* enter info file for current room */
FILE *fp;
- char infofilename[32];
+ char infofilename[64];
char buf[256];
if (!(CC->logged_in)) {
cprintf("%d Send info...\n",SEND_LISTING);
- sprintf(infofilename,"./info/%d",CC->curr_rm);
+ assoc_file_name(infofilename, &CC->quickroom, "info");
fp=fopen(infofilename,"w");
do {
fclose(fp);
/* now update the room index so people will see our new info */
- lgetroom(&CC->quickroom,CC->curr_rm); /* lock so no one steps on us */
+ lgetroom(&CC->quickroom,CC->quickroom.QRname); /* lock so no one steps on us */
CC->quickroom.QRinfo = CC->quickroom.QRhighest + 1L;
- lputroom(&CC->quickroom,CC->curr_rm);
+ lputroom(&CC->quickroom,CC->quickroom.QRname);
}