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