home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / perl / os2perl / director.c < prev    next >
C/C++ Source or Header  |  1991-03-20  |  5KB  |  251 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 <stdlib.h>
  17. #include <stdio.h>
  18. #include <malloc.h>
  19. #include <string.h>
  20. #include <ctype.h>
  21.  
  22. #define INCL_NOPM
  23. #include <os2.h>
  24.  
  25.  
  26. #ifndef PERLGLOB
  27. int attributes = A_DIR | A_HIDDEN;
  28.  
  29.  
  30. static char *getdirent(char *);
  31. static void free_dircontents(struct _dircontents *);
  32.  
  33. static HDIR hdir;
  34. static USHORT count;
  35. static FILEFINDBUF find;
  36. static BOOL lower;
  37.  
  38.  
  39. DIR *opendir(char *name)
  40. {
  41.   struct stat statb;
  42.   DIR *dirp;
  43.   char c;
  44.   char *s;
  45.   struct _dircontents *dp;
  46.   char nbuf[MAXPATHLEN + 1];
  47.  
  48.   strcpy(nbuf, name);
  49.  
  50.   if ( ((c = nbuf[strlen(nbuf) - 1]) == '\\' || c == '/') &&
  51.        (strlen(nbuf) > 1) )
  52.   {
  53.     nbuf[strlen(nbuf) - 1] = 0;
  54.  
  55.     if ( nbuf[strlen(nbuf) - 1] == ':' )
  56.       strcat(nbuf, "\\.");
  57.   }
  58.   else
  59.     if ( nbuf[strlen(nbuf) - 1] == ':' )
  60.       strcat(nbuf, ".");
  61.  
  62.   if (stat(nbuf, &statb) < 0 || (statb.st_mode & S_IFMT) != S_IFDIR)
  63.     return NULL;
  64.  
  65.   if ( (dirp = malloc(sizeof(DIR))) == NULL )
  66.     return NULL;
  67.  
  68.   if ( nbuf[strlen(nbuf) - 1] == '.' )
  69.     strcpy(nbuf + strlen(nbuf) - 1, "*.*");
  70.   else
  71.     if ( ((c = nbuf[strlen(nbuf) - 1]) == '\\' || c == '/') &&
  72.          (strlen(nbuf) == 1) )
  73.       strcat(nbuf, "*.*");
  74.     else
  75.       strcat(nbuf, "\\*.*");
  76.  
  77.   dirp -> dd_loc = 0;
  78.   dirp -> dd_contents = dirp -> dd_cp = NULL;
  79.  
  80.   if ((s = getdirent(nbuf)) == NULL)
  81.     return dirp;
  82.  
  83.   do
  84.   {
  85.     if (((dp = malloc(sizeof(struct _dircontents))) == NULL) ||
  86.         ((dp -> _d_entry = malloc(strlen(s) + 1)) == NULL)      )
  87.     {
  88.       if (dp)
  89.         free(dp);
  90.       free_dircontents(dirp -> dd_contents);
  91.  
  92.       return NULL;
  93.     }
  94.  
  95.     if (dirp -> dd_contents)
  96.       dirp -> dd_cp = dirp -> dd_cp -> _d_next = dp;
  97.     else
  98.       dirp -> dd_contents = dirp -> dd_cp = dp;
  99.  
  100.     strcpy(dp -> _d_entry, s);
  101.     dp -> _d_next = NULL;
  102.  
  103.     dp -> _d_size = find.cbFile;
  104.     dp -> _d_mode = find.attrFile;
  105.     dp -> _d_time = *(unsigned *) &(find.ftimeLastWrite);
  106.     dp -> _d_date = *(unsigned *) &(find.fdateLastWrite);
  107.   }
  108.   while ((s = getdirent(NULL)) != NULL);
  109.  
  110.   dirp -> dd_cp = dirp -> dd_contents;
  111.  
  112.   return dirp;
  113. }
  114.  
  115.  
  116. void closedir(DIR * dirp)
  117. {
  118.   free_dircontents(dirp -> dd_contents);
  119.   free(dirp);
  120. }
  121.  
  122.  
  123. struct direct *readdir(DIR * dirp)
  124. {
  125.   static struct direct dp;
  126.  
  127.   if (dirp -> dd_cp == NULL)
  128.     return NULL;
  129.  
  130.   dp.d_namlen = dp.d_reclen =
  131.     strlen(strcpy(dp.d_name, dirp -> dd_cp -> _d_entry));
  132.  
  133.   dp.d_ino = 0;
  134.  
  135.   dp.d_size = dirp -> dd_cp -> _d_size;
  136.   dp.d_mode = dirp -> dd_cp -> _d_mode;
  137.   dp.d_time = dirp -> dd_cp -> _d_time;
  138.   dp.d_date = dirp -> dd_cp -> _d_date;
  139.  
  140.   dirp -> dd_cp = dirp -> dd_cp -> _d_next;
  141.   dirp -> dd_loc++;
  142.  
  143.   return &dp;
  144. }
  145.  
  146.  
  147. void seekdir(DIR * dirp, long off)
  148. {
  149.   long i = off;
  150.   struct _dircontents *dp;
  151.  
  152.   if (off >= 0)
  153.   {
  154.     for (dp = dirp -> dd_contents; --i >= 0 && dp; dp = dp -> _d_next);
  155.  
  156.     dirp -> dd_loc = off - (i + 1);
  157.     dirp -> dd_cp = dp;
  158.   }
  159. }
  160.  
  161.  
  162. long telldir(DIR * dirp)
  163. {
  164.   return dirp -> dd_loc;
  165. }
  166.  
  167.  
  168. static void free_dircontents(struct _dircontents * dp)
  169. {
  170.   struct _dircontents *odp;
  171.  
  172.   while (dp)
  173.   {
  174.     if (dp -> _d_entry)
  175.       free(dp -> _d_entry);
  176.  
  177.     dp = (odp = dp) -> _d_next;
  178.     free(odp);
  179.   }
  180. }
  181.  
  182.  
  183. static
  184. #endif
  185. int IsFileSystemFAT(char *dir)
  186. {
  187.   USHORT nDrive;
  188.   ULONG lMap;
  189.   BYTE bData[64], bName[3];
  190.   USHORT cbData;
  191.  
  192.   if ( _osmode == DOS_MODE )
  193.     return TRUE;
  194.   else
  195.   {
  196.     /* We separate FAT and HPFS file systems here.
  197.      * Filenames read from a FAT system are converted to lower case
  198.      * while the case of filenames read from a HPFS (and other future
  199.      * file systems, like Unix-compatibles) is preserved.
  200.      */
  201.  
  202.     if ( isalpha(dir[0]) && (dir[1] == ':') )
  203.       nDrive = toupper(dir[0]) - '@';
  204.     else
  205.       DosQCurDisk(&nDrive, &lMap);
  206.  
  207.     bName[0] = (char) (nDrive + '@');
  208.     bName[1] = ':';
  209.     bName[2] = 0;
  210.  
  211.     cbData = sizeof(bData);
  212.  
  213.     if ( !DosQFSAttach(bName, 0U, 1U, bData, &cbData, 0L) )
  214.       return !strcmp(bData + (*(USHORT *) (bData + 2) + 7), "FAT");
  215.     else
  216.       return FALSE;
  217.  
  218.     /* End of this ugly code */
  219.   }
  220. }
  221.  
  222. #ifndef PERLGLOB
  223. static char *getdirent(char *dir)
  224. {
  225.   int done;
  226.  
  227.   if (dir != NULL)
  228.   {                       /* get first entry */
  229.     lower = IsFileSystemFAT(dir);
  230.  
  231.     hdir = HDIR_CREATE;
  232.     count = 1;
  233.     done = DosFindFirst(dir, &hdir, attributes,
  234.             &find, sizeof(find), &count, 0L);
  235.   }
  236.   else                       /* get next entry */
  237.     done = DosFindNext(hdir, &find, sizeof(find), &count);
  238.  
  239.   if ( lower )
  240.     strlwr(find.achName);
  241.  
  242.   if (done == 0)
  243.     return find.achName;
  244.   else
  245.   {
  246.     DosFindClose(hdir);
  247.     return NULL;
  248.   }
  249. }
  250. #endif
  251.