]> granicus.if.org Git - mutt/commitdiff
Version header cache against MD5 of structures on which it depends
authorBrendan Cully <brendan@kublai.com>
Thu, 5 Apr 2007 19:55:31 +0000 (12:55 -0700)
committerBrendan Cully <brendan@kublai.com>
Thu, 5 Apr 2007 19:55:31 +0000 (12:55 -0700)
Makefile.am
hcache.c
hcachever.sh [new file with mode: 0755]

index b6aad020929e178a668b86aa5459ed0f5100070b..b3c905298d01a237d08890c2fa6f3c2b05976b5a 100644 (file)
@@ -13,7 +13,7 @@ SUBDIRS = m4 po intl doc contrib $(IMAP_SUBDIR)
 
 bin_SCRIPTS = muttbug flea @SMIMEAUX_TARGET@
 
-BUILT_SOURCES = keymap_defs.h patchlist.c reldate.h
+BUILT_SOURCES = keymap_defs.h patchlist.c reldate.h hcversion.h
 
 bin_PROGRAMS = mutt @DOTLOCK_TARGET@ @PGPAUX_TARGET@
 mutt_SOURCES = $(BUILT_SOURCES) \
@@ -78,7 +78,7 @@ EXTRA_DIST = COPYRIGHT GPL OPS OPS.PGP OPS.CRYPT OPS.SMIME TODO UPDATING \
        makedoc.c makedoc-defs.h stamp-doc-rc README.SSL smime.h \
        muttbug pgppacket.h depcomp ascii.h BEWARE PATCHES patchlist.sh \
        ChangeLog ChangeLog.old mkchangelog.sh cvslog2changelog.pl mutt_idna.h \
-       snprintf.c regex.c crypt-gpgme.h
+       snprintf.c regex.c crypt-gpgme.h hcachever.sh
 
 EXTRA_SCRIPTS = smime_keys
 
@@ -126,6 +126,10 @@ reldate.h: $(srcdir)/ChangeLog
        cmp -s reldate.h.tmp reldate.h || cp reldate.h.tmp reldate.h; \
        rm reldate.h.tmp
 
+hcversion.h: $(srcdir)/mutt.h $(srcdir)/rfc822.h
+       ( echo '#include "config.h"'; echo '#include "mutt.h"'; ) \
+       | $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) - | $(srcdir)/hcachever.sh hcversion.h
+
 patchlist.c: $(srcdir)/PATCHES $(srcdir)/patchlist.sh
        $(srcdir)/patchlist.sh < $(srcdir)/PATCHES > patchlist.c
 
index 05574d9838d94b45cf3bd4be904911ce4fedd3c7..9f10cb13c2274a44c4eab463f63506e1061bdc89 100644 (file)
--- a/hcache.c
+++ b/hcache.c
@@ -18,8 +18,6 @@
  *     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  */
 
-/* this comment bumps Id after $assumed_charset changed BODY. */
-
 #if HAVE_CONFIG_H
 #include "config.h"
 #endif                         /* HAVE_CONFIG_H */
@@ -41,6 +39,7 @@
 #endif
 #include "mutt.h"
 #include "hcache.h"
+#include "hcversion.h"
 #ifdef USE_IMAP
 #include "message.h"
 #endif
@@ -447,75 +446,8 @@ restore_envelope(ENVELOPE * e, const unsigned char *d, int *off)
   restore_list(&e->userhdrs, d, off);
 }
 
-static unsigned int
-crc32(unsigned int crc, unsigned char const *p, size_t len)
-{
-  int i;
-  while (len--)
-  {
-    crc ^= *p++;
-    for (i = 0; i < 8; i++)
-      crc = (crc >> 1) ^ ((crc & 1) ? 0xedb88320 : 0);
-  }
-  return crc;
-}
-
-static int
-generate_crc32()
-{
-  int crc = 0;
-  SPAM_LIST *sp = SpamList;
-  RX_LIST *rx = NoSpamList;
-
-  crc = crc32(crc, (unsigned char const *) "$Id$", mutt_strlen("$Id$"));
-
-#if HAVE_LANGINFO_CODESET
-  crc = crc32(crc, (unsigned char const *) Charset, mutt_strlen(Charset));
-  crc = crc32(crc, (unsigned char const *) "HAVE_LANGINFO_CODESET",
-       mutt_strlen("HAVE_LANGINFO_CODESET"));
-#endif
-
-#if EXACT_ADDRESS
-  crc = crc32(crc, (unsigned char const *) "EXACT_ADDRESS",
-       mutt_strlen("EXACT_ADDRESS"));
-#endif
-
-#ifdef USE_POP
-  crc = crc32(crc, (unsigned char const *) "USE_POP", mutt_strlen("USE_POP"));
-#endif
-
-#ifdef MIXMASTER
-  crc = crc32(crc, (unsigned char const *) "MIXMASTER",
-        mutt_strlen("MIXMASTER"));
-#endif
-
-#ifdef USE_IMAP
-  crc = crc32(crc, (unsigned char const *) "USE_IMAP", mutt_strlen("USE_IMAP"));
-  crc = crc32(crc, (unsigned char const *) ImapHeaders,
-        mutt_strlen(ImapHeaders));
-#endif
-  while (sp)
-  {
-    crc = crc32(crc, (unsigned char const *) sp->rx->pattern,
-         mutt_strlen(sp->rx->pattern));
-    sp = sp->next;
-  }
-
-  crc = crc32(crc, (unsigned char const *) "SPAM_SEPERATOR",
-       mutt_strlen("SPAM_SEPERATOR"));
-
-  while (rx)
-  {
-    crc = crc32(crc, (unsigned char const *) rx->rx->pattern,
-         mutt_strlen(rx->rx->pattern));
-    rx = rx->next;
-  }
-
-  return crc;
-}
-
 static int
-crc32_matches(const char *d, unsigned int crc)
+crc_matches(const char *d, unsigned int crc)
 {
   int off = sizeof (validate);
   unsigned int mycrc = 0;
@@ -639,7 +571,7 @@ mutt_hcache_fetch(header_cache_t *h, const char *filename,
 
   data = mutt_hcache_fetch_raw (h, filename, keylen);
 
-  if (!data || !crc32_matches(data, h->crc))
+  if (!data || !crc_matches(data, h->crc))
   {
     FREE(&data);
     return NULL;
@@ -795,7 +727,7 @@ mutt_hcache_open(const char *path, const char *folder)
 
   h->db = NULL;
   h->folder = get_foldername(folder);
-  h->crc = generate_crc32();
+  h->crc = HCACHEVER;
 
   if (!path || path[0] == '\0')
   {
@@ -860,7 +792,7 @@ mutt_hcache_open(const char *path, const char *folder)
 
   h->db = NULL;
   h->folder = get_foldername(folder);
-  h->crc = generate_crc32();
+  h->crc = HCACHEVER;
 
   if (!path || path[0] == '\0')
   {
@@ -946,7 +878,7 @@ mutt_hcache_open(const char *path, const char *folder)
   int pagesize = atoi(HeaderCachePageSize);
   char* tmp;
 
-  h->crc = generate_crc32();
+  h->crc = HCACHEVER;
 
   if (!path || path[0] == '\0')
   {
diff --git a/hcachever.sh b/hcachever.sh
new file mode 100755 (executable)
index 0000000..838b124
--- /dev/null
@@ -0,0 +1,107 @@
+#!/bin/sh
+
+BASEVERSION=1
+
+if which md5 > /dev/null
+then
+  MD5=md5
+elif which md5sum > /dev/null
+then
+  MD5=md5sum
+elif which openssl > /dev/null
+then
+  MD5="openssl md5 -hex"
+else
+  echo "ERROR: no MD5 tool found"
+  exit 1
+fi
+
+cleanstruct () {
+  STRUCT="$1"
+  STRUCT=${STRUCT#\} }
+  STRUCT=${STRUCT%\;}
+
+  echo $STRUCT
+}
+
+cleanbody () {
+  echo "$1" | sed -e 's/{ *//'
+}
+
+getstruct () {
+  STRUCT=""
+  BODY=''
+  inbody=0
+  case "$1" in
+    *'{') inbody=1 ;;
+    *';') return ;;
+  esac
+
+  while read line
+  do
+    if test $inbody -eq 0
+    then
+      case "$line" in
+        '{'*) inbody=1 ;;
+        *';') return ;;
+      esac
+    fi
+
+    case "$line" in
+      '} '*)
+        STRUCT=`cleanstruct "$line"`
+        break
+      ;;
+      '}')
+        read line
+        STRUCT=`cleanstruct "$line"`
+        break
+      ;;
+      '#'*) continue ;;
+      *)
+        if test $inbody -ne 0
+        then
+          BODY="$BODY $line"
+        fi
+      ;;
+    esac
+  done
+
+  case $STRUCT in
+    ADDRESS|LIST|BUFFER|PARAMETER|BODY|ENVELOPE)
+      BODY=`cleanbody "$BODY"`
+      echo "$STRUCT: $BODY"
+    ;;
+  esac
+  return
+}
+
+DEST="$1"
+TMPD="$DEST.tmp"
+
+TEXT="$BASEVERSION"
+
+echo "/* base version: $BASEVERSION" > $TMPD
+while read line
+do
+  case "$line" in
+    'typedef struct'*)
+       STRUCT=`getstruct "$line"`
+       if test -n "$STRUCT"
+       then
+         NAME=${STRUCT%%:*}
+         BODY=${STRUCT#*:}
+         echo " * $NAME:" $BODY >> $TMPD
+         TEXT="$TEXT $NAME {$BODY}"
+       fi
+    ;;
+  esac
+done
+echo " */" >> $TMPD
+
+MD5TEXT=`echo $TEXT | $MD5`
+echo "#define HCACHEVER 0x"${MD5TEXT:0:8} >> $TMPD
+
+# TODO: validate we have all structs
+
+mv $TMPD $DEST