Cache the most recently fetched msglist in CtdlForEachMessage()
authorArt Cancro <ajc@citadel.org>
Wed, 26 Jan 2011 23:08:16 +0000 (18:08 -0500)
committerWilfried Goesgens <dothebart@citadel.org>
Sun, 4 Sep 2011 13:19:48 +0000 (13:19 +0000)
(This will be used for a security check in an upcoming commit)

citadel/citserver.c
citadel/context.c
citadel/context.h
citadel/msgbase.c

index 3bec05b1ed79418c23fe8c800dbfa9ebaf6aaa11..3f9ac42ab5acd01ca8ac6a4b6bb7e726fa760b10 100644 (file)
@@ -906,6 +906,7 @@ void begin_session(CitContext *con)
        con->internal_pgm = 0;
        con->download_fp = NULL;
        con->upload_fp = NULL;
+       con->cached_msglist = NULL;
        con->FirstExpressMessage = NULL;
        time(&con->lastcmd);
        time(&con->lastidle);
index bf34f255e0ce0dbfc9eddc450c425f9db9416426..2b1cce1b0d84a457157f55a3d88c590c496ae6f0 100644 (file)
@@ -368,6 +368,10 @@ void RemoveContext (CitContext *con)
 
        FreeStrBuf(&con->MigrateBuf);
        FreeStrBuf(&con->RecvBuf.Buf);
+       if (con->cached_msglist) {
+               free(con->cached_msglist);
+       }
+
        syslog(LOG_DEBUG, "Done with RemoveContext()\n");
 }
 
index 205cf4f1eefa9a00c5da43ba577fc38f49e5fc04..4c7c117a5dee4488b4d089522917ead43f6c495a 100644 (file)
@@ -41,7 +41,7 @@ struct CitContext {
        struct CitContext *next;        /* Link to next session in the list */
 
        int cs_pid;             /* session ID */
-       int dont_term;          /* for special activities like artv so we don't get killed */
+       int dont_term;          /* for special activities like artv so we don't get killed */
        time_t lastcmd;         /* time of last command executed */
        time_t lastidle;        /* For computing idle time */
        CCState state;          /* thread state (see CON_ values below) */
@@ -131,10 +131,11 @@ struct CitContext {
        void *openid_data;                      /* Data stored by the OpenID module */
        char *ldap_dn;                          /* DN of user when using AUTHMODE_LDAP */
 
-
        void (*h_command_function) (void) ;     /* service command function */
        void (*h_async_function) (void) ;       /* do async msgs function */
        void (*h_greeting_function) (void) ;    /* greeting function for session startup */
+
+       long *cached_msglist;                   /* results of the previous CtdlForEachMessage() */
 };
 
 typedef struct CitContext CitContext;
index ec76c0aed117594c1d11a4bded9d489007fc41b5..be46195a4509a7583495ed8e7807d76c131faf2b 100644 (file)
@@ -1,9 +1,9 @@
 /*
  * Implements the message store.
  *
- * Copyright (c) 1987-2010 by the citadel.org team
+ * Copyright (c) 1987-2011 by the citadel.org team
  *
- * This program is free software; you can redistribute it and/or modify
+ * This program is open source software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 3 of the License, or
  * (at your option) any later version.
@@ -15,7 +15,7 @@
  *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 
 #include "sysdep.h"
@@ -633,14 +633,27 @@ int CtdlForEachMessage(int mode, long ref, char *search_string,
 
        /* Load the message list */
        cdbfr = cdb_fetch(CDB_MSGLISTS, &CC->room.QRnumber, sizeof(long));
-       if (cdbfr != NULL) {
-               msglist = (long *) cdbfr->ptr;
-               num_msgs = cdbfr->len / sizeof(long);
-       } else {
+       if (cdbfr == NULL) {
                if (need_to_free_re) regfree(&re);
                return 0;       /* No messages at all?  No further action. */
        }
 
+       msglist = (long *) cdbfr->ptr;
+       num_msgs = cdbfr->len / sizeof(long);
+
+       cdbfr->ptr = NULL;      /* clear this so that cdb_free() doesn't free it */
+       cdb_free(cdbfr);        /* we own this memory now */
+
+       /*
+        * We cache the most recent msglist in order to do security checks later
+        */
+       if (CC->client_socket > 0) {
+               if (CC->cached_msglist != NULL) {
+                       free(CC->cached_msglist);
+               }
+       
+               CC->cached_msglist = msglist;
+       }
 
        /*
         * Now begin the traversal.
@@ -772,8 +785,8 @@ int CtdlForEachMessage(int mode, long ref, char *search_string,
                                ++num_processed;
                        }
                }
-       cdb_free(cdbfr);        /* Clean up */
        if (need_to_free_re) regfree(&re);
+       if (CC->client_socket <= 0) free(msglist);
        return num_processed;
 }