bincimap

Log | Files | Refs | LICENSE

maildir-updateflags.cc (3573B)


      1 /* -*- Mode: c++; -*- */
      2 /*  --------------------------------------------------------------------
      3  *  Filename:
      4  *    maildir-updateflags.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 <dirent.h>
     41 #include <unistd.h>
     42 
     43 #include "io.h"
     44 
     45 using namespace ::std;
     46 
     47 //------------------------------------------------------------------------
     48 void Binc::Maildir::updateFlags(void)
     49 {
     50   IO &logger = IOFactory::getInstance().get(2);
     51 
     52   if (readOnly) return;
     53 
     54   // open the cur/ directory
     55   string curpath = path + "/cur/";
     56   DIR *pdir = opendir(curpath.c_str());
     57   if (pdir == 0) {
     58     string reason = "failed to open " + curpath + ": ";
     59     reason += strerror(errno);
     60 
     61     logger << reason << endl;
     62     return;
     63   }
     64 
     65   // read all entries in the directory
     66   vector<string> entries;  
     67   struct dirent *pdirent;
     68   while ((pdirent = readdir(pdir)) != 0) {
     69     string filename = pdirent->d_name;
     70     if (filename[0] == '.')
     71       continue;
     72     entries.push_back(filename);
     73   }
     74   closedir(pdir);
     75 
     76   for (vector<string>::const_iterator it = entries.begin(); it != entries.end(); ++it) {
     77     string filename = *it;
     78 
     79     string uniquename;
     80     string::size_type pos;
     81     if ((pos = filename.find(":2,")) != string::npos)
     82       uniquename = filename.substr(0, pos);
     83     else
     84       uniquename = filename;    
     85 
     86     MaildirMessage *message = get(uniquename);
     87     if (message) {
     88       string flags;
     89       int mflags = message->getStdFlags();
     90       if (mflags & Message::F_DRAFT) flags += "D";
     91       if (mflags & Message::F_FLAGGED) flags += "F";
     92       if (mflags & Message::F_ANSWERED) flags += "R";
     93       if (mflags & Message::F_SEEN) flags += "S";
     94       if (mflags & Message::F_DELETED) flags += "T";
     95 
     96       string srcname = curpath + filename;
     97       string destname = curpath + uniquename + ":2," + flags;
     98      
     99       if (srcname != destname) {
    100 	if (rename(srcname.c_str(), destname.c_str()) != 0) {
    101 	  if (errno == ENOENT) {
    102             closedir(pdir);
    103             pdir = opendir(curpath.c_str());
    104 	    if (pdir == 0) {
    105               string reason = "failed to open " + curpath + ": ";
    106               reason += strerror(errno);
    107               logger << reason << endl;
    108               return;
    109 	    }
    110 
    111 	    continue;
    112 	  }
    113 
    114 	  logger << "warning: rename(" << srcname
    115 		 << "," << destname << ") == "
    116 		 << errno << ": " << strerror(errno) << endl;
    117 	} else {
    118 	  index.insert(uniquename, 0,  uniquename + ":2," + flags);
    119 	}
    120       }
    121    
    122       continue;
    123     }
    124   }
    125 }