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