mirror of https://github.com/AR1972/DOS3.3
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
271 lines
5.5 KiB
271 lines
5.5 KiB
#include "types.h"
|
|
#include "dpb.h"
|
|
#include <dos.h>
|
|
|
|
/* #define KANJI TRUE */
|
|
|
|
/* return FALSE if drive is valid AND the path is not a prefix of a non-root
|
|
* current directory.
|
|
*/
|
|
char fPathErr(p)
|
|
char *p ;
|
|
{
|
|
char buf[MAXARG] ;
|
|
int d ;
|
|
#ifdef KANJI
|
|
char *p1;
|
|
#endif
|
|
|
|
if (p[1] == ':')
|
|
d = *p-'A'+1 ;
|
|
else
|
|
d = 0 ;
|
|
|
|
if (curdir(buf, d) == -1) /* drive is invalid => error */
|
|
return(TRUE) ;
|
|
|
|
if (strlen(buf) == 3) /* current directory is root => OK */
|
|
return(FALSE) ;
|
|
|
|
if (strpre(p, buf)) {
|
|
#ifdef KANJI
|
|
p1 = p;
|
|
while (*p1 != NULL) {
|
|
if(testkanj(*p1 & 0xFF))
|
|
p1 += 2 ;
|
|
else
|
|
if((*p1++ == '\\') && (*p1 == NULL))
|
|
return(TRUE) ;
|
|
}
|
|
#else
|
|
if (p[strlen(p)-1] == '\\') /* prefix matched, prefix had...*/
|
|
return(TRUE) ; /* ...trailing / => valid ... */
|
|
/* ...prefix => ERROR */
|
|
#endif
|
|
d = buf[strlen(p)] ;
|
|
if (d == 0 || d == '\\') /* prefix matched,... */
|
|
return(TRUE) ; /* ...prefix had no trailing /, */
|
|
/* ...next char was / => ... */
|
|
/* ...valid prefix => ERROR */
|
|
} ;
|
|
|
|
return(FALSE) ; /* drive letter good and not valid prefix => OK */
|
|
}
|
|
|
|
|
|
strpre(pre, tot)
|
|
char *pre;
|
|
char *tot;
|
|
{
|
|
return(!strncmp(pre, tot, strlen(pre)));
|
|
}
|
|
|
|
|
|
|
|
Fatal(p)
|
|
char *p ;
|
|
{
|
|
printf("%s\n", p) ;
|
|
exit(1) ;
|
|
}
|
|
|
|
|
|
|
|
|
|
ffirst(pb, attr, pfbuf)
|
|
char *pb ;
|
|
int attr ;
|
|
struct findType *pfbuf ;
|
|
{
|
|
union REGS regs ;
|
|
|
|
/* set DMA to point to buffer */
|
|
|
|
regs.h.ah = 0x1A ;
|
|
regs.x.dx = (unsigned) pfbuf ;
|
|
intdos (®s, ®s) ;
|
|
|
|
/* perform system call */
|
|
|
|
regs.h.ah = 0x4E ;
|
|
regs.x.cx = attr ;
|
|
regs.x.dx = (unsigned) pb ;
|
|
intdos (®s, ®s) ;
|
|
|
|
return (regs.x.cflag ? -1 : 0) ;
|
|
}
|
|
|
|
fnext (pfbuf)
|
|
struct findType *pfbuf;
|
|
{
|
|
union REGS regs;
|
|
|
|
/* set DMA to point to buffer */
|
|
regs.h.ah = 0x1A;
|
|
regs.x.dx = (unsigned) pfbuf;
|
|
intdos (®s, ®s);
|
|
/* perform system call */
|
|
regs.h.ah = 0x4F;
|
|
intdos (®s, ®s);
|
|
return (regs.x.cflag ? -1 : 0) ;
|
|
}
|
|
|
|
|
|
char *strbscan(str, class)
|
|
char *str ;
|
|
char *class ;
|
|
{
|
|
char *p ;
|
|
char *strpbrk() ;
|
|
|
|
p = strpbrk(str, class) ;
|
|
return((p == NULL) ? (str + strlen(str)) : p) ;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* curdir.c - return text of current directory for a particular drive */
|
|
|
|
|
|
curdir (dst, drive)
|
|
char *dst ;
|
|
int drive ;
|
|
{
|
|
union REGS regs ;
|
|
|
|
*dst++ = PathChr ;
|
|
regs.h.ah = 0x47 ;
|
|
regs.h.dl = drive ;
|
|
regs.x.si = (unsigned) dst ;
|
|
intdos (®s, ®s) ;
|
|
return(regs.x.cflag ? -1 : 0) ;
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
rootpath
|
|
*/
|
|
|
|
/*** rootpath -- convert a pathname argument to root based cannonical form
|
|
*
|
|
* rootpath determines the current directory, appends the path argument (which
|
|
* may affect which disk the current directory is relative to), and qualifies
|
|
* "." and ".." references. The result is a complete, simple, path name with
|
|
* drive specifier.
|
|
*
|
|
* If the relative path the user specifies does not include a drive spec., the
|
|
* default drive will be used as the base. (The default drive will never be
|
|
* changed.)
|
|
*
|
|
* entry: relpath -- pointer to the pathname to be expanded
|
|
* fullpath -- must point to a working buffer, see warning
|
|
* exit: fullpath -- the full path which results
|
|
* return: true if an error occurs, false otherwise
|
|
*
|
|
* calls: curdir, getdrv
|
|
*
|
|
* warning: fullpath must point to a working buffer large enough to hold the
|
|
* longest possible relative path argument plus the longest possible
|
|
* current directory path.
|
|
*
|
|
*/
|
|
int rootpath(relpath, fullpath)
|
|
char *relpath ;
|
|
char *fullpath ;
|
|
{
|
|
int drivenum ;
|
|
char tempchar, getdrv() ;
|
|
register char *lead, *follow ;
|
|
char *p1, *p2;
|
|
|
|
|
|
/* extract drive spec */
|
|
drivenum = getdrv() ;
|
|
if ((*relpath != NULL) && (relpath[1] == COLON)) {
|
|
drivenum = toupper(*relpath) - 'A' ;
|
|
relpath += 2 ;
|
|
}
|
|
fullpath[0] = (char) ('A' + drivenum) ;
|
|
fullpath[1] = COLON ;
|
|
|
|
/* append relpath to fullpath/base */
|
|
if (*relpath == PathChr) {
|
|
/* relpath starts at base */
|
|
strcpy(fullpath+2, relpath) ;
|
|
}
|
|
else {
|
|
/* must get base path first */
|
|
if (curdir(fullpath+2, drivenum+1))
|
|
return(TRUE) ; /* terrible error */
|
|
if ((*relpath != ASCNULL) && (strlen(fullpath) > 3))
|
|
strcat(fullpath, "\\") ;
|
|
strcat(fullpath, relpath) ;
|
|
}
|
|
|
|
|
|
/* convert path to cannonical form */
|
|
lead = fullpath ;
|
|
while(*lead != ASCNULL) {
|
|
/* mark next path segment */
|
|
follow = lead ;
|
|
lead = (char *) strpbrk(follow+1, "\\") ;
|
|
if (lead == NULL)
|
|
lead = fullpath + strlen(fullpath) ;
|
|
tempchar = *lead ;
|
|
if (tempchar == PathChr)
|
|
tempchar = BACKSLASH ; /* make breaks uniform */
|
|
*lead = ASCNULL ;
|
|
|
|
/* "." segment? */
|
|
if (strcmp(follow+1, ".") == 0) {
|
|
*lead = tempchar ;
|
|
strcpy(follow, lead) ; /* remove "." segment */
|
|
lead = follow ;
|
|
}
|
|
|
|
/* ".." segment? */
|
|
else if (strcmp(follow+1, "..") == 0) {
|
|
*lead = tempchar ;
|
|
tempchar = *follow ;
|
|
*follow = NULL ;
|
|
p2 = fullpath - 1 ;
|
|
while(*(p2=strbscan(p1=p2+1,"\\")) != NULL) ;
|
|
/* p1 now points to the start of the previous element */
|
|
*follow = tempchar ;
|
|
if(p1 == fullpath)
|
|
return(TRUE) ; /* tried to .. the root */
|
|
follow = p1 - 1 ; /* follow points to path sep */
|
|
strcpy(follow, lead) ; /* remove ".." segment */
|
|
lead = follow ;
|
|
}
|
|
|
|
/* normal segment */
|
|
else
|
|
*lead = tempchar ;
|
|
}
|
|
if (strlen(fullpath) == 2) /* 'D:' or some such */
|
|
strcat(fullpath, "\\") ;
|
|
|
|
/* shift to upper case */
|
|
strupr(fullpath) ;
|
|
|
|
return(FALSE) ;
|
|
}
|
|
|
|
|
|
/* getdrv - return current drive as a character */
|
|
|
|
|
|
char getdrv()
|
|
{
|
|
union REGS regs ;
|
|
|
|
regs.h.ah = CURDISK ; /* Function 0x19 */
|
|
intdos (®s, ®s) ;
|
|
return(regs.h.al) ;
|
|
}
|
|
|