]> code.citadel.org Git - citadel.git/blobdiff - citadel/room_ops.c
Started implementing global room numbers.
[citadel.git] / citadel / room_ops.c
index 9b2f3d6b021b1d5783842efee97b0d7f3e24ec77..7b306ae585b937bd1e851680751079c3f2b76775 100644 (file)
@@ -1,3 +1,4 @@
+/* $Id$ */
 #include <stdlib.h>
 #include <unistd.h>
 #include <stdio.h>
@@ -17,6 +18,7 @@
 #include "msgbase.h"
 #include "serv_chat.h"
 #include "citserver.h"
+#include "control.h"
 
 /*
  * Generic routine for determining user access to rooms
@@ -25,17 +27,9 @@ int CtdlRoomAccess(struct quickroom *roombuf, struct usersupp *userbuf) {
        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 */
@@ -48,6 +42,26 @@ int CtdlRoomAccess(struct quickroom *roombuf, struct usersupp *userbuf) {
        /* 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;
@@ -90,11 +104,11 @@ int CtdlRoomAccess(struct quickroom *roombuf, struct usersupp *userbuf) {
 
        /* 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;
                }
@@ -124,6 +138,12 @@ int getroom(struct quickroom *qrbuf, char *room_name)
                        ( (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 {
@@ -259,32 +279,19 @@ void ForEachRoom(void (*CallBack)(struct quickroom *EachRoom)) {
 
 
 
-/*
- * Create a database key for storage of message lists
- */
-void msglist_key(char *dbkey, struct quickroom *whichroom) {
-       int a;
-       
-       sprintf(dbkey, "%s%ld", whichroom->QRname, whichroom->QRgen);
-       for (a=0; a<strlen(dbkey); ++a) dbkey[a]=tolower(dbkey[a]);
-       }
-
 /*
  * get_msglist()  -  retrieve room message pointers
  */
 void get_msglist(struct quickroom *whichroom) {
        struct cdbdata *cdbfr;
-       char dbkey[256];
 
-       msglist_key(dbkey, whichroom);  
-       
        if (CC->msglist != NULL) {
                free(CC->msglist);
                }
        CC->msglist = NULL;
        CC->num_msgs = 0;
 
-       cdbfr = cdb_fetch(CDB_MSGLISTS, dbkey, strlen(dbkey));
+       cdbfr = cdb_fetch(CDB_MSGLISTS, &whichroom->QRnumber, sizeof(long));
        if (cdbfr == NULL) {
                return;
                }
@@ -300,22 +307,22 @@ void get_msglist(struct quickroom *whichroom) {
  * put_msglist()  -  retrieve room message pointers
  */
 void put_msglist(struct quickroom *whichroom) {
-       char dbkey[256];
 
-       msglist_key(dbkey, whichroom);  
-       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];
 
-       msglist_key(dbkey, whichroom);  
-       cdb_delete(CDB_MSGLISTS, dbkey, strlen(dbkey));
+       cdb_delete(CDB_MSGLISTS, &whichroom->QRnumber, sizeof(long));
        }
 
 
@@ -326,13 +333,11 @@ void delete_msglist(struct quickroom *whichroom) {
  * may not be the current room (as is the case with cmd_move() for example).
  */
 void AddMessageToRoom(struct quickroom *whichroom, long newmsgid) {
-       char dbkey[256];
        struct cdbdata *cdbfr;
        int num_msgs;
        long *msglist;
        
-       msglist_key(dbkey, whichroom);
-       cdbfr = cdb_fetch(CDB_MSGLISTS, dbkey, strlen(dbkey));
+       cdbfr = cdb_fetch(CDB_MSGLISTS, &whichroom->QRnumber, sizeof(long));
        if (cdbfr == NULL) {
                msglist = NULL;
                num_msgs = 0;
@@ -356,7 +361,7 @@ void AddMessageToRoom(struct quickroom *whichroom, long newmsgid) {
        msglist[num_msgs - 1] = newmsgid;
 
        /* Write it back to disk. */
-       cdb_store(CDB_MSGLISTS, dbkey, strlen(dbkey),
+       cdb_store(CDB_MSGLISTS, &whichroom->QRnumber, sizeof(long),
                msglist, num_msgs * sizeof(long));
 
        /* And finally, free up the memory we used. */
@@ -425,11 +430,18 @@ int sort_msglist(long listptrs[], int oldcount)
 
 
 /*
- * 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);
        }
 
@@ -447,9 +459,8 @@ void list_roomname(struct quickroom *qrbuf) {
                strcpy(truncated_roomname, &truncated_roomname[11]);
                cprintf("%s", truncated_roomname);
                }
-
        /* For all other rooms, just display the name in its entirety */
-       else {  
+       else {
                cprintf("%s", qrbuf->QRname);
                }
 
@@ -500,7 +511,7 @@ void cmd_lkra_backend(struct quickroom *qrbuf) {
        if ( ((CtdlRoomAccess(qrbuf, &CC->usersupp)
             & (UA_KNOWN)))
        && ((qrbuf->QRfloor == (CC->FloorBeingSearched))
-          ||((CC->FloorBeingSearched)<0)) ) 
+          ||((CC->FloorBeingSearched)<0)) )
                list_roomname(qrbuf);
        }
 
@@ -699,12 +710,7 @@ void usergoto(char *where, int display_result)
                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();
        }
 
 
@@ -922,6 +928,7 @@ void cmd_getr(void) {
 void cmd_setr(char *args) {
        char buf[256];
        struct floor flbuf;
+       char old_name[ROOMNAMELEN];
        int old_floor;
 
        if (!(CC->logged_in)) {
@@ -950,6 +957,7 @@ void cmd_setr(char *args) {
                }
 
        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;
@@ -978,8 +986,20 @@ void cmd_setr(char *args) {
                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;
@@ -1122,6 +1142,8 @@ void delete_room(struct quickroom *qrbuf) {
        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);
@@ -1220,6 +1242,7 @@ unsigned create_room(char *new_room_name,
        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);