#include <string.h>
#include <dos.h>

/* CurrentDir - return text of current directory for a particular drive */


CurrentDir (dst, drive)
char *dst ;
int drive ;
{
	union REGS regs;

	*dst++ = '\\';
	regs.h.ah = 0x47;
	regs.h.dl = drive;
	regs.x.si = (unsigned) dst;
	intdos(&regs, &regs);
	return (regs.x.cflag ? -1 : 0);
}


/*** 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: CurrentDir 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 ;


	/* extract drive spec */
	drivenum = getdrv() ;
	if ((*relpath != '\0') && (relpath[1] == ':')) {
		drivenum = toupper(*relpath) - 'A' ;
		relpath += 2 ;
	}
	fullpath[0] = (char) ('A' + drivenum) ;
	fullpath[1] = ':' ;

	/* append relpath to fullpath/base */
	if (*relpath == '\\') {
		/* relpath starts at base */
		strcpy(fullpath+2, relpath) ;
	} else {
		/* must get base path first */
		if (CurrentDir(fullpath+2, drivenum+1))
			return 1;			/* terrible error */
		if ((*relpath != '\0') && (strlen(fullpath) > 3))
			strcat(fullpath, "\\") ;
		strcat(fullpath, relpath) ;
	}

	
	/* convert path to cannonical form */
	lead = fullpath ;
	while(*lead != '\0') {
		/* mark next path segment */
		follow = lead ;
		lead = (char *) strchr(follow+1, '\\') ;
		if (!lead)
			lead = fullpath + strlen(fullpath) ;
		tempchar = *lead ;
		if (tempchar == '\\')
			tempchar = '\\';	/* make breaks uniform */
		*lead = '\0';

		/* "." segment? */
		if (strcmp(follow+1, ".") == 0) {
			*lead = tempchar ;
			strcpy(follow, lead);	/* remove "." segment */
			lead = follow ;
		}

		/* ".." segment? */
		else if (strcmp(follow+1, "..") == 0) {
			*lead = tempchar ;
			do {
				if (--follow < fullpath)
					return 1;
			} while (*follow != '\\') ;
			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 0;
}


/* getdrv - return current drive as a character */


char getdrv()
{
    union REGS regs ;

    regs.h.ah = 0x19;
    intdos (&regs, &regs) ;
    return(regs.h.al) ;
}