/*
 * $Copyright:	$
 * Copyright (c) 1984, 1985, 1986, 1987, 1988, 1989, 1990 
 * Sequent Computer Systems, Inc.   All rights reserved.
 *  
 * This software is furnished under a license and may be used
 * only in accordance with the terms of that license and with the
 * inclusion of the above copyright notice.   This software may not
 * be provided or otherwise made available to, or used by, any
 * other person.  No title to or ownership of the software is
 * hereby transferred.
 *
 */

/*	Copyright (c) 1984 AT&T	*/
/*	  All Rights Reserved  	*/

/*	THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T	*/
/*	The copyright notice above does not evidence any   	*/
/*	actual or intended publication of such source code.	*/

#ident	"$Header: lock.c 1.7 90/08/31 $@(#)mailx:lock.c	1.5"
#

/*
 * mailx -- a modified version of a University of California at Berkeley
 *	mail program
 *
 * Stuff to do version 7 style locking.
 */

#include "rcv.h"
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <dirent.h>

extern int errno;
extern char *strrchr();

#ifdef USG
char	*maillock	= ".lock";		/* Lock suffix for mailname */
#else
char	*maillock	= ".mail";		/* Lock suffix for mailname */
#endif
static char		curlock[MAXNAMLEN];		/* Last used name of lock */
static	int		locked;			/* To note that we locked it */

lock(file)
char *file;
{
	int filedes, i, lpid, len;
	FILE *stream;
	char *cptr, buf[10];

	holdsigs();
	if (file == NOSTR) {
		printf(gettxt("mailx:127", "Locked = %d\n"), locked);
		return(0);
	}

	/*
		Cannot lock a file with a basename of more than
		MAXNAMLEN characters
	*/
	if ((cptr = strrchr(file,'/')) != NULL) cptr++;
	else cptr = file;

	if (strlen(cptr) > MAXNAMLEN) {
		fprintf(stderr,gettxt("mailx:236", "mailx: Cannot lock file as length of basename '%s' is > %d characters\n"),cptr,MAXNAMLEN);
		relsesigs();
		return;
	}

	if (locked) {
		relsesigs();
		return;
	}
	strcpy(curlock,file);
	strcat(curlock,maillock);

	/*
		Check to see if lock file exists.

		If it does and it contains the pid of a live process,
		or we fail to read a numeric from the file, leave it 
		alone; else delete the file.
	*/
	if ((stream = fopen(curlock,"r")) != NULL) {

		if (fscanf(stream,"%d",&lpid) == 1)
			if (kill(lpid,0) == -1) 
				(void)unlink(curlock);

		(void)fclose(stream);
	}

	for (i = 0; i < 10; i++) {
		if ((filedes = open(curlock,O_WRONLY | O_CREAT | O_EXCL)) != -1) {
			chmod(curlock,0660);
			len = sprintf(buf,"%d",getpid());
			if (write(filedes,buf,len) != len) {
				close(filedes);
				perror(gettxt("mailx:129", "Error writing lock pid"));
				if ( unlink(curlock) != 0 ) 
					perror(gettxt("mailx:130", "Couldn't unlink lock file"));
				exit(1);
			}
			close(filedes);
			locked = 1;
			relsesigs();
			return;
		}
		sleep(5*(i+1));

	/* 
	   Recheck the contents of the lock file to make sure that
	   the process that created the file is still alive. 
	*/
		if ((stream = fopen(curlock,"r")) != NULL) {
	
			if (fscanf(stream,"%d",&lpid) == 1)
				if (kill(lpid,0) == -1) 
					(void)unlink(curlock);

			(void)fclose(stream);
		}
	}
	fprintf(stderr,gettxt("mailx:131", "mailx: Cannot create lock file\n"));
	exit(1);
}
/*
 * Remove the mail lock, and note that we no longer
 * have it locked.
 */

unlock()
{
	remove(curlock);
	locked = 0;
}
