home *** CD-ROM | disk | FTP | other *** search
/ Der Mediaplex Sampler - Die 6 von Plex / 6_v_plex.zip / 6_v_plex / DISK6 / OS_15 / SH.ZIP / DIR.C < prev    next >
C/C++ Source or Header  |  1994-01-24  |  5KB  |  270 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.  
  15. #include <stdio.h>
  16. #include <stdlib.h>
  17. #include <string.h>
  18. #include <ctype.h>
  19.  
  20. #define INCL_NOPM
  21. #include <os2.h>
  22.  
  23. #include "dir.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.  
  233.  
  234. int IsFileSystemFAT(char *dir)
  235. {
  236.   USHORT nDrive;
  237.   ULONG lMap;
  238.   BYTE bData[64], bName[3];
  239.   USHORT cbData;
  240.  
  241.   if ( _osmode == DOS_MODE )
  242.     return TRUE;
  243.   else
  244.   {
  245.     /* We separate FAT and HPFS file systems here.
  246.      * Filenames read from a FAT system are converted to lower case
  247.      * while the case of filenames read from a HPFS (and other future
  248.      * file systems, like Unix-compatibles) is preserved.
  249.      */
  250.  
  251.     if ( isalpha(dir[0]) && (dir[1] == ':') )
  252.       nDrive = toupper(dir[0]) - '@';
  253.     else
  254.       DosQCurDisk(&nDrive, &lMap);
  255.  
  256.     bName[0] = (char) (nDrive + '@');
  257.     bName[1] = ':';
  258.     bName[2] = 0;
  259.  
  260.     cbData = sizeof(bData);
  261.  
  262.     if ( !DosQFSAttach(bName, 0U, 1U, bData, &cbData, 0L) )
  263.       return !strcmp(bData + (*(USHORT *) (bData + 2) + 7), "FAT");
  264.     else
  265.       return FALSE;
  266.  
  267.     /* End of this ugly code */
  268.   }
  269. }
  270.