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
/
handler.h
< prev
next >
Wrap
C/C++ Source or Header
|
1989-08-09
|
17KB
|
451 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 */
/* | . |// */
/* ====== */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include <exec/types.h>
#include <exec/nodes.h>
#include <exec/lists.h>
#include <exec/ports.h>
#include <exec/libraries.h>
#include <exec/devices.h>
#include <exec/io.h>
#include <exec/memory.h>
#include <exec/interrupts.h>
#include <devices/console.h>
#include <devices/timer.h>
#include <devices/trackdisk.h>
#include <intuition/intuition.h>
#include <libraries/dos.h>
#include <libraries/dosextens.h>
#include <libraries/filehandler.h>
#include <string.h>
#include <stdlib.h>
#ifdef MANX
#define U_ARGS(a) () /* No support for prototypes - oh well */
#else
#define U_ARGS(a) a /* prototype checking to ensure all is well */
#include <proto/exec.h>
#include <proto/dos.h>
#endif
/* Unfortunately the 4.1 memcmp doesn't seem to work correctly so just */
/* tell the compiler not to use the builtin function */
#ifdef memcmp
#undef memcmp
int memcmp(char *, char *, int);
#endif
#ifndef min
#define min(a,b) ((a)<(b)?(a):(b))
#endif
#undef GLOBAL
/* my version of BADDR() has no problems with casting */
#undef BADDR
#define BADDR(x) ((APTR)((long)x << 2))
#define MKBADDR(x) ((BPTR)((long)x >> 2))
#define ACTION_FIND_WRITE 1004L
#define ACTION_FIND_INPUT 1005L /* please refer to DOS Tech. Ref. */
#define ACTION_FIND_OUTPUT 1006L
#define ACTION_END 1007L
#define ACTION_SEEK 1008L
#ifndef ACTION_MORE_CACHE
#define ACTION_MORE_CACHE 18L
#endif
#ifndef ACTION_FLUSH
#define ACTION_FLUSH 27L
#endif
#define ACTION_SET_FILE_DATE 34L
#define ACTION_SET_RAW_MODE 994L
#define DOS_FALSE 0L
#define DOS_TRUE -1L /* BCPL "TRUE" */
typedef long KEY;
typedef int (*fptr)();
/* handler support routines */
#define BUFSIZE 488
#define BLOCKSIZE 488
/* We define this because the AmigaDos one is so deficient in types */
struct EFileHandle {
struct EFileHandle *efh_Next; /* Next efh in system. */
long efh_CurPos; /* Current position in block */
KEY efh_CurKey; /* Key of current block */
long efh_CurBlock; /* Sequence number of current block */
struct FileLock *efh_Lock; /* Lock of file to be accessed */
long efh_CurExtBlock; /* Current extension block number */
KEY efh_ExtBlockKey; /* Key of current extension block */
long efh_Protect; /* Current protection attributes */
};
typedef struct EFileHandle *EFH;
/* We define this because the AmigaDos one is so deficient in types */
struct XFileHandle {
struct Message *fh_Link; /* Not used - for user to link on his list */
struct MsgPort *fh_Port; /* Reply port for packet */
struct MsgPort *fh_Type; /* Process ID of handler process */
char *fh_Buf; /* Buffer for file I/O */
char *fh_Pos; /* Current position in buffer */
char *fh_End; /* Pointer to end of buffer */
fptr fh_Funcs; /* Function to call to fill buffer */
fptr fh_Func2; /* Function to call to empty buffer */
fptr fh_Func3; /* Function to call when file is closed */
EFH fh_Args; /* For Internal Use - Root of file */
LONG fh_Arg2; /* For Internal Use - Block of Current pos */
};
#define FileHandle XFileHandle
#define BLOCKSPERENTRY 72
#define HASHTABLESIZE 72
#define COMMENTSIZE 23
#define NAMESIZE 16*4
#define VOLNAMESIZE 13*4
#define BITMAPSIZE 26
struct DirBlock
{
long db_Type;
long db_OwnKey;
long db_HighSeq; /* Highest Sequence number */
long db_HashTableSize;
long db_FirstData;
long db_CheckSum;
long db_HashTable[HASHTABLESIZE];
long db_Spare1; /* Start of bitmap pages on root */
long db_Spare2;
long db_Protect; /* Protection bits */
long db_Size;
long db_Comment[COMMENTSIZE];
long db_Days;
long db_Minutes;
long db_Ticks;
char db_Name[NAMESIZE];
long db_HashChain;
long db_Parent;
long db_Extension;
long db_SecondaryType;
};
struct FileBlock
{
long fb_Type;
long fb_OwnKey;
long fb_HighSeq;
long fb_DataBlockCount;
long fb_FirstData;
long fb_CheckSum;
long fb_DataBlock[BLOCKSPERENTRY];
long fb_Spare1;
long fb_Spare2;
long fb_Protect;
long fb_Size;
long fb_Comment[COMMENTSIZE];
long fb_Days;
long fb_Minutes;
long fb_Ticks;
char fb_Name[NAMESIZE];
long fb_HashChain;
long fb_Parent;
long fb_Extension;
long fb_SecondaryType;
};
struct RootBlock
{
long rb_Type;
long rb_OwnKey; /* Always Zero */
long rb_HighSeq; /* Highest Sequence number */
long rb_HashTableSize;
long rb_fill1;
long rb_CheckSum;
long rb_HashTable[HASHTABLESIZE];
long rb_BitMapFlag;
long rb_BitMapPages[BITMAPSIZE];
long rb_AltDays;
long rb_AltMinutes;
long rb_AltTicks;
char rb_Name[VOLNAMESIZE];
long rb_CreateDays;
long rb_CreateMinutes;
long rb_CreateTicks;
long rb_HashChain;
long rb_Parent;
long rb_Extension;
long rb_SecondaryType;
};
struct DataBlock
{
long db_Type;
long db_Header;
long db_SeqNum;
long db_DataSize;
long db_NextData;
long db_CheckSum;
long db_Data[122];
};
/* Primary types that appear as first longword in a block */
#define T_SHORT 2 /* Primary type - Root, UserDir, FileHeader blocks */
#define T_LONG 4 /* Unused - indicates long files */
#define T_DATA 8 /* Primary type for Data blocks */
#define T_LIST 16 /* Primary type for file list blocks */
#define T_DELETED 1 /* Bit to indicate a deleted block */
/* Secondary types that appear as the last longword in a block */
#define ST_ROOT 1 /* Secondary type for root block */
#define ST_USERDIR 2 /* Secondary type for a user directory */
#define ST_FILE -3 /* Secondary type for a file */
#define ST_BITMAP 99 /* Bitmap type for checksum */
#define OLDFILE 8
#define NEWFILE 16
#ifdef DEBUG
/* Debugging routines */
void myputbstr U_ARGS((char *,));
void myputlstr U_ARGS((char *,));
void myprintf U_ARGS((char *,));
void xwrite U_ARGS((char *, int));
int sprintf U_ARGS((char *, char *,));
#define BUG(a) myprintf a;
#define BUGBSTR(a,b) myputbstr(a,b);
#define BUGLSTR(a,b,c) myputlstr(a,b,c);
#else
#define BUG(a)
#define BUGBSTR(a,b)
#define BUGLSTR(a,b,c)
#endif
extern struct DosLibrary *DOSBase;
#define alloc(a,b) DosAllocMem(a,b)
#define free(p) DosFreeMem(p)
typedef struct TimerPacket {
struct timerequest tm_req;
struct DosPacket tm_pkt;
};
typedef struct DskChngPacket {
struct IOExtTD dc_req;
struct Interrupt dc_int;
};
typedef struct DiskEnvironment {
ULONG de_sizeblock;
ULONG de_blkspertrk;
ULONG de_reservedblks;
ULONG de_numblks;
ULONG de_lowcyl;
ULONG de_uppercyl;
ULONG de_numbufs;
ULONG de_membuftype;
};
typedef struct BlockBuffer{
char *bb_blk; /* ptr to data buffer associated */
UBYTE bb_used; /* used flag */
UBYTE bb_priority; /* blk priority */
UBYTE bb_dirty; /* dirty minded blk */
ULONG bb_key; /* key associated with this block */
};
typedef struct Bitmap {
SHORT bm_blocks; /* number of disk blocks required */
SHORT bm_dirty; /* bitmap modification flag */
ULONG *bm_bitmap; /* pointer to bitmap in memory */
};
typedef struct global
{
struct DosPacket *pkt; /* the packet we are processing */
struct TimerPacket *timerpkt; /* pkt used for timer request */
struct timerequest *systimepkt; /* pkt for getting the current time */
struct DskChngPacket *dskchngpkt; /* pkt used for diskchange */
struct DeviceNode *node; /* our device node */
struct DeviceList *volume; /* currently mounted volume */
struct Process *self; /* my process */
struct MsgPort *port; /* our message port */
struct DiskEnvironment dskenv; /* stuff need for the device */
struct BlockBuffer *blkbuf; /* ptr to allocated blks for buffers */
struct Bitmap bitmap; /* ptr to bitmap data */
struct IOExtTD *devreq; /* device io request pointer */
struct MsgPort *devport; /* msg port for device io */
EFH AllHandles; /* Chain of all known file handles */
char *devname; /* pointer to device name */
long ErrorCount; /* Error count for current volume */
long DiskChange; /* Current disk change number */
long Root; /* Root block on current volume */
KEY prevkey; /* Previous key in a search */
int run; /* flag to continue running */
int reply; /* flag to inhibit replying to message */
long diskstatus; /* Status of disk in the drive */
long diskstate; /* Status of disk in the drive */
long unitnum; /* Unit number of drive */
long changedisk; /* Flag to indicate a disk change */
UBYTE deviotimeout; /* device io timeout for r/w */
/* These are the fields of the autorequest structure we want to create */
struct IntuiText line1; /* Top Line of requester */
struct IntuiText line2; /* Second Line of requester */
struct IntuiText line3; /* Bottom Line of requester */
struct IntuiText retrytxt; /* Retry information */
struct IntuiText canceltxt; /* CANCEL information */
char buf3[16]; /* Buffer to hold unit information */
}* GLOBAL;
/* Routines in buff.c called directly from io.c */
int initbuf U_ARGS((GLOBAL, int, int));
void termbuf U_ARGS((GLOBAL, EFH));
/* Bitmap.c */
int AllocBitMap U_ARGS((GLOBAL));
int FreeBitMap U_ARGS((GLOBAL));
int CountBlocks U_ARGS((GLOBAL));
void DoCheckSum U_ARGS((GLOBAL,char *));
void WriteBitMap U_ARGS((GLOBAL));
void SetBlock U_ARGS((GLOBAL,KEY));
void FreeBlock U_ARGS((GLOBAL, KEY));
KEY AllocateBlock U_ARGS((GLOBAL, KEY, int /* type */));
/* file.c */
void ActDelete U_ARGS((GLOBAL, struct DosPacket *));
void ActRename U_ARGS((GLOBAL, struct DosPacket *));
void ActSetComment U_ARGS((GLOBAL, struct DosPacket *));
void ActSetProtection U_ARGS((GLOBAL, struct DosPacket *));
/* io.c */
void ActFindwrite U_ARGS((GLOBAL, struct DosPacket *));
void ActFindin U_ARGS((GLOBAL, struct DosPacket *));
void ActFindout U_ARGS((GLOBAL, struct DosPacket *));
void ActEnd U_ARGS((GLOBAL, struct DosPacket *));
void ActRead U_ARGS((GLOBAL, struct DosPacket *));
void ActWrite U_ARGS((GLOBAL, struct DosPacket *));
void ActSeek U_ARGS((GLOBAL, struct DosPacket *));
int unsafe U_ARGS((GLOBAL, EFH, int));
/* dir.c */
void ActCreateDir U_ARGS((GLOBAL, struct DosPacket *));
void ActExamine U_ARGS((GLOBAL, struct DosPacket *));
void ActExNext U_ARGS((GLOBAL, struct DosPacket *));
void ActParent U_ARGS((GLOBAL, struct DosPacket *));
/* databuff.c */
char *GetBlock U_ARGS((GLOBAL, KEY));
char *ModBlock U_ARGS((GLOBAL, KEY));
int FindBuffer U_ARGS((GLOBAL,KEY, long));
int AllocBlkBuffs U_ARGS((GLOBAL, long));
void FreeBlkBuffs U_ARGS((GLOBAL));
void FlushOne U_ARGS((GLOBAL,long));
void FlushBuffers U_ARGS((GLOBAL,KEY));
/* Subs.c */
struct DosPacket *taskwait U_ARGS((GLOBAL));
void initdebug U_ARGS((void));
void retpkt U_ARGS((GLOBAL, struct DosPacket *));
char *DosAllocMem U_ARGS((GLOBAL, long));
void DosFreeMem U_ARGS((char *));
/* Disk.c */
int AddDskChngInt U_ARGS((GLOBAL));
void RemDskChngInt U_ARGS((GLOBAL));
int Motor U_ARGS((GLOBAL, int));
int ResetDrive U_ARGS((GLOBAL));
int ReadPhy U_ARGS((GLOBAL, char *, KEY));
int WritePhy U_ARGS((GLOBAL, char *, KEY));
void demanddisk U_ARGS((GLOBAL));
/* mount.c */
void DisMount U_ARGS((GLOBAL));
void Mount U_ARGS((GLOBAL));
/* lock.c */
long GetKey U_ARGS((struct global *,struct FileLock *));
struct FileLock *CreateLock U_ARGS((GLOBAL, KEY, long));
void freelock U_ARGS((GLOBAL, struct FileLock *));
void ActLock U_ARGS((GLOBAL, struct DosPacket *));
void ActDupLock U_ARGS((GLOBAL, struct DosPacket *));
void ActUnLock U_ARGS((GLOBAL, struct DosPacket *));
/* Process.c */
void ActDie U_ARGS((GLOBAL, struct DosPacket *));
void ActInhibit U_ARGS((GLOBAL, struct DosPacket *));
void ActFlush U_ARGS((GLOBAL, struct DosPacket *));
void ActTimer U_ARGS((GLOBAL, struct DosPacket *));
/* volume.c */
void ActCurentVol U_ARGS((GLOBAL, struct DosPacket *));
void ActRenameDisk U_ARGS((GLOBAL, struct DosPacket *));
void ActDiskInfo U_ARGS((GLOBAL, struct DosPacket *));
void ActInfo U_ARGS((GLOBAL, struct DosPacket *));
void GetVolInfo U_ARGS((GLOBAL, struct InfoData *));
/* device.c */
int GetDevice U_ARGS((GLOBAL, struct FileSysStartupMsg *));
int InitDevice U_ARGS((GLOBAL));
int TermDevice U_ARGS((GLOBAL));
/* inhibit.c */
int inhibit U_ARGS((struct MsgPort *, long));
long sendpkt U_ARGS((struct MsgPort *, long, long*, long));
/* timer.c */
int OpenTimer U_ARGS((GLOBAL));
void PostTimerReq U_ARGS((GLOBAL));
void GetDateStamp U_ARGS((GLOBAL, struct DateStamp *));
void MakeDateStamp U_ARGS((struct timeval *, struct DateStamp *));
/* dos1_2.c */
int IsSameName U_ARGS((char *, char *, int));
KEY NextKey U_ARGS((GLOBAL, KEY, struct FileInfoBlock *, KEY));
KEY ParentKey U_ARGS((GLOBAL, KEY));
int hash U_ARGS((char *, int));
int parse U_ARGS((char **, int *, char *));
long GetProtect U_ARGS((GLOBAL, KEY));
int SetProtect U_ARGS((GLOBAL, KEY, long /*Protection*/));
int GetType U_ARGS((GLOBAL, KEY));
int SetCommentStr U_ARGS((GLOBAL, KEY, char *));
int GetInfo U_ARGS((GLOBAL, KEY, struct FileInfoBlock *));
KEY FindDir U_ARGS((GLOBAL, KEY, char **, int *));
KEY FindEntry U_ARGS((GLOBAL, KEY, char *, int));
KEY MakeEntry U_ARGS((GLOBAL, KEY, char *, int, int));
KEY LocateEntry U_ARGS((GLOBAL, KEY, char * /* Name */));
KEY CreateEntry U_ARGS((GLOBAL, KEY, char * /* Name */,
int /* Mode */, int /* Type */));
int FreeDataChain U_ARGS((GLOBAL, KEY));
KEY SeekDataChain U_ARGS((GLOBAL, EFH, long));
KEY AppendDataChain U_ARGS((GLOBAL, EFH, long));
long GetFileSize U_ARGS((GLOBAL, EFH));
int UpdateFile U_ARGS((GLOBAL, EFH, long, long));
void GETDATA U_ARGS((char *, long, char *, long));
void PUTDATA U_ARGS((char *, long, char *, long));
KEY BlockKey U_ARGS((GLOBAL, EFH, long, int));
void SetDateInfo U_ARGS((GLOBAL, struct DirBlock *));
KEY GetParent U_ARGS((GLOBAL, KEY));
int GetExtInfo U_ARGS((GLOBAL, KEY, struct ExtInfoBlock *));
int SetExtInfo U_ARGS((GLOBAL, KEY, struct ExtInfoBlock *));
int FreeDirEntry U_ARGS((GLOBAL, KEY));
int RenameDisk U_ARGS((GLOBAL, char *));
int DeleteEntry U_ARGS((GLOBAL, KEY, char *));
int RenameEntry U_ARGS((GLOBAL, KEY, KEY, char *, char *));
KEY LinkDir U_ARGS((GLOBAL, KEY, KEY, int));
/* Directory/File level maintainence */
KEY MakeEntry U_ARGS((GLOBAL,KEY, char *, int, int));
KEY NextDataBlock U_ARGS((GLOBAL, KEY));
/* Requester routine */
int request U_ARGS((GLOBAL, int, char *));
#define REQ_MUST 0
#define REQ_ERROR 1
#define REQ_GENERAL 2