home *** CD-ROM | disk | FTP | other *** search
- /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
- /* |_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;
- }
-