home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 9 Archive / 09-Archive.zip / PAX20.ZIP / DIR_DOS.C < prev    next >
C/C++ Source or Header  |  1990-11-12  |  4KB  |  176 lines

  1. /*
  2.  * @(#)msd_dir.c 1.4 87/11/06    Public Domain.
  3.  *
  4.  *  A public domain implementation of BSD directory routines for
  5.  *  MS-DOS.  Written by Michael Rendell ({uunet,utai}michael@garfield),
  6.  *  August 1897
  7.  *  Modified to use modern library functions by Kai Uwe Rommel
  8.  *  December 1989
  9.  */
  10.  
  11. #include    <sys/types.h>
  12. #include    <sys/stat.h>
  13. #include    <sys/dir.h>
  14. #include    <malloc.h>
  15. #include    <string.h>
  16.  
  17. #include        <dos.h>
  18.  
  19. #ifndef    NULL
  20. # define    NULL    0
  21. #endif    /* NULL */
  22.  
  23. #ifndef    MAXPATHLEN
  24. # define    MAXPATHLEN    255
  25. #endif    /* MAXPATHLEN */
  26.  
  27. /* attribute stuff */
  28. #define    A_RONLY        0x01
  29. #define    A_HIDDEN    0x02
  30. #define    A_SYSTEM    0x04
  31. #define    A_LABEL        0x08
  32. #define    A_DIR        0x10
  33. #define    A_ARCHIVE    0x20
  34.  
  35.  
  36. #define Newisnull(a, t) ((a = (t *) malloc(sizeof(t))) == (t *) NULL)
  37.  
  38. #define ATTRIBUTES      (A_DIR | A_HIDDEN)
  39. /* #define ATTRIBUTES      (A_DIR | A_HIDDEN | A_SYSTEM) */
  40. /* #define ATTRIBUTES      (A_RONLY | A_SYSTEM | A_DIR) */
  41.  
  42. static  char    *getdirent(char *);
  43. static    void    free_dircontents(struct _dircontents *);
  44.  
  45. static struct find_t find;
  46.  
  47.  
  48. DIR    *
  49. opendir(name)
  50.     char    *name;
  51. {
  52.     struct    stat        statb;
  53.     DIR            *dirp;
  54.     char            c;
  55.     char            *s;
  56.     struct _dircontents    *dp;
  57.     char            nbuf[MAXPATHLEN + 1];
  58.  
  59.         strcpy(nbuf, name);
  60.         if ( (c = nbuf[strlen(nbuf) - 1]) == '\\' || c == '/')
  61.           nbuf[strlen(nbuf) - 1] = 0;
  62.  
  63.         if (stat(nbuf, &statb) < 0 || (statb.st_mode & S_IFMT) != S_IFDIR)
  64.         return (DIR *) NULL;
  65.     if (Newisnull(dirp, DIR))
  66.         return (DIR *) NULL;
  67.     if (*name && (c = name[strlen(name) - 1]) != '\\' && c != '/')
  68.         (void) strcat(strcpy(nbuf, name), "\\*.*");
  69.     else
  70.         (void) strcat(strcpy(nbuf, name), "*.*");
  71.     dirp->dd_loc = 0;
  72.         dirp->dd_contents = dirp->dd_cp = (struct _dircontents *) NULL;
  73.  
  74.     if ((s = getdirent(nbuf)) == (char *) NULL)
  75.         return dirp;
  76.     do {
  77.         if (Newisnull(dp, struct _dircontents) || (dp->_d_entry =
  78.             malloc((unsigned) (strlen(s) + 1))) == (char *) NULL)
  79.         {
  80.             if (dp)
  81.                 free((char *) dp);
  82.             free_dircontents(dirp->dd_contents);
  83.             return (DIR *) NULL;
  84.         }
  85.         if (dirp->dd_contents)
  86.             dirp->dd_cp = dirp->dd_cp->_d_next = dp;
  87.         else
  88.             dirp->dd_contents = dirp->dd_cp = dp;
  89.         (void) strcpy(dp->_d_entry, s);
  90.         dp->_d_next = (struct _dircontents *) NULL;
  91.         } while ((s = getdirent((char *) NULL)) != (char *) NULL);
  92.  
  93.     dirp->dd_cp = dirp->dd_contents;
  94.  
  95.     return dirp;
  96. }
  97.  
  98. void
  99. closedir(dirp)
  100.     DIR    *dirp;
  101. {
  102.     free_dircontents(dirp->dd_contents);
  103.     free((char *) dirp);
  104. }
  105.  
  106. struct direct    *
  107. readdir(dirp)
  108.     DIR    *dirp;
  109. {
  110.     static    struct direct    dp;
  111.     
  112.     if (dirp->dd_cp == (struct _dircontents *) NULL)
  113.         return (struct direct *) NULL;
  114.     dp.d_namlen = dp.d_reclen =
  115.         strlen(strcpy(dp.d_name, dirp->dd_cp->_d_entry));
  116.     strlwr(dp.d_name);        /* JF */
  117.     dp.d_ino = 0;
  118.     dirp->dd_cp = dirp->dd_cp->_d_next;
  119.     dirp->dd_loc++;
  120.  
  121.     return &dp;
  122. }
  123.  
  124. void
  125. seekdir(dirp, off)
  126.     DIR    *dirp;
  127.     long    off;
  128. {
  129.     long            i = off;
  130.     struct _dircontents    *dp;
  131.  
  132.     if (off < 0)
  133.         return;
  134.     for (dp = dirp->dd_contents ; --i >= 0 && dp ; dp = dp->_d_next)
  135.         ;
  136.     dirp->dd_loc = off - (i + 1);
  137.     dirp->dd_cp = dp;
  138. }
  139.  
  140. long
  141. telldir(dirp)
  142.     DIR    *dirp;
  143. {
  144.     return dirp->dd_loc;
  145. }
  146.  
  147. static    void
  148. free_dircontents(dp)
  149.     struct    _dircontents    *dp;
  150. {
  151.     struct _dircontents    *odp;
  152.  
  153.     while (dp) {
  154.         if (dp->_d_entry)
  155.             free(dp->_d_entry);
  156.         dp = (odp = dp)->_d_next;
  157.         free((char *) odp);
  158.     }
  159. }
  160.  
  161. static char *getdirent(dir)
  162. char *dir;
  163. {
  164.   int done;
  165.  
  166.   if (dir != (char *) NULL)
  167.     done = _dos_findfirst(dir, ATTRIBUTES, &find);
  168.   else                                  /* get next entry */
  169.     done = _dos_findnext(&find);
  170.  
  171.   if (done==0)
  172.     return find.name;
  173.   else
  174.     return (char *) NULL;
  175. }
  176.