home *** CD-ROM | disk | FTP | other *** search
/ ARM Club 1 / ARM_CLUB_CD.iso / contents / apps / clib / progs / utilslib / c / Dir < prev    next >
Encoding:
Text File  |  1991-04-20  |  3.6 KB  |  193 lines

  1. /* C.Dir: Directory handling */
  2.  
  3. #include <stddef.h>
  4. #include <stdlib.h>
  5. #include <string.h>
  6. #include "kernel.h"
  7. #include "swis.h"
  8.  
  9. #include "sys/dir.h"
  10.  
  11. #define ReadDir     9
  12.  
  13. /* Constants. The function assumes that a directory can hold no more than
  14.  * MAX_DIR entries, and a filename can be no longer than MAXNAMELEN (which
  15.  * is defined in the header file to be 10 as a default) characters. It also
  16.  * assumes that OS_GBPB 9 will only ever fail to return all possible
  17.  * filenames on the first call if the supplied buffer becomes full. In this
  18.  * case, dirscan() will ignore any omitted entries. This behaviour is not
  19.  * ideal, but gains significantly in efficiency. (The given buffer size
  20.  * should be easily enough for all normal cases).
  21.  */
  22. #define MAX_DIR        255
  23. #define CACHE_SIZE    (MAX_DIR * (MAXNAMELEN + 1))
  24.  
  25. DIR *opendir (char *name)
  26. {
  27.     register char *cache;
  28.     register DIR *dirp;
  29.     _kernel_swi_regs regs;
  30.  
  31.     dirp = malloc(sizeof(DIR));
  32.     if (dirp == 0)
  33.         return NULL;
  34.  
  35.     cache = malloc(CACHE_SIZE);
  36.     if (cache == NULL)
  37.     {
  38.         free(dirp);
  39.         return NULL;
  40.     }
  41.  
  42.     regs.r[0] = ReadDir;
  43.     regs.r[1] = (int) name;
  44.     regs.r[2] = (int) cache;
  45.     regs.r[3] = CACHE_SIZE;
  46.     regs.r[4] = 0;
  47.     regs.r[5] = CACHE_SIZE;
  48.     regs.r[6] = (int) "*";
  49.  
  50.     if (_kernel_swi(OS_GBPB, ®s, ®s))
  51.     {
  52.         free (cache);
  53.         free (dirp);
  54.         return NULL;
  55.     }
  56.  
  57.     dirp->dd_pos = 0;
  58.     dirp->dd_num = regs.r[3];
  59.     dirp->dd_loc = cache;
  60.     dirp->dd_cache = cache;
  61.  
  62.     return dirp;
  63. }
  64.  
  65. struct direct *readdir (DIR *dirp)
  66. {
  67.     register char *from;
  68.     register char *to;
  69.     static struct direct dir;
  70.  
  71.     /* If no more entries, return NULL */
  72.     if (dirp->dd_pos >= dirp->dd_num)
  73.         return NULL;
  74.  
  75.     /* Copy the name into the struct direct */
  76.     to = dir.d_name;
  77.     from = dirp->dd_loc;
  78.     while ((*to++ = *from++) != 0)
  79.         ;
  80.  
  81.     /* Update the DIR structure */
  82.     ++dirp->dd_pos;
  83.     dirp->dd_loc = from;
  84.  
  85.     /* Set up the rest of the struct direct */
  86.     dir.d_ino = 0;
  87.     dir.d_reclen = dir.d_namlen = strlen(dir.d_name);
  88.  
  89.     return &dir;
  90. }
  91.  
  92. extern void closedir (DIR *dirp)
  93. {
  94.     if (dirp != NULL)
  95.     {
  96.         if (dirp->dd_cache != NULL)
  97.             free(dirp->dd_cache);
  98.  
  99.         free(dirp);
  100.     }
  101. }
  102.  
  103. extern int seekdir (DIR *dirp, int pos)
  104. {
  105.     register int old_pos = dirp->dd_pos;
  106.     register int i = 0;
  107.     register char *p = dirp->dd_cache;
  108.  
  109.     while (i < pos)
  110.     {
  111.         while (*p++ != 0)
  112.             ;
  113.         ++i;
  114.     }
  115.  
  116.     dirp->dd_pos = pos;
  117.     dirp->dd_loc = p;
  118.  
  119.     return old_pos;
  120. }
  121.  
  122. /* ---------------------------------------------------------------------- */
  123.  
  124. #ifdef test
  125.  
  126. #include <ctype.h>
  127. #include <stdio.h>
  128.  
  129. #define BUFLEN 255
  130.  
  131. int main (void)
  132. {
  133.     char buf[BUFLEN];
  134.     char s[20];
  135.     int i;
  136.     DIR *dp;
  137.  
  138.     for ( ; ; )
  139.     {
  140.         printf(">");
  141.         fgets(buf,BUFLEN,stdin);
  142.  
  143.         if ( buf[0] == '\n' || buf[0] == '\0' )
  144.             continue;
  145.         else if ( sscanf(buf,"dir %s",&s) == 1 )
  146.             dp = opendir(s);
  147.         else if ( strncmp(buf,"dir",3) == 0 )
  148.             dp = opendir("");
  149.         else if ( sscanf(buf,"goto %d",&i) == 1 )
  150.             printf("From: %d\n",seekdir(dp,i));
  151.         else if ( strncmp(buf,"close",5) == 0 )
  152.             closedir(dp);
  153.         else if ( *buf == 'n' )
  154.         {
  155.             int pos = telldir(dp);
  156.             struct direct *d = readdir(dp);
  157.             if (d)
  158.                 printf("Pos: %d, Name: %s\n", pos, d->d_name);
  159.             else
  160.                 printf("Finished...\n");
  161.         }
  162.         else if ( strncmp(buf,"dump",4) == 0 )
  163.         {
  164.             int max = dp->dd_num * 11;
  165.             char *p = dp->dd_cache;
  166.  
  167.             printf("Pos: %d\n", dp->dd_pos);
  168.             printf("Num: %d\n", dp->dd_num);
  169.             printf("Loc: %p\n", dp->dd_loc);
  170.             printf("Cache: %p\n", dp->dd_cache);
  171.  
  172.             while (p < &dp->dd_cache[max])
  173.             {
  174.                 if (isgraph(*p) || *p == ' ')
  175.                     putchar(*p);
  176.                 else
  177.                     putchar('.');
  178.                 ++p;
  179.             }
  180.         }
  181.         else if ( strncmp(buf,"quit",4) == 0 )
  182.             break;
  183.         else if ( *buf == '*' )
  184.             system(&buf[1]);
  185.         else
  186.             printf("Mistake\n");
  187.     }
  188.  
  189.     return 0;
  190. }
  191.  
  192. #endif
  193.