home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Fred Fish Collection 1.5
/
ffcollection-1-5-1992-11.iso
/
ff_disks
/
200-299
/
ff236.lzh
/
DiskHandler
/
lock.c
< prev
next >
Wrap
C/C++ Source or Header
|
1989-08-09
|
6KB
|
226 lines
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* |_o_o|\\ Copyright (c) 1987 The Software Distillery. All Rights Reserved */
/* |. o.| || This program may not be distributed without the permission of */
/* | . | || the authors: BBS: */
/* | o | || John Toebes Dave Baker John Mainwaring */
/* | . |// */
/* ====== */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* Lock.c - lock manipulation */
/* ActLock, ActDupLock, ActUnLock */
/*---------------------------------------------------------------------------*/
/* Structure of a Lock: */
/* struct FileLock { */
/* BPTR fl_Link; Next lock in the chain of device locks */
/* LONG fl_Key; Block number of directory or file header */
/* LONG fl_Access; Shared Read (-2) or Exclusive Write (-1) */
/* struct MsgPort * fl_Task; Handler process for Lock (Us) */
/* BPTR fl_Volume; Node in DevInfo structure for Lock */
/* }; */
/*---------------------------------------------------------------------------*/
#include "handler.h"
long GetKey(global,lock)
struct global *global;
struct FileLock *lock;
{
if (global->volume == NULL)
{
global->pkt->dp_Res2 = ERROR_DEVICE_NOT_MOUNTED;
return(0);
}
if (lock == NULL)
return(global->Root);
return(lock->fl_Key);
}
/* create a lock to be returned */
struct FileLock *CreateLock(global, key, mode)
GLOBAL global;
KEY key;
int mode;
{
struct FileLock *lock;
int access;
lock = NULL;
if (global->volume == NULL)
{
global->pkt->dp_Res2 = ERROR_DEVICE_NOT_MOUNTED;
key = 0;
}
if (key)
{
/* if we are creating a write lock, make sure we can lock the disk */
access = 0;
BUG(("Searching for locks from %08lx\n", BADDR(global->volume->dl_Lock)));
Forbid();
/* Now run through the list of locks for this volume to figure out */
/* What level of access it is currently locked for */
for (lock = (struct FileLock *)BADDR(global->volume->dl_Lock);
lock != NULL && access == 0;
lock = (struct FileLock *)BADDR(lock->fl_Link))
{
/* Does it match what we want to access? */
if (lock->fl_Key == key)
access = lock->fl_Access;
}
Permit();
BUG(("Access outstanding is %ld\n", access));
/* Given the prevailing access mode, see if we will allow the new lock */
switch(mode)
{
case SHARED_LOCK:
if (access == EXCLUSIVE_LOCK)
{
/* Not legal, tell them so... */
global->pkt->dp_Res2 = ERROR_OBJECT_IN_USE;
return(NULL);
}
break;
case EXCLUSIVE_LOCK:
/* Does anyone else have it open? */
if (access)
{
/* Not legal, tell them so... */
global->pkt->dp_Res2 = ERROR_OBJECT_IN_USE;
return(NULL);
}
break;
default:
BUG(("Invalid access %ld requested for key %ld\n", mode, key));
global->pkt->dp_Res2 = ERROR_INVALID_LOCK;
return(NULL);
}
if ((lock = (struct FileLock *)
DosAllocMem(global, sizeof(struct FileLock))) != NULL)
{
BUG(("Creating the lock %08lx for key=%ld\n", lock, key));
/* now fill in the lock */
lock->fl_Key = key;
lock->fl_Access = mode;
lock->fl_Task = global->port;
lock->fl_Volume = MKBADDR(global->volume);
Forbid();
lock->fl_Link = global->volume->dl_Lock;
global->volume->dl_Lock = MKBADDR(lock);
Permit();
BUG(("Task=%08lx Vol=%08lx\n", lock->fl_Task, lock->fl_Volume));
}
}
return(lock);
}
void freelock(global, lock)
GLOBAL global;
struct FileLock *lock;
{
struct FileLock *this;
/* freeing NULL (root lock) is a bad move */
if (lock == NULL)
{
BUG(("NULL Lock\n"));
return;
}
if (global->volume == NULL)
{
global->pkt->dp_Res2 = ERROR_DEVICE_NOT_MOUNTED;
return;
}
/* locate the lock on the global volume list */
Forbid();
if ((this = (struct FileLock *)BADDR(global->volume->dl_Lock)) == lock)
global->volume->dl_Lock = lock->fl_Link;
else
{
while(this != NULL && (struct FileLock *)BADDR(this->fl_Link) != lock)
this = (struct FileLock *)BADDR(this->fl_Link);
if (this == NULL)
/* lock wasn't in chain - don't drop through to free memory */
{
Permit();
BUG(("Lock not found in chain\n"));
return;
}
else
this->fl_Link = lock->fl_Link;
}
Permit();
DosFreeMem((char *)lock);
}
void ActLock(global, pkt)
GLOBAL global;
struct DosPacket *pkt; /* a pointer to the dos packet sent */
/* Arg1: Lock */
/* Arg2: Name */
/* Arg3: Mode: ACCESS_READ, ACCESS_WRITE */
{
KEY key;
struct FileLock *lock;
BUG(("Action Lock\n"));
BUGBSTR("File to lock: ", pkt->dp_Arg2);
key = GetKey(global,(struct FileLock *)pkt->dp_Arg1);
key = LocateEntry(global, key, (char *)pkt->dp_Arg2);
lock = CreateLock(global, key, pkt->dp_Arg3);
BUG(("Lock created at %08lx\n", lock));
pkt->dp_Res1 = MKBADDR(lock);
}
void ActDupLock(global,pkt)
GLOBAL global;
struct DosPacket *pkt; /* a pointer to the dos packet sent */
{
struct FileLock *lock;
BUG(("Action DupLock\n"));
lock = (struct FileLock *)pkt->dp_Arg1;
lock = CreateLock(global, lock->fl_Key, lock->fl_Access);
pkt->dp_Res1 = MKBADDR(lock);
}
void ActUnLock(global, pkt)
GLOBAL global;
struct DosPacket *pkt; /* a pointer to the dos packet sent */
{
struct FileLock *lock;
lock = (struct FileLock *)pkt->dp_Arg1;
BUG(("Action UnLock\n"));
freelock(global, lock);
pkt->dp_Res1 = DOS_TRUE;
}