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 }