home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / SH164X.ZIP / DIR.C < prev    next >
C/C++ Source or Header  |  1991-02-14  |  5KB  |  232 lines

  1. /*
  2.  * @(#)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.  *  Ported to OS/2 by Kai Uwe Rommel
  8.  *  December 1989, February 1990
  9.  *  Change for HPFS support, October 1990
  10.  */
  11.  
  12. #include <sys/types.h>
  13. #include <sys/stat.h>
  14. #include <sys/dir.h>
  15.  
  16. #include <stdio.h>
  17. #include <malloc.h>
  18. #include <string.h>
  19.  
  20. #define INCL_NOPM
  21. #include <os2.h>
  22.  
  23. #include <extlib.h>
  24.  
  25.  
  26. int attributes = A_DIR | A_HIDDEN;
  27.  
  28.  
  29. static char *getdirent(char *);
  30. static void free_dircontents(struct _dircontents *);
  31.  
  32. static HDIR hdir;
  33. static USHORT count;
  34. static FILEFINDBUF find;
  35. static BOOL lower;
  36.  
  37.  
  38. DIR *opendir(char *name)
  39. {
  40.   struct stat statb;
  41.   DIR *dirp;
  42.   char c;
  43.   char *s;
  44.   struct _dircontents *dp;
  45.   char nbuf[MAXPATHLEN + 1];
  46.   int len;
  47.  
  48.   strcpy(nbuf, name);
  49.   len = strlen (nbuf);
  50.   s = nbuf + len;
  51.  
  52. #if 0
  53.   if ( ((c = nbuf[strlen(nbuf) - 1]) == '\\' || c == '/') &&
  54.        (strlen(nbuf) > 1) )
  55.   {
  56.     nbuf[strlen(nbuf) - 1] = 0;
  57.  
  58.     if ( nbuf[strlen(nbuf) - 1] == ':' )
  59.       strcat(nbuf, "\\.");
  60.   }
  61.   else
  62.     if ( nbuf[strlen(nbuf) - 1] == ':' )
  63.       strcat(nbuf, ".");
  64. #else
  65.   if ( len && ((c = nbuf[len-1]) == '\\' || c == '/' || c == ':') )
  66.   {
  67.     nbuf[len++] = '.';      /* s now points to '.' */
  68.     nbuf[len] = 0;
  69.   }
  70. #endif
  71.  
  72.   if (stat(nbuf, &statb) < 0 || (statb.st_mode & S_IFMT) != S_IFDIR)
  73.     return NULL;
  74.  
  75.   if ( (dirp = malloc(sizeof(DIR))) == NULL )
  76.     return NULL;
  77.  
  78. #if 0
  79.   if ( nbuf[strlen(nbuf) - 1] == '.' )
  80.     strcpy(nbuf + strlen(nbuf) - 1, "*.*");
  81.   else
  82.     if ( ((c = nbuf[strlen(nbuf) - 1]) == '\\' || c == '/') &&
  83.          (strlen(nbuf) == 1) )
  84.       strcat(nbuf, "*.*");
  85.     else
  86.       strcat(nbuf, "\\*.*");
  87. #else
  88.   if ( *s == 0 )
  89.     *s++ = '\\';
  90.  
  91.   strcpy (s, "*.*");
  92. #endif
  93.  
  94.   dirp -> dd_loc = 0;
  95.   dirp -> dd_contents = dirp -> dd_cp = NULL;
  96.  
  97.   if ((s = getdirent(nbuf)) == NULL)
  98.     return dirp;
  99.  
  100.   do
  101.   {
  102.     if (((dp = malloc(sizeof(struct _dircontents))) == NULL) ||
  103.         ((dp -> _d_entry = malloc(strlen(s) + 1)) == NULL)      )
  104.     {
  105.       if (dp)
  106.         free(dp);
  107.       free_dircontents(dirp -> dd_contents);
  108.  
  109.       return NULL;
  110.     }
  111.  
  112.     if (dirp -> dd_contents)
  113.     {
  114.       dirp -> dd_cp -> _d_next = dp;
  115.       dirp -> dd_cp = dirp -> dd_cp -> _d_next;
  116.     }
  117.     else
  118.       dirp -> dd_contents = dirp -> dd_cp = dp;
  119.  
  120.     strcpy(dp -> _d_entry, s);
  121.     dp -> _d_next = NULL;
  122.  
  123.     dp -> _d_size = find.cbFile;
  124.     dp -> _d_mode = find.attrFile;
  125.     dp -> _d_time = *(unsigned *) &(find.ftimeLastWrite);
  126.     dp -> _d_date = *(unsigned *) &(find.fdateLastWrite);
  127.   }
  128.   while ((s = getdirent(NULL)) != NULL);
  129.  
  130.   dirp -> dd_cp = dirp -> dd_contents;
  131.  
  132.   return dirp;
  133. }
  134.  
  135.  
  136. void closedir(DIR * dirp)
  137. {
  138.   free_dircontents(dirp -> dd_contents);
  139.   free(dirp);
  140. }
  141.  
  142.  
  143. struct direct *readdir(DIR * dirp)
  144. {
  145.   static struct direct dp;
  146.  
  147.   if (dirp -> dd_cp == NULL)
  148.     return NULL;
  149.  
  150.   dp.d_namlen = dp.d_reclen =
  151.     strlen(strcpy(dp.d_name, dirp -> dd_cp -> _d_entry));
  152.  
  153.   dp.d_ino = 0;
  154.  
  155.   dp.d_size = dirp -> dd_cp -> _d_size;
  156.   dp.d_mode = dirp -> dd_cp -> _d_mode;
  157.   dp.d_time = dirp -> dd_cp -> _d_time;
  158.   dp.d_date = dirp -> dd_cp -> _d_date;
  159.  
  160.   dirp -> dd_cp = dirp -> dd_cp -> _d_next;
  161.   dirp -> dd_loc++;
  162.  
  163.   return &dp;
  164. }
  165.  
  166.  
  167. void seekdir(DIR * dirp, long off)
  168. {
  169.   long i = off;
  170.   struct _dircontents *dp;
  171.  
  172.   if (off >= 0)
  173.   {
  174.     for (dp = dirp -> dd_contents; --i >= 0 && dp; dp = dp -> _d_next);
  175.  
  176.     dirp -> dd_loc = off - (i + 1);
  177.     dirp -> dd_cp = dp;
  178.   }
  179. }
  180.  
  181.  
  182. long telldir(DIR * dirp)
  183. {
  184.   return dirp -> dd_loc;
  185. }
  186.  
  187.  
  188. static void free_dircontents(struct _dircontents * dp)
  189. {
  190.   struct _dircontents *odp;
  191.  
  192.   while (dp)
  193.   {
  194.     if (dp -> _d_entry)
  195.       free(dp -> _d_entry);
  196.  
  197.     dp = (odp = dp) -> _d_next;
  198.     free(odp);
  199.   }
  200. }
  201.  
  202.  
  203. static char *getdirent(char *dir)
  204. {
  205.   int done;
  206.  
  207.   if (dir != NULL)
  208.   {                       /* get first entry */
  209.     lower = IsFileSystemFAT(dir);
  210.  
  211.     hdir = HDIR_CREATE;
  212.     count = 1;
  213.     done = DosFindFirst(dir, &hdir, attributes,
  214.             &find, sizeof(find), &count, 0L);
  215.   }
  216.   else                       /* get next entry */
  217.     done = DosFindNext(hdir, &find, sizeof(find), &count);
  218.  
  219.   if (done == 0)
  220.   {
  221.     if ( lower )
  222.       strlwr(find.achName);
  223.  
  224.     return find.achName;
  225.   }
  226.   else
  227.   {
  228.     DosFindClose(hdir);
  229.     return NULL;
  230.   }
  231. }
  232.