home *** CD-ROM | disk | FTP | other *** search
/ Simtel MSDOS - Coast to Coast / simteldosarchivecoasttocoast2.iso / c / rootpath.c < prev    next >
C/C++ Source or Header  |  1994-03-04  |  3KB  |  133 lines

  1. #include <string.h>
  2. #include <dos.h>
  3.  
  4. /* CurrentDir - return text of current directory for a particular drive */
  5.  
  6.  
  7. CurrentDir (dst, drive)
  8. char *dst ;
  9. int drive ;
  10. {
  11.     union REGS regs;
  12.  
  13.     *dst++ = '\\';
  14.     regs.h.ah = 0x47;
  15.     regs.h.dl = drive;
  16.     regs.x.si = (unsigned) dst;
  17.     intdos(®s, ®s);
  18.     return (regs.x.cflag ? -1 : 0);
  19. }
  20.  
  21.  
  22. /*** rootpath  --  convert a pathname argument to root based cannonical form
  23.  *
  24.  * rootpath determines the current directory, appends the path argument (which
  25.  * may affect which disk the current directory is relative to), and qualifies
  26.  * "." and ".." references.  The result is a complete, simple, path name with
  27.  * drive specifier.
  28.  *
  29.  * If the relative path the user specifies does not include a drive spec., the
  30.  * default drive will be used as the base.  (The default drive will never be
  31.  * changed.)
  32.  *
  33.  *  entry: relpath  -- pointer to the pathname to be expanded
  34.  *         fullpath -- must point to a working buffer, see warning
  35.  *   exit: fullpath -- the full path which results
  36.  * return: true if an error occurs, false otherwise
  37.  *
  38.  * calls: CurrentDir getdrv
  39.  *
  40.  * warning: fullpath must point to a working buffer large enough to hold the
  41.  *          longest possible relative path argument plus the longest possible
  42.  *          current directory path.
  43.  *
  44.  */
  45. int rootpath(relpath, fullpath)
  46. char *relpath ;
  47. char *fullpath ;
  48. {
  49.     int drivenum ;
  50.     char tempchar, getdrv() ; 
  51.     register char *lead, *follow ;
  52.  
  53.  
  54.     /* extract drive spec */
  55.     drivenum = getdrv() ;
  56.     if ((*relpath != '\0') && (relpath[1] == ':')) {
  57.         drivenum = toupper(*relpath) - 'A' ;
  58.         relpath += 2 ;
  59.     }
  60.     fullpath[0] = (char) ('A' + drivenum) ;
  61.     fullpath[1] = ':' ;
  62.  
  63.     /* append relpath to fullpath/base */
  64.     if (*relpath == '\\') {
  65.         /* relpath starts at base */
  66.         strcpy(fullpath+2, relpath) ;
  67.     } else {
  68.         /* must get base path first */
  69.         if (CurrentDir(fullpath+2, drivenum+1))
  70.             return 1;            /* terrible error */
  71.         if ((*relpath != '\0') && (strlen(fullpath) > 3))
  72.             strcat(fullpath, "\\") ;
  73.         strcat(fullpath, relpath) ;
  74.     }
  75.  
  76.     
  77.     /* convert path to cannonical form */
  78.     lead = fullpath ;
  79.     while(*lead != '\0') {
  80.         /* mark next path segment */
  81.         follow = lead ;
  82.         lead = (char *) strchr(follow+1, '\\') ;
  83.         if (!lead)
  84.             lead = fullpath + strlen(fullpath) ;
  85.         tempchar = *lead ;
  86.         if (tempchar == '\\')
  87.             tempchar = '\\';    /* make breaks uniform */
  88.         *lead = '\0';
  89.  
  90.         /* "." segment? */
  91.         if (strcmp(follow+1, ".") == 0) {
  92.             *lead = tempchar ;
  93.             strcpy(follow, lead);    /* remove "." segment */
  94.             lead = follow ;
  95.         }
  96.  
  97.         /* ".." segment? */
  98.         else if (strcmp(follow+1, "..") == 0) {
  99.             *lead = tempchar ;
  100.             do {
  101.                 if (--follow < fullpath)
  102.                     return 1;
  103.             } while (*follow != '\\') ;
  104.             strcpy(follow, lead);        /* remove ".." segment */
  105.             lead = follow ;
  106.         }
  107.  
  108.         /* normal segment */
  109.         else
  110.             *lead = tempchar ;
  111.     }
  112.     if (strlen(fullpath) == 2)    /* 'D:' or some such */
  113.         strcat(fullpath, "\\") ;
  114.  
  115.     /* shift to upper case */
  116.     strupr(fullpath) ;
  117.  
  118.     return 0;
  119. }
  120.  
  121.  
  122. /* getdrv - return current drive as a character */
  123.  
  124.  
  125. char getdrv()
  126. {
  127.     union REGS regs ;
  128.  
  129.     regs.h.ah = 0x19;
  130.     intdos (®s, ®s) ;
  131.     return(regs.h.al) ;
  132. }
  133.