home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / OSK / SRC / msdos_diskaccess.lzh / MS_DISK_ACCESS / subdir.c < prev    next >
Text File  |  1990-05-10  |  4KB  |  178 lines

  1. /*
  2.  * subdir(), getdir(), get_chain(), reset_dir()
  3.  */
  4.  
  5. #include <stdio.h>
  6. #include "msdos.h"
  7.  
  8. extern int dir_chain[25], dir_start, dir_len, dir_entries, clus_size;
  9. extern char *mcwd;
  10. static char lastpath[MAX_PATH];
  11.  
  12. /*
  13.  * Parse the path names of a sub directory.  Both '/' and '\' are
  14.  * valid separators.  However, the use of '\' will force the operator
  15.  * to use quotes in the command line to protect '\' from the shell.
  16.  * Returns 1 on error.  Attempts to optimize by remembering the last
  17.  * path it parsed
  18.  */
  19.  
  20. int
  21. subdir(name)
  22. char *name;
  23. {
  24.     char *s, *tmp, tbuf[MAX_PATH], *path, *strcpy(), *strcat();
  25.     int code;
  26.     void reset_dir();
  27.                     /* if full pathname */
  28.     if (*name == '/' || *name == '\\')
  29.         strcpy(tbuf, name);
  30.                     /* if relative to MCWD */
  31.     else {
  32.         if (!strlen(name))
  33.             strcpy(tbuf, mcwd);
  34.         else {
  35.             strcpy(tbuf, mcwd);
  36.             strcat(tbuf, "/");
  37.             strcat(tbuf, name);
  38.         }
  39.     }
  40.                     /* if paths are same, do nothing */
  41.     if (!strcmp(tbuf, lastpath))
  42.         return(0);
  43.                     /* not recursive, start at root */
  44.     reset_dir();
  45.     strcpy(lastpath, tbuf);
  46.                     /* zap the leading separator */
  47.     tmp = tbuf;
  48.     if (*tmp == '\\' || *tmp == '/')
  49.         tmp++;
  50.     for (s = tmp; *s; ++s) {
  51.         if (*s == '\\' || *s == '/') {
  52.             path = tmp;
  53.             *s = '\0';
  54.             if (getdir(path))
  55.                 return(1);
  56.             tmp = s+1;
  57.         }
  58.     }
  59.     code = getdir(tmp);
  60.     return(code);
  61. }
  62.  
  63. /*
  64.  * Find the directory and get the starting cluster.  A null directory
  65.  * is ok.  Returns a 1 on error.
  66.  */
  67.  
  68. int
  69. getdir(path)
  70. char *path;
  71. {
  72.     int entry, start;
  73.     char *newname, *unixname(), *strncpy(), name[9], ext[4];
  74.     struct directory *dir, *search();
  75.     void reset_dir(), free();
  76.                     /* nothing required */
  77.     if (*path == '\0')
  78.         return(0);
  79.  
  80.     for (entry=0; entry<dir_entries; entry++) {
  81.         dir = search(entry);
  82.                     /* if empty */
  83.         if (dir->name[0] == 0x0)
  84.             break;
  85.                     /* if erased */
  86.         if (dir->name[0] == 0xe5)
  87.             continue;
  88.                     /* skip if not a directory */
  89.         if (!(dir->attr & 0x10))
  90.             continue;
  91.  
  92.         strncpy(name, (char *) dir->name, 8);
  93.         strncpy(ext, (char *) dir->ext, 3);
  94.         name[8] = '\0';
  95.         ext[3] = '\0';
  96.  
  97.         newname = unixname(name, ext);
  98.         if (!strcmp(newname, path)) {
  99.             start = dir->start[1]*0x100 + dir->start[0];
  100.                     /* if '..' pointing to root */
  101.             if (!start && !strcmp(path, "..")) {
  102.                 reset_dir();
  103.                 return(0);
  104.             }
  105.                     /* fill in the directory chain */
  106.             dir_entries = get_chain(start) * 16;
  107.             return(0);
  108.         }
  109.         free(newname);
  110.     }
  111.                     /* if '.' or '..', must be root */
  112.     if (!strcmp(path, ".") || !strcmp(path, "..")) {
  113.         reset_dir();
  114.         return(0);
  115.     }
  116.     fprintf(stderr, "Path component \"%s\" is not a directory\n", path);
  117.     return(1);
  118. }
  119.  
  120. /*
  121.  * Fill in the global variable dir_chain.  Argument is the starting
  122.  * cluster number.  Info, in this variable is used by search() to 
  123.  * scan a directory.  An arbitrary limit of 25 sectors is placed, this
  124.  * equates to 400 entries.  Returns the number of sectors in the chain.
  125.  */
  126.  
  127. int
  128. get_chain(num)                /* fill the directory chain */
  129. int num;
  130. {
  131.     int i, next;
  132.     void exit();
  133.  
  134.     i = 0;
  135.     while (1) {
  136.         dir_chain[i] = (num - 2)*clus_size + dir_start + dir_len;
  137.                     /* sectors, not clusters! */
  138.         if (clus_size == 2) {
  139.             dir_chain[i+1] = dir_chain[i] + 1;
  140.             i++;
  141.         }
  142.         i++;
  143.         if (i >= 25) {
  144.             fprintf(stderr, "get_chain: directory too large\n");
  145.             exit(1);
  146.         }
  147.                     /* get next cluster number */
  148.         next = getfat(num);
  149.         if (next == -1) {
  150.             fprintf(stderr, "get_chain: FAT problem\n");
  151.             exit(1);
  152.         }
  153.                     /* end of cluster chain */
  154.         if (next >= 0xff8) {
  155.             break;
  156.         }
  157.         num = next;
  158.     }
  159.     return(i);
  160. }
  161.  
  162. /* 
  163.  * Reset the global variable dir_chain to the root directory.
  164.  */
  165.  
  166. void
  167. reset_dir()
  168. {
  169.     register int i;
  170.  
  171.     for (i=0; i<dir_len; i++)
  172.         dir_chain[i] = dir_start + i;
  173.     dir_entries = dir_len * 16;
  174.                     /* disable subdir() optimization */
  175.     lastpath[0] = '\0';
  176.     return;
  177. }
  178.