#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <time.h>
#include <fcntl.h>
#include <signal.h>
#ifndef WIN32
#include <unistd.h>
#endif
#include <fstream.h>
#include <tools.h>
#include <folder.h>
#include <logf.h>
#include "getrfc.h"
const char *getrfct::getpath()
{
return fp.getpath();
}
getrfct::getrfct()
{
cached_nr=0xffffffff;
rfcm.data=(char *)NULL;
mimestruct=(mimestructt *)NULL;
index=header=-1;
opened=FALSE;
}
getrfct::~getrfct()
{
clear_cached();
if(index>=0) ::close(index);
if(header>=0) ::close(header);
}
dword getrfct::get_number_of_messages()
{
if(index<0) return 0;
return filelength(index)/sizeof fi;
}
bool getrfct::close()
{
clear_cached();
if(index>=0) ::close(index);
if(header>=0) ::close(header);
index=header=-1;
opened=FALSE;
return FALSE;
}
bool getrfct::open_files()
{
char filename[DIRLEN];
if(opened) close();
snprintf(filename, DIRLEN, "%sindex", fp.getpath());
index=::open(filename, O_RDWR|O_BINARY|O_CREAT, S_IREAD|S_IWRITE);
snprintf(filename, DIRLEN, "%sheader", fp.getpath());
header=::open(filename, O_RDWR|O_BINARY|O_CREAT, S_IREAD|S_IWRITE);
return index<0 || header<0;
}
bool getrfct::open_mail(const std::string &name, const std::string &subfolder)
{
std::string folder_name;
if(subfolder=="")
{
folder_name="0@"; // default subfolder
folder_name+=name;
}
else
folder_name=subfolder+"@"+name;
fp.setname(folder_name);
fp.read();
return open_files();
}
bool getrfct::open_news(const std::string &name)
{
fp.setname(name);
fp.read();
return open_files();
}
//
// Binary search for uids
//
bool getrfct::search_uid(dword uid, dword &nr)
{
if(index<0) return TRUE;
dword number_of_messages=get_number_of_messages();
#if 1
dword begin=0, end=number_of_messages;
while(begin<end)
{
nr=begin+(end-begin)/2;
get_folderindex(nr);
if(fi.id==uid)
return FALSE;
if(fi.id<uid)
begin=nr+1;
else // fi.uid>uid
end=nr;
}
#else
for(nr=0; nr<number_of_messages; nr++)
{
get_folderindex(nr);
if(fi.id==uid)
return FALSE;
}
#endif
return TRUE;
}
void getrfct::clear_cached()
{
if(rfcm.data!=(char *)NULL) { delete (char *)rfcm.data; rfcm.data=(char *)NULL; }
if(mimestruct!=(mimestructt *)NULL) { delete mimestruct; mimestruct=(mimestructt *)NULL; }
cached_body=cached_folderindex=cached_header=cached_structure=FALSE;
}
void getrfct::check_cache(dword nr)
{
if(nr!=cached_nr)
{
clear_cached();
cached_nr=nr;
}
}
bool getrfct::get_folderindex(dword nr)
{
check_cache(nr);
if(!cached_folderindex)
{
lseek(index, nr*sizeof(fi), SEEK_SET);
if(read(index, &fi, sizeof fi)!=sizeof fi)
return TRUE;
cached_folderindex=TRUE;
}
return FALSE;
}
bool getrfct::get_header(dword nr)
{
check_cache(nr);
if(get_folderindex(nr))
return TRUE;
if(!cached_header)
{
char *data;
data=new char[fi.headerlen];
if(data==(char *)NULL)
logf.internalerror("getrfct::getheader", "out of memory");
lseek(header, fi.headeroffs, SEEK_SET);
if(read(header, data, fi.headerlen)!=(ssize_t)fi.headerlen)
{
delete data;
return TRUE;
}
if(fi.flags.rfc)
{
if(rfcm.data!=NULL) delete (char *)rfcm.data;
rfcm.data=data;
rfcm.endofmail=rfcm.endoffile=data+fi.headerlen;
rfcm.parse();
}
else // Zconnect
{
}
cached_header=TRUE;
}
return FALSE;
}
bool getrfct::get_body(dword nr)
{
check_cache(nr);
if(get_folderindex(nr))
return TRUE;
if(!cached_body)
{
char *data;
data=new char[fi.len+fi.headerlen];
if(data==(char *)NULL)
logf.internalerror("getrfct::getbody", "out of memory");
lseek(header, fi.headeroffs, SEEK_SET);
if(!fi.flags.bodyextern)
{
dword total=fi.len+fi.headerlen;
if(read(header, data, total)!=total)
return TRUE;
}
else
{
char filename[DIRLEN];
if(read(header, data, fi.headerlen)!=fi.headerlen)
return TRUE;
snprintf(filename, DIRLEN, "%s%s", fp.getpath(), fi.file);
ifstream bodyfile(filename, ios::binary|ios::in);
if(!bodyfile) return TRUE;
if(!bodyfile.read(data+fi.headerlen, fi.len)) return TRUE;
}
if(fi.flags.rfc)
{
if(rfcm.data!=NULL) delete (char *)rfcm.data;
rfcm.data=data;
rfcm.endofmail=rfcm.endoffile=data+fi.len+fi.headerlen;
rfcm.parse();
}
else // Zconnect
{
}
cached_body=TRUE;
cached_header=TRUE;
}
return FALSE;
}
bool getrfct::get_structure(dword nr)
{
check_cache(nr);
if(get_body(nr))
return TRUE;
if(!cached_structure)
{
mimestruct=new mimestructt;
mimestruct->mimeparse(rfcm);
cached_structure=TRUE;
}
return FALSE;
}
syntax highlighted by Code2HTML, v. 0.9.1