|
|
researchv10 Norman
/* %W%
*/
#include "uucp.h"
VERSION(%W%);
#ifdef V7
#define O_RDONLY 0
#endif
static void stlock();
static int onelock();
#ifdef ATTSVKILL
/*
* create a lock file (file).
* If one already exists, send a signal 0 to the process--if
* it fails, then unlink it and make a new one.
*
* input:
* file - name of the lock file
* atime - is unused, but we keep it for lint compatibility with non-ATTSVKILL
*
* return:
* 0 -> success
* FAIL -> failure
*/
ulockf(file, atime)
register char *file;
time_t atime;
{
#ifdef ASCIILOCKS
static char pid[SIZEOFPID+2] = { '\0' }; /* +2 for '\n' and NULL */
#else
static int pid = -1;
#endif
static char tempfile[MAXNAMESIZE];
#ifdef V8
char *cp;
#endif
#ifdef ASCIILOCKS
if (pid[0] == '\0') {
(void) sprintf(pid, "%*d\n", SIZEOFPID, getpid());
#else
if (pid < 0) {
pid = getpid();
#endif
(void) sprintf(tempfile, "%s/LTMP.%d", X_LOCKDIR, getpid());
}
#ifdef V8 /* this wouldn't be a problem if we used lock directories */
/* some day the truncation of system names will bite us */
cp = strrchr(file, '/');
if (cp++ != CNULL)
if (strlen(cp) > V8DIRSIZ)
*(cp+V8DIRSIZ) = NULLCHAR;
#endif V8
if (onelock(pid, tempfile, file) == -1) {
(void) unlink(tempfile);
if (checkLock(file))
return(FAIL);
else {
if (onelock(pid, tempfile, file)) {
(void) unlink(tempfile);
DEBUG(4,"ulockf failed in onelock()\n","");
return(FAIL);
}
}
}
stlock(file);
return(0);
}
/*
* check to see if the lock file exists and is still active
* - use kill(pid,0) - (this only works on ATTSV and some hacked
* BSD systems at this time)
* return:
* 0 -> success (lock file removed - no longer active
* FAIL -> lock file still active
*/
checkLock(file)
register char *file;
{
register int ret;
int lpid = -1;
#ifdef ASCIILOCKS
char alpid[SIZEOFPID+2]; /* +2 for '\n' and NULL */
#endif
int fd;
extern int errno;
fd = open(file, O_RDONLY);
DEBUG(4, "ulockf file %s\n", file);
if (fd == -1) {
if (errno == ENOENT) /* file does not exist -- OK */
return(0);
DEBUG(4,"Lock File--can't read (errno %d) --remove it!\n", errno);
goto unlk;
}
#ifdef ASCIILOCKS
ret = read(fd, (char *) alpid, SIZEOFPID+1); /* +1 for '\n' */
(void) close(fd);
if (ret != (SIZEOFPID+1)) {
#else
ret = read(fd, (char *) &lpid, sizeof(int));
(void) close(fd);
if (ret != sizeof(int)) {
#endif
DEBUG(4, "Lock File--bad format--remove it!\n", "");
goto unlk;
}
#ifdef ASCIILOCKS
lpid = atoi(alpid);
#endif
if ((ret=kill(lpid, 0)) == 0 || errno == EPERM) {
DEBUG(4, "Lock File--process still active--not removed\n","");
return(FAIL);
}
else { /* process no longer active */
DEBUG(4, "kill pid (%d), ", lpid);
DEBUG(4, "returned %d", ret);
DEBUG(4, "--ok to remove lock file (%s)\n", file);
}
unlk:
if (unlink(file) != 0) {
DEBUG(4,"ulockf failed in unlink()\n","");
return(FAIL);
}
return(0);
}
#else
/*
* check to see if the lock file exists and is still active
* - consider the lock expired after SLCKTIME seconds.
* return:
* 0 -> success (lock file removed - no longer active
* FAIL -> lock file still active
*/
checkLock(file)
register char *file;
{
register int ret;
int lpid = -1;
int fd;
extern int errno;
struct stat stbuf;
time_t ptime, time();
fd = open(file, 0);
DEBUG(4, "ulockf file %s\n", file);
if (fd == -1) {
if (errno == ENOENT) /* file does not exist -- OK */
return(0);
DEBUG(4,"Lock File--can't read (errno %d) --remove it!\n", errno);
goto unlk;
}
ret = stat(file, &stbuf);
if (ret != -1) {
(void) time(&ptime);
if ((ptime - stbuf.st_ctime) < SLCKTIME) {
/*
* file not old enough to delete
*/
return(FAIL);
}
}
unlk:
DEBUG(4, "--ok to remove lock file (%s)\n", file);
if (unlink(file) != 0) {
DEBUG(4,"ulockf failed in unlink()\n","");
return(FAIL);
}
return(0);
}
/*
* create a lock file (file).
* If one already exists, the create time is checked for
* older than the age time (atime).
* If it is older, an attempt will be made to unlink it
* and create a new one.
* return:
* 0 -> success
* FAIL -> failure
*/
ulockf(file, atime)
register char *file;
time_t atime;
{
register int ret;
struct stat stbuf;
#ifdef ASCIILOCKS
static char pid[SIZEOFPID+2] = { '\0' }; /* +2 for '\n' and null */
#else
static int pid = -1;
#endif
static char tempfile[MAXNAMESIZE];
time_t ptime, time();
#ifdef V8
char *cp;
#endif
#ifdef ASCIILOCKS
if (pid[0] == '\0') {
(void) sprintf(pid, "%*d\n", SIZEOFPID, getpid());
#else
if (pid < 0) {
pid = getpid();
#endif
(void) sprintf(tempfile, "%s/LTMP.%d", X_LOCKDIR, getpid());
}
#ifdef V8 /* this wouldn't be a problem if we used lock directories */
/* some day the truncation of system names will bite us */
cp = strrchr(file, '/');
if (cp++ != CNULL)
if (strlen(cp) > V8DIRSIZ)
*(cp+V8DIRSIZ) = NULLCHAR;
#endif V8
if (onelock(pid, tempfile, file) == -1) {
/*
* lock file exists
* get status to check age of the lock file
*/
(void) unlink(tempfile);
ret = stat(file, &stbuf);
if (ret != -1) {
(void) time(&ptime);
if ((ptime - stbuf.st_ctime) < atime) {
/*
* file not old enough to delete
*/
return(FAIL);
}
}
ret = unlink(file);
ret = onelock(pid, tempfile, file);
if (ret != 0)
return(FAIL);
}
stlock(file);
return(0);
}
#endif
#define MAXLOCKS 10 /* maximum number of lock files */
char *Lockfile[MAXLOCKS];
int Nlocks = 0;
/*
* put name in list of lock files
* return:
* none
*/
static
void
stlock(name)
char *name;
{
register int i;
char *p;
for (i = 0; i < Nlocks; i++) {
if (Lockfile[i] == NULL)
break;
}
ASSERT(i < MAXLOCKS, "TOO MANY LOCKS", "", i);
if (i >= Nlocks)
i = Nlocks++;
p = calloc((unsigned) strlen(name) + 1, sizeof (char));
ASSERT(p != NULL, "CAN NOT ALLOCATE FOR", name, 0);
(void) strcpy(p, name);
Lockfile[i] = p;
return;
}
/*
* remove all lock files in list
* return:
* none
*/
void
rmlock(name)
register char *name;
{
register int i;
#ifdef V8
char *cp;
if (name != CNULL) {
cp = strrchr(name, '/');
if (cp++ != CNULL)
if (strlen(cp) > V8DIRSIZ)
*(cp+V8DIRSIZ) = NULLCHAR;
}
#endif V8
for (i = 0; i < Nlocks; i++) {
if (Lockfile[i] == NULL)
continue;
if (name == NULL || EQUALS(name, Lockfile[i])) {
(void) unlink(Lockfile[i]);
(void) free(Lockfile[i]);
Lockfile[i] = NULL;
}
}
return;
}
/*
* remove a lock file
* return:
* 0 -> success
* FAIL -> failure
*/
delock(s)
char *s;
{
char ln[MAXNAMESIZE];
(void) sprintf(ln, "%s.%s", LOCKPRE, s);
BASENAME(ln, '/')[MAXBASENAME] = '\0';
rmlock(ln);
}
/*
* create system lock
* return:
* 0 -> success
* FAIL -> failure
*/
mlock(sys)
char *sys;
{
char lname[MAXNAMESIZE];
(void) sprintf(lname, "%s.%s", LOCKPRE, sys);
BASENAME(lname, '/')[MAXBASENAME] = '\0';
return(ulockf(lname, SLCKTIME) < 0 ? FAIL : 0);
}
/*
* update access and modify times for lock files
* return:
* none
*/
void
ultouch()
{
register int i;
time_t time();
struct ut {
time_t actime;
time_t modtime;
} ut;
ut.actime = time(&ut.modtime);
for (i = 0; i < Nlocks; i++) {
if (Lockfile[i] == NULL)
continue;
utime(Lockfile[i], &ut);
}
return;
}
/*
* makes a lock on behalf of pid.
* input:
* pid - process id
* tempfile - name of a temporary in the same file system
* name - lock file name (full path name)
* return:
* -1 - failed
* 0 - lock made successfully
*/
static
onelock(pid,tempfile,name)
#ifdef ASCIILOCKS
char *pid;
#else
int pid;
#endif
char *tempfile, *name;
{
register int fd;
char cb[100];
fd=creat(tempfile, 0444);
if(fd < 0){
(void) sprintf(cb, "%s %s %d",tempfile, name, errno);
logent("ULOCKC", cb);
if((errno == EMFILE) || (errno == ENFILE))
(void) unlink(tempfile);
return(-1);
}
#ifdef ASCIILOCKS
(void) write(fd, pid, SIZEOFPID+1); /* +1 for '\n' */
#else
(void) write(fd,(char *) &pid,sizeof(int));
#endif
(void) chmod(tempfile,0444); /* silly */
(void) chown(tempfile, UUCPUID, UUCPGID);
(void) close(fd);
if(link(tempfile,name)<0){
DEBUG(4, "%s: ", sys_errlist[errno]);
DEBUG(4, "link(%s, ", tempfile);
DEBUG(4, "%s)\n", name);
if(unlink(tempfile)< 0){
(void) sprintf(cb, "ULK err %s %d", tempfile, errno);
logent("ULOCKLNK", cb);
}
return(-1);
}
if(unlink(tempfile)<0){
(void) sprintf(cb, "%s %d",tempfile,errno);
logent("ULOCKF", cb);
}
return(0);
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.