summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--tools/filters.conf2
-rw-r--r--tools/greylist.c57
2 files changed, 38 insertions, 21 deletions
diff --git a/tools/filters.conf b/tools/filters.conf
index 7768e6a..bd8eb33 100644
--- a/tools/filters.conf
+++ b/tools/filters.conf
@@ -5,4 +5,4 @@ sa /usr/local/bin/spamc -Y 0 -s 1000000 -x
qq /var/qmail/bin/qmail-queue
# postspam /var/qmail/bin/greylist -suffix (post) -penalize 86400 -v
-postspam /var/qmail/bin/greylist -suffix (post) -penalize 1 -v
+postspam /var/qmail/bin/greylist -suffix (post) -stain 1 -v
diff --git a/tools/greylist.c b/tools/greylist.c
index fd5ac4f..92e638f 100644
--- a/tools/greylist.c
+++ b/tools/greylist.c
@@ -113,10 +113,10 @@ public:
{
gettimeofday(&now, NULL);
}
- int doit(const int penalty=0);
+ int doit(const int penalty, const int stain);
// access comes after modification:
void update(const string msg, const timeval new_mod,
- const timeval new_ac, const int penalty=0);
+ const timeval new_ac, const int penalty, const int stain);
int setup();
int check_dns();
int check_dns_sub(string &addr, string &host, vector<string> &checked);
@@ -216,27 +216,37 @@ void scan(const string progid, const string p, const int copies=1){
}
void whatsit::update(const string msg, const timeval new_mod,
- const timeval new_ac, const int penalty){
+ const timeval new_ac, const int penalty, const int stain){
if (verbosity){
cerr << progid << ": ";
- if (penalty) cerr << " penalty+";
- cerr << msg << ": " << ipbase;
- if (hostname.length()) cerr << " " << hostname;
- cerr << " mod_age: " << time_out(mod_age)
- << " ac_age: " << time_out(ac_age)
- << endl;
+ if (penalty) cerr << " penalty " << penalty;
+ if (stain) cerr << " stain " << stain;
+ if (verbosity > 1) {
+ if (penalty || stain) cerr << "+"; // separation, punctuation
+ cerr << msg << ": " << ipbase;
+ if (hostname.length()) cerr << " " << hostname;
+ cerr << " mod_age: " << time_out(mod_age)
+ << " ac_age: " << time_out(ac_age);
+ }
+ cerr << endl;
}
timeval pen_mod(new_mod);
+ timeval stain_ac(new_ac);
if (penalty) {
pen_mod = now;
pen_mod.tv_sec += penalty;
}
+ if (stain) {
+ stain_ac = now;
+ stain_ac.tv_sec -= stain;
+ }
timeval upd[2] = {
// beware: access illogically comes *before* modification here:
- new_ac,
+ stain_ac,
pen_mod
};
- utimes(ipname.c_str(), upd);
+ if (utimes(ipname.c_str(), upd))
+ cerr << "oops" << endl;
}
@@ -249,6 +259,7 @@ int main(int _argc, char** _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++;
@@ -267,6 +278,12 @@ int main(int _argc, char** _argv){
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;
@@ -285,7 +302,7 @@ int main(int _argc, char** _argv){
return 0;
}
- int sts = foo.doit(penalty);
+ int sts = foo.doit(penalty, stain);
if (sts == ex_syserr) return sts;
if (!check) return ex_good;
@@ -299,7 +316,7 @@ int main(int _argc, char** _argv){
exeunt(sts);
}
-int whatsit::doit(const int penalty){
+int whatsit::doit(const int penalty, const int stain){
if (!ipvar) {
cerr << progid
@@ -346,7 +363,7 @@ int whatsit::doit(const int penalty){
perror(0);
}
close(fd);
- update("new customer", now, now, penalty);
+ update("new customer", now, now, penalty, stain);
return(ex_greylisting);
}
@@ -355,29 +372,29 @@ int whatsit::doit(const int penalty){
ac_age = now.tv_sec - ipstat.st_atime;
timeval mod_orig = {ipstat.st_mtime, 0};
if (mod_age < 0) {
- update("penalty box", mod_orig, now, penalty);
+ update("penalty box", mod_orig, now, penalty, stain);
return(ex_penaltybox);
}
if (mod_age < ac_age){
// when he comes out on parole, he starts over with no reputation:
- update("paroled spammer", now, now, penalty);
+ update("paroled spammer", now, now, penalty, stain);
return(ex_greylisting);
}
if (mod_age < minimum_age) {
- update("early bird", mod_orig, now, penalty);
+ update("early bird", mod_orig, now, penalty, stain);
return(ex_greylisting);
}
if (mod_age - ac_age < minimum_age // early bird, or completely unused
&& mod_age > probation) { // did not diligently resubmit
- update("disprobation", now, now, penalty);
+ update("disprobation", now, now, penalty, stain);
return(ex_greylisting);
}
if (ac_age > maximum_age) {
- update("too old, starting over", now, now, penalty);
+ update("too old, starting over", now, now, penalty, stain);
return(ex_greylisting);
}
// if all checks are passed, must be OK:
- update("returning customer", mod_orig, now, penalty);
+ update("returning customer", mod_orig, now, penalty, stain);
return 0;
}