]> code.citadel.org Git - citadel.git/blobdiff - citadel/room_ops.c
* sort_msglist() now uses qsort() instead of a bubble sort
[citadel.git] / citadel / room_ops.c
index 285256807dd7fc05ffa0a46552f902dbac7735d1..e1d501a1c4cf7860a4544126136d64de52111303 100644 (file)
@@ -12,6 +12,7 @@
 #include <sys/stat.h>
 #include <ctype.h>
 #include <string.h>
+#include <dirent.h>    /* for cmd_rdir to read contents of the directory */
 
 #if TIME_WITH_SYS_TIME
 # include <sys/time.h>
@@ -27,8 +28,8 @@
 #include <limits.h>
 #include <errno.h>
 #include "citadel.h"
+#include <libcitadel.h>
 #include "server.h"
-#include "serv_extensions.h"
 #include "database.h"
 #include "config.h"
 #include "room_ops.h"
 #include "msgbase.h"
 #include "citserver.h"
 #include "control.h"
-#include "tools.h"
 #include "citadel_dirs.h"
+#include "threads.h"
 
 struct floor *floorcache[MAXFLOORS];
 
 /*
- * Generic routine for determining user access to rooms
+ * Retrieve access control information for any user/room pair
  */
 void CtdlRoomAccess(struct ctdlroom *roombuf, struct ctdluser *userbuf,
                int *result, int *view)
@@ -54,7 +55,7 @@ void CtdlRoomAccess(struct ctdlroom *roombuf, struct ctdluser *userbuf,
 
        /* for internal programs, always do everything */
        if (((CC->internal_pgm)) && (roombuf->QRflags & QR_INUSE)) {
-               retval = (UA_KNOWN | UA_GOTOALLOWED);
+               retval = (UA_KNOWN | UA_GOTOALLOWED | UA_POSTALLOWED);
                vbuf.v_view = 0;
                goto SKIP_EVERYTHING;
        }
@@ -65,7 +66,7 @@ void CtdlRoomAccess(struct ctdlroom *roombuf, struct ctdluser *userbuf,
        /* Force the properties of the Aide room */
        if (!strcasecmp(roombuf->QRname, config.c_aideroom)) {
                if (userbuf->axlevel >= 6) {
-                       retval = UA_KNOWN | UA_GOTOALLOWED;
+                       retval = UA_KNOWN | UA_GOTOALLOWED | UA_POSTALLOWED | UA_DELETEALLOWED;
                } else {
                        retval = 0;
                }
@@ -103,15 +104,43 @@ void CtdlRoomAccess(struct ctdlroom *roombuf, struct ctdluser *userbuf,
                }
        }
 
-       /* For mailbox rooms, also check the generation number matchups */
+       /* For mailbox rooms, also check the namespace */
+       /* Also, mailbox owners can delete their messages */
        if (roombuf->QRflags & QR_MAILBOX) {
                if (userbuf->usernum == atol(roombuf->QRname)) {
-                       retval = retval | UA_KNOWN | UA_GOTOALLOWED;
+                       retval = retval | UA_KNOWN | UA_GOTOALLOWED | UA_POSTALLOWED | UA_DELETEALLOWED;
                }
                /* An explicit match means the user belongs in this room */
                if (vbuf.v_flags & V_ACCESS) {
-                       retval = retval | UA_KNOWN | UA_GOTOALLOWED;
+                       retval = retval | UA_KNOWN | UA_GOTOALLOWED | UA_POSTALLOWED | UA_DELETEALLOWED;
+               }
+       }
+
+       /* For non-mailbox rooms... */
+       else {
+
+               /* User is allowed to post in the room unless:
+                * - User is not validated
+                * - User has no net privileges and it is a shared network room
+                * - It is a read-only room
+                */
+               int post_allowed = 1;
+               if (CC->user.axlevel < 2) post_allowed = 0;
+               if ((CC->user.axlevel < 4) && (CC->room.QRflags & QR_NETWORK)) post_allowed = 0;
+               if (roombuf->QRflags & QR_READONLY) post_allowed = 0;
+               if (post_allowed) {
+                       retval = retval | UA_POSTALLOWED;
+               }
+
+               /* If "collaborative deletion" is active for this room, any user who can post
+                * is also allowed to delete
+                */
+               if (CC->room.QRflags2 & QR2_COLLABDEL) {
+                       if (retval & UA_POSTALLOWED) {
+                               retval = retval | UA_DELETEALLOWED;
+                       }
                }
+
        }
 
        /* Check to see if the user has forgotten this room */
@@ -126,17 +155,17 @@ void CtdlRoomAccess(struct ctdlroom *roombuf, struct ctdluser *userbuf,
        }
        /* If user is explicitly locked out of this room, deny everything */
        if (vbuf.v_flags & V_LOCKOUT) {
-               retval = retval & ~UA_KNOWN & ~UA_GOTOALLOWED;
+               retval = retval & ~UA_KNOWN & ~UA_GOTOALLOWED & ~UA_POSTALLOWED;
        }
 
        /* 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;
+                       retval = retval | UA_GOTOALLOWED | UA_POSTALLOWED;
                }
                else {
-                       retval = retval | UA_KNOWN | UA_GOTOALLOWED;
+                       retval = retval | UA_KNOWN | UA_GOTOALLOWED | UA_POSTALLOWED;
                }
        }
 
@@ -145,7 +174,14 @@ void CtdlRoomAccess(struct ctdlroom *roombuf, struct ctdluser *userbuf,
         */
        if ( (userbuf->axlevel >= 6)
           && (roombuf->QRflags & QR_MAILBOX) ) {
-               retval = retval | UA_GOTOALLOWED;
+               retval = retval | UA_GOTOALLOWED | UA_POSTALLOWED;
+       }
+
+       /* Aides and Room Aides have admin privileges */
+       if ( (userbuf->axlevel >= 6)
+          || (userbuf->usernum == roombuf->QRroomaide)
+          ) {
+               retval = retval | UA_ADMINALLOWED | UA_DELETEALLOWED | UA_POSTALLOWED;
        }
 
 NEWMSG:        /* By the way, we also check for the presence of new messages */
@@ -191,12 +227,16 @@ int getroom(struct ctdlroom *qrbuf, char *room_name)
        struct cdbdata *cdbqr;
        char lowercase_name[ROOMNAMELEN];
        char personal_lowercase_name[ROOMNAMELEN];
-       int a;
+       char *dptr, *sptr, *eptr;
 
-       for (a = 0; room_name[a] && a < sizeof lowercase_name - 1; ++a) {
-               lowercase_name[a] = tolower(room_name[a]);
+       dptr = lowercase_name;
+       sptr = room_name;
+       eptr = (dptr + (sizeof lowercase_name - 1));
+       while (!IsEmptyStr(sptr) && (dptr < eptr)){
+               *dptr = tolower(*sptr);
+               sptr++; dptr++;
        }
-       lowercase_name[a] = 0;
+       *dptr = '\0';
 
        memset(qrbuf, 0, sizeof(struct ctdlroom));
 
@@ -246,19 +286,27 @@ int lgetroom(struct ctdlroom *qrbuf, char *room_name)
 void b_putroom(struct ctdlroom *qrbuf, char *room_name)
 {
        char lowercase_name[ROOMNAMELEN];
-       int a;
+       char *aptr, *bptr;
+       long len;
 
-       for (a = 0; a <= strlen(room_name); ++a) {
-               lowercase_name[a] = tolower(room_name[a]);
+       aptr = room_name;
+       bptr = lowercase_name;
+       while (!IsEmptyStr(aptr))
+       {
+               *bptr = tolower(*aptr);
+               aptr++;
+               bptr++;
        }
+       *bptr='\0';
 
+       len = bptr - lowercase_name;
        if (qrbuf == NULL) {
                cdb_delete(CDB_ROOMS,
-                          lowercase_name, strlen(lowercase_name));
+                          lowercase_name, len);
        } else {
                time(&qrbuf->QRmtime);
                cdb_store(CDB_ROOMS,
-                         lowercase_name, strlen(lowercase_name),
+                         lowercase_name, len,
                          qrbuf, sizeof(struct ctdlroom));
        }
 }
@@ -445,6 +493,15 @@ void delete_msglist(struct ctdlroom *whichroom)
 
 
 
+/*
+ * Message pointer compare function for sort_msglist()
+ */
+int sort_msglist_cmp(long *m1, long *m2) {
+       if (*m1 > *m2) return(1);
+       if (*m1 < *m2) return(-1);
+       return(0);
+}
+
 
 /*
  * sort message pointers
@@ -452,29 +509,19 @@ void delete_msglist(struct ctdlroom *whichroom)
  */
 int sort_msglist(long listptrs[], int oldcount)
 {
-       int a, b;
-       long hold1, hold2;
        int numitems;
 
        numitems = oldcount;
-       if (numitems < 2)
+       if (numitems < 2) {
                return (oldcount);
+       }
 
        /* do the sort */
-       for (a = numitems - 2; a >= 0; --a) {
-               for (b = 0; b <= a; ++b) {
-                       if (listptrs[b] > (listptrs[b + 1])) {
-                               hold1 = listptrs[b];
-                               hold2 = listptrs[b + 1];
-                               listptrs[b] = hold2;
-                               listptrs[b + 1] = hold1;
-                       }
-               }
-       }
+       qsort(listptrs, numitems, sizeof(long), sort_msglist_cmp);
 
        /* and yank any nulls */
        while ((numitems > 0) && (listptrs[0] == 0L)) {
-               memcpy(&listptrs[0], &listptrs[1],
+               memmove(&listptrs[0], &listptrs[1],
                       (sizeof(long) * (numitems - 1)));
                --numitems;
        }
@@ -554,7 +601,7 @@ void cmd_lrms_backend(struct ctdlroom *qrbuf, void *data)
 void cmd_lrms(char *argbuf)
 {
        int FloorBeingSearched = (-1);
-       if (strlen(argbuf) > 0)
+       if (!IsEmptyStr(argbuf))
                FloorBeingSearched = extract_int(argbuf, 0);
 
        if (CtdlAccessCheck(ac_logged_in)) return;
@@ -592,7 +639,7 @@ void cmd_lkra_backend(struct ctdlroom *qrbuf, void *data)
 void cmd_lkra(char *argbuf)
 {
        int FloorBeingSearched = (-1);
-       if (strlen(argbuf) > 0)
+       if (!IsEmptyStr(argbuf))
                FloorBeingSearched = extract_int(argbuf, 0);
 
        if (CtdlAccessCheck(ac_logged_in)) return;
@@ -628,7 +675,7 @@ void cmd_lprm_backend(struct ctdlroom *qrbuf, void *data)
 void cmd_lprm(char *argbuf)
 {
        int FloorBeingSearched = (-1);
-       if (strlen(argbuf) > 0)
+       if (!IsEmptyStr(argbuf))
                FloorBeingSearched = extract_int(argbuf, 0);
 
        cprintf("%d Publiic rooms:\n", LISTING_FOLLOWS);
@@ -661,7 +708,7 @@ void cmd_lkrn_backend(struct ctdlroom *qrbuf, void *data)
 void cmd_lkrn(char *argbuf)
 {
        int FloorBeingSearched = (-1);
-       if (strlen(argbuf) > 0)
+       if (!IsEmptyStr(argbuf))
                FloorBeingSearched = extract_int(argbuf, 0);
 
        if (CtdlAccessCheck(ac_logged_in)) return;
@@ -700,7 +747,7 @@ void cmd_lkro_backend(struct ctdlroom *qrbuf, void *data)
 void cmd_lkro(char *argbuf)
 {
        int FloorBeingSearched = (-1);
-       if (strlen(argbuf) > 0)
+       if (!IsEmptyStr(argbuf))
                FloorBeingSearched = extract_int(argbuf, 0);
 
        if (CtdlAccessCheck(ac_logged_in)) return;
@@ -739,7 +786,7 @@ void cmd_lzrm_backend(struct ctdlroom *qrbuf, void *data)
 void cmd_lzrm(char *argbuf)
 {
        int FloorBeingSearched = (-1);
-       if (strlen(argbuf) > 0)
+       if (!IsEmptyStr(argbuf))
                FloorBeingSearched = extract_int(argbuf, 0);
 
        if (CtdlAccessCheck(ac_logged_in)) return;
@@ -821,7 +868,6 @@ void usergoto(char *where, int display_result, int transiently,
                info = 1;
        }
 
-       get_mm();
         cdbfr = cdb_fetch(CDB_MSGLISTS, &CC->room.QRnumber, sizeof(long));
         if (cdbfr != NULL) {
                msglist = (long *) cdbfr->ptr;
@@ -886,7 +932,7 @@ void usergoto(char *where, int display_result, int transiently,
 
        if (retmsgs != NULL) *retmsgs = total_messages;
        if (retnew != NULL) *retnew = new_messages;
-       lprintf(CTDL_DEBUG, "<%s> %d new of %d total messages\n",
+       CtdlLogPrintf(CTDL_DEBUG, "<%s> %d new of %d total messages\n",
                CC->room.QRname,
                new_messages, total_messages
        );
@@ -894,7 +940,7 @@ void usergoto(char *where, int display_result, int transiently,
        CC->curr_view = (int)vbuf.v_view;
 
        if (display_result) {
-               cprintf("%d%c%s|%d|%d|%d|%d|%ld|%ld|%d|%d|%d|%d|%d|%d|%d|\n",
+               cprintf("%d%c%s|%d|%d|%d|%d|%ld|%ld|%d|%d|%d|%d|%d|%d|%d|%d|\n",
                        CIT_OK, CtdlCheckExpress(),
                        truncated_roomname,
                        (int)new_messages,
@@ -909,7 +955,8 @@ void usergoto(char *where, int display_result, int transiently,
                        (int)CC->room.QRfloor,
                        (int)vbuf.v_view,
                        (int)CC->room.QRdefaultview,
-                       (int)is_trash
+                       (int)is_trash,
+                       (int)CC->room.QRflags2
                );
        }
 }
@@ -1025,7 +1072,7 @@ void cmd_goto(char *gargs)
                                   ((ra & UA_KNOWN) == 0) &&
                                   (CC->user.axlevel < 6)
                                   ) {
-                               lprintf(CTDL_DEBUG, "Failed to acquire private room\n");
+                               CtdlLogPrintf(CTDL_DEBUG, "Failed to acquire private room\n");
                        } else {
                                memcpy(&CC->room, &QRscratch,
                                        sizeof(struct ctdlroom));
@@ -1068,14 +1115,17 @@ void cmd_whok(void)
 void cmd_rdir(void)
 {
        char buf[256];
-       char flnm[256];
        char comment[256];
-       FILE *ls, *fd;
+       FILE *fd;
        struct stat statbuf;
-       char tempfilename[PATH_MAX];
-
+       DIR *filedir = NULL;
+       struct dirent *filedir_entry;
+       int d_namelen;
+       char buf2[SIZ];
+       char mimebuf[64];
+       long len;
+       
        if (CtdlAccessCheck(ac_logged_in)) return;
-       CtdlMakeTempFileName(tempfilename, sizeof tempfilename);
        
        getroom(&CC->room, CC->room.QRname);
        getuser(&CC->user, CC->curr_user);
@@ -1090,55 +1140,62 @@ void cmd_rdir(void)
                cprintf("%d not here.\n", ERROR + HIGHER_ACCESS_REQUIRED);
                return;
        }
-       cprintf("%d %s|%s/%s\n",
-                       LISTING_FOLLOWS, 
-                       config.c_fqdn,
-                       ctdl_file_dir, 
-                       CC->room.QRdirname);
-
-       snprintf(buf, sizeof buf, 
-                        "ls %s/%s >%s 2>/dev/null",
-                        ctdl_file_dir,
-                        CC->room.QRdirname, 
-                        tempfilename);
-       system(buf);
-
-       snprintf(buf, sizeof buf, 
-                        "%s/%s/filedir",
-                        ctdl_file_dir,
-                        CC->room.QRdirname);
+
+       snprintf(buf, sizeof buf, "%s/%s", ctdl_file_dir, CC->room.QRdirname);
+       filedir = opendir (buf);
+       
+       if (filedir == NULL) {
+               cprintf("%d not here.\n", ERROR + HIGHER_ACCESS_REQUIRED);
+               return;
+       }
+       cprintf("%d %s|%s/%s\n", LISTING_FOLLOWS, config.c_fqdn, ctdl_file_dir, CC->room.QRdirname);
+       
+       snprintf(buf, sizeof buf, "%s/%s/filedir", ctdl_file_dir, CC->room.QRdirname);
        fd = fopen(buf, "r");
        if (fd == NULL)
                fd = fopen("/dev/null", "r");
-
-       ls = fopen(tempfilename, "r");
-       while (fgets(flnm, sizeof flnm, ls) != NULL) {
-               flnm[strlen(flnm) - 1] = 0;
-               if (strcasecmp(flnm, "filedir")) {
-                       snprintf(buf, sizeof buf, 
-                                        "%s/%s/%s",
-                                        ctdl_file_dir,
-                                        CC->room.QRdirname,
-                                        flnm);
-                       stat(buf, &statbuf);
+       while ((filedir_entry = readdir(filedir)))
+       {
+               if (strcasecmp(filedir_entry->d_name, "filedir") && filedir_entry->d_name[0] != '.')
+               {
+#ifdef _DIRENT_HAVE_D_NAMELEN
+                       d_namelen = filedir_entry->d_namelen;
+#else
+                       d_namelen = strlen(filedir_entry->d_name);
+#endif
+                       snprintf(buf, sizeof buf, "%s/%s/%s", ctdl_file_dir, CC->room.QRdirname, filedir_entry->d_name);
+                       stat(buf, &statbuf);    /* stat the file */
+                       if (!(statbuf.st_mode & S_IFREG))
+                       {
+                               snprintf(buf2, sizeof buf2, "Command RDIR found something that is not a useable file. It should be cleaned up.\n RDIR found this non regular file:\n%s\n", buf);
+                               aide_message(buf2, "RDIR found bad file");
+                               continue;       /* not a useable file type so don't show it */
+                       }
                        safestrncpy(comment, "", sizeof comment);
-                       fseek(fd, 0L, 0);
-                       while ((fgets(buf, sizeof buf, fd) != NULL)
-                              && (strlen(comment) == 0)) {
+                       fseek(fd, 0L, 0);       /* rewind descriptions file */
+                       /* Get the description from the descriptions file */
+                       while ((fgets(buf, sizeof buf, fd) != NULL) && (IsEmptyStr(comment))) 
+                       {
                                buf[strlen(buf) - 1] = 0;
-                               if ((!strncasecmp(buf, flnm, strlen(flnm)))
-                                   && (buf[strlen(flnm)] == ' '))
-                                       safestrncpy(comment,
-                                           &buf[strlen(flnm) + 1],
-                                           sizeof comment);
+                               if ((!strncasecmp(buf, filedir_entry->d_name, d_namelen)) && (buf[d_namelen] == ' '))
+                                       safestrncpy(comment, &buf[d_namelen + 1], sizeof comment);
+                       }
+                       len = extract_token (mimebuf, comment, 0,' ', 64);
+                       if ((len <0) || strchr(mimebuf, '/') == NULL)
+                       {
+                               snprintf (mimebuf, 64, "application/octetstream");
+                               len = 0;
                        }
-                       cprintf("%s|%ld|%s\n", flnm, (long)statbuf.st_size, comment);
+                       cprintf("%s|%ld|%s|%s\n", 
+                               filedir_entry->d_name, 
+                               (long)statbuf.st_size, 
+                               mimebuf, 
+                               &comment[len]);
                }
        }
-       fclose(ls);
        fclose(fd);
-       unlink(tempfilename);
-
+       closedir(filedir);
+       
        cprintf("000\n");
 }
 
@@ -1191,7 +1248,7 @@ int CtdlRenameRoom(char *old_name, char *new_name, int new_floor) {
        long owner = 0L;
        char actual_old_name[ROOMNAMELEN];
 
-       lprintf(CTDL_DEBUG, "CtdlRenameRoom(%s, %s, %d)\n",
+       CtdlLogPrintf(CTDL_DEBUG, "CtdlRenameRoom(%s, %s, %d)\n",
                old_name, new_name, new_floor);
 
        if (new_floor >= 0) {
@@ -1282,11 +1339,11 @@ int CtdlRenameRoom(char *old_name, char *new_name, int new_floor) {
                lgetfloor(&flbuf, old_floor);
                --flbuf.f_ref_count;
                lputfloor(&flbuf, old_floor);
-               lprintf(CTDL_DEBUG, "Reference count for floor %d is now %d\n", old_floor, flbuf.f_ref_count);
+               CtdlLogPrintf(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, new_floor);
-               lprintf(CTDL_DEBUG, "Reference count for floor %d is now %d\n", new_floor, flbuf.f_ref_count);
+               CtdlLogPrintf(CTDL_DEBUG, "Reference count for floor %d is now %d\n", new_floor, flbuf.f_ref_count);
        }
 
        /* ...and everybody say "YATTA!" */     
@@ -1486,7 +1543,7 @@ void cmd_seta(char *new_ra)
         * the room table, otherwise it would deadlock!
         */
        if (post_notice == 1) {
-               if (strlen(usbuf.fullname) > 0)
+               if (!IsEmptyStr(usbuf.fullname))
                        snprintf(buf, sizeof buf,
                                "%s is now the room aide for \"%s\".\n",
                                usbuf.fullname, CC->room.QRname);
@@ -1517,7 +1574,7 @@ void cmd_rinf(void)
        }
        cprintf("%d Info:\n", LISTING_FOLLOWS);
        while (fgets(buf, sizeof buf, info_fp) != NULL) {
-               if (strlen(buf) > 0)
+               if (!IsEmptyStr(buf))
                        buf[strlen(buf) - 1] = 0;
                cprintf("%s\n", buf);
        }
@@ -1535,7 +1592,7 @@ void schedule_room_for_deletion(struct ctdlroom *qrbuf)
        char old_name[ROOMNAMELEN];
        static int seq = 0;
 
-       lprintf(CTDL_NOTICE, "Scheduling room <%s> for deletion\n",
+       CtdlLogPrintf(CTDL_NOTICE, "Scheduling room <%s> for deletion\n",
                qrbuf->QRname);
 
        safestrncpy(old_name, qrbuf->QRname, sizeof old_name);
@@ -1573,7 +1630,7 @@ void delete_room(struct ctdlroom *qrbuf)
        char filename[100];
        /* TODO: filename magic? does this realy work? */
 
-       lprintf(CTDL_NOTICE, "Deleting room <%s>\n", qrbuf->QRname);
+       CtdlLogPrintf(CTDL_NOTICE, "Deleting room <%s>\n", qrbuf->QRname);
 
        /* Delete the info file */
        assoc_file_name(filename, sizeof filename, qrbuf, ctdl_info_dir);
@@ -1704,11 +1761,11 @@ unsigned create_room(char *new_room_name,
        struct floor flbuf;
        struct visit vbuf;
 
-       lprintf(CTDL_DEBUG, "create_room(name=%s, type=%d, view=%d)\n",
+       CtdlLogPrintf(CTDL_DEBUG, "create_room(name=%s, type=%d, view=%d)\n",
                new_room_name, new_room_type, new_room_view);
 
        if (getroom(&qrbuf, new_room_name) == 0) {
-               lprintf(CTDL_DEBUG, "%s already exists.\n", new_room_name);
+               CtdlLogPrintf(CTDL_DEBUG, "%s already exists.\n", new_room_name);
                return(0);
        }
 
@@ -1721,8 +1778,10 @@ unsigned create_room(char *new_room_name,
                qrbuf.QRflags = (qrbuf.QRflags | QR_GUESSNAME);
        if (new_room_type == 2)
                qrbuf.QRflags = (qrbuf.QRflags | QR_PASSWORDED);
-       if ( (new_room_type == 4) || (new_room_type == 5) )
+       if ( (new_room_type == 4) || (new_room_type == 5) ) {
                qrbuf.QRflags = (qrbuf.QRflags | QR_MAILBOX);
+               /* qrbuf.QRflags2 |= QR2_SUBJECTREQ; */
+       }
 
        /* If the user is requesting a personal room, set up the room
         * name accordingly (prepend the user number)
@@ -1805,7 +1864,7 @@ void cmd_cre8(char *args)
        new_room_pass[9] = 0;
        new_room_floor = 0;
 
-       if ((strlen(new_room_name) == 0) && (cre8_ok == 1)) {
+       if ((IsEmptyStr(new_room_name)) && (cre8_ok == 1)) {
                cprintf("%d Invalid room name.\n", ERROR + ILLEGAL_VALUE);
                return;
        }
@@ -1834,13 +1893,13 @@ void cmd_cre8(char *args)
 
        if (CtdlAccessCheck(ac_logged_in)) return;
 
-       if (CC->user.axlevel < config.c_createax || CC->internal_pgm) {
+       if (CC->user.axlevel < config.c_createax && !CC->internal_pgm) {
                cprintf("%d You need higher access to create rooms.\n",
                        ERROR + HIGHER_ACCESS_REQUIRED);
                return;
        }
 
-       if ((strlen(new_room_name) == 0) && (cre8_ok == 0)) {
+       if ((IsEmptyStr(new_room_name)) && (cre8_ok == 0)) {
                cprintf("%d Ok to create rooms.\n", CIT_OK);
                return;
        }
@@ -1914,9 +1973,9 @@ void cmd_einf(char *ok)
                return;
        }
        assoc_file_name(infofilename, sizeof infofilename, &CC->room, ctdl_info_dir);
-       lprintf(CTDL_DEBUG, "opening\n");
+       CtdlLogPrintf(CTDL_DEBUG, "opening\n");
        fp = fopen(infofilename, "w");
-       lprintf(CTDL_DEBUG, "checking\n");
+       CtdlLogPrintf(CTDL_DEBUG, "checking\n");
        if (fp == NULL) {
                cprintf("%d Cannot open %s: %s\n",
                  ERROR + INTERNAL_ERROR, infofilename, strerror(errno));
@@ -1980,7 +2039,7 @@ void cmd_cflr(char *argbuf)
 
        if (CtdlAccessCheck(ac_aide)) return;
 
-       if (strlen(new_floor_name) == 0) {
+       if (IsEmptyStr(new_floor_name)) {
                cprintf("%d Blank floor name not allowed.\n",
                        ERROR + ILLEGAL_VALUE);
                return;