]> code.citadel.org Git - citadel.git/blobdiff - citadel/room_ops.c
* Set up the framework for different "views" of a room
[citadel.git] / citadel / room_ops.c
index ecaf8d84b0d4192daccca9f8e34ed23605b37ea7..f694c348179c34bfec5d8f6da08477f5660f0d38 100644 (file)
@@ -128,19 +128,24 @@ int CtdlRoomAccess(struct quickroom *roombuf, struct usersupp *userbuf)
                retval = retval & ~UA_KNOWN & ~UA_GOTOALLOWED;
        }
 
-       /* Aides get access to everything */
-       if (userbuf->axlevel >= 6) {
+       /* Aides get access to all private rooms */
+       if ( (userbuf->axlevel >= 6)
+          && ((roombuf->QRflags & QR_MAILBOX) == 0) ) {
                if (vbuf.v_flags & V_FORGET) {
                        retval = retval | UA_GOTOALLOWED;
                }
                else {
-                       retval = retval | UA_GOTOALLOWED;
-                       if ((roombuf->QRflags & QR_MAILBOX) == 0) {
-                               retval = retval | UA_KNOWN;
-                       }
+                       retval = retval | UA_KNOWN | UA_GOTOALLOWED;
                }
        }
 
+       /* On some systems, Aides can gain access to mailboxes as well */
+       if ( (config.c_aide_mailboxes)
+          && (userbuf->axlevel >= 6)
+          && (roombuf->QRflags & QR_MAILBOX) ) {
+               retval = retval | UA_GOTOALLOWED;
+       }
+
 NEWMSG:        /* By the way, we also check for the presence of new messages */
        if (is_msg_in_mset(vbuf.v_seen, roombuf->QRhighest) == 0) {
                retval = retval | UA_HASNEWMSGS;
@@ -763,16 +768,16 @@ void usergoto(char *where, int display_result, int *retmsgs, int *retnew)
                CC->quickroom.QRname, new_messages, total_messages);
 
        if (display_result)
-               cprintf("%d%c%s|%d|%d|%d|%d|%ld|%ld|%d|%d|%d|%d\n",
-                       OK, CtdlCheckExpress(),
+               cprintf("%d%c%s|%d|%d|%d|%d|%ld|%ld|%d|%d|%d|%d|%d\n",
+                       CIT_OK, CtdlCheckExpress(),
                        truncated_roomname,
                        new_messages, total_messages,
                        info, CC->quickroom.QRflags,
                        CC->quickroom.QRhighest,
                        vbuf.v_lastseen,
                        rmailflag, raideflag, newmailcount,
-                       CC->quickroom.QRfloor);
-
+                       CC->quickroom.QRfloor,
+                       vbuf.v_view);
 }
 
 
@@ -811,7 +816,8 @@ void cmd_goto(char *gargs)
 
        /* Then try a mailbox name match */
        if (c != 0) {
-               MailboxName(augmented_roomname, &CC->usersupp, towhere);
+               MailboxName(augmented_roomname, sizeof augmented_roomname,
+                           &CC->usersupp, towhere);
                c = getroom(&QRscratch, augmented_roomname);
                if (c == 0)
                        strcpy(towhere, augmented_roomname);
@@ -872,7 +878,21 @@ void cmd_whok(void)
        struct cdbdata *cdbus;
 
        getuser(&CC->usersupp, CC->curr_user);
-       if (CtdlAccessCheck(ac_room_aide)) return;
+
+       /*
+        * This command is only allowed by aides, room aides,
+        * and room namespace owners
+        */
+       if (is_room_aide()
+          || (atol(CC->quickroom.QRname) == CC->usersupp.usernum) ) {
+               /* access granted */
+       }
+       else {
+               /* access denied */
+                cprintf("%d Higher access or room ownership required.\n",
+                        ERROR + HIGHER_ACCESS_REQUIRED);
+                return;
+        }
 
        cprintf("%d Who knows room:\n", LISTING_FOLLOWS);
        cdb_rewind(CDB_USERSUPP);
@@ -963,22 +983,122 @@ void cmd_getr(void)
 {
        if (CtdlAccessCheck(ac_room_aide)) return;
 
-       /********
-       if (is_noneditable(&CC->quickroom)) {
-               cprintf("%d Can't edit this room.\n", ERROR + NOT_HERE);
-               return;
-       }
-       ************/
-
        getroom(&CC->quickroom, CC->quickroom.QRname);
-       cprintf("%d%c%s|%s|%s|%d|%d|%d\n",
-               OK, CtdlCheckExpress(),
-               CC->quickroom.QRname,
-               ((CC->quickroom.QRflags & QR_PASSWORDED) ? CC->quickroom.QRpasswd : ""),
-               ((CC->quickroom.QRflags & QR_DIRECTORY) ? CC->quickroom.QRdirname : ""),
+       cprintf("%d%c%s|%s|%s|%d|%d|%d|%d\n",
+               CIT_OK,
+               CtdlCheckExpress(),
+
+               ((CC->quickroom.QRflags & QR_MAILBOX) ?
+                       &CC->quickroom.QRname[11] : CC->quickroom.QRname),
+
+               ((CC->quickroom.QRflags & QR_PASSWORDED) ?
+                       CC->quickroom.QRpasswd : ""),
+
+               ((CC->quickroom.QRflags & QR_DIRECTORY) ?
+                       CC->quickroom.QRdirname : ""),
+
                CC->quickroom.QRflags,
                (int) CC->quickroom.QRfloor,
-               (int) CC->quickroom.QRorder);
+               (int) CC->quickroom.QRorder,
+
+               CC->quickroom.QRdefaultview);
+}
+
+
+/*
+ * Back end function to rename a room.
+ * You can also specify which floor to move the room to, or specify -1 to
+ * keep the room on the same floor it was on.
+ *
+ * If you are renaming a mailbox room, you must supply the namespace prefix
+ * in *at least* the old name!
+ */
+int CtdlRenameRoom(char *old_name, char *new_name, int new_floor) {
+       int old_floor = 0;
+       struct quickroom qrbuf;
+       struct quickroom qrtmp;
+       int ret = 0;
+       struct floor *fl;
+       struct floor flbuf;
+       long owner = 0L;
+
+       lprintf(9, "CtdlRenameRoom(%s, %s, %d)\n",
+               old_name, new_name, new_floor);
+
+       if (new_floor >= 0) {
+               fl = cgetfloor(new_floor);
+               if ((fl->f_flags & F_INUSE) == 0) {
+                       return(crr_invalid_floor);
+               }
+       }
+
+       begin_critical_section(S_QUICKROOM);
+
+       if ( (getroom(&qrtmp, new_name) == 0) 
+          && (strcasecmp(new_name, old_name)) ) {
+               ret = crr_already_exists;
+       }
+
+       else if (getroom(&qrbuf, old_name) != 0) {
+               ret = crr_room_not_found;
+       }
+
+       else if ( (CC->usersupp.axlevel < 6)
+                 && (CC->usersupp.usernum != qrbuf.QRroomaide)
+                 && ( (((qrbuf.QRflags & QR_MAILBOX) == 0) || (atol(qrbuf.QRname) != CC->usersupp.usernum))) )  {
+               ret = crr_access_denied;
+       }
+
+       else if (is_noneditable(&qrbuf)) {
+               ret = crr_noneditable;
+       }
+
+       else {
+               /* Rename it */
+               if (qrbuf.QRflags & QR_MAILBOX) {
+                       owner = atol(qrbuf.QRname);
+               }
+               if ( (owner > 0L) && (atol(new_name) == 0L) ) {
+                       snprintf(qrbuf.QRname, sizeof(qrbuf.QRname),
+                                       "%010ld.%s", owner, new_name);
+               }
+               else {
+                       safestrncpy(qrbuf.QRname, new_name,
+                                               sizeof(qrbuf.QRname));
+               }
+
+               /* Take care of floor stuff */
+               old_floor = qrbuf.QRfloor;
+               if (new_floor < 0) {
+                       new_floor = old_floor;
+               }
+               qrbuf.QRfloor = new_floor;
+               putroom(&qrbuf);
+
+               /* If the room name changed, then there are now two room
+                * records, so we have to delete the old one.
+                */
+               if (strcasecmp(new_name, old_name)) {
+                       b_deleteroom(old_name);
+               }
+
+               ret = crr_ok;
+       }
+
+       end_critical_section(S_QUICKROOM);
+
+       /* 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->quickroom.QRfloor);
+               ++flbuf.f_ref_count;
+               lputfloor(&flbuf, CC->quickroom.QRfloor);
+       }
+
+       /* ...and everybody say "YATTA!" */     
+       return(ret);
 }
 
 
@@ -988,34 +1108,65 @@ void cmd_getr(void)
 void cmd_setr(char *args)
 {
        char buf[SIZ];
-       struct floor *fl;
-       struct floor flbuf;
-       char old_name[ROOMNAMELEN];
-       int old_floor;
        int new_order = 0;
-       int ne = 0;
+       int r;
+       int new_floor;
+       char new_name[ROOMNAMELEN];
 
-       if (CtdlAccessCheck(ac_room_aide)) return;
+       if (CtdlAccessCheck(ac_logged_in)) return;
 
-       if (is_noneditable(&CC->quickroom)) {
-               ne = 1;
+       if (num_parms(args) >= 6) {
+               new_floor = extract_int(args, 5);
+       }
+       else {
+               new_floor = (-1);       /* don't change the floor */
        }
 
-       /***
-               cprintf("%d Can't edit this room.\n", ERROR + NOT_HERE);
-               return;
+       /* When is a new name more than just a new name?  When the old name
+        * has a namespace prefix.
+        */
+       if (CC->quickroom.QRflags & QR_MAILBOX) {
+               sprintf(new_name, "%010ld.", atol(CC->quickroom.QRname) );
+       }
+       else {
+               strcpy(new_name, "");
        }
-       ***/
+       extract(&new_name[strlen(new_name)], args, 0);
 
+       r = CtdlRenameRoom(CC->quickroom.QRname, new_name, new_floor);
 
-       if (num_parms(args) >= 6) {
-               fl = cgetfloor(extract_int(args, 5));
-               if ((fl->f_flags & F_INUSE) == 0) {
-                       cprintf("%d Invalid floor number.\n",
-                               ERROR + INVALID_FLOOR_OPERATION);
-                       return;
-               }
+       if (r == crr_room_not_found) {
+               cprintf("%d Internal error - room not found?\n", 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);
+       }
+       else if (r == crr_invalid_floor) {
+               cprintf("%d Target floor does not exist.\n",
+                       ERROR + INVALID_FLOOR_OPERATION);
+       }
+       else if (r == crr_access_denied) {
+               cprintf("%d You do not have permission to edit '%s'\n",
+                       ERROR + HIGHER_ACCESS_REQUIRED,
+                       CC->quickroom.QRname);
+       }
+       else if (r != crr_ok) {
+               cprintf("%d Error: CtdlRenameRoom() returned %d\n",
+                       ERROR, r);
+       }
+
+       if (r != crr_ok) {
+               return;
        }
+
+       getroom(&CC->quickroom, new_name);
+
+       /* Now we have to do a bunch of other stuff */
+
        if (num_parms(args) >= 7) {
                new_order = extract_int(args, 6);
                if (new_order < 1)
@@ -1025,15 +1176,6 @@ void cmd_setr(char *args)
        }
        lgetroom(&CC->quickroom, CC->quickroom.QRname);
 
-       /* Non-editable base rooms can't be renamed */
-       strcpy(old_name, CC->quickroom.QRname);
-       if (!ne) {
-               extract(buf, args, 0);
-               buf[ROOMNAMELEN] = 0;
-               safestrncpy(CC->quickroom.QRname, buf,
-                       sizeof CC->quickroom.QRname);
-       }
-
        extract(buf, args, 1);
        buf[10] = 0;
        safestrncpy(CC->quickroom.QRpasswd, buf, sizeof CC->quickroom.QRpasswd);
@@ -1059,27 +1201,15 @@ void cmd_setr(char *args)
        if (extract_int(args, 4)) {
                time(&CC->quickroom.QRgen);
        }
-       old_floor = CC->quickroom.QRfloor;
-       if (num_parms(args) >= 6) {
-               CC->quickroom.QRfloor = extract_int(args, 5);
+
+       if (num_parms(args) >= 8) {
+               CC->quickroom.QRdefaultview = extract_int(args, 7);
        }
+
+
        /* Write the room record back to disk */
        lputroom(&CC->quickroom);
 
-       /* If the room name changed, then there are now two room records,
-        * so we have to delete the old one.
-        */
-       if (strcasecmp(CC->quickroom.QRname, old_name)) {
-               b_deleteroom(old_name);
-       }
-       /* adjust the floor reference counts */
-       lgetfloor(&flbuf, old_floor);
-       --flbuf.f_ref_count;
-       lputfloor(&flbuf, old_floor);
-       lgetfloor(&flbuf, CC->quickroom.QRfloor);
-       ++flbuf.f_ref_count;
-       lputfloor(&flbuf, CC->quickroom.QRfloor);
-
        /* create a room directory if necessary */
        if (CC->quickroom.QRflags & QR_DIRECTORY) {
                snprintf(buf, sizeof buf,
@@ -1089,7 +1219,7 @@ void cmd_setr(char *args)
        }
        snprintf(buf, sizeof buf, "%s> edited by %s\n", CC->quickroom.QRname, CC->curr_user);
        aide_message(buf);
-       cprintf("%d Ok\n", OK);
+       cprintf("%d Ok\n", CIT_OK);
 }
 
 
@@ -1108,9 +1238,9 @@ void cmd_geta(void)
                return;
        }
        if (getuserbynumber(&usbuf, CC->quickroom.QRroomaide) == 0) {
-               cprintf("%d %s\n", OK, usbuf.fullname);
+               cprintf("%d %s\n", CIT_OK, usbuf.fullname);
        } else {
-               cprintf("%d \n", OK);
+               cprintf("%d \n", CIT_OK);
        }
 }
 
@@ -1150,7 +1280,7 @@ void cmd_seta(char *new_ra)
                        usbuf.fullname, CC->quickroom.QRname);
                aide_message(buf);
        }
-       cprintf("%d Ok\n", OK);
+       cprintf("%d Ok\n", CIT_OK);
 }
 
 /*
@@ -1297,9 +1427,9 @@ void cmd_kill(char *argbuf)
                snprintf(aaa, sizeof aaa, "%s> killed by %s\n",
                         deleted_room_name, CC->curr_user);
                aide_message(aaa);
-               cprintf("%d '%s' deleted.\n", OK, deleted_room_name);
+               cprintf("%d '%s' deleted.\n", CIT_OK, deleted_room_name);
        } else {
-               cprintf("%d ok to delete.\n", OK);
+               cprintf("%d ok to delete.\n", CIT_OK);
        }
 }
 
@@ -1344,7 +1474,7 @@ unsigned create_room(char *new_room_name,
         * name accordingly (prepend the user number)
         */
        if (new_room_type == 4) {
-               MailboxName(qrbuf.QRname, &CC->usersupp, new_room_name);
+               MailboxName(qrbuf.QRname, sizeof qrbuf.QRname, &CC->usersupp, new_room_name);
        }
        else {
                safestrncpy(qrbuf.QRname, new_room_name, sizeof qrbuf.QRname);
@@ -1445,7 +1575,7 @@ void cmd_cre8(char *args)
        }
 
        if ((strlen(new_room_name) == 0) && (cre8_ok == 0)) {
-               cprintf("%d Ok to create rooms.\n", OK);
+               cprintf("%d Ok to create rooms.\n", CIT_OK);
                return;
        }
 
@@ -1464,7 +1594,7 @@ void cmd_cre8(char *args)
        }
 
        if (cre8_ok == 0) {
-               cprintf("%d OK to create '%s'\n", OK, new_room_name);
+               cprintf("%d OK to create '%s'\n", CIT_OK, new_room_name);
                return;
        }
 
@@ -1490,7 +1620,7 @@ void cmd_cre8(char *args)
        strcat(aaa, "\n");
        aide_message(aaa);
 
-       cprintf("%d '%s' has been created.\n", OK, new_room_name);
+       cprintf("%d '%s' has been created.\n", CIT_OK, new_room_name);
 }
 
 
@@ -1504,7 +1634,7 @@ void cmd_einf(char *ok)
        if (CtdlAccessCheck(ac_room_aide)) return;
 
        if (atoi(ok) == 0) {
-               cprintf("%d Ok.\n", OK);
+               cprintf("%d Ok.\n", CIT_OK);
                return;
        }
        assoc_file_name(infofilename, sizeof infofilename, &CC->quickroom, "info");
@@ -1599,7 +1729,7 @@ void cmd_cflr(char *argbuf)
                return;
        }
        if (cflr_ok == 0) {
-               cprintf("%d ok to create...\n", OK);
+               cprintf("%d ok to create...\n", CIT_OK);
                return;
        }
        lgetfloor(&flbuf, free_slot);
@@ -1607,7 +1737,7 @@ void cmd_cflr(char *argbuf)
        flbuf.f_ref_count = 0;
        safestrncpy(flbuf.f_name, new_floor_name, sizeof flbuf.f_name);
        lputfloor(&flbuf, free_slot);
-       cprintf("%d %d\n", OK, free_slot);
+       cprintf("%d %d\n", CIT_OK, free_slot);
 }
 
 
@@ -1642,9 +1772,9 @@ void cmd_kflr(char *argbuf)
                        delete_ok = 0;
                } else {
                        if (kflr_ok == 1) {
-                               cprintf("%d Ok\n", OK);
+                               cprintf("%d Ok\n", CIT_OK);
                        } else {
-                               cprintf("%d Ok to delete...\n", OK);
+                               cprintf("%d Ok to delete...\n", CIT_OK);
                        }
 
                }
@@ -1685,5 +1815,5 @@ void cmd_eflr(char *argbuf)
                extract(flbuf.f_name, argbuf, 1);
        lputfloor(&flbuf, floor_num);
 
-       cprintf("%d Ok\n", OK);
+       cprintf("%d Ok\n", CIT_OK);
 }