From d2564d25e802d1ee3230cf045c4940e836b5c6a2 Mon Sep 17 00:00:00 2001 From: John Denker Date: Sun, 29 Jul 2012 16:50:11 -0700 Subject: split ltgrey (and libltgrey) off from greylist; put some utility functions into their own file. --- tools/ltgrey.c | 153 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 153 insertions(+) create mode 100644 tools/ltgrey.c (limited to 'tools/ltgrey.c') diff --git a/tools/ltgrey.c b/tools/ltgrey.c new file mode 100644 index 0000000..afdb4c1 --- /dev/null +++ b/tools/ltgrey.c @@ -0,0 +1,153 @@ +#include +#include /* for exit(), atoi() */ + +#include "libltgrey.h" +#include "utils.h" +#include "qq_exit_codes.h" + +using namespace std; +pid_t mypid; +string progname; + +#define exeunt exit + +// forward reference: +void scan(const string progid, const string p, const int copies=1); + +int main(int _argc, char** _argv){ + mypid = getpid(); + int argc(_argc); + char** argv(_argv); + const string dirname("/var/qmail/greylist"); + whatsit foo(argv[0], dirname); argc--; argv++; + int scanmode(0); + int copies(1); + int penalty(0); + int stain(0); + int check(0); + while (argc > 0) { + string arg = argv[0]; argc--; argv++; + if (prefix(arg, "-scan")) { + scanmode++; + } else if (prefix(arg, "-copy")) { + copies++; + } else if (prefix(arg, "-verbose")) { + foo.verbosity++; + } else if (prefix(arg, "-check")) { + check++; + } else if (prefix(arg, "-penalize") + || prefix(arg, "-penalty")) { + if (!argc){ + cerr << "Option '" << arg << "' requires an argument" << endl; + exeunt(ex_syserr); + } + penalty = atoi(*argv++); argc--; + } else if (prefix(arg, "-stain")) { + if (!argc){ + cerr << "Option '" << arg << "' requires an argument" << endl; + exeunt(ex_syserr); + } + stain = atoi(*argv++); argc--; + } else if (prefix(arg, "-suffix")) { + if (!argc){ + cerr << "Option '" << arg << "' requires an argument" << endl; + exeunt(ex_syserr); + } + foo.suffix += *argv++; argc--; + } else { + cerr << "Unrecognized arg: " << arg << endl; + exeunt(ex_syserr); + } + } + if (foo.setup()) return ex_syserr; + + if (scanmode) { + scan(foo.progid, dirname, copies); + return 0; + } + + int sts = foo.doit(penalty, stain); + if (sts == ex_syserr) return sts; + if (!check) return ex_good; + +// check mode ... perform some extra checks. +// Probably a better design would be to +// (a) make more thorough DNS checks, and +// (b) move all the DNS checking to a separate module + + int dns = foo.check_dns(); + if (dns == ex_syserr || dns == ex_spam) return dns; + exeunt(sts); +} + +////////////////////////////////////////////////////////////////////// +// requires apt-get install libboost-filesystem-dev: +#include +#include +#include /* for stat(), getaddrinfo() */ +#include /* for stat() */ +#include /* for stat() */ +#include /* for perror */ +#include + +const int minute(60); +const int hour(60*minute); +const int day(24*hour); + +const int minimum_age(15*minute); +const int maximum_age(32*day); +const int probation(4*hour); + +void scan(const string progid, const string p, const int copies){ + timeval now; + gettimeofday(&now, NULL); + using namespace boost::filesystem; + + if (is_directory(p)) { + for (directory_iterator itr(p); itr!=directory_iterator(); ++itr) { + string basename = itr->path().filename(); + for (int ii = 0; ii < copies; ii++) + cout << setw(20) << left << basename << ' '; // display filename only + if (is_regular_file(itr->status())) { +// cout << " [" << file_size(itr->path()) << ']'; + struct stat mystat; + string fn = p + "/" + basename; + int rslt = stat(fn.c_str(), &mystat); + if (rslt != 0){ + cerr << progid << ": stat failed for '" + << fn << "' : "; + perror(0); + } + int mod_age = now.tv_sec - mystat.st_mtime; + int ac_age = now.tv_sec - mystat.st_atime; + cout << setw(10) << time_out(mod_age) + << " " << setw(10) << time_out(ac_age); + if (0) { + + } else if (mod_age < 0) { + cout << " penalty"; + } else if (mod_age < ac_age) { + cout << " parole"; + } else if (mod_age - ac_age < minimum_age // early bird, or completely unused + && mod_age > probation) { // did not diligently resubmit + cout << " disprobation"; + if (mod_age != ac_age) cout << "!"; + } else if (mod_age < minimum_age) { + cout << " young"; + if (mod_age != ac_age) cout << "!"; + } else if (mod_age == ac_age) { + cout << " unused"; + } else if (mod_age > maximum_age) { + cout << " expired"; + } else { + cout << " OK"; + } + } + cout << '\n'; + } + } + else { + // starting point is not a directory: + cout << (exists(p) ? "Found: " : "Not found: ") << p << '\n'; + } +} -- cgit v1.2.3