summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--tools/greylist.c75
1 files changed, 66 insertions, 9 deletions
diff --git a/tools/greylist.c b/tools/greylist.c
index 8adac05..d769ff4 100644
--- a/tools/greylist.c
+++ b/tools/greylist.c
@@ -9,6 +9,8 @@
#include <errno.h> /* for ENOENT */
#include <fstream> /* for ofstream() */
#include <fcntl.h> /* for creat() */
+#include <sys/time.h> /* for gettimeofday() */
+
using namespace std;
const int sa_good = 0;
@@ -21,7 +23,7 @@ string progname;
void dump(const string var){
char* str = getenv(var.c_str());
- cerr << progname
+ cerr << progname
<< "[" << mypid << "] "
<< var;
if (str) cerr << " is set to '" << str << "'" << endl;
@@ -34,12 +36,53 @@ const string dirname("/var/qmail/greylist");
// int fstat(int fd, struct stat *buf);
// int lstat(const char *path, struct stat *buf);
+const int minute(60);
+const int hour(60*minute);
+const int day(24*hour);
+
+class whatsit{
+public:
+ string progname;
+ pid_t mypid;
+ timeval now;
+ string ipname;
+ int mod_age;
+ int ac_age;
+
+ whatsit(const string name)
+ : progname(name), mypid(getpid())
+ {
+ gettimeofday(&now, NULL);
+ }
+ int doit();
+// access comes after modification:
+ void update(const string msg, const timeval new_mod, const timeval new_ac);
+};
+
+void whatsit::update(const string msg, const timeval new_mod, const timeval new_ac){
+ cerr << progname << ": "
+ << msg << ": " << ipname
+ << " mod_age: " << mod_age
+ << " ac_age: " << ac_age
+ << endl;
+ timeval upd[2] = {
+// beware: access illogically comes *before* modification here:
+ new_ac,
+ new_mod
+ };
+ utimes(ipname.c_str(), upd);
+}
+
int main(int argc, char** argv){
- mypid = getpid();
- progname = argv[0];
+
// dump("TCPREMOTEIP");
// dump("TCPREMOTEHOST");
+ whatsit foo(argv[0]);
+ return foo.doit();
+}
+
+int whatsit::doit(){
char* ipvar = getenv("TCPREMOTEIP");
if (!ipvar) {
cerr << progname << ": TCPREMOTEIP not set???" << endl;
@@ -66,8 +109,8 @@ int main(int argc, char** argv){
exit(sa_syserr);
}
}
-
- string ipname = dirname + "/" + ipbase;
+
+ ipname = dirname + "/" + ipbase;
struct stat ipstat;
rslt = stat(ipname.c_str(), &ipstat);
if (rslt != 0){
@@ -84,9 +127,23 @@ int main(int argc, char** argv){
perror(0);
}
close(fd);
+ update("new customer", now, now);
return(bug_bait_grey);
- } else {
- cerr << "file exists: " << ipname << endl;
}
- return 0;
-}
+// here if stat succeeded
+ mod_age = now.tv_sec - ipstat.st_mtime;
+ ac_age = now.tv_sec - ipstat.st_atime;
+ timeval mod_orig = {ipstat.st_mtime, 0};
+ if (mod_age < 5*minute) {
+ update("early bird", mod_orig, now);
+ return(bug_bait_grey);
+ }
+ if (ac_age < 32*day) {
+ update("returning customer", mod_orig, now);
+ return 0;
+ }
+
+// here if it is too old:
+ update("too old, starting over", now, now);
+ return(bug_bait_grey);
+} \ No newline at end of file