00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include <dirent.h>
00020 #include <stdio.h>
00021 #include <sys/stat.h>
00022 #include <sys/time.h>
00023 #include <time.h>
00024 #include <unistd.h>
00025
00026 #include "Debug.h"
00027 #include "Error.h"
00028 #include "ArtSpooler.h"
00029 #include "util.h"
00030
00031 #ifdef HAVE_SSTREAM
00032 #include <sstream>
00033 #else
00034 #include <strstream>
00035 #endif
00036
00037 using namespace std;
00038
00039 ArtSpooler::ArtSpooler(const string & spoolDir)
00040 {
00041 VERB(slog.p(Logger::Debug) << "ArtSpooler::ArtSpooler ("
00042 << spoolDir << ")\n");
00043
00044 string tmp;
00045
00046 this->spoolDir = spoolDir;
00047 if (mkpdir(spoolDir.c_str(), 0700) == -1) {
00048 string errtxt("Error creating spoolDirectory");
00049 errtxt += spoolDir;
00050 throw(Error(errtxt.c_str(), ERROR_LOCATION));
00051 }
00052 artSpool = spoolDir + "/.artSpool";
00053 if (mkpdir(artSpool.c_str(), 0700) == -1) {
00054 string errtxt("Error creating spoolDirectory");
00055 errtxt += artSpool;
00056 throw(Error(errtxt.c_str(), ERROR_LOCATION));
00057 }
00058 badArticles = spoolDir + "/.badArticles";
00059 if (mkpdir(badArticles.c_str(), 0700) == -1) {
00060 string errtxt("Error creating spoolDirectory");
00061 errtxt += artSpool;
00062 throw(Error(errtxt.c_str(), ERROR_LOCATION));
00063 }
00064 tmp = spoolDir + "/.resourceSpooler.lock";
00065 pLock = new ObjLock(tmp);
00066 }
00067
00068 ArtSpooler::~ArtSpooler()
00069 {
00070 VERB(slog.p(Logger::Debug) << "ArtSpooler::~ArtSpooler ()\n");
00071
00072 delete pLock;
00073 }
00074
00075 void ArtSpooler::spoolArt(Article & a)
00076 {
00077 VERB(slog.
00078 p(Logger::Debug) << "ArtSpooler::spoolArt (Article &)\n");
00079 int s;
00080
00081 pLock->lockExBlk();
00082 s = storeArticle(artSpool, a);
00083 pLock->unlock();
00084
00085 if (s != 0) {
00086 throw(Error("spoolArt: duplicateArt", ERROR_LOCATION));
00087 }
00088
00089 }
00090
00091 void ArtSpooler::storeBadArt(Article & a)
00092 {
00093 VERB(slog.
00094 p(Logger::Debug) << "ArtSpooler::storeBadArt (Article &)\n");
00095 int s;
00096
00097 pLock->lockExBlk();
00098 s = storeArticle(badArticles, a);
00099 pLock->unlock();
00100 if (s != 0) {
00101 throw(Error("storeBadArt: duplicateArt", ERROR_LOCATION));
00102 }
00103 }
00104
00105 int ArtSpooler::storeArticle(const string & path, Article & a)
00106 {
00107 ofstream os;
00108 string fn, id;
00109 struct stat st;
00110 int s;
00111
00112 id = createID();;
00113 fn = path + "/art_" + id;
00114 s = lstat(fn.c_str(), &st);
00115 if (s == -1) {
00116 os.open(fn.c_str());
00117 os << a;
00118 os.close();
00119 s = 0;
00120 } else {
00121 s = 1;
00122 }
00123 return (s);
00124 }
00125
00126 Article *ArtSpooler::getSpooledArt(void)
00127 {
00128 VERB(slog.p(Logger::Debug) << "ArtSpooler::getSpooledArt ()\n");
00129 string an;
00130 Article *pa = NULL;
00131 ifstream is;
00132 struct dirent *d;
00133 DIR *dir;
00134
00135 pLock->lockExBlk();
00136 dir = opendir(artSpool.c_str());
00137 for (d = readdir(dir); d != NULL; d = readdir(dir)) {
00138 if (strncmp("art_", d->d_name, 4) == 0) {
00139 an = artSpool + "/" + d->d_name;
00140 pa = new Article();
00141 is.open(an.c_str());
00142
00143 pa->read(is);
00144 is.close();
00145 unlink(an.c_str());
00146
00147 break;
00148 }
00149 }
00150 closedir(dir);
00151 pLock->unlock();
00152
00153 return pa;
00154 }
00155
00156 string ArtSpooler::createID(void)
00157 {
00158 #ifdef HAVE_SSTREAM
00159 stringstream sb;
00160 #else
00161 strstream sb;
00162 #endif
00163 pid_t pid;
00164 struct timeval t;
00165
00166 pid = getpid();
00167 gettimeofday(&t, NULL);
00168 sb << (int) pid << (int) t.tv_sec << (int) t.tv_usec;
00169 return sb.rdbuf()->str();
00170 }
00171
00172 string ArtSpooler::extractID(Article & a)
00173 {
00174 string ID = a.getfield("message-id");
00175 ID.replace(0, 3, "");
00176 ID.replace(ID.length() - 1, 1, "");
00177 return ID;
00178 }