/*
* Generic routine for determining user access to rooms
*/
-int CtdlRoomAccess(struct room *roombuf, struct user *userbuf)
+int CtdlRoomAccess(struct ctdlroom *roombuf, struct ctdluser *userbuf)
{
int retval = 0;
struct visit vbuf;
}
}
- /* On some systems, Aides can gain access to mailboxes as well */
- if ( (config.c_aide_mailboxes)
- && (userbuf->axlevel >= 6)
+ /* Aides can gain access to mailboxes as well, but they don't show
+ * by default.
+ */
+ if ( (userbuf->axlevel >= 6)
&& (roombuf->QRflags & QR_MAILBOX) ) {
retval = retval | UA_GOTOALLOWED;
}
/*
* Self-checking stuff for a room record read into memory
*/
-void room_sanity_check(struct room *qrbuf)
+void room_sanity_check(struct ctdlroom *qrbuf)
{
/* Mailbox rooms are always on the lowest floor */
if (qrbuf->QRflags & QR_MAILBOX) {
/*
* getroom() - retrieve room data from disk
*/
-int getroom(struct room *qrbuf, char *room_name)
+int getroom(struct ctdlroom *qrbuf, char *room_name)
{
struct cdbdata *cdbqr;
char lowercase_name[ROOMNAMELEN];
}
lowercase_name[a] = 0;
- memset(qrbuf, 0, sizeof(struct room));
+ memset(qrbuf, 0, sizeof(struct ctdlroom));
/* First, try the public namespace */
- cdbqr = cdb_fetch(CDB_QUICKROOM,
+ cdbqr = cdb_fetch(CDB_ROOMS,
lowercase_name, strlen(lowercase_name));
/* If that didn't work, try the user's personal namespace */
snprintf(personal_lowercase_name,
sizeof personal_lowercase_name, "%010ld.%s",
CC->user.usernum, lowercase_name);
- cdbqr = cdb_fetch(CDB_QUICKROOM,
+ cdbqr = cdb_fetch(CDB_ROOMS,
personal_lowercase_name,
strlen(personal_lowercase_name));
}
if (cdbqr != NULL) {
memcpy(qrbuf, cdbqr->ptr,
- ((cdbqr->len > sizeof(struct room)) ?
- sizeof(struct room) : cdbqr->len));
+ ((cdbqr->len > sizeof(struct ctdlroom)) ?
+ sizeof(struct ctdlroom) : cdbqr->len));
cdb_free(cdbqr);
room_sanity_check(qrbuf);
/*
* lgetroom() - same as getroom() but locks the record (if supported)
*/
-int lgetroom(struct room *qrbuf, char *room_name)
+int lgetroom(struct ctdlroom *qrbuf, char *room_name)
{
register int retval;
retval = getroom(qrbuf, room_name);
- if (retval == 0) begin_critical_section(S_QUICKROOM);
+ if (retval == 0) begin_critical_section(S_ROOMS);
return(retval);
}
* b_putroom() - back end to putroom() and b_deleteroom()
* (if the supplied buffer is NULL, delete the room record)
*/
-void b_putroom(struct room *qrbuf, char *room_name)
+void b_putroom(struct ctdlroom *qrbuf, char *room_name)
{
char lowercase_name[ROOMNAMELEN];
int a;
}
if (qrbuf == NULL) {
- cdb_delete(CDB_QUICKROOM,
+ cdb_delete(CDB_ROOMS,
lowercase_name, strlen(lowercase_name));
} else {
time(&qrbuf->QRmtime);
- cdb_store(CDB_QUICKROOM,
+ cdb_store(CDB_ROOMS,
lowercase_name, strlen(lowercase_name),
- qrbuf, sizeof(struct room));
+ qrbuf, sizeof(struct ctdlroom));
}
}
/*
* putroom() - store room data to disk
*/
-void putroom(struct room *qrbuf) {
+void putroom(struct ctdlroom *qrbuf) {
b_putroom(qrbuf, qrbuf->QRname);
}
/*
* lputroom() - same as putroom() but unlocks the record (if supported)
*/
-void lputroom(struct room *qrbuf)
+void lputroom(struct ctdlroom *qrbuf)
{
putroom(qrbuf);
- end_critical_section(S_QUICKROOM);
+ end_critical_section(S_ROOMS);
}
cdb_free(cdbfl);
} else {
if (floor_num == 0) {
- strcpy(flbuf->f_name, "Main Floor");
+ safestrncpy(flbuf->f_name, "Main Floor",
+ sizeof flbuf->f_name);
flbuf->f_flags = F_INUSE;
flbuf->f_ref_count = 3;
}
struct floor *cgetfloor(int floor_num) {
static int initialized = 0;
int i;
+ int fetch_new = 0;
+ struct floor *fl = NULL;
+ begin_critical_section(S_FLOORCACHE);
if (initialized == 0) {
for (i=0; i<MAXFLOORS; ++i) {
floorcache[floor_num] = NULL;
}
initialized = 1;
}
-
if (floorcache[floor_num] == NULL) {
- floorcache[floor_num] = mallok(sizeof(struct floor));
- getfloor(floorcache[floor_num], floor_num);
+ fetch_new = 1;
+ }
+ end_critical_section(S_FLOORCACHE);
+
+ if (fetch_new) {
+ lprintf(CTDL_DEBUG, "fetch_new is active ... going to disk\n");
+ fl = malloc(sizeof(struct floor));
+ getfloor(fl, floor_num);
+ begin_critical_section(S_FLOORCACHE);
+ if (floorcache[floor_num] != NULL) {
+ free(floorcache[floor_num]);
+ }
+ floorcache[floor_num] = fl;
+ end_critical_section(S_FLOORCACHE);
}
return(floorcache[floor_num]);
*/
void putfloor(struct floor *flbuf, int floor_num)
{
- cdb_store(CDB_FLOORTAB, &floor_num, sizeof(int),
- flbuf, sizeof(struct floor));
-
/* If we've cached this, clear it out, 'cuz it's WRONG now! */
+ begin_critical_section(S_FLOORCACHE);
if (floorcache[floor_num] != NULL) {
- phree(floorcache[floor_num]);
- floorcache[floor_num] = NULL;
+ free(floorcache[floor_num]);
+ floorcache[floor_num] = malloc(sizeof(struct floor));
+ memcpy(floorcache[floor_num], flbuf, sizeof(struct floor));
}
+ end_critical_section(S_FLOORCACHE);
+
+ cdb_store(CDB_FLOORTAB, &floor_num, sizeof(int),
+ flbuf, sizeof(struct floor));
}
/*
* Traverse the room file...
*/
-void ForEachRoom(void (*CallBack) (struct room *EachRoom, void *out_data),
+void ForEachRoom(void (*CallBack) (struct ctdlroom *EachRoom, void *out_data),
void *in_data)
{
- struct room qrbuf;
+ struct ctdlroom qrbuf;
struct cdbdata *cdbqr;
- cdb_rewind(CDB_QUICKROOM);
+ cdb_rewind(CDB_ROOMS);
- while (cdbqr = cdb_next_item(CDB_QUICKROOM), cdbqr != NULL) {
- memset(&qrbuf, 0, sizeof(struct room));
+ while (cdbqr = cdb_next_item(CDB_ROOMS), cdbqr != NULL) {
+ memset(&qrbuf, 0, sizeof(struct ctdlroom));
memcpy(&qrbuf, cdbqr->ptr,
- ((cdbqr->len > sizeof(struct room)) ?
- sizeof(struct room) : cdbqr->len));
+ ((cdbqr->len > sizeof(struct ctdlroom)) ?
+ sizeof(struct ctdlroom) : cdbqr->len));
cdb_free(cdbqr);
room_sanity_check(&qrbuf);
if (qrbuf.QRflags & QR_INUSE)
/*
* delete_msglist() - delete room message pointers
*/
-void delete_msglist(struct room *whichroom)
+void delete_msglist(struct ctdlroom *whichroom)
{
struct cdbdata *cdbml;
/*
* Determine whether a given room is non-editable.
*/
-int is_noneditable(struct room *qrbuf)
+int is_noneditable(struct ctdlroom *qrbuf)
{
/* Mail> rooms are non-editable */
/*
* Back-back-end for all room listing commands
*/
-void list_roomname(struct room *qrbuf, int ra)
+void list_roomname(struct ctdlroom *qrbuf, int ra)
{
char truncated_roomname[ROOMNAMELEN];
/*
* cmd_lrms() - List all accessible rooms, known or forgotten
*/
-void cmd_lrms_backend(struct room *qrbuf, void *data)
+void cmd_lrms_backend(struct ctdlroom *qrbuf, void *data)
{
int FloorBeingSearched = (-1);
int ra;
/*
* cmd_lkra() - List all known rooms
*/
-void cmd_lkra_backend(struct room *qrbuf, void *data)
+void cmd_lkra_backend(struct ctdlroom *qrbuf, void *data)
{
int FloorBeingSearched = (-1);
int ra;
-void cmd_lprm_backend(struct room *qrbuf, void *data)
+void cmd_lprm_backend(struct ctdlroom *qrbuf, void *data)
{
int FloorBeingSearched = (-1);
int ra;
/*
* cmd_lkrn() - List all known rooms with new messages
*/
-void cmd_lkrn_backend(struct room *qrbuf, void *data)
+void cmd_lkrn_backend(struct ctdlroom *qrbuf, void *data)
{
int FloorBeingSearched = (-1);
int ra;
/*
* cmd_lkro() - List all known rooms
*/
-void cmd_lkro_backend(struct room *qrbuf, void *data)
+void cmd_lkro_backend(struct ctdlroom *qrbuf, void *data)
{
int FloorBeingSearched = (-1);
int ra;
/*
* cmd_lzrm() - List all forgotten rooms
*/
-void cmd_lzrm_backend(struct room *qrbuf, void *data)
+void cmd_lzrm_backend(struct ctdlroom *qrbuf, void *data)
{
int FloorBeingSearched = (-1);
struct cdbdata *cdbfr;
long *msglist = NULL;
int num_msgs = 0;
+ unsigned int original_v_flags;
/* If the supplied room name is NULL, the caller wants us to know that
* it has already copied the room record into CC->room, so
* we can skip the extra database fetch.
*/
if (where != NULL) {
- strcpy(CC->room.QRname, where);
+ safestrncpy(CC->room.QRname, where, sizeof CC->room.QRname);
getroom(&CC->room, where);
}
/* Take care of all the formalities. */
- begin_critical_section(S_USERSUPP);
+ begin_critical_section(S_USERS);
CtdlGetRelationship(&vbuf, &CC->user, &CC->room);
+ original_v_flags = vbuf.v_flags;
/* Know the room ... but not if it's the page log room, or if the
* caller specified that we're only entering this room transiently.
vbuf.v_flags = vbuf.v_flags & ~V_FORGET & ~V_LOCKOUT;
vbuf.v_flags = vbuf.v_flags | V_ACCESS;
}
- CtdlSetRelationship(&vbuf, &CC->user, &CC->room);
- end_critical_section(S_USERSUPP);
+
+ /* Only rewrite the database record if we changed something */
+ if (vbuf.v_flags != original_v_flags) {
+ CtdlSetRelationship(&vbuf, &CC->user, &CC->room);
+ }
+ end_critical_section(S_USERS);
/* Check for new mail */
newmailcount = NewMailCount();
get_mm();
cdbfr = cdb_fetch(CDB_MSGLISTS, &CC->room.QRnumber, sizeof(long));
if (cdbfr != NULL) {
- msglist = mallok(cdbfr->len);
+ msglist = malloc(cdbfr->len);
memcpy(msglist, cdbfr->ptr, cdbfr->len);
num_msgs = cdbfr->len / sizeof(long);
cdb_free(cdbfr);
}
}
- if (msglist != NULL) phree(msglist);
+ if (msglist != NULL) free(msglist);
if (CC->room.QRflags & QR_MAILBOX)
rmailflag = 1;
if (retmsgs != NULL) *retmsgs = total_messages;
if (retnew != NULL) *retnew = new_messages;
- lprintf(9, "<%s> %d new of %d total messages\n",
+ lprintf(CTDL_DEBUG, "<%s> %d new of %d total messages\n",
CC->room.QRname,
new_messages, total_messages
);
*/
void cmd_goto(char *gargs)
{
- struct room QRscratch;
+ struct ctdlroom QRscratch;
int c;
int ok = 0;
int ra;
/* Let internal programs go directly to any room. */
if (CC->internal_pgm) {
memcpy(&CC->room, &QRscratch,
- sizeof(struct room));
+ sizeof(struct ctdlroom));
usergoto(NULL, 1, transiently, NULL, NULL);
return;
}
if ((QRscratch.QRflags & QR_MAILBOX) &&
((ra & UA_GOTOALLOWED))) {
memcpy(&CC->room, &QRscratch,
- sizeof(struct room));
+ sizeof(struct ctdlroom));
usergoto(NULL, 1, transiently, NULL, NULL);
return;
} else if ((QRscratch.QRflags & QR_PASSWORDED) &&
((ra & UA_KNOWN) == 0) &&
(CC->user.axlevel < 6)
) {
- lprintf(9, "Failed to acquire private room\n");
- goto NOPE;
+ lprintf(CTDL_DEBUG, "Failed to acquire private room\n");
} else {
memcpy(&CC->room, &QRscratch,
- sizeof(struct room));
+ sizeof(struct ctdlroom));
usergoto(NULL, 1, transiently, NULL, NULL);
return;
}
}
}
-NOPE: cprintf("%d room '%s' not found\n", ERROR + ROOM_NOT_FOUND, towhere);
+ cprintf("%d room '%s' not found\n", ERROR + ROOM_NOT_FOUND, towhere);
}
void cmd_whok(void)
{
- struct user temp;
+ struct ctdluser temp;
struct cdbdata *cdbus;
getuser(&CC->user, CC->curr_user);
}
cprintf("%d Who knows room:\n", LISTING_FOLLOWS);
- cdb_rewind(CDB_USERSUPP);
- while (cdbus = cdb_next_item(CDB_USERSUPP), cdbus != NULL) {
+ cdb_rewind(CDB_USERS);
+ while (cdbus = cdb_next_item(CDB_USERS), cdbus != NULL) {
memset(&temp, 0, sizeof temp);
memcpy(&temp, cdbus->ptr, sizeof temp);
cdb_free(cdbus);
*/
int CtdlRenameRoom(char *old_name, char *new_name, int new_floor) {
int old_floor = 0;
- struct room qrbuf;
- struct room qrtmp;
+ struct ctdlroom qrbuf;
+ struct ctdlroom qrtmp;
int ret = 0;
struct floor *fl;
struct floor flbuf;
long owner = 0L;
char actual_old_name[SIZ];
- lprintf(9, "CtdlRenameRoom(%s, %s, %d)\n",
+ lprintf(CTDL_DEBUG, "CtdlRenameRoom(%s, %s, %d)\n",
old_name, new_name, new_floor);
if (new_floor >= 0) {
}
}
- begin_critical_section(S_QUICKROOM);
+ begin_critical_section(S_ROOMS);
if ( (getroom(&qrtmp, new_name) == 0)
&& (strcasecmp(new_name, old_name)) ) {
ret = crr_ok;
}
- end_critical_section(S_QUICKROOM);
+ end_critical_section(S_ROOMS);
/* Adjust the floor reference counts if necessary */
if (new_floor != old_floor) {
lgetfloor(&flbuf, old_floor);
--flbuf.f_ref_count;
lputfloor(&flbuf, old_floor);
- lgetfloor(&flbuf, CC->room.QRfloor);
+ lprintf(CTDL_DEBUG, "Reference count for floor %d is now %d\n", old_floor, flbuf.f_ref_count);
+ lgetfloor(&flbuf, new_floor);
++flbuf.f_ref_count;
- lputfloor(&flbuf, CC->room.QRfloor);
+ lputfloor(&flbuf, new_floor);
+ lprintf(CTDL_DEBUG, "Reference count for floor %d is now %d\n", new_floor, flbuf.f_ref_count);
}
/* ...and everybody say "YATTA!" */
r = CtdlRenameRoom(CC->room.QRname, new_name, new_floor);
if (r == crr_room_not_found) {
- cprintf("%d Internal error - room not found?\n", ERROR);
+ cprintf("%d Internal error - room not found?\n", ERROR + INTERNAL_ERROR);
} else if (r == crr_already_exists) {
cprintf("%d '%s' already exists.\n",
ERROR + ALREADY_EXISTS, new_name);
} else if (r == crr_noneditable) {
- cprintf("%d Cannot edit this room.\n", ERROR);
+ cprintf("%d Cannot edit this room.\n", ERROR + NOT_HERE);
} else if (r == crr_invalid_floor) {
cprintf("%d Target floor does not exist.\n",
ERROR + INVALID_FLOOR_OPERATION);
CC->room.QRname);
} else if (r != crr_ok) {
cprintf("%d Error: CtdlRenameRoom() returned %d\n",
- ERROR, r);
+ ERROR + INTERNAL_ERROR, r);
}
if (r != crr_ok) {
*/
void cmd_geta(void)
{
- struct user usbuf;
+ struct ctdluser usbuf;
if (CtdlAccessCheck(ac_logged_in)) return;
*/
void cmd_seta(char *new_ra)
{
- struct user usbuf;
+ struct ctdluser usbuf;
long newu;
char buf[SIZ];
int post_notice;
* Generate an associated file name for a room
*/
void assoc_file_name(char *buf, size_t n,
- struct room *qrbuf, const char *prefix)
+ struct ctdlroom *qrbuf, const char *prefix)
{
snprintf(buf, n, "./%s/%ld", prefix, qrbuf->QRnumber);
}
info_fp = fopen(filename, "r");
if (info_fp == NULL) {
- cprintf("%d No info file.\n", ERROR);
+ cprintf("%d No info file.\n", ERROR + FILE_NOT_FOUND);
return;
}
cprintf("%d Info:\n", LISTING_FOLLOWS);
/*
* Back end processing to delete a room and everything associated with it
*/
-void delete_room(struct room *qrbuf)
+void delete_room(struct ctdlroom *qrbuf)
{
struct floor flbuf;
char filename[100];
- lprintf(9, "Deleting room <%s>\n", qrbuf->QRname);
+ lprintf(CTDL_NOTICE, "Deleting room <%s>\n", qrbuf->QRname);
/* Delete the info file */
assoc_file_name(filename, sizeof filename, qrbuf, "info");
unlink(filename);
/* Delete the messages in the room
- * (Careful: this opens an S_QUICKROOM critical section!)
+ * (Careful: this opens an S_ROOMS critical section!)
*/
CtdlDeleteMessages(qrbuf->QRname, 0L, "");
/*
* Check access control for deleting a room
*/
-int CtdlDoIHavePermissionToDeleteThisRoom(struct room *qr) {
+int CtdlDoIHavePermissionToDeleteThisRoom(struct ctdlroom *qr) {
if ((!(CC->logged_in)) && (!(CC->internal_pgm))) {
return(0);
int avoid_access)
{
- struct room qrbuf;
+ struct ctdlroom qrbuf;
struct floor flbuf;
struct visit vbuf;
- lprintf(9, "create_room(%s)\n", new_room_name);
+ lprintf(CTDL_DEBUG, "create_room(%s)\n", new_room_name);
if (getroom(&qrbuf, new_room_name) == 0) {
- lprintf(9, "%s already exists.\n", new_room_name);
+ lprintf(CTDL_DEBUG, "%s already exists.\n", new_room_name);
return (0); /* already exists */
}
- memset(&qrbuf, 0, sizeof(struct room));
+ memset(&qrbuf, 0, sizeof(struct ctdlroom));
safestrncpy(qrbuf.QRpasswd, new_room_pass, sizeof qrbuf.QRpasswd);
qrbuf.QRflags = QR_INUSE;
if (new_room_type > 0)
new_room_floor = 0;
if ((strlen(new_room_name) == 0) && (cre8_ok == 1)) {
- cprintf("%d Invalid room name.\n", ERROR);
+ cprintf("%d Invalid room name.\n", ERROR + ILLEGAL_VALUE);
return;
}
if (num_parms(args) >= 5) {
fl = cgetfloor(extract_int(args, 4));
- if ((fl->f_flags & F_INUSE) == 0) {
+ if (fl == NULL) {
+ cprintf("%d Invalid floor number.\n",
+ ERROR + INVALID_FLOOR_OPERATION);
+ return;
+ }
+ else if ((fl->f_flags & F_INUSE) == 0) {
cprintf("%d Invalid floor number.\n",
ERROR + INVALID_FLOOR_OPERATION);
return;
}
if ((new_room_type < 0) || (new_room_type > 5)) {
- cprintf("%d Invalid room type.\n", ERROR);
+ cprintf("%d Invalid room type.\n", ERROR + ILLEGAL_VALUE);
return;
}
if (new_room_type == 5) {
- if ((config.c_aide_mailboxes == 0)
- || (CC->user.axlevel < 6)) {
+ if (CC->user.axlevel < 6) {
cprintf("%d Higher access required\n",
- ERROR+HIGHER_ACCESS_REQUIRED);
+ ERROR + HIGHER_ACCESS_REQUIRED);
return;
}
}
return;
}
assoc_file_name(infofilename, sizeof infofilename, &CC->room, "info");
- lprintf(9, "opening\n");
+ lprintf(CTDL_DEBUG, "opening\n");
fp = fopen(infofilename, "w");
- lprintf(9, "checking\n");
+ lprintf(CTDL_DEBUG, "checking\n");
if (fp == NULL) {
cprintf("%d Cannot open %s: %s\n",
ERROR + INTERNAL_ERROR, infofilename, strerror(errno));
return;
}
cprintf("%d Send info...\n", SEND_LISTING);
+ flush_output();
do {
client_gets(buf);
if (strlen(new_floor_name) == 0) {
cprintf("%d Blank floor name not allowed.\n",
- ERROR+ILLEGAL_VALUE);
+ ERROR + ILLEGAL_VALUE);
return;
}
np = num_parms(argbuf);
if (np < 1) {
- cprintf("%d Usage error.\n", ERROR);
+ cprintf("%d Usage error.\n", ERROR + ILLEGAL_VALUE);
return;
}