Paying the Rent
I missed paying rent quite some time ago, so to prevent further breaches of contract, I set up a cronjob to remind me. cron makes it easy to do something like this: on the first hour of the first day of every month, I send an e-mail to myself that says "Pay rent, dummy!". Piece of cake.
Of course, this has always bothered me, because I shouldn't be getting the e-mail on the day rent is due; I should be getting it the day before. Sadly — albeit predictably — cron is crippled by its design in this regard. You can specify integer values (day 1, day 13, day 28), but you cannot specify fuzzier quantities (like first Sunday of the month, second Tuesday of November, or the last day of the month).
So I wrote a brain-dead easy program to fix this. Sure, now that I've written it, some cron guru is going to tell me how I could just set up a cronjob with a "-1" in it somewhere. Oh well.
Simply, I wrote a program that returns tomorrow's day of the month. If it's the 9th, return 10. If it's the 31st, return 1. I chose to write this application in C, but one could do this in any language that supports a gettimeofday()-type system call. (My theory is that one could write a crude but similarly-functional application in two lines of Python.) At this point, the program can be cronned to run daily, and the return code would determine whether or not a mail gets sent.
My biggest problem was getting cron to branch correctly:
00 0 * * * tomorrow; if [ "X$?" = "X1" ]; then echo "Pay rent, \ dummy!" | /var/qmail/bin/mailsubj 'rent' toby ; fi
I don't know what to call this program, so in the example it's just "tomorrow". Since it only returns dates, one could just as easily edit either the program or the cronjob to notify you a week in advance, or ten days, or on leap years if you want:
#include "caldate.h"
#include "caltime.h"
#include "strerr.h"
#include "tai.h"
#define FATAL "tomorrow: fatal: "
void die_overflow(){strerr_die2x(111,FATAL,"overflow error");}
struct tai t;
struct caltime ct;
int main(void) {
long d = 0;
tai_now(&t);
caltime_utc(&ct,&t,(int *)0,(int *)0);
if (0 > (d = 1 + caldate_mjd(&ct.date))) die_overflow();
caldate_frommjd(&ct.date,d,(int *)0,(int *)0);
return ct.date.day;
}
Downsides? This cronjob runs every day instead of once a month. Upsides? I get 24 hours notice instead of 0.
No comments:
Post a Comment