|
|
researchv10 Norman
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "string.h"
#include "mail.h"
/*
* open a file for appending. if the file doesn't exist, create it.
* return the file descriptor.
*/
appendopen(file)
char *file;
{
int out;
long lseek();
lock(file);
out = open(file, 2);
if (out < 0)
out = creat(file, 0666);
else
chmod(file, 0666);
lseek(out, 0L, 2);
return out;
}
/*
* close an append only file
*/
appendclose(fd)
int fd;
{
close(fd);
unlock();
}
/*
* lock and open file. If the file doesn't exist and mode!=0, create it.
* return the file descriptor.
*/
FILE *
lockopen(file, omode, pmode, uid, gid)
char *file;
char *omode;
int pmode;
{
FILE *fp;
struct stat sbuf;
int newfile;
lock(file);
if(stat(file, &sbuf)<0)
newfile = 1;
else
newfile = 0;
fp = fopen(file, omode);
if(fp==NULL){
unlock();
return NULL;
}
if(newfile){
chown(file, uid, gid);
chmod(file, pmode);
}
return fp;
}
/*
* close and unlock a file.
*/
lockclose(fp)
FILE *fp;
{
fclose(fp);
unlock();
}
/*
* reopen a file without losing the lock.
*/
FILE *
lockreopen(file, omode, fp)
char *file;
char *omode;
FILE *fp;
{
return freopen(file, omode, fp);
}
/*
* unlink ALL locks
*/
cleanlocks()
{
unlock();
}
#ifndef lint
static char *sccsid = "@(#)lock.c 1.5 88/02/08 SMI"; /* from S5R2 1.1 */
#endif
/*
* mailx -- a modified version of a University of California at Berkeley
* mail program
*
* Stuff to do version 7 style locking.
*/
char *maillock = ".lock"; /* Lock suffix for mailname */
#ifdef USG
char *lockname = "/usr/mail/tmXXXXXX";
#else
char *lockname = "/usr/spool/mail/tmXXXXXX";
#endif
char locktmp[30]; /* Usable lock temporary */
static char curlock[50]; /* Last used name of lock */
static int locked; /* To note that we locked it */
/*
* Lock the specified mail file by setting the file mailfile.lock.
* We must, of course, be careful to unlink the lock file by a call
* to unlock before we stop. The algorithm used here is to see if
* the lock exists, and if it does, to check its modify time. If it
* is older than 5 minutes, we assume error and set our own file.
* Otherwise, we wait for 5 seconds and try again.
*/
lock(file)
char *file;
{
register int f;
struct stat sbuf;
long curtime;
if (file == (char *)0) {
printf("Locked = %d\n", locked);
return(0);
}
if (locked)
return(0);
strcpy(curlock, file);
strcat(curlock, maillock);
strcpy(locktmp, lockname);
mktemp(locktmp);
unlink(locktmp);
for (;;) {
f = lock1(locktmp, curlock);
if (f == 0) {
locked = 1;
return(0);
}
if (stat(curlock, &sbuf) < 0)
return(0);
time(&curtime);
if (curtime < sbuf.st_ctime + 300) {
sleep(5);
continue;
}
unlink(curlock);
}
}
/*
* Remove the mail lock, and note that we no longer
* have it locked.
*/
unlock()
{
unlink(curlock);
locked = 0;
}
/*
* Attempt to set the lock by creating the temporary file,
* then doing a link/unlink. If it fails, return -1 else 0
*/
lock1(tempfile, name)
char tempfile[], name[];
{
register int fd;
fd = creat(tempfile, 0);
if (fd < 0)
return(-1);
close(fd);
if (link(tempfile, name) < 0) {
unlink(tempfile);
return(-1);
}
unlink(tempfile);
return(0);
}
/* Return true if file has been locked by us or another program using the same
* lock name scheme.
* But remove the lock file if the locking process has gone away.
*/
int
islocked(file)
char *file;
{
char thelock[50];
struct stat sbuf;
long curtime;
strcpy(thelock, file);
strcat(thelock, maillock);
if(locked && strcmp(curlock, thelock)==0)
return(1);
for (;;) {
if (stat(thelock, &sbuf) < 0)
return(0);
time(&curtime);
if (curtime < sbuf.st_ctime + 300) {
sleep(5);
continue;
}
unlink(thelock);
return(0);
}
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.