bincimap

Log | Files | Refs | LICENSE

maildir-readcache.cc (4863B)


      1 /* -*- Mode: c++; -*- */
      2 /*  --------------------------------------------------------------------
      3  *  Filename:
      4  *    maildir.cc
      5  *  
      6  *  Description:
      7  *    Implementation of the Maildir class.
      8  *
      9  *  Authors:
     10  *    Andreas Aardal Hanssen <andreas-binc curly bincimap spot org>
     11  *
     12  *  Bugs:
     13  *
     14  *  ChangeLog:
     15  *
     16  *  --------------------------------------------------------------------
     17  *  Copyright 2002-2005 Andreas Aardal Hanssen
     18  *
     19  *  This program is free software; you can redistribute it and/or modify
     20  *  it under the terms of the GNU General Public License as published by
     21  *  the Free Software Foundation; either version 2 of the License, or
     22  *  (at your option) any later version.
     23  *
     24  *  This program is distributed in the hope that it will be useful,
     25  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
     26  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     27  *  GNU General Public License for more details.
     28  *
     29  *  You should have received a copy of the GNU General Public License
     30  *  along with this program; if not, write to the Free Software
     31  *  Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
     32  *  --------------------------------------------------------------------
     33  */
     34 #ifdef HAVE_CONFIG_H
     35 #include <config.h>
     36 #endif
     37 
     38 #include "maildir.h"
     39 
     40 #include "io.h"
     41 #include "convert.h"
     42 #include "storage.h"
     43 
     44 using namespace ::std;
     45 using namespace Binc;
     46 
     47 //------------------------------------------------------------------------
     48 Maildir::ReadCacheResult Maildir::readCache(void)
     49 {
     50   const string uidvalfilename = path + "/bincimap-uidvalidity";
     51   const string cachefilename = path + "/bincimap-cache";
     52 
     53   bool uidvalfiledropped = false;
     54 
     55   Storage uidvalfile(uidvalfilename, Storage::ReadOnly);
     56   string section, key, value;
     57   string uidvalfileversion;
     58 
     59   if (!uidvalfile.ok()) {
     60     uidnext = 1;
     61     uidvalidity = time(0);
     62     uidvalfiledropped = true;
     63     setLastError(uidvalfile.getLastError());
     64     return NoCache;
     65   }
     66 
     67   uidvalidity = 0;
     68   uidnext = 0;
     69 
     70   while (uidvalfile.get(&section, &key, &value)) {
     71     if (section == "depot" && key == "_uidvalidity")
     72       uidvalidity = (unsigned int) atoi(value);
     73     else if (section == "depot" && key == "_uidnext")
     74       uidnext  = (unsigned int) atoi(value);
     75     else if (section == "depot" && key == "_version")
     76       uidvalfileversion = value;
     77   }
     78 
     79   if (!uidvalfile.eof()) {
     80     uidnext = 1;
     81     uidvalidity = time(0);
     82     uidvalfiledropped = true;
     83     setLastError(uidvalfile.getLastError());
     84     return NoCache;
     85   }
     86 
     87   if (uidvalfileversion != UIDVALFILEVERSION 
     88       || uidvalidity == 0 || uidnext == 0) {
     89     uidnext = 1;
     90     uidvalidity = time(0);
     91     uidvalfiledropped = true;
     92     return NoCache;
     93   }
     94 
     95   index.clearUids();
     96 
     97   Storage cache(cachefilename, Storage::ReadOnly);
     98   string lastsection;
     99   unsigned int _uid = 0;
    100   unsigned int _size = 0;
    101   unsigned int _internaldate = 0;
    102   string _id;
    103 
    104   if (!cache.ok()) {
    105     uidnext = 1;
    106     uidvalidity = time(0);
    107     uidvalfiledropped = true;
    108     setLastError(uidvalfile.getLastError());
    109     return NoCache;
    110   }
    111 
    112   while (cache.get(&section, &key, &value)) {
    113     if (section == "depot" && key == "_version" && value != CACHEFILEVERSION) {
    114       uidnext = 1;
    115       uidvalidity = time(0);
    116       uidvalfiledropped = true;
    117       return NoCache;
    118     } else if (isdigit(section[0])) {
    119       // Perhaps a bit confusing. We need to set all attributes in one
    120       // go, so when the section changes, we add the message.
    121       if (lastsection != section) {
    122 	lastsection = section;
    123 	if (_id != "") {
    124 	  MaildirMessage m(*this);
    125 	  m.setUnique(_id);
    126 	  m.setInternalDate(_internaldate);
    127 
    128 	  if (index.find(_id) == 0) {
    129 	    m.setUID(_uid);
    130 	    m.setInternalFlag(MaildirMessage::JustArrived);
    131 	    m.setSize(_size);
    132 	    add(m);
    133 	  } else {
    134 	    // Remember to insert the uid of the message again - we reset this
    135 	    // at the top of this function.
    136 	    index.insert(_id, _uid);
    137 	  }
    138 	} 
    139 	 
    140 	_uid = 0;
    141 	_size = 0;
    142 	_internaldate = 0;
    143 	_id = "";
    144       }
    145 
    146       unsigned int n = (unsigned int)atoi(value);
    147       if (key == "_ID") _id = value;
    148       else if (key == "_Size") _size = n;
    149       else if (key == "_InternalDate") _internaldate = n;
    150       else if (key == "_UID") _uid = n;
    151     }
    152   }
    153 
    154   // Catch the last message too.
    155   if (lastsection != "") {
    156     if (index.find(_id) == 0) {
    157       MaildirMessage m(*this);
    158       m.setUnique(_id);
    159       m.setInternalDate(_internaldate);
    160       m.setUID(_uid);
    161       m.setInternalFlag(MaildirMessage::JustArrived);
    162       add(m);
    163     } else {
    164       // Remember to insert the uid of the message again - we reset this
    165       // at the top of this function.
    166       index.insert(_id, _uid);
    167     }
    168   }
    169 
    170   if (!cache.eof()) {
    171     // Assume there is no cache file.
    172     uidnext = 1;
    173     uidvalidity = time(0);
    174     uidvalfiledropped = true;
    175     return NoCache;
    176   }
    177 
    178   return Ok;
    179 }
    180