Xinu7/contrib/distodt/src/lock.c

Compare this file to the similar file:
Show the results in this format:

/*---------------------------------------------------------------------------
 * lock.c
 * 	This file contains routines for locking (really reserving)
 * 	a machine, for finding out who owns the lock, and for releasing
 *	a lock.
 * 	Note: we are using 'cooperative' locking, so that we really
 *  	aren't locking at all; anyone can unlock any backend machine,
 *  	which makes this code trivial; it just deletes the file if it
 *  	exists.
 *---------------------------------------------------------------------------
 */

#include <stdio.h>
#include <sys/file.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <sys/timeb.h>

#include "../h/bed.h"

/*---------------------------------------------------------------------------
 * getlock(user, host, backend)
 * 	char *user, *host, *backend;
 *
 * get the lock on the backend machine for user@host, if possible.
 * if a) no one holds the lock, or
 *    b) user@host holds the lock,
 * SYSOK is returned, else SYSERR (i.e. someone else holds the lock,
 * or the user holds it at a different host).
 *---------------------------------------------------------------------------
 */
int getlock(user, host, backend)
char *user, *host, *backend;
{
	FILE *fs;
	char filename[256];
	struct stat statbuf;
	char buf[256];
	char *atsign;
	int fd;
	int flags;
	
	strcpy(filename, BASEDIR);
	strcat(filename, backend);

	flags = O_CREAT | O_TRUNC | O_WRONLY | O_EXCL;
	if (stat(filename, &statbuf) < 0) {   /* no file, so make it */
		if ((fd = open(filename, flags, 0666)) < 0)
		    return(SYSERR);
		sprintf(buf, "%s@%s", user, host);
		write(fd, buf, strlen(buf));
		close(fd);
		return(SYSOK);
	}

	flags = O_RDONLY;
	fd = open(filename, flags, 0666);
	fs = fdopen(fd, "r");
	flock(fd, LOCK_SH);
	fscanf(fs, "%s", buf);
	close(fd);
	atsign = strchr(buf, '@');
	
	*atsign = '\0';
	
	if (strcmp(buf, user)) {
		return(SYSERR);    /* someone else holds it */
	}
	
	return(SYSOK);   /* the joker already has it */
	
}


/*---------------------------------------------------------------------------
 * unlock(backend)
 * 	char *backend;
 *
 * release the lock on the backend machine.
 *---------------------------------------------------------------------------
 */
int unlock(backend)
char *backend;
{
	char filename[256];
	struct stat statbuf;
	int fd;
	
	strcpy(filename, BASEDIR);
	strcat(filename, backend);
	
	if (stat(filename, &statbuf) < 0) {   /* machine already unlocked */
		return(SYSERR);
	}

	fd = open(filename, O_RDONLY, 0666);
	flock(fd, LOCK_EX);		/* wait for exclusive use	*/
	unlink(filename);
	
	return(SYSOK);   /* always succeeds */
	
}


/*---------------------------------------------------------------------------
 * checklock(user, host, backend, idletime)
 * 	char *user, *host, *backend, *idletime;
 *
 * check who is using the backend, return user@host, else if noone holds
 * the lock, then return nobody@nowhere
 *---------------------------------------------------------------------------
 */
int checklock(user, host, backend, idletime)
char *user, *host, *backend, *idletime;
{
	FILE *fs;
	int fd;
	char filename[256];
	struct stat statbuf;
	char buf[256];
	char *atsign;
	long curtime;
	long modtime;
	long notusedtime;
	int hours;
	int minutes;
	int seconds;
	

	strcpy(filename, BASEDIR);
	strcat(filename, backend);
	
	if (stat(filename, &statbuf) < 0) {   /* no file, so make it */
		strcpy(user, NOBODY);
		strcpy(host, NOWHERE);
		strcpy(idletime, "00:00:00");
		return(SYSOK);
	}

	modtime = statbuf.st_mtime;
	curtime = time(0);
	notusedtime = curtime - modtime;
	hours = (int) (notusedtime / 3600);
	notusedtime = notusedtime % 3600;
	minutes = (int) (notusedtime / 60);
	seconds = (int) (notusedtime % 60);

	sprintf(idletime, "%02d:%02d:%02d", hours, minutes, seconds);


	if ((fd = open(filename, O_RDONLY, 0666)) < 0)
	    return(SYSERR);
	fs = fdopen(fd, "r");
	flock(fd, LOCK_SH);
	fscanf(fs, "%s", buf);
	fclose(fs);

	atsign = strchr(buf, '@');
	
	*atsign = '\0';

	strcpy(user, buf);
	strcpy(host, atsign+1);

	return(SYSOK);  
	
}



/*---------------------------------------------------------------------------
 * touchlock(backend)
 * 	char *backend;
 *
 * touch the lock file so the access time is modified
 *---------------------------------------------------------------------------
 */
touchlock(backend)
char *backend;
{
	FILE *fs;
	int fd;
	char filename[256];
	struct stat statbuf;
	char buf[256];

	strcpy(filename, BASEDIR);
	strcat(filename, backend);
	
	if (stat(filename, &statbuf) < 0) {   /* no file to touch */
		return(SYSOK);
	}

	/* open and read/write file - this modifies the modify time */
	fd = open(filename, O_RDONLY, 0666);
	fs = fdopen(fd, "r");
	flock(fd, LOCK_SH);
	fscanf(fs, "%s", buf);
	fclose(fs);

	fd = open(filename, O_CREAT|O_TRUNC|O_WRONLY, 0666);
	fs = fdopen(fd, "w+");
	flock(fd, LOCK_EX);		/* wait for exclusive use	*/
	fprintf(fs, "%s", buf);
	fclose(fs);
	
	return(SYSOK);  
	
}