converted iostream to stdio because of mysterious read errors at the last position in the offsets file

This commit is contained in:
dockes 2009-11-28 06:39:06 +00:00
parent c78a3bb567
commit 457e7d2e17

View File

@ -25,11 +25,10 @@ static char rcsid[] = "@(#$Id: mh_mbox.cpp,v 1.5 2008-10-04 14:26:59 dockes Exp
#include <time.h> #include <time.h>
#include <regex.h> #include <regex.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <errno.h>
#include <cstring> #include <cstring>
#include <map> #include <map>
#include <sstream>
#include <fstream>
#include "mimehandler.h" #include "mimehandler.h"
#include "debuglog.h" #include "debuglog.h"
@ -41,6 +40,19 @@ static char rcsid[] = "@(#$Id: mh_mbox.cpp,v 1.5 2008-10-04 14:26:59 dockes Exp
#include "conftree.h" #include "conftree.h"
using namespace std; using namespace std;
class FpKeeper {
public:
FpKeeper(FILE **fpp) : m_fpp(fpp) {}
~FpKeeper()
{
if (m_fpp && *m_fpp) {
fclose(*m_fpp);
*m_fpp = 0;
}
}
private: FILE **m_fpp;
};
/** /**
* Handles a cache for message numbers to offset translations. Permits direct * Handles a cache for message numbers to offset translations. Permits direct
@ -65,37 +77,48 @@ public:
} }
~MboxCache() {} ~MboxCache() {}
mbhoff_type get_offset(const string& udi, int msgnum) mbhoff_type get_offset(const string& udi, int msgnum)
{ {
if (!ok()) LOGDEB0(("MboxCache::get_offsets: udi [%s] msgnum %d\n", udi.c_str(),
msgnum));
if (!ok()) {
LOGDEB0(("MboxCache::get_offsets: init failed\n"));
return -1; return -1;
}
string fn = makefilename(udi); string fn = makefilename(udi);
ifstream input(fn.c_str(), ios::in | ios::binary); FILE *fp = 0;
if (!input.is_open()) if ((fp = fopen(fn.c_str(), "r")) == 0) {
LOGDEB(("MboxCache::get_offsets: open failed, errno %d\n", errno));
return -1; return -1;
}
FpKeeper keeper(&fp);
char blk1[o_b1size]; char blk1[o_b1size];
input.read(blk1, o_b1size); if (fread(blk1, 1, o_b1size, fp) != o_b1size) {
if (!input) LOGDEB0(("MboxCache::get_offsets: read blk1 errno %d\n", errno));
return -1; return -1;
}
ConfSimple cf(string(blk1, o_b1size)); ConfSimple cf(string(blk1, o_b1size));
string fudi; string fudi;
if (!cf.get("udi", fudi) || fudi.compare(udi)) { if (!cf.get("udi", fudi) || fudi.compare(udi)) {
LOGINFO(("MboxCache::get_offset:badudi fn %s udi [%s], fudi [%s]\n", LOGINFO(("MboxCache::get_offset:badudi fn %s udi [%s], fudi [%s]\n",
fn.c_str(), udi.c_str(), fudi.c_str())); fn.c_str(), udi.c_str(), fudi.c_str()));
input.close();
return -1; return -1;
} }
input.seekg(cacheoffset(msgnum)); if (fseeko(fp, cacheoffset(msgnum), SEEK_SET) != 0) {
if (!input) { LOGDEB0(("MboxCache::get_offsets: seek %ld errno %d\n",
LOGINFO(("MboxCache::get_offset: fn %s, seek(%ld) failed\n", (long)cacheoffset(msgnum), errno));
fn.c_str(), cacheoffset(msgnum)));
input.close();
return -1; return -1;
} }
mbhoff_type offset = -1; mbhoff_type offset = -1;
input.read((char *)&offset, sizeof(mbhoff_type)); int ret;
input.close(); if ((ret = fread(&offset, 1, sizeof(mbhoff_type), fp))
!= sizeof(mbhoff_type)) {
LOGDEB0(("MboxCache::get_offsets: read ret %d errno %d\n",
ret, errno));
return -1;
}
LOGDEB0(("MboxCache::get_offsets: ret %lld\n", (long long)offset));
return offset; return offset;
} }
@ -109,27 +132,30 @@ public:
if (fsize < m_minfsize) if (fsize < m_minfsize)
return; return;
string fn = makefilename(udi); string fn = makefilename(udi);
ofstream output(fn.c_str(), ios::out|ios::trunc|ios::binary); FILE *fp;
if (!output.is_open()) if ((fp = fopen(fn.c_str(), "w")) == 0) {
LOGDEB(("MboxCache::put_offsets: fopen errno %d\n", errno));
return; return;
}
FpKeeper keeper(&fp);
string blk1; string blk1;
blk1.append("udi="); blk1.append("udi=");
blk1.append(udi); blk1.append(udi);
blk1.append("\n"); blk1.append("\n");
blk1.resize(o_b1size, 0); blk1.resize(o_b1size, 0);
output << blk1; if (fwrite(blk1.c_str(), 1, o_b1size, fp) != o_b1size) {
if (!output.good()) LOGDEB(("MboxCache::put_offsets: fwrite errno %d\n", errno));
return; return;
}
for (vector<mbhoff_type>::const_iterator it = offs.begin(); for (vector<mbhoff_type>::const_iterator it = offs.begin();
it != offs.end(); it++) { it != offs.end(); it++) {
mbhoff_type off = *it; mbhoff_type off = *it;
output.write((char*)&off, sizeof(mbhoff_type)); if (fwrite((char*)&off, 1, sizeof(mbhoff_type), fp) !=
if (!output.good()) { sizeof(mbhoff_type)) {
output.close();
return; return;
} }
} }
output.close();
} }
// Check state, possibly initialize // Check state, possibly initialize
@ -140,7 +166,7 @@ public:
RclConfig *config = RclConfig::getMainConfig(); RclConfig *config = RclConfig::getMainConfig();
if (config == 0) if (config == 0)
return false; return false;
int minmbs = 10; int minmbs = 5;
config->getConfParam("mboxcacheminmbs", &minmbs); config->getConfParam("mboxcacheminmbs", &minmbs);
if (minmbs < 0) { if (minmbs < 0) {
// minmbs set to negative to disable cache // minmbs set to negative to disable cache
@ -168,7 +194,7 @@ private:
string m_dir; string m_dir;
// Don't cache smaller files. If -1, don't do anything. // Don't cache smaller files. If -1, don't do anything.
mbhoff_type m_minfsize; mbhoff_type m_minfsize;
static const int o_b1size; static const size_t o_b1size;
// Create the cache directory if it does not exist // Create the cache directory if it does not exist
bool maybemakedir() bool maybemakedir()
@ -195,7 +221,7 @@ private:
} }
}; };
const int MboxCache::o_b1size = 1024; const size_t MboxCache::o_b1size = 1024;
static class MboxCache mcache; static class MboxCache mcache;
MimeHandlerMbox::~MimeHandlerMbox() MimeHandlerMbox::~MimeHandlerMbox()