/*--------------------------------------------------------------------*/
/* l o c k . c */
/* */
/* Locking functions for UUPC/extended */
/* */
/* Copyright (c) 1992 by Kendra Electronic Wonderworks; all */
/* rights reserved except those explicitly granted by the */
/* UUPC/extended license. */
/*--------------------------------------------------------------------*/
/*--------------------------------------------------------------------*/
/* RCS Information */
/*--------------------------------------------------------------------*/
/*
* $Id: LOCK.C 1.8 1993/04/11 00:31:04 ahd Exp $
*
* Revision history:
* $Log: LOCK.C $
* Revision 1.8 1993/04/11 00:31:04 ahd
* Global edits for year, TEXT, etc.
*
* Revision 1.7 1993/03/24 01:57:30 ahd
* Add string.h include
*
* Revision 1.6 1993/03/06 22:48:23 ahd
* Allow nested locks
*
* Revision 1.5 1992/11/28 19:51:16 ahd
* Issue lock based on lock file existence to avoid FOPEN retry loop
*
* Revision 1.4 1992/11/19 02:58:54 ahd
* drop rcsid
*
* Revision 1.3 1992/11/19 02:54:47 ahd
* Revision 1.2 1992/11/17 13:47:30 ahd
* Do not buffer lock file
*
* Revision 1.1 1992/11/16 05:00:26 ahd
* Initial revision
*
*/
/*--------------------------------------------------------------------*/
/* Standard library include files */
/*--------------------------------------------------------------------*/
#include
#include
#include
#include
#include
#include
/*--------------------------------------------------------------------*/
/* UUPC/extended include files */
/*--------------------------------------------------------------------*/
#include "lib.h"
#include "dater.h"
#include "stater.h"
#include "lock.h"
#include "hlib.h"
#include "import.h"
/*--------------------------------------------------------------------*/
/* Define current file name */
/*--------------------------------------------------------------------*/
currentfile();
/*--------------------------------------------------------------------*/
/* Local variables */
/*--------------------------------------------------------------------*/
static FILE *locket = NULL;
static char lname[FILENAME_MAX];
boolean locked = FALSE;
/*--------------------------------------------------------------------*/
/* L o c k S y s t e m */
/* */
/* Get the lock for a system */
/*--------------------------------------------------------------------*/
boolean LockSystem( const char *system , long program )
{
time_t age;
char fname[FILENAME_MAX];
char *extension;
/*--------------------------------------------------------------------*/
/* Don't lock unless in multitask mode */
/*--------------------------------------------------------------------*/
if ( ! bflag[ F_MULTITASK ] )
return TRUE;
/*--------------------------------------------------------------------*/
/* Verify our lock is not already in use */
/*--------------------------------------------------------------------*/
if ( locket != NULL )
{
printmsg(0,
"LockSystem: Attempt to lock %s with lock file %s already open",
system,
lname );
panic();
} /* if */
/*--------------------------------------------------------------------*/
/* Try to get the lock */
/*--------------------------------------------------------------------*/
switch( program )
{
case B_NEWS:
extension = "LCN";
break;
case B_UUSTAT:
extension = "LCS";
break;
case B_UUCICO:
extension = "LCK";
break;
case B_UUXQT:
extension = "LCX";
break;
default:
extension = "LCZ";
break;
} /* switch */
sprintf( fname,
"%s/locks.lck/%.8s.%s",
E_spooldir,
system,
extension );
importpath( lname, fname, system );
/*--------------------------------------------------------------------*/
/* Determine if the lock exists, and unlink it if so. If this */
/* fails, we can't get the lock, so we return gracefully. */
/* (This allows to bypass the "helpful" FOPEN retries of the */
/* failed open. */
/*--------------------------------------------------------------------*/
if ( access( lname, 0 ) || !unlink( lname ))
locket = FOPEN( lname, "w",TEXT_MODE );
if ( locket == NULL )
{
long size;
age = stater( lname, &size );
printmsg(1, "System %s already locked since %s",
system,
(size > 0) ? dater( age, NULL ) : "UNKNOWN" );
return FALSE;
}
setvbuf( locket, NULL, _IONBF, 0);
time( &age );
fprintf( locket, "%s locked by process %ld at %s",
system, (long) getpid(), ctime( &age ));
fflush( locket ); /* Force the file to exist on disk */
/*--------------------------------------------------------------------*/
/* We don't close the file, since the open file *is* the lock */
/*--------------------------------------------------------------------*/
locked = TRUE;
return TRUE;
} /* LockSystem */
/*--------------------------------------------------------------------*/
/* U n l o c k S y s t e m */
/* */
/* Release a lock created by LockSystem */
/*--------------------------------------------------------------------*/
void UnlockSystem( void )
{
/*--------------------------------------------------------------------*/
/* Don't lock unless in multitask mode */
/*--------------------------------------------------------------------*/
if ( ! bflag[ F_MULTITASK ] )
return;
/*--------------------------------------------------------------------*/
/* Verify we hold a lock */
/*--------------------------------------------------------------------*/
if ( locket == NULL )
{
printmsg(0,"UnlockSystem: No lock held");
panic();
} /* if */
/*--------------------------------------------------------------------*/
/* Release the lock */
/*--------------------------------------------------------------------*/
fclose( locket );
locket = NULL;
locked = FALSE;
unlink( lname );
} /* UnlockSystem */
/*--------------------------------------------------------------------*/
/* P u s h L o c k */
/* */
/* Save lock status in order to perform second lock */
/*--------------------------------------------------------------------*/
void PushLock( LOCKSTACK *top )
{
top->locket = locket;
if ( locket != NULL )
{
strcpy( top->lname, lname );
locket = NULL;
}
locked = FALSE;
}
/*--------------------------------------------------------------------*/
/* P o p L o c k */
/* */
/* Restore previous lock information */
/*--------------------------------------------------------------------*/
void PopLock( LOCKSTACK *top )
{
locket = top->locket;
if ( locket != NULL )
{
strcpy( lname, top->lname );
locked = TRUE;
}
} /* PopLock */