home *** CD-ROM | disk | FTP | other *** search
- /*
- ** Patches dos.library functions to allow use of '.' and '..' ala UNIX.
- ** Largely inspired from UnixDirsII from Martin Scott.
- **
- ** List of patched functions :
- **
- ** AssignLate
- ** AssignPath
- ** CreateDir
- ** DeleteFile
- ** LoadSeg
- ** Lock
- ** MakeLink
- ** MatchFirst
- ** NewLoadSeg
- ** Open
- ** ParsePattern
- ** Rename
- ** SetComment
- ** SetFileDate
- ** SetProtection
- **
- ** Author: Gael Marziou
- ** Created: 14 July 94 (Bastille day ;-)
- **
- **
- */
-
- #define __USE_SYSBASE
-
- #include <exec/types.h>
- #include <exec/execbase.h>
- #include <exec/memory.h>
- #include <exec/semaphores.h>
- #include <dos/dos.h>
- #include <libraries/commodities.h>
- #include <string.h>
- #include <proto/dos.h>
- #include <proto/exec.h>
-
- #include "Patch_Libs.h"
- #include "yak.h"
- #include "Settings.h"
-
- /* Local protos */
- SAVEDS BOOL adjustpath(UBYTE *path, UBYTE *newpath, LONG len);
-
- /* The number of 'replacement' functions for UnixDirs feature */
- #define UNIXDIRS_NUMBEROFFUNCTIONS (15)
-
- /* declare stuff for standard one-parameter function */
- /* UBYTE * in d1 */
- #define DEC11_OLD(oldname) LONG (*ASM oldname) (REG(d1) UBYTE *, REG(a6) struct Library *base)
- #define DEC11_NEW(newname) SAVEDS LONG ASM newname(REG(d1) UBYTE *, REG(a6) struct Library *base)
- #define DEC11(name) DEC11_OLD(old## name); DEC11_NEW(new## name); DEC_LVO(LVO## name)
-
- /* declare stuff for standard two-parameter function */
- /* UBYTE * in d1 */
- #define DEC21_OLD(oldname) LONG (*ASM oldname) (REG(d1) UBYTE *, REG(d2) LONG, REG(a6) struct Library *base)
- #define DEC21_NEW(newname) SAVEDS LONG ASM newname(REG(d1) UBYTE *, REG(d2) LONG, REG(a6) struct Library *base)
- #define DEC21(name) DEC21_OLD(old## name); DEC21_NEW(new## name); DEC_LVO(LVO## name)
-
- /* declare stuff for standard two-parameter function */
- /* UBYTE * in d2 */
- #define DEC22_OLD(oldname) LONG (*ASM oldname) (REG(d1) LONG, REG(d2) UBYTE *, REG(a6) struct Library *base)
- #define DEC22_NEW(newname) SAVEDS LONG ASM newname(REG(d1) LONG, REG(d2) UBYTE *, REG(a6) struct Library *base)
- #define DEC22(name) DEC22_OLD(old## name); DEC22_NEW(new## name); DEC_LVO(LVO## name)
-
- /* the patched functions themselves */
- DEC22(AssignLate);
- DEC22(AssignPath);
- DEC11(CreateDir);
- DEC11(DeleteFile);
- DEC11(LoadSeg);
- DEC21(Lock);
- DEC21(MatchFirst);
- DEC21(NewLoadSeg);
- DEC21(Open);
- DEC21(SetComment);
- DEC21(SetFileDate);
- DEC21(SetProtection);
-
-
- /* manually declared, because different from standard */
-
- LONG (*ASM oldMakeLink) (REG(d1) UBYTE *, REG(d2) LONG, REG(d3) LONG, REG(a6) struct Library *);
- SAVEDS LONG ASM newMakeLink(REG(d1) UBYTE *, REG(d2) LONG, REG(d3) LONG, REG(a6) struct Library *);
- extern LVOMakeLink;
-
- LONG (*ASM oldRename) (REG(d1) UBYTE *, REG(d2) UBYTE *, REG(a6) struct Library *);
- SAVEDS LONG ASM newRename(REG(d1) UBYTE *, REG(d2) UBYTE *, REG(a6) struct Library *);
- extern LVORename;
-
- LONG (*ASM oldParsePattern) (REG(d1) UBYTE *, REG(d2) UBYTE *, REG(d3) LONG, REG(a6) struct Library *);
- SAVEDS LONG ASM newParsePattern(REG(d1) UBYTE *, REG(d2) UBYTE *, REG(d3) LONG, REG(a6) struct Library *);
- extern LVOParsePattern;
-
- struct LVOTable LVOArrayUnixDirs[] =
- {
- {(LONG)&LVOCreateDir, (struct Library *)&DOSBase, (ULONG)&oldCreateDir, (ULONG)&newCreateDir },
- {(LONG)&LVODeleteFile, (struct Library *)&DOSBase, (ULONG)&oldDeleteFile, (ULONG)&newDeleteFile },
- {(LONG)&LVOLoadSeg, (struct Library *)&DOSBase, (ULONG)&oldLoadSeg, (ULONG)&newLoadSeg },
-
- {(LONG)&LVOLock, (struct Library *)&DOSBase, (ULONG)&oldLock, (ULONG)&newLock },
- {(LONG)&LVONewLoadSeg, (struct Library *)&DOSBase, (ULONG)&oldNewLoadSeg, (ULONG)&newNewLoadSeg },
- {(LONG)&LVOOpen, (struct Library *)&DOSBase, (ULONG)&oldOpen, (ULONG)&newOpen },
-
- {(LONG)&LVOSetComment, (struct Library *)&DOSBase, (ULONG)&oldSetComment, (ULONG)&newSetComment },
- {(LONG)&LVOSetFileDate, (struct Library *)&DOSBase, (ULONG)&oldSetFileDate, (ULONG)&newSetFileDate },
-
- {(LONG)&LVOSetProtection, (struct Library *)&DOSBase, (ULONG)&oldSetProtection, (ULONG)&newSetProtection },
- {(LONG)&LVOAssignLate, (struct Library *)&DOSBase, (ULONG)&oldAssignLate, (ULONG)&newAssignLate },
- {(LONG)&LVOAssignPath, (struct Library *)&DOSBase, (ULONG)&oldAssignPath, (ULONG)&newAssignPath },
- {(LONG)&LVORename, (struct Library *)&DOSBase, (ULONG)&oldRename, (ULONG)&newRename },
- {(LONG)&LVOMakeLink, (struct Library *)&DOSBase, (ULONG)&oldMakeLink, (ULONG)&newMakeLink },
- {(LONG)&LVOMatchFirst, (struct Library *) & DOSBase, (ULONG)&oldMatchFirst, (ULONG)&newMatchFirst },
- {(LONG)&LVOParsePattern, (struct Library *) & DOSBase, (ULONG)&oldParsePattern, (ULONG)&newParsePattern }
- };
-
-
- struct UnixDirsJumpTable
- {
- struct SignalSemaphore jt_Semaphore;
- UWORD pad_word;
- struct Task *jt_Owner;
- UBYTE jt_Function[UNIXDIRS_NUMBEROFFUNCTIONS * 6];
- };
-
- /* Strings */
- /* The name this JumpTable/Semaphore will get. */
- static UBYTE *UnixDirsJTName = "YakUnixDirs-JT";
-
- static BOOL UnixDirsPatchInstalled = FALSE;
-
-
- __regargs void
- ToggleUnixDirs( BOOL toggle )
- {
- if (toggle == TRUE)
- {
- if (UnixDirsPatchInstalled == FALSE)
- {
- InstallWedge(UnixDirsJTName,
- LVOArrayUnixDirs,
- (UBYTE) UNIXDIRS_NUMBEROFFUNCTIONS);
- UnixDirsPatchInstalled = TRUE;
- }
- }
- else
- {
- if (UnixDirsPatchInstalled == TRUE)
- {
- RemoveWedge(UnixDirsJTName,
- LVOArrayUnixDirs,
- (UBYTE) UNIXDIRS_NUMBEROFFUNCTIONS);
- UnixDirsPatchInstalled = FALSE;
- }
- }
- }
-
-
- /******************************************************************************/
- /******************* **************************/
- /******************* NEW DOS ROUTINES START HERE **************************/
- /******************* **************************/
- /******************************************************************************/
-
- /********************************************
-
- Example of the simplest patch (does nothing)
-
- SAVEDS LONG ASM
- new(REG(d1) LONG arg1, REG(d2) LONG arg2,
- REG(a6) struct Library *base)
- {
- return old(arg1, arg2, base);
- }
-
- ********************************************/
-
- /*
- * These are the generic patch routines.
- * They handle most patches automatically.
- */
-
- #define PATHSIZE 512L /* enough for most purposes? */
-
- /* 1 args, convert arg in d1 */
- LONG ASM Wedge11 (REG(a0) LONG (*ASM dosroutine)(REG(d1) UBYTE *, REG(a6) struct Library *),
- REG(d1) UBYTE *arg1,
- REG(a6) struct Library *base)
- {
- struct SignalSemaphore *jt;
- UBYTE *newpath;
- LONG rc = 0;
-
- if (jt = FindSemaphore(UnixDirsJTName))
- {
- ObtainSemaphoreShared(jt);
-
- if (newpath = AllocVec(PATHSIZE, 0L))
- {
- if (adjustpath(arg1, newpath, PATHSIZE))
- rc = dosroutine(newpath, base);
- else
- rc = dosroutine(arg1, base);
-
- FreeVec(newpath);
- }
- else SetIoErr(ERROR_NO_FREE_STORE);
-
- ReleaseSemaphore(jt);
- }
- return rc;
- }
-
- /* 2 args, convert arg in d1 */
- LONG ASM Wedge21 (REG(a0) LONG (*ASM dosroutine)(REG(d1) UBYTE *, REG(d2) LONG, REG(a6) struct Library *),
- REG(d1) UBYTE *arg1,
- REG(d2) LONG arg2,
- REG(a6) struct Library *base)
- {
- struct SignalSemaphore *jt;
- UBYTE *newpath;
- LONG rc = 0;
-
- if (jt = FindSemaphore(UnixDirsJTName))
- {
- ObtainSemaphoreShared(jt);
-
- if (newpath = AllocVec(PATHSIZE, 0L))
- {
- if (adjustpath(arg1, newpath, PATHSIZE))
- rc = dosroutine(newpath, arg2, base);
- else
- rc = dosroutine(arg1, arg2, base);
- FreeVec(newpath);
- }
- else SetIoErr(ERROR_NO_FREE_STORE);
-
- ReleaseSemaphore(jt);
- }
- return rc;
- }
-
- /* 2 args, convert arg in d2 */
-
- LONG ASM Wedge22 (REG(a0) LONG (*ASM dosroutine)(REG(d1) LONG, REG(d2) UBYTE *, REG(a6) struct Library *),
- REG(d1) LONG arg1,
- REG(d2) UBYTE *arg2,
- REG(a6) struct Library *base)
- {
- struct SignalSemaphore *jt;
- UBYTE *newpath;
- LONG rc = 0;
-
- if (jt = FindSemaphore(UnixDirsJTName))
- {
- ObtainSemaphoreShared(jt);
-
- if (newpath = AllocVec(PATHSIZE, 0L))
- {
- if (adjustpath(arg2, newpath, PATHSIZE))
- rc = dosroutine(arg1, newpath, base);
- else
- rc = dosroutine(arg1, arg2, base);
-
- FreeVec(newpath);
- }
- else SetIoErr(ERROR_NO_FREE_STORE);
-
- ReleaseSemaphore(jt);
- }
- return rc;
- }
-
- #define PATCH11(name) \
- SAVEDS LONG ASM \
- new## name(REG(d1) UBYTE *arg1, \
- REG(a6) struct Library *base) \
- { return Wedge11(old## name, arg1, base); }
-
- #define PATCH21(name) \
- SAVEDS LONG ASM \
- new## name(REG(d1) UBYTE *arg1, REG(d2) LONG arg2, \
- REG(a6) struct Library *base) \
- { return Wedge21(old## name, arg1, arg2, base); }
-
- #define PATCH22(name) \
- SAVEDS LONG ASM \
- new## name(REG(d1) LONG arg1, REG(d2) UBYTE *arg2, \
- REG(a6) struct Library *base) \
- { return Wedge22(old## name, arg1, arg2, base); }
-
- PATCH22(AssignLate)
- PATCH22(AssignPath)
- PATCH11(CreateDir)
- PATCH11(DeleteFile)
- PATCH11(LoadSeg)
- PATCH21(Lock)
- PATCH21(MatchFirst)
- PATCH21(NewLoadSeg)
- PATCH21(Open)
- PATCH21(SetComment)
- PATCH21(SetFileDate)
- PATCH21(SetProtection)
-
- /*** And the following routines are handmade ***/
-
- SAVEDS LONG ASM
- newRename(REG(d1) UBYTE *oldname, REG(d2) UBYTE *newname,
- REG(a6) struct Library *base)
- {
- struct SignalSemaphore *jt;
- UBYTE *from, *to;
- LONG rc = 0;
-
- if (jt = FindSemaphore(UnixDirsJTName))
- {
- ObtainSemaphoreShared(jt);
-
- if (from = AllocVec(PATHSIZE, 0L))
- {
- adjustpath(oldname, from, PATHSIZE);
- if (to = AllocVec(PATHSIZE, 0L))
- {
- adjustpath(newname, to, PATHSIZE);
- rc = oldRename(from, to, base);
- FreeVec(to);
- }
- else SetIoErr(ERROR_NO_FREE_STORE);
- FreeVec(from);
- }
- else SetIoErr(ERROR_NO_FREE_STORE);
-
- ReleaseSemaphore(jt);
- }
- return rc;
- }
-
-
- /* a bit more suspect this; will buflen be big enough given a . substitution? */
- SAVEDS LONG ASM
- newParsePattern(REG(d1) UBYTE *pat,
- REG(d2) UBYTE *buf,
- REG(d3) LONG buflen,
- REG(a6) struct Library *base)
- {
- struct SignalSemaphore *jt;
- UBYTE *newpat;
- LONG rc = 0;
-
- if (jt = FindSemaphore(UnixDirsJTName))
- {
- ObtainSemaphoreShared(jt);
-
- if (newpat = AllocVec(PATHSIZE, 0L))
- {
- adjustpath(pat, newpat, PATHSIZE);
- rc = oldParsePattern(newpat, buf, buflen, base);
- FreeVec(newpat);
- }
- else SetIoErr(ERROR_NO_FREE_STORE);
-
- ReleaseSemaphore(jt);
- }
- return rc;
- }
-
-
- SAVEDS LONG ASM
- newMakeLink (REG(d1) UBYTE *name,
- REG(d2) LONG dest,
- REG(d3) LONG soft,
- REG(a6) struct Library *base)
- {
- struct SignalSemaphore *jt;
- UBYTE *from, *to;
- LONG rc = 0;
-
- if (jt = FindSemaphore(UnixDirsJTName))
- {
- ObtainSemaphoreShared(jt);
-
- if (from = AllocVec(PATHSIZE, 0L))
- {
- adjustpath(name, from, PATHSIZE);
- if (soft)
- {
- /* dest points to a null-terminated path string */
- if (to = AllocVec(PATHSIZE, 0L))
- {
- adjustpath((STRPTR)dest, to, PATHSIZE);
- rc = oldMakeLink(from, (LONG)to, soft, base);
- FreeVec(to);
- }
- else SetIoErr(ERROR_NO_FREE_STORE);
- }
- else
- {
- /* dest is a lock (BPTR) */
- rc = oldMakeLink(from, dest, soft, base);
- }
- FreeVec(from);
- }
- else SetIoErr(ERROR_NO_FREE_STORE);
-
- ReleaseSemaphore(jt);
- }
- return rc;
- }
-
-
-
-
- /*
- * Routine to convert a UNIX-style path to an AmigaDOS path.
- * A UNIX-style path is understood here as follows:
- *
- * leading . means current dir; like "", but filled in explicitly
- * ../ means /
- * .. means /
- *
- * Written as part of UnixDirs2, a (to be written) system patch which allows
- * use of UNIX-style paths everywhere.
- *
- * Martin W. Scott, 8 January 1993
- */
-
-
- /* insert $cwd into s, return pointer to next free char */
- SAVEDS char *
- insertcwd(char *s, LONG len)
- {
- if (NameFromLock(((struct Process *)(((struct ExecBase *)SysBase)->ThisTask))->pr_CurrentDir, s, len))
- {
- while (*s)
- s++;
- }
- return s;
- }
-
- /* adjust path from UNIX-style to Amiga-style */
- /* TO DO: length checking when building new path */
-
- SAVEDS BOOL
- adjustpath(UBYTE *path, UBYTE *newpath, LONG len)
- {
- UBYTE *s, *t;
- char *origpath = path;
-
- s = newpath;
-
- if (path == NULL) /* bypass */
- return FALSE;
-
- if (slashdir && (path[0] == '/'))
- {
- path[0]=':'; /* to accommodate unix-style root paths */
- }
-
- if (t = strchr(path, ':')) /* check for ':' in path */
- {
- t++; /* copy device component */
- while (path < t)
- *s++ = *path++;
- }
- else if (path[0] == '.') /*** translate '.' to $cwd ***/
- {
- if (!path[1]) /* only "." */
- {
- s = insertcwd(s, len);
- path++; /* path[0] == '\0' - STOP */
- }
- else if (path[1] == '/') /* initial component is $cwd */
- {
- s = insertcwd(s, len);
- if (*(s-1) != ':')
- *s++ = '/'; /* copy '/', increment pointers */
- path += 2;
- }
- }
-
- while (path[0]) /*** copy remainder of path ***/
- {
- if ((path[0] == '.') && (path[1] == '.'))
- {
- if (path[2] == '/') /* just skip "..", copying '/' */
- {
- path += 2;
- *s++ = *path++;
- }
- else if (!path[2] ) /* append '/' and stop */
- {
- if ((path == origpath) ||
- (*(path-1) == '/') ||
- (*(path-1) == ':'))
- {
- path += 2;
- *s++ = '/';
- }
- else
- {
- *s++ = *path++;
- *s++ = *path++;
- }
- }
- else *s++ = *path++;
- }
- else *s++ = *path++;
- }
- *s = '\0';
-
- return TRUE;
- }
-