#include "config.h"#include <string.h>#include <getopt.h>#include <sys/param.h>#include <sys/stat.h>#include <sys/time.h>#include <sys/types.h>#include <dirent.h>#include <unistd.h>#include <string>#include <vector>#include <algorithm>#include "Debug.h"#include "setugid.h"#include "Config.h"#include "Logger.h"#include "NServer.h"Go to the source code of this file.
Classes | |
| class | Entry |
| struct | cache_statistic |
Defines | |
| #define | PACKAGE PACKAGE_NEWSCACHECLEAN |
| #define | MAX(a, b) (((a)>(b))?(a):(b)) |
| #define | FILE_ACCESS_TABLE_ENTRIES 100000 |
| #define | USAGE |
Functions | |
| bool | sort_entries (const Entry *l, const Entry *r) |
| void | clean (const char *cpath) |
| void | remove_elements (long max_blocks, struct cache_statistic *pS) |
| int | main (int argc, char **argv) |
Variables | |
| Logger | slog |
| const char * | cmnd |
| Config | Cfg |
| vector< Entry * > | pvector |
| long | _blocks = 0 |
|
|
Definition at line 66 of file NewsCacheClean.cc. |
|
|
Definition at line 65 of file NewsCacheClean.cc. |
|
|
Definition at line 62 of file NewsCacheClean.cc. |
|
|
Value: " -h, --help\n"\ " Show summary of options.\n"\ "\n"\ " -v, --version\n"\ " Show version of program.\n"\ "\n"\ " -c --configuration config-file\n"\ "\n"\ " -s --statistic\n"\ " Show statistic informations.\n"\ "\n"\ " -p --print-purgetable\n"\ " Print the sorted purge table.\n"\ "\n"\ " -t --try\n"\ " Try, not really removing files.\n"\ Definition at line 321 of file NewsCacheClean.cc. |
|
|
Definition at line 204 of file NewsCacheClean.cc. References _blocks, Cfg, Logger::Error, NVNewsgroup::firstnbr(), NVNewsgroup::lastnbr(), MAX, NC_CATCH_ALL, Logger::p(), pvector, slog, Config::SpoolDirectory, and VERB. Referenced by main().
00205 {
00206 VERB(slog.p(Logger::Debug) << "clean(" << cpath << ")\n");
00207 DIR *d;
00208 time_t dbatime;
00209 char buf[MAXPATHLEN];
00210
00211 struct dirent *f;
00212 struct stat s;
00213
00214 sprintf(buf, "%s/.db", cpath);
00215 // Exception Directories
00216 if (strcmp(buf, "./.artSpool") == 0)
00217 return;
00218 if (strcmp(buf, "./.badArticles") == 0)
00219 return;
00220 if (stat(buf, &s) == 0) {
00221 dbatime = MAX(s.st_atime, s.st_mtime);
00222 pvector.push_back( new Entry (buf, dbatime, s.st_blocks) );
00223 _blocks += s.st_blocks;
00224 --dbatime;
00225 } else {
00226 dbatime = 0;
00227 }
00228
00229 if ((d = opendir(cpath)) == NULL) {
00230 slog.p(Logger::Error) << "cannot open " << cpath << "\n";
00231 return;
00232 }
00233 while ((f = readdir(d)) != NULL) {
00234 if (strcmp(f->d_name, ".") == 0)
00235 continue;
00236 if (strcmp(f->d_name, "..") == 0)
00237 continue;
00238 sprintf(buf, "%s/%s", cpath, f->d_name);
00239 if (stat(buf, &s) == 0) {
00240 if (S_ISDIR(s.st_mode))
00241 clean(buf);
00242 } else {
00243 slog.
00244 p(Logger::
00245 Error) << "cannot stat " << buf << "\n";
00246 }
00247 }
00248 closedir(d);
00249
00250 if ((d = opendir(cpath)) == NULL) {
00251 slog.p(Logger::Error) << "cannot reopen " << cpath << "\n";
00252 return;
00253 }
00254 // sanity check
00255 string ngname (cpath);
00256 // ./be/comp/os/unix -> be.comp.os.unix
00257 ngname.replace (0, 2, "");
00258 int i;
00259 while ((i=ngname.find ("/")) != -1) {
00260 ngname[i] = '.';
00261 }
00262 NVNewsgroup *ng;
00263 OverviewFmt *fmt = new OverviewFmt ();
00264 int firstnr;
00265 int lastnr;
00266 try {
00267 string dbname = cpath;
00268 dbname += "/.db";
00269 struct stat s;
00270 if (stat (dbname.c_str(), &s) == 0) {
00271 ng = new NVNewsgroup (fmt,
00272 (const char *) Cfg.SpoolDirectory,
00273 ngname.c_str());
00274 } else {
00275 ng = NULL;
00276 }
00277 } catch (NoSuchGroupError e) {
00278 ng = NULL;
00279 }
00280 // FIXME: what we are doing with bad database files?
00281 NC_CATCH_ALL ("Error, please report bug!");
00282 if (ng != NULL) {
00283 firstnr = ng->firstnbr ();
00284 lastnr = ng->lastnbr ();
00285 delete ng;
00286 }
00287 string art;
00288 int nr;
00289 while ((f = readdir(d)) != NULL) {
00290 sprintf(buf, "%s/%s", cpath, f->d_name);
00291 if (stat(buf, &s) == 0) {
00292 if (S_ISREG(s.st_mode) && dbatime != 0 &&
00293 strncmp(f->d_name, ".art", 4) == 0) {
00294 time_t at = MAX(s.st_atime, s.st_mtime);
00295 if (dbatime <= at)
00296 at = dbatime;
00297 art = f->d_name;
00298 art.replace (0,4, "");
00299 if (sscanf (art.c_str(), "%d", &nr) != 1) {
00300 slog.p(Logger::Error) << "error "
00301 << "parsing " << f->d_name;
00302 } else if ( ng == NULL | nr < firstnr || nr > lastnr) {
00303 at = 0;
00304 }
00305 pvector.push_back (new Entry(buf, at,
00306 s.st_blocks) );
00307 _blocks += s.st_blocks;
00308 }
00309 } else {
00310 slog.
00311 p(Logger::
00312 Error) << "cannot stat " << buf << "\n";
00313 }
00314 }
00315 closedir(d);
00316 return;
00317 }
|
|
||||||||||||
|
Definition at line 340 of file NewsCacheClean.cc. References _blocks, Cfg, clean(), cmnd, CONF_UIDROOT, Config::Groupname, Config::LogDirectory, Config::NiceServer, Logger::open(), Logger::p(), PACKAGE, pvector, Config::read(), remove_elements(), setugid(), slog, sort_entries(), Config::SpoolDirectory, Config::SpoolSize, SYSCONFDIR, USAGE, Config::Username, and VERSION.
00341 {
00342 #ifndef WITH_SYSLOG
00343 char logfile[MAXPATHLEN];
00344 time_t t;
00345 pid_t p;
00346 #endif
00347 char conffile[MAXPATHLEN];
00348 int opt_config = 0;
00349 int c, aerr = 0;
00350 struct cache_statistic Stat;
00351 int nice;
00352 int stat=0;
00353 int try_flag = 0;
00354 char p_flag=0;
00355 vector<Entry *>::iterator begin, end;
00356
00357 memset ((void *) &Stat, 0, sizeof (struct cache_statistic));
00358
00359 sprintf(conffile, "%s/newscache.conf", SYSCONFDIR);
00360
00361 cmnd = argv[0];
00362 while (1) {
00363 int option_index = 0;
00364 static struct option long_options[] = {
00365 {"version", 0, 0, 'v'},
00366 {"help", 0, 0, 'h'},
00367 {"configuration", 1, 0, 'c'},
00368 {"statistic", 0, 0, 's'},
00369 {"try", 0, 0, 't'},
00370 {"print-purgetable", 0, 0, 'p'},
00371 {0, 0, 0, 0}
00372 };
00373
00374 c = getopt_long (argc, argv, "vhc:stp", long_options,
00375 &option_index);
00376
00377 if (c == -1)
00378 break;
00379
00380 switch (c) {
00381 case 'v':
00382 cout << PACKAGE << " " << VERSION << endl;
00383 exit (0);
00384 break;
00385
00386 case 'h':
00387 cout << "Usage: " << cmnd << endl;
00388 cout << USAGE << endl;
00389 exit (0);
00390 break;
00391
00392 case 'c':
00393 strcpy (conffile, optarg);
00394 ++opt_config;
00395 break;
00396
00397 case 's':
00398 stat = 1;
00399 break;
00400
00401 case 't':
00402 try_flag = 1;
00403 break;
00404
00405 case 'p':
00406 p_flag = 1;
00407 break;
00408
00409 default:
00410 aerr = 1;
00411 break;
00412 }
00413 }
00414
00415 if (aerr || optind != argc) {
00416 cerr << "Usage: " << cmnd << " [options]\n" << USAGE;
00417 exit(1);
00418 }
00419
00420 try {
00421 Cfg.read(conffile);
00422 // strcpy(nntp_hostname,Cfg.Hostname);
00423 }
00424 catch(IOError & io) {
00425 cerr << "unexpected EOF in " << conffile << "\n";
00426 exit(2);
00427 }
00428 catch(SyntaxError & se) {
00429 cerr << se._errtext << "\n";
00430 exit(2);
00431 }
00432
00433 #ifdef WITH_SYSLOG
00434 slog.open(PACKAGE, LOG_NDELAY | LOG_PID, LOG_NEWS);
00435 #else
00436 sprintf (logfile, "%s/newscache_newscacheclean.log", Cfg.LogDirectory);
00437 slog.open (logfile);
00438 #endif
00439 slog.p(Logger::Info) << "cleaning spool directory\n";
00440
00441
00442 /* set nice value for master server */
00443 #ifdef HAVE_SETPRIORITY
00444 errno = 0;
00445 nice = Cfg.NiceServer;
00446 nice += getpriority(PRIO_PROCESS, 0);
00447 if (nice == -1 && errno != 0) {
00448 slog.
00449 p(Logger::
00450 Error) << "getpriority failed: " << strerror(errno)
00451 << "\n";
00452 } else {
00453 if (setpriority(PRIO_PROCESS, 0, nice) == -1)
00454 slog.
00455 p(Logger::
00456 Error) << "setpriority failed: " <<
00457 strerror(errno) << "\n";
00458 }
00459 #endif
00460
00461 if (chdir(Cfg.SpoolDirectory) < 0) {
00462 slog.
00463 p(Logger::
00464 Error) <<
00465 "cannot change to spool directory -- exiting\n";
00466 exit(1);
00467 }
00468 if (getuid() == CONF_UIDROOT)
00469 setugid(Cfg.Username, Cfg.Groupname);
00470 clean(".");
00471 sort (pvector.begin(), pvector.end(), sort_entries);
00472 if (p_flag) {
00473 cout << "---------------- Purge table ----------------" << endl;
00474 for (begin=pvector.begin(), end=pvector.end();
00475 begin != end; begin++) {
00476 (*begin)->print (cout);
00477 }
00478 cout << "---------------- Purge table ----------------" << endl;
00479 }
00480 if (!try_flag) {
00481 remove_elements(Cfg.SpoolSize * 2, &Stat);
00482 }
00483 if (stat) {
00484 print_statistic(cout, &Stat);
00485 }
00486
00487 slog.p(Logger::Info) << "|SpoolDirectory|="
00488 << (unsigned int) (_blocks / 2) << "K\n";
00489 return 0;
00490 }
|
|
||||||||||||
|
Definition at line 143 of file NewsCacheClean.cc. References _blocks, Logger::Error, Logger::p(), pvector, slog, cache_statistic::stArtCnt, cache_statistic::stArtSize, cache_statistic::stDbCnt, cache_statistic::stDbSize, cache_statistic::stOutArtCnt, cache_statistic::stOutArtSize, cache_statistic::stPurgedArtCnt, cache_statistic::stPurgedArtSize, cache_statistic::stPurgedDbCnt, cache_statistic::stPurgedDbSize, cache_statistic::stPurgedDirCnt, cache_statistic::stPurgedOutArtCnt, and cache_statistic::stPurgedOutArtSize. Referenced by main().
00144 {
00145 int isDb;
00146 char cBuffer[MAXPATHLEN];
00147 vector<Entry *>::iterator begin, end;
00148
00149 for (begin=pvector.begin(), end=pvector.end();
00150 begin != end; begin++) {
00151 (*begin)->Path.length();
00152 if (strcmp((*begin)->Path.c_str() + (*begin)->Path.length() - 3, ".db") == 0) {
00153 isDb = 1;
00154 pS->stDbCnt++;
00155 pS->stDbSize += (*begin)->blocks;
00156 } else {
00157 isDb = 0;
00158 if ((*begin)->atime != 0) {
00159 pS->stArtCnt++;
00160 pS->stArtSize += (*begin)->blocks;
00161 } else {
00162 pS->stOutArtCnt++;
00163 pS->stOutArtSize += (*begin)->blocks;
00164 }
00165 }
00166 if ((*begin)->atime != 0 && _blocks <= max_blocks)
00167 continue;
00168 if (unlink((*begin)->Path.c_str()) == 0) {
00169 _blocks -= (*begin)->blocks;
00170 if (!isDb) {
00171 if ((*begin)->atime != 0) {
00172 pS->stPurgedArtCnt++;
00173 pS->stPurgedArtSize += (*begin)->blocks;
00174 } else {
00175 pS->stPurgedOutArtCnt++;
00176 pS->stPurgedOutArtSize += (*begin)->blocks;
00177 }
00178 } else {
00179 pS->stPurgedDbCnt++;
00180 pS->stPurgedDbSize += (*begin)->blocks;
00181 strcpy(cBuffer, (*begin)->Path.c_str());
00182 cBuffer[strlen(cBuffer) - 3] = '\0';
00183 if (rmdir(cBuffer) == 0) {
00184 pS->stPurgedDirCnt++;
00185 } else if (errno == ENOTEMPTY) {
00186 slog.p(Logger::Debug)
00187 << "Error rmdir "
00188 << "(Directory not empty) "
00189 << (*begin)->Path << "\n";
00190 } else {
00191 slog.p(Logger::Error)
00192 << "Error rmdir "
00193 << (*begin)->Path << "\n";
00194 }
00195 }
00196 } else {
00197 slog.
00198 p(Logger::
00199 Error) << "Error unlink " << (*begin)->Path << "\n";
00200 }
00201 }
00202 }
|
|
||||||||||||
|
Definition at line 134 of file NewsCacheClean.cc. References Entry::atime. Referenced by main().
|
|
|
Definition at line 110 of file NewsCacheClean.cc. Referenced by clean(), main(), and remove_elements(). |
|
|
Definition at line 70 of file NewsCacheClean.cc. |
|
|
Definition at line 69 of file NewsCacheClean.cc. |
|
|
Definition at line 87 of file NewsCacheClean.cc. Referenced by clean(), main(), and remove_elements(). |
|
|
Definition at line 68 of file NewsCacheClean.cc. |
1.3.6-20040222