home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Professional / OS2PRO194.ISO / os2 / packer / lharc / sources / dir.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-02-03  |  4.1 KB  |  209 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.  
  47.   strcpy(nbuf, name);
  48.  
  49.   if ( ((c = nbuf[strlen(nbuf) - 1]) == '\\' || c == '/') &&
  50.        (strlen(nbuf) > 1) )
  51.   {
  52.     nbuf[strlen(nbuf) - 1] = 0;
  53.  
  54.     if ( nbuf[strlen(nbuf) - 1] == ':' )
  55.       strcat(nbuf, "\\.");
  56.   }
  57.   else
  58.     if ( nbuf[strlen(nbuf) - 1] == ':' )
  59.       strcat(nbuf, ".");
  60.  
  61.   if (stat(nbuf, &statb) < 0 || (statb.st_mode & S_IFMT) != S_IFDIR)
  62.     return NULL;
  63.  
  64.   if ( (dirp = malloc(sizeof(DIR))) == NULL )
  65.     return NULL;
  66.  
  67.   if ( nbuf[strlen(nbuf) - 1] == '.' )
  68.     strcpy(nbuf + strlen(nbuf) - 1, "*.*");
  69.   else
  70.     if ( ((c = nbuf[strlen(nbuf) - 1]) == '\\' || c == '/') &&
  71.          (strlen(nbuf) == 1) )
  72.       strcat(nbuf, "*.*");
  73.     else
  74.       strcat(nbuf, "\\*.*");
  75.  
  76.   dirp -> dd_loc = 0;
  77.   dirp -> dd_contents = dirp -> dd_cp = NULL;
  78.  
  79.   if ((s = getdirent(nbuf)) == NULL)
  80.     return dirp;
  81.  
  82.   do
  83.   {
  84.     if (((dp = malloc(sizeof(struct _dircontents))) == NULL) ||
  85.         ((dp -> _d_entry = malloc(strlen(s) + 1)) == NULL)      )
  86.     {
  87.       if (dp)
  88.         free(dp);
  89.       free_dircontents(dirp -> dd_contents);
  90.  
  91.       return NULL;
  92.     }
  93.  
  94.     if (dirp -> dd_contents)
  95.       dirp -> dd_cp = dirp -> dd_cp -> _d_next = dp;
  96.     else
  97.       dirp -> dd_contents = dirp -> dd_cp = dp;
  98.  
  99.     strcpy(dp -> _d_entry, s);
  100.     dp -> _d_next = NULL;
  101.  
  102.     dp -> _d_size = find.cbFile;
  103.     dp -> _d_mode = find.attrFile;
  104.     dp -> _d_time = *(unsigned *) &(find.ftimeLastWrite);
  105.     dp -> _d_date = *(unsigned *) &(find.fdateLastWrite);
  106.   }
  107.   while ((s = getdirent(NULL)) != NULL);
  108.  
  109.   dirp -> dd_cp = dirp -> dd_contents;
  110.  
  111.   return dirp;
  112. }
  113.  
  114.  
  115. void closedir(DIR * dirp)
  116. {
  117.   free_dircontents(dirp -> dd_contents);
  118.   free(dirp);
  119. }
  120.  
  121.  
  122. struct direct *readdir(DIR * dirp)
  123. {
  124.   static struct direct dp;
  125.  
  126.   if (dirp -> dd_cp == NULL)
  127.     return NULL;
  128.  
  129.   dp.d_namlen = dp.d_reclen =
  130.     strlen(strcpy(dp.d_name, dirp -> dd_cp -> _d_entry));
  131.  
  132.   dp.d_ino = 0;
  133.  
  134.   dp.d_size = dirp -> dd_cp -> _d_size;
  135.   dp.d_mode = dirp -> dd_cp -> _d_mode;
  136.   dp.d_time = dirp -> dd_cp -> _d_time;
  137.   dp.d_date = dirp -> dd_cp -> _d_date;
  138.  
  139.   dirp -> dd_cp = dirp -> dd_cp -> _d_next;
  140.   dirp -> dd_loc++;
  141.  
  142.   return &dp;
  143. }
  144.  
  145.  
  146. void seekdir(DIR * dirp, long off)
  147. {
  148.   long i = off;
  149.   struct _dircontents *dp;
  150.  
  151.   if (off >= 0)
  152.   {
  153.     for (dp = dirp -> dd_contents; --i >= 0 && dp; dp = dp -> _d_next);
  154.  
  155.     dirp -> dd_loc = off - (i + 1);
  156.     dirp -> dd_cp = dp;
  157.   }
  158. }
  159.  
  160.  
  161. long telldir(DIR * dirp)
  162. {
  163.   return dirp -> dd_loc;
  164. }
  165.  
  166.  
  167. static void free_dircontents(struct _dircontents * dp)
  168. {
  169.   struct _dircontents *odp;
  170.  
  171.   while (dp)
  172.   {
  173.     if (dp -> _d_entry)
  174.       free(dp -> _d_entry);
  175.  
  176.     dp = (odp = dp) -> _d_next;
  177.     free(odp);
  178.   }
  179. }
  180.  
  181.  
  182. static char *getdirent(char *dir)
  183. {
  184.   int done;
  185.  
  186.   if (dir != NULL)
  187.   {                       /* get first entry */
  188.     lower = IsFileSystemFAT(dir);
  189.  
  190.     hdir = HDIR_CREATE;
  191.     count = 1;
  192.     done = DosFindFirst(dir, &hdir, attributes,
  193.             &find, sizeof(find), &count, 0L);
  194.   }
  195.   else                       /* get next entry */
  196.     done = DosFindNext(hdir, &find, sizeof(find), &count);
  197.  
  198.   if ( lower )
  199.     strlwr(find.achName);
  200.  
  201.   if (done == 0)
  202.     return find.achName;
  203.   else
  204.   {
  205.     DosFindClose(hdir);
  206.     return NULL;
  207.   }
  208. }
  209.