|
a/src/internfile/mh_mbox.cpp |
|
b/src/internfile/mh_mbox.cpp |
|
... |
|
... |
23 |
#include <errno.h>
|
23 |
#include <errno.h>
|
24 |
#include <unistd.h>
|
24 |
#include <unistd.h>
|
25 |
#include <time.h>
|
25 |
#include <time.h>
|
26 |
#include <regex.h>
|
26 |
#include <regex.h>
|
27 |
#include <sys/stat.h>
|
27 |
#include <sys/stat.h>
|
|
|
28 |
#include <errno.h>
|
28 |
|
29 |
|
29 |
#include <cstring>
|
30 |
#include <cstring>
|
30 |
#include <map>
|
31 |
#include <map>
|
31 |
#include <sstream>
|
|
|
32 |
#include <fstream>
|
|
|
33 |
|
32 |
|
34 |
#include "mimehandler.h"
|
33 |
#include "mimehandler.h"
|
35 |
#include "debuglog.h"
|
34 |
#include "debuglog.h"
|
36 |
#include "readfile.h"
|
35 |
#include "readfile.h"
|
37 |
#include "mh_mbox.h"
|
36 |
#include "mh_mbox.h"
|
|
... |
|
... |
39 |
#include "rclconfig.h"
|
38 |
#include "rclconfig.h"
|
40 |
#include "md5.h"
|
39 |
#include "md5.h"
|
41 |
#include "conftree.h"
|
40 |
#include "conftree.h"
|
42 |
|
41 |
|
43 |
using namespace std;
|
42 |
using namespace std;
|
|
|
43 |
class FpKeeper {
|
|
|
44 |
public:
|
|
|
45 |
FpKeeper(FILE **fpp) : m_fpp(fpp) {}
|
|
|
46 |
~FpKeeper()
|
|
|
47 |
{
|
|
|
48 |
if (m_fpp && *m_fpp) {
|
|
|
49 |
fclose(*m_fpp);
|
|
|
50 |
*m_fpp = 0;
|
|
|
51 |
}
|
|
|
52 |
}
|
|
|
53 |
private: FILE **m_fpp;
|
|
|
54 |
};
|
|
|
55 |
|
44 |
|
56 |
|
45 |
/**
|
57 |
/**
|
46 |
* Handles a cache for message numbers to offset translations. Permits direct
|
58 |
* Handles a cache for message numbers to offset translations. Permits direct
|
47 |
* accesses inside big folders instead of having to scan up to the right place
|
59 |
* accesses inside big folders instead of having to scan up to the right place
|
48 |
*
|
60 |
*
|
|
... |
|
... |
63 |
// Can't access rclconfig here, we're a static object, would
|
75 |
// Can't access rclconfig here, we're a static object, would
|
64 |
// have to make sure it's initialized.
|
76 |
// have to make sure it's initialized.
|
65 |
}
|
77 |
}
|
66 |
|
78 |
|
67 |
~MboxCache() {}
|
79 |
~MboxCache() {}
|
68 |
|
|
|
69 |
mbhoff_type get_offset(const string& udi, int msgnum)
|
80 |
mbhoff_type get_offset(const string& udi, int msgnum)
|
70 |
{
|
81 |
{
|
|
|
82 |
LOGDEB0(("MboxCache::get_offsets: udi [%s] msgnum %d\n", udi.c_str(),
|
|
|
83 |
msgnum));
|
71 |
if (!ok())
|
84 |
if (!ok()) {
|
|
|
85 |
LOGDEB0(("MboxCache::get_offsets: init failed\n"));
|
72 |
return -1;
|
86 |
return -1;
|
|
|
87 |
}
|
73 |
string fn = makefilename(udi);
|
88 |
string fn = makefilename(udi);
|
74 |
ifstream input(fn.c_str(), ios::in | ios::binary);
|
89 |
FILE *fp = 0;
|
75 |
if (!input.is_open())
|
90 |
if ((fp = fopen(fn.c_str(), "r")) == 0) {
|
|
|
91 |
LOGDEB(("MboxCache::get_offsets: open failed, errno %d\n", errno));
|
76 |
return -1;
|
92 |
return -1;
|
|
|
93 |
}
|
|
|
94 |
FpKeeper keeper(&fp);
|
|
|
95 |
|
77 |
char blk1[o_b1size];
|
96 |
char blk1[o_b1size];
|
78 |
input.read(blk1, o_b1size);
|
97 |
if (fread(blk1, 1, o_b1size, fp) != o_b1size) {
|
79 |
if (!input)
|
98 |
LOGDEB0(("MboxCache::get_offsets: read blk1 errno %d\n", errno));
|
80 |
return -1;
|
99 |
return -1;
|
|
|
100 |
}
|
81 |
ConfSimple cf(string(blk1, o_b1size));
|
101 |
ConfSimple cf(string(blk1, o_b1size));
|
82 |
string fudi;
|
102 |
string fudi;
|
83 |
if (!cf.get("udi", fudi) || fudi.compare(udi)) {
|
103 |
if (!cf.get("udi", fudi) || fudi.compare(udi)) {
|
84 |
LOGINFO(("MboxCache::get_offset:badudi fn %s udi [%s], fudi [%s]\n",
|
104 |
LOGINFO(("MboxCache::get_offset:badudi fn %s udi [%s], fudi [%s]\n",
|
85 |
fn.c_str(), udi.c_str(), fudi.c_str()));
|
105 |
fn.c_str(), udi.c_str(), fudi.c_str()));
|
86 |
input.close();
|
|
|
87 |
return -1;
|
106 |
return -1;
|
88 |
}
|
107 |
}
|
89 |
input.seekg(cacheoffset(msgnum));
|
108 |
if (fseeko(fp, cacheoffset(msgnum), SEEK_SET) != 0) {
|
90 |
if (!input) {
|
|
|
91 |
LOGINFO(("MboxCache::get_offset: fn %s, seek(%ld) failed\n",
|
109 |
LOGDEB0(("MboxCache::get_offsets: seek %ld errno %d\n",
|
92 |
fn.c_str(), cacheoffset(msgnum)));
|
110 |
(long)cacheoffset(msgnum), errno));
|
93 |
input.close();
|
|
|
94 |
return -1;
|
111 |
return -1;
|
95 |
}
|
112 |
}
|
96 |
mbhoff_type offset = -1;
|
113 |
mbhoff_type offset = -1;
|
97 |
input.read((char *)&offset, sizeof(mbhoff_type));
|
114 |
int ret;
|
98 |
input.close();
|
115 |
if ((ret = fread(&offset, 1, sizeof(mbhoff_type), fp))
|
|
|
116 |
!= sizeof(mbhoff_type)) {
|
|
|
117 |
LOGDEB0(("MboxCache::get_offsets: read ret %d errno %d\n",
|
|
|
118 |
ret, errno));
|
|
|
119 |
return -1;
|
|
|
120 |
}
|
|
|
121 |
LOGDEB0(("MboxCache::get_offsets: ret %lld\n", (long long)offset));
|
99 |
return offset;
|
122 |
return offset;
|
100 |
}
|
123 |
}
|
101 |
|
124 |
|
102 |
// Save array of offsets for a given file, designated by Udi
|
125 |
// Save array of offsets for a given file, designated by Udi
|
103 |
void put_offsets(const string& udi, mbhoff_type fsize,
|
126 |
void put_offsets(const string& udi, mbhoff_type fsize,
|
|
... |
|
... |
107 |
if (!ok() || !maybemakedir())
|
130 |
if (!ok() || !maybemakedir())
|
108 |
return;
|
131 |
return;
|
109 |
if (fsize < m_minfsize)
|
132 |
if (fsize < m_minfsize)
|
110 |
return;
|
133 |
return;
|
111 |
string fn = makefilename(udi);
|
134 |
string fn = makefilename(udi);
|
112 |
ofstream output(fn.c_str(), ios::out|ios::trunc|ios::binary);
|
135 |
FILE *fp;
|
113 |
if (!output.is_open())
|
136 |
if ((fp = fopen(fn.c_str(), "w")) == 0) {
|
|
|
137 |
LOGDEB(("MboxCache::put_offsets: fopen errno %d\n", errno));
|
114 |
return;
|
138 |
return;
|
|
|
139 |
}
|
|
|
140 |
FpKeeper keeper(&fp);
|
115 |
string blk1;
|
141 |
string blk1;
|
116 |
blk1.append("udi=");
|
142 |
blk1.append("udi=");
|
117 |
blk1.append(udi);
|
143 |
blk1.append(udi);
|
118 |
blk1.append("\n");
|
144 |
blk1.append("\n");
|
119 |
blk1.resize(o_b1size, 0);
|
145 |
blk1.resize(o_b1size, 0);
|
120 |
output << blk1;
|
146 |
if (fwrite(blk1.c_str(), 1, o_b1size, fp) != o_b1size) {
|
121 |
if (!output.good())
|
147 |
LOGDEB(("MboxCache::put_offsets: fwrite errno %d\n", errno));
|
122 |
return;
|
148 |
return;
|
|
|
149 |
}
|
|
|
150 |
|
123 |
for (vector<mbhoff_type>::const_iterator it = offs.begin();
|
151 |
for (vector<mbhoff_type>::const_iterator it = offs.begin();
|
124 |
it != offs.end(); it++) {
|
152 |
it != offs.end(); it++) {
|
125 |
mbhoff_type off = *it;
|
153 |
mbhoff_type off = *it;
|
126 |
output.write((char*)&off, sizeof(mbhoff_type));
|
154 |
if (fwrite((char*)&off, 1, sizeof(mbhoff_type), fp) !=
|
127 |
if (!output.good()) {
|
155 |
sizeof(mbhoff_type)) {
|
128 |
output.close();
|
|
|
129 |
return;
|
156 |
return;
|
130 |
}
|
157 |
}
|
131 |
}
|
158 |
}
|
132 |
output.close();
|
|
|
133 |
}
|
159 |
}
|
134 |
|
160 |
|
135 |
// Check state, possibly initialize
|
161 |
// Check state, possibly initialize
|
136 |
bool ok() {
|
162 |
bool ok() {
|
137 |
if (m_minfsize == -1)
|
163 |
if (m_minfsize == -1)
|
138 |
return false;
|
164 |
return false;
|
139 |
if (!m_ok) {
|
165 |
if (!m_ok) {
|
140 |
RclConfig *config = RclConfig::getMainConfig();
|
166 |
RclConfig *config = RclConfig::getMainConfig();
|
141 |
if (config == 0)
|
167 |
if (config == 0)
|
142 |
return false;
|
168 |
return false;
|
143 |
int minmbs = 10;
|
169 |
int minmbs = 5;
|
144 |
config->getConfParam("mboxcacheminmbs", &minmbs);
|
170 |
config->getConfParam("mboxcacheminmbs", &minmbs);
|
145 |
if (minmbs < 0) {
|
171 |
if (minmbs < 0) {
|
146 |
// minmbs set to negative to disable cache
|
172 |
// minmbs set to negative to disable cache
|
147 |
m_minfsize = -1;
|
173 |
m_minfsize = -1;
|
148 |
return false;
|
174 |
return false;
|
|
... |
|
... |
166 |
|
192 |
|
167 |
// Place where we store things
|
193 |
// Place where we store things
|
168 |
string m_dir;
|
194 |
string m_dir;
|
169 |
// Don't cache smaller files. If -1, don't do anything.
|
195 |
// Don't cache smaller files. If -1, don't do anything.
|
170 |
mbhoff_type m_minfsize;
|
196 |
mbhoff_type m_minfsize;
|
171 |
static const int o_b1size;
|
197 |
static const size_t o_b1size;
|
172 |
|
198 |
|
173 |
// Create the cache directory if it does not exist
|
199 |
// Create the cache directory if it does not exist
|
174 |
bool maybemakedir()
|
200 |
bool maybemakedir()
|
175 |
{
|
201 |
{
|
176 |
struct stat st;
|
202 |
struct stat st;
|
|
... |
|
... |
193 |
{// Msgnums are from 1
|
219 |
{// Msgnums are from 1
|
194 |
return o_b1size + (msgnum-1) * sizeof(mbhoff_type);
|
220 |
return o_b1size + (msgnum-1) * sizeof(mbhoff_type);
|
195 |
}
|
221 |
}
|
196 |
};
|
222 |
};
|
197 |
|
223 |
|
198 |
const int MboxCache::o_b1size = 1024;
|
224 |
const size_t MboxCache::o_b1size = 1024;
|
199 |
static class MboxCache mcache;
|
225 |
static class MboxCache mcache;
|
200 |
|
226 |
|
201 |
MimeHandlerMbox::~MimeHandlerMbox()
|
227 |
MimeHandlerMbox::~MimeHandlerMbox()
|
202 |
{
|
228 |
{
|
203 |
clear();
|
229 |
clear();
|