DOS 3.30 source code leak
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

#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 (&regs, &regs) ;
/* perform system call */
regs.h.ah = 0x4E ;
regs.x.cx = attr ;
regs.x.dx = (unsigned) pb ;
intdos (&regs, &regs) ;
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 (&regs, &regs);
/* perform system call */
regs.h.ah = 0x4F;
intdos (&regs, &regs);
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 (&regs, &regs) ;
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 (&regs, &regs) ;
return(regs.h.al) ;
}