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 */
- /* | . |// */
- /* ====== */
- /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-
- #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
-