Xinu7/contrib/distodt/src/releaselock.c

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


/* 
 * releaselock.c - This file contains routines for releasing a lock
 * 
 * Author:	Jim Griffioen
 * 		Dept. of Computer Sciences
 * 		Purdue University
 * Date:	Thu May 26 17:23:44 1988
 *
 * Copyright (c) 1988 Jim Griffioen
 */


#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <signal.h>
#include <errno.h>
#include <setjmp.h>
#include <sys/file.h>
#include <sys/stat.h>
#include <string.h>

#include "../h/utils.h"
#include "../h/bed.h"
#include "../h/bmutils.h"
#include "../h/netutils.h"


extern char *getlogin();		/* sys routine to get login id	*/


/*----------------------------------------------------------------------
 * requnlock - request unlock on remote machine 
 *----------------------------------------------------------------------
 */
requnlock(fename, bename)
char *fename;				/* name of frontend with bename	*/
char *bename;				/* name of backend desired	*/
{
	int i;
	struct bm bm;
	struct lockreq *lreq;
	char *sb;
	char buf[MAXMACHINENAME];
	int sock;

	

					/* make lock request packet	*/
	bm.ver = CURVER;
	sprintf(bm.cmd, "%d", REQ_UNLOCK);
	lreq = (struct lockreq *) bm.detail;
	sb = getlogin();
	strcpy(lreq->uid, sb);
	if (gethostname(buf, MAXMACHINENAME) != 0) {
		strcpy(buf, "dunno");
		fprintf(stderr, "error getting local host name\n");
	}
	strcpy(lreq->hostid, buf);
	strcpy(lreq->bename, bename);

	
	sock = ConnectUdp (fename, KNOWN_UDP_PORT);

	if (bmsend (sock, &bm, lbm, 0) <= 0)
	    SysError ("send");

	bmrecv (sock, &bm, lbm, 0);
	if (atoi(bm.cmd) != RESP_OK)
	    return(SYSERR);
	else
	    return(SYSOK);
}


/*---------------------------------------------------------------------------
 * releaselock - release lock on a backend machine
 *			- release specified backend machine is bename!=""
 *			- else release last machine reservered by user in
 *			  class is class is not ""
 *			- else release last machine used by user
 *---------------------------------------------------------------------------
 */
releaselock(class, bename, remove)
char *class;				/* class to release machine from*/
char *bename;				/* back end to use (out param)	*/
char remove;				/* boolean - remove local lock?	*/
{
	FILE *fs;			/* lock file ptr		*/
	char filename[256];		/* temp filename variable	*/
	struct stat statbuf;		/* status of file struct	*/
	char femachine[MAXMACHINENAME];	/* temp fename str variable	*/
	char bemachine[MAXMACHINENAME];	/* temp bename str variable	*/
	char beclass[CLASSLEN];		/* temp class str variable	*/
	int i, j;			/* counter variable		*/
	struct bm *bm[30];		/* list of status messages	*/
	struct statresp *stresp;	/* temp status response ptr	*/
	struct bestatus *bestat;	/* temp backend status ptr	*/
	int nummach;			/* number of machines		*/
	

	

	strcpy(filename, BASEDIR);
	strcat(filename, getlogin());
		
	if (strlen(bename) == 0) {	/* release machine reserved */
		if (stat(filename, &statbuf) == 0) { /* has mach reserved */
			fs = fopen(filename, "r");
			fscanf(fs, "%s %s %s", femachine, bemachine, beclass);
			fclose(fs);
			if ((strlen(class) == 0) ||
			    (strcmp(class, beclass) == 0)) {
				if (requnlock(femachine, bemachine) == SYSOK) {
					strcpy(bename, bemachine);
					if (remove) {
						if (unlink(filename) != 0) {
							return(SYSERR);
						}
					}
					return(SYSOK);
				}
				else {
					fprintf(stderr, "error unlocking %s\n",
						bemachine);
					if (remove) {
						if (unlink(filename) != 0) {
							return(SYSERR);
						}
					}
					return(SYSERR);
				}
			}
			else {
				fprintf(stderr, "dunno what to do here yet\n");
				return(SYSERR);
			}
		}
		else {
			fprintf(stderr, "no machine reserver\n");
			return(SYSERR);
		}
	}
	
	/* if we get to this point we need to find a particular machine	*/
	nummach = obtainstatus(bm);	/* get status from all machines	*/
	for (i = 0; i < nummach; i++) {
		stresp = (struct statresp *) bm[i]->detail;
		for (j = 0; j < atoi(stresp->festatus.numbends); j++) {
			bestat = &(stresp->bestatus[j]);
			if (strcmp(bename, bestat->bename) == 0) {
				if (requnlock(stresp->festatus.fename,
					    bestat->bename) == SYSOK) {
  					if (remove) {
						fs = fopen(filename, "r");
						fscanf(fs, "%s %s %s", femachine, bemachine, beclass);
						fclose(fs);
						if (strcmp(bemachine,bename) == 0) {
							if (unlink(filename) != 0) {
								return(SYSERR);
							}
						}
					}
					return(SYSOK);
				}
				else {
					fprintf(stderr, "error releasing %s\n", bename);
					return(SYSERR);
				}
			}
		}
	}
	return(SYSERR);
}