From cde220ead7b80a9a3958eb98e9d5bb541ed6daaf Mon Sep 17 00:00:00 2001 From: Michiel Broek Date: Sun, 13 Jul 2003 13:22:32 +0000 Subject: [PATCH] Added lockfile age check --- ChangeLog | 3 + TODO | 11 +-- lib/nodelock.c | 202 +++++++++++++++++++++++++------------------------ 3 files changed, 109 insertions(+), 107 deletions(-) diff --git a/ChangeLog b/ChangeLog index 7476312f..0bd84d39 100644 --- a/ChangeLog +++ b/ChangeLog @@ -7,6 +7,9 @@ $Id$ v0.37.5 12-Jul-2003 + common.a: + Node locking tests for non-stale lockfiles older then 6 hours. + v0.37.4 10-May-2003 - 12-Jul-2003 diff --git a/TODO b/TODO index 2354abe6..06ce2a96 100644 --- a/TODO +++ b/TODO @@ -1,6 +1,6 @@ $Id$ - MBSE BBS V0.37.03 TODO list. + MBSE BBS V0.37.05 TODO list. ---------------------------- These are a list of things that must be implemented one way or @@ -106,9 +106,6 @@ mbcico: N: Implement binkp resync when getting files. Transmit works. - N: Add better check for stale outbound locks, check if the pid is from - a non-mbse program or add a age check. - mbfile: N: Add a check to see if the magic filenames are (still) valid. @@ -133,12 +130,6 @@ mbaff: mbindex: N: Add usernames index. -mbmon: - L: Logfile tail functions. - -mbtask: - N: Add events. - mbnewusr: N: On NetBSD, supress error message from mbpasswd. diff --git a/lib/nodelock.c b/lib/nodelock.c index f9f0783c..0ad07234 100644 --- a/lib/nodelock.c +++ b/lib/nodelock.c @@ -4,7 +4,7 @@ * Purpose ...............: Node locking * ***************************************************************************** - * Copyright (C) 1997-2002 + * Copyright (C) 1997-2003 * * Michiel Broek FIDO: 2:280/2802 * Beekmansbos 10 @@ -39,120 +39,128 @@ int nodelock(faddr *addr) { - char *fn,*tfn,*p; - char tmp[16]; - FILE *fp; - pid_t pid,mypid; - int tmppid,sverr; + char *fn, *tfn, *p, tmp[16]; + FILE *fp; + pid_t pid, mypid; + int tmppid, sverr; + time_t ltime, now; - fn = bsyname(addr); - tfn = xstrcpy(fn); - if ((p=strrchr(tfn,'/'))) - *++p='\0'; - mypid = getpid(); - sprintf(tmp, "aa%d", mypid); - tfn = xstrcat(tfn, tmp); - mkdirs(tfn, 0770); + fn = bsyname(addr); + tfn = xstrcpy(fn); + if ((p=strrchr(tfn,'/'))) + *++p='\0'; + mypid = getpid(); + sprintf(tmp, "aa%d", mypid); + tfn = xstrcat(tfn, tmp); + mkdirs(tfn, 0770); - if ((fp = fopen(tfn,"w")) == NULL) { - WriteError("$Can't open tmp file for bsy lock (%s) \"%s\"",ascfnode(addr, 0x1f), tfn); - free(tfn); - return 1; - } + if ((fp = fopen(tfn,"w")) == NULL) { + WriteError("$Can't open tmp file for bsy lock (%s) \"%s\"",ascfnode(addr, 0x1f), tfn); + free(tfn); + return 1; + } - fprintf(fp,"%10d\n", mypid); - fclose(fp); - chmod(tfn, 0440); - if (link(tfn, fn) == 0) { - unlink(tfn); - free(tfn); - return 0; - } else { - sverr=errno; - } + fprintf(fp,"%10d\n", mypid); + fclose(fp); + chmod(tfn, 0440); + if (link(tfn, fn) == 0) { + unlink(tfn); + free(tfn); + return 0; + } else { + sverr = errno; + } - if (sverr != EEXIST) { - WriteError("$Could not link \"%s\" to \"%s\"",tfn,fn); - WriteError("Locking %s failed", ascfnode(addr, 0x1f)); - unlink(tfn); - free(tfn); - return 1; - } + if (sverr != EEXIST) { + WriteError("$Could not link \"%s\" to \"%s\"",tfn,fn); + WriteError("Locking %s failed", ascfnode(addr, 0x1f)); + unlink(tfn); + free(tfn); + return 1; + } - if ((fp=fopen(fn,"r")) == NULL) { - WriteError("$Could not open existing lock file \"%s\"",fn); - WriteError("Locking %s failed", ascfnode(addr, 0x1f)); - unlink(tfn); - free(tfn); - return 1; - } + if ((fp = fopen(fn,"r")) == NULL) { + WriteError("$Could not open existing lock file \"%s\"",fn); + WriteError("Locking %s failed", ascfnode(addr, 0x1f)); + unlink(tfn); + free(tfn); + return 1; + } - /* - * Lock exists, check owner - */ - fscanf(fp, "%d", &tmppid); - pid = tmppid; - fclose(fp); + /* + * Lock exists, check owner + */ + fscanf(fp, "%d", &tmppid); + pid = tmppid; + fclose(fp); - /* - * If lock is our own lock, then it's ok and we are ready. - */ - if (getpid() == pid) { - unlink(tfn); - free(tfn); - return 0; - } + /* + * If lock is our own lock, then it's ok and we are ready. + */ + if (getpid() == pid) { + unlink(tfn); + free(tfn); + return 0; + } - if (kill(pid, 0) && (errno == ESRCH)) { - Syslog('+', "Found stale bsy file for %s, unlink", ascfnode(addr,0x1f)); - unlink(fn); - } else { - Syslog('+', "Node %s is locked by pid %d", ascfnode(addr, 0x1f), pid); - unlink(tfn); - free(tfn); - return 1; - } + /* + * Stale or old lock tests + */ + ltime = file_time(fn); + now = time(NULL); + if (kill(pid, 0) && (errno == ESRCH)) { + Syslog('+', "Found stale bsy file for %s, unlink", ascfnode(addr,0x1f)); + unlink(fn); + } else if (((unsigned long)now - (unsigned long)ltime) > 21600) { + Syslog('+', "Found lock older then 6 hours for %s, unlink", ascfnode(addr,0x1f)); + unlink(fn); + } else { + Syslog('+', "Node %s is locked by pid %d", ascfnode(addr, 0x1f), pid); + unlink(tfn); + free(tfn); + return 1; + } - if (link(tfn,fn) == 0) { - unlink(tfn); - free(tfn); - return 0; - } else { - WriteError("$Could not link \"%s\" to \"%s\"",tfn,fn); - WriteError("Locking %s failed", ascfnode(addr, 0x1f)); - unlink(tfn); - free(tfn); - return 1; - } + if (link(tfn,fn) == 0) { + unlink(tfn); + free(tfn); + return 0; + } else { + WriteError("$Could not link \"%s\" to \"%s\"",tfn,fn); + WriteError("Locking %s failed", ascfnode(addr, 0x1f)); + unlink(tfn); + free(tfn); + return 1; + } } int nodeulock(faddr *addr) { - char *fn; - FILE *fp; - pid_t pid,mypid; - int tmppid; + char *fn; + FILE *fp; + pid_t pid, mypid; + int tmppid; - fn = bsyname(addr); - if ((fp = fopen(fn, "r")) == NULL) { - WriteError("$Can't open lock file (%s) \"%s\"", ascfnode(addr, 0x1f), fn); - return 1; - } + fn = bsyname(addr); + if ((fp = fopen(fn, "r")) == NULL) { + WriteError("$Can't open lock file (%s) \"%s\"", ascfnode(addr, 0x1f), fn); + return 1; + } - fscanf(fp, "%d", &tmppid); - pid = tmppid; - fclose(fp); - mypid = getpid(); + fscanf(fp, "%d", &tmppid); + pid = tmppid; + fclose(fp); + mypid = getpid(); - if (pid == mypid) { - unlink(fn); - return 0; - } else { - WriteError("Unlock (%s) file failed for process %u, we are %u", ascfnode(addr, 0x1f), pid,mypid); - return 1; - } + if (pid == mypid) { + unlink(fn); + return 0; + } else { + WriteError("Unlock (%s) file failed for process %u, we are %u", ascfnode(addr, 0x1f), pid,mypid); + return 1; + } }