Cache the most recently fetched msglist in CtdlForEachMessage()
authorArt Cancro <ajc@citadel.org>
Wed, 26 Jan 2011 23:08:16 +0000 (18:08 -0500)
committerArt Cancro <ajc@citadel.org>
Wed, 26 Jan 2011 23:08:16 +0000 (18:08 -0500)
(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 f43f8736e81dc4bf48e1f4ade916f7c053d487cf..d2dee4a04ebf1973d7c8f3923c3bcd0d23cab8c8 100644 (file)
@@ -880,6 +880,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 84244401d41dd55401c967ec7444b576edb689ae..be48e865116027eea97dc7d36c04adb17f13bbdc 100644 (file)
@@ -362,6 +362,10 @@ void RemoveContext (CitContext *con)
 
        FreeStrBuf(&con->MigrateBuf);
        FreeStrBuf(&con->ReadBuf);
+       if (con->cached_msglist) {
+               free(con->cached_msglist);
+       }
+
        syslog(LOG_DEBUG, "Done with RemoveContext()\n");
 }
 
index d734728971812863058c4b8d04a8ce15bd205fa4..c29e582002ca92efb6b64f326f0d409ad20e808f 100644 (file)
@@ -21,19 +21,18 @@ 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 */
        int state;              /* thread state (see CON_ values below) */
        int kill_me;            /* Set to nonzero to flag for termination */
 
-       const char *Pos;        /* Our read position inside of the ReadBuf */
-       StrBuf *ReadBuf;        /* Our block buffered read buffer */
-       StrBuf *MigrateBuf;        /* Our block buffered read buffer */
-
-       const char *sPos;        /* Our read position inside of the ReadBuf */
-       StrBuf *sReadBuf;        /* Our block buffered read buffer */
-       StrBuf *sMigrateBuf;        /* Our block buffered read buffer */
+       const char *Pos;        /* Our read position inside of the ReadBuf */
+       StrBuf *ReadBuf;        /* Our block buffered read buffer */
+       StrBuf *MigrateBuf;     /* Our block buffered read buffer */
+       const char *sPos;       /* Our read position inside of the ReadBuf */
+       StrBuf *sReadBuf;       /* Our block buffered read buffer */
+       StrBuf *sMigrateBuf;    /* Our block buffered read buffer */
        int client_socket;
        int is_local_socket;    /* set to 1 if client is on unix domain sock */
        /* Redirect this session's output to a memory buffer? */
@@ -111,10 +110,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 79537f6d4e7d52b1b8a346e401a1d67b7215f13b..608d2a114820b96c610b5599d5b818f89216b2a0 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;
 }