From 19f9ba962a5f9862572f993e134ec5e039217cdf Mon Sep 17 00:00:00 2001 From: Michiel Broek Date: Tue, 24 Sep 2002 19:54:42 +0000 Subject: [PATCH] Improved mbfido locking --- ChangeLog | 7 +++++++ mbfido/dirlock.c | 26 ++++++++++++++++++++++++-- mbfido/mbfido.c | 34 +++++++++++++++++++++++----------- 3 files changed, 54 insertions(+), 13 deletions(-) diff --git a/ChangeLog b/ChangeLog index f04febd1..19ac75d8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -63,6 +63,13 @@ v0.35.03 06-Jul-2002 there is now better filtering to get that garbage out of the received tic files. We will forward plain ascii of course. Fixed the outbound queue to send to nodes not in the setup. + When mbfido stops with error 110 it doesn't remove any locks + because this error is only being used before that main lock is + made. + Changed the error codes during init until the main lock is + made, this must prevent destroying a another lock. + Added extra check to unlock directory function to check that + only the owned lock is removed. newuser: Check for Unix accounts is now case sensitive. diff --git a/mbfido/dirlock.c b/mbfido/dirlock.c index bca5dca4..9adbdd3f 100644 --- a/mbfido/dirlock.c +++ b/mbfido/dirlock.c @@ -45,7 +45,7 @@ /* - * Put a lock on this program. + * Put a lock on a directory. */ int lockdir(char *directory) { @@ -116,14 +116,36 @@ int lockdir(char *directory) +/* + * Unlock directory, make extra check to see if it is our own lock. + */ void ulockdir(char *directory) { char *lockfile; + FILE *fp; + pid_t oldpid; lockfile = calloc(PATH_MAX, sizeof(char)); sprintf(lockfile, "%s/", directory); sprintf(lockfile + strlen(lockfile), "%s", LCKNAME); - (void)unlink(lockfile); + + if ((fp = fopen(lockfile, "r")) == NULL) { + Syslog('-', "Lockfile \"%s\" doesn't exist", lockfile); + free(lockfile); + return; + } + + if (fscanf(fp, "%u", &oldpid) != 1) { + WriteError("$Can't read old pid from \"%s\"", lockfile); + } else { + if (getpid() != oldpid) { + WriteError("Attempt to remove lock %s of pid %d", lockfile, oldpid); + } else { + unlink(lockfile); + } + } + + fclose(fp); free(lockfile); } diff --git a/mbfido/mbfido.c b/mbfido/mbfido.c index 64f9b609..42f38ef7 100644 --- a/mbfido/mbfido.c +++ b/mbfido/mbfido.c @@ -189,7 +189,8 @@ void die(int onsig) system("stty sane"); } - CloseDupes(); + if (onsig != 110) + CloseDupes(); /* * Check for locked and open message base. @@ -239,11 +240,15 @@ void die(int onsig) /* * There should be no locks anymore, but in case of a crash try to unlock - * all possible directories. + * all possible directories. Only if onsig <> 110, this was a lock error + * and there should be no lock. We prevent removing the lock of another + * mbfido this way. */ - ulockdir(CFG.inbound); - ulockdir(CFG.pinbound); - ulockdir(CFG.out_queue); + if (onsig != 110) { + ulockdir(CFG.inbound); + ulockdir(CFG.pinbound); + ulockdir(CFG.out_queue); + } t_end = time(NULL); Syslog(' ', "MBFIDO finished in %s", t_elapsed(t_start, t_end)); @@ -427,10 +432,11 @@ int main(int argc, char **argv) Syslog(' ', cmd); free(cmd); - InitDupes(); - + /* + * Not yet locked, if anything goes wrong, exit with die(110) + */ if (!diskfree(CFG.freespace)) - die(101); + die(110); if (do_mail) { /* @@ -452,7 +458,7 @@ int main(int argc, char **argv) i--; if (! i) { WriteError("Lock timeout, aborting"); - die(101); + die(110); } sleep(20); Nopper(); @@ -464,13 +470,17 @@ int main(int argc, char **argv) */ if (do_unprot) { if (! lockdir(CFG.inbound)) - die(101); + die(110); } else { if (! lockdir(CFG.pinbound)) - die(101); + die(110); } } + /* + * Locking succeeded, no more abort alowed with die(110) + */ + if (initnl()) die(101); if (!do_mail && !do_uucp) @@ -513,6 +523,8 @@ int main(int argc, char **argv) die(0); } + InitDupes(); + if (do_notify) if (Notify(Options)) { do_flush = TRUE;