home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 5 Edit / 05-Edit.zip / cvt304.zip / DIRENT.C < prev    next >
C/C++ Source or Header  |  1996-02-19  |  7KB  |  311 lines

  1.  
  2.  
  3. /*
  4.  *              Author:     Bob Withers     E-Mail: bwit@mo.net
  5.  *              Copyright (c) 1993, All Rights Reserved
  6.  *
  7.  *                              NOTICE
  8.  *
  9.  * Permission to use, copy, modify, and distribute this software and
  10.  * its documentation for any purpose and without fee is hereby granted
  11.  * provided that the above copyright notice appears in all copies and
  12.  * that both the copyright notice and this permission notice appear in
  13.  * supporting documentation.
  14.  *
  15.  * The author makes no representations about the suitability of this
  16.  * software for any purpose.  This software is provided ``as is''
  17.  * without express or implied warranty.
  18.  *
  19.  *      Define      Operating System        Compiler Tested
  20.  *      -------     ----------------        ---------------
  21.  *      MSDOS_16    DOS                     Microsoft VC++ V1.51
  22.  *      NT_32       Win NT, Win95           Microsoft VC++ V2.1
  23.  *      OS2_16      OS/2 V1+                Microsoft C V6.00
  24.  *      OS2_32      OS/2 V2+                IBM C Set++ V2.1
  25.  *      BORLAND     OS/2                    Borland C++ for OS/2 V1.0
  26.  *      BORLAND     DOS, Win NT             Borland C++ V4.5
  27.  */
  28.  
  29. #ifndef UNIX
  30.  
  31. #include <stdlib.h>
  32. #include <string.h>
  33.  
  34. #if defined(OS2_16) || defined(OS2_32)
  35. #define INCL_DOSFILEMGR
  36. #define INCL_DOSERRORS
  37. #include <os2.h>
  38. #endif
  39.  
  40. #if defined(OS2_16)
  41. #undef FIL_STANDARD
  42. #define FIL_STANDARD                0
  43. #endif
  44.  
  45. #if defined(BORLAND)
  46. #define NO_ERROR                    0
  47. #define ERROR_NOT_ENOUGH_MEMORY     -1
  48. #define ERROR_NO_MORE_FILES         ENMFILE
  49. #include <dir.h>
  50. #include <dos.h>
  51. #include <errno.h>
  52. #endif
  53.  
  54. #if defined(MSDOS_16)
  55. #define NO_ERROR                    0
  56. #define ERROR_NOT_ENOUGH_MEMORY     -1
  57. #define ERROR_NO_MORE_FILES         ENOENT
  58. #include <dos.h>
  59. #include <errno.h>
  60. #endif
  61.  
  62. #if defined(NT_32)
  63. #define NO_ERROR                    0
  64. #define ERROR_NOT_ENOUGH_MEMORY     -1
  65. #define ERROR_NO_MORE_FILES         ENOENT
  66. #include <io.h>
  67. #include <errno.h>
  68. #endif
  69.  
  70. #include "dirent.h"
  71.  
  72. #define DIRENT_INCR                 25
  73.  
  74.  
  75. DIR *opendir(char *filename)
  76. {
  77.     auto     DIR               *dirp;
  78.     auto     char              *p;
  79.     auto     int                len;
  80.     auto     int                isdir;
  81.  
  82. #if  defined(OS2_32)
  83.     auto     APIRET             rc;         /* for 32 bit OS/2          */
  84.     auto     FILEFINDBUF3       ff;
  85.     auto     ULONG              cnt;
  86.     auto     HDIR               hdir;
  87. #endif
  88.  
  89. #if defined(OS2_16)
  90.     auto     USHORT             rc;         /* for 16 bit OS/2          */
  91.     auto     FILEFINDBUF        ff;
  92.     auto     USHORT             cnt;
  93.     auto     HDIR               hdir;
  94. #endif
  95.  
  96. #if defined(BORLAND)
  97.     auto     struct ffblk       ff;         /* for Borland C++          */
  98.     auto     int                rc;
  99. #endif
  100.  
  101. #if defined(MSDOS_16)
  102.     auto     struct _find_t     ff;         /* for Microsoft VC++ 1.52  */
  103.     auto     unsigned int       rc;
  104. #endif
  105.  
  106. #if defined(NT_32)
  107.     auto     struct _finddata_t ff;
  108.     auto     int                rc;
  109.     auto     long               hdir;
  110. #endif
  111.  
  112.     if (NULL == filename || '\0' == filename[0])
  113.         filename = ".";
  114.  
  115.     dirp = malloc(sizeof(*dirp));
  116.     if (NULL == dirp)
  117.         return(NULL);
  118.  
  119.     len = strlen(filename);
  120.     dirp->dirname = malloc(len + 5);
  121.     if (NULL == dirp->dirname)
  122.     {
  123.         free(dirp);
  124.         return(NULL);
  125.     }
  126.  
  127.     dirp->max_ent = 0;
  128.     dirp->tot_ent = 0;
  129.     dirp->cur_ent = 0;
  130.     dirp->entp    = NULL;
  131.     strcpy(dirp->dirname, filename);
  132.     for (p = dirp->dirname; *p; ++p)
  133.     {
  134.         if ('/' == *p)
  135.             *p = '\\';
  136.     }
  137.  
  138.     if ('\\' != dirp->dirname[len - 1])
  139.         strcat(dirp->dirname, "\\");
  140.  
  141.     strcat(dirp->dirname, "*.*");
  142.  
  143. #if defined(OS2_16) || defined(OS2_32)
  144.     hdir = HDIR_SYSTEM;
  145.     cnt  = 1;
  146.     rc = DosFindFirst(dirp->dirname, &hdir,
  147.                       FILE_NORMAL | FILE_READONLY | FILE_HIDDEN |
  148.                       FILE_SYSTEM | FILE_DIRECTORY | FILE_ARCHIVED,
  149.                       &ff, sizeof(ff), &cnt, FIL_STANDARD);
  150. #endif
  151.  
  152. #if defined(BORLAND)
  153.     rc = findfirst(dirp->dirname, &ff, FA_DIREC | FA_ARCH);
  154.     if (0 != rc)
  155.         rc = _doserrno;
  156. #endif
  157.  
  158. #if defined(MSDOS_16)
  159.     rc = _dos_findfirst(dirp->dirname, _A_ARCH | _A_SUBDIR, &ff);
  160. #endif
  161.  
  162. #if defined(NT_32)
  163.     hdir = _findfirst(dirp->dirname, &ff);
  164.     rc = (-1 == hdir) ? errno : NO_ERROR;
  165. #endif
  166.  
  167.     while (NO_ERROR == rc)
  168.     {
  169.         auto     struct dirent     *entp;
  170.  
  171.         if (dirp->tot_ent >= dirp->max_ent)
  172.         {
  173.             auto     struct dirent    **p;
  174.  
  175.             dirp->max_ent += DIRENT_INCR;
  176.             p = realloc(dirp->entp, dirp->max_ent * sizeof(entp));
  177.             if (NULL == p)
  178.             {
  179.                 rc = ERROR_NOT_ENOUGH_MEMORY;
  180.                 break;
  181.             }
  182.  
  183.             dirp->entp = p;
  184.         }
  185.  
  186. #if defined(OS2_16) || defined(OS2_32)
  187.         p = (char *) ff.achName;
  188.         len = (int) ff.cchName;
  189.         isdir = (ff.attrFile & FILE_DIRECTORY) ? 1 : 0;
  190. #endif
  191.  
  192. #if defined(BORLAND)
  193.         p = (char *) ff.ff_name;
  194.         len = strlen(p);
  195.         isdir = (ff.ff_attrib & FA_DIREC) ? 1 : 0;
  196. #endif
  197.  
  198. #if defined(MSDOS_16) || defined(NT_32)
  199.         p = ff.name;
  200.         len = strlen(p);
  201.         isdir = (ff.attrib & _A_SUBDIR) ? 1 : 0;
  202. #endif
  203.  
  204.         entp = malloc(sizeof(*entp) + (size_t) len);
  205.         if (NULL == entp)
  206.         {
  207.             rc = ERROR_NOT_ENOUGH_MEMORY;
  208.             break;
  209.         }
  210.  
  211.         entp->d_ino = 0;
  212.         entp->d_off = dirp->tot_ent;
  213.         entp->d_isdir = isdir;
  214.         entp->d_reclen = (unsigned short) len;
  215.         memcpy(entp->d_name, p, len);
  216.         entp->d_name[len] = '\0';
  217.         dirp->entp[dirp->tot_ent++] = entp;
  218.  
  219. #if defined(OS2_16) || defined(OS2_32)
  220.         cnt = 1;
  221.         rc = DosFindNext(hdir, &ff, sizeof(ff), &cnt);
  222. #endif
  223.  
  224. #if defined(BORLAND)
  225.         rc = findnext(&ff);
  226.         if (0 != rc)
  227.             rc = _doserrno;
  228. #endif
  229.  
  230. #if defined(MSDOS_16)
  231.         rc = _dos_findnext(&ff);
  232.         if (0 != rc)
  233.             rc = ERROR_NO_MORE_FILES;
  234. #endif
  235.  
  236. #if defined(NT_32)
  237.         rc = _findnext(hdir, &ff);
  238.         if (-1 == rc)
  239.             rc = ERROR_NO_MORE_FILES;
  240. #endif
  241.     }
  242.  
  243. #if defined(OS2_16) || defined(OS2_32)
  244.     DosFindClose(hdir);
  245. #endif
  246.  
  247. #if defined(NT_32)
  248.     _findclose(hdir);
  249. #endif
  250.  
  251.     if (ERROR_NO_MORE_FILES == rc)
  252.         return(dirp);
  253.  
  254.     closedir(dirp);
  255.     return(NULL);
  256. }
  257.  
  258.  
  259. struct dirent *readdir(DIR *dirp)
  260. {
  261.     if (dirp->cur_ent < 0 || dirp->cur_ent >= dirp->tot_ent)
  262.         return(NULL);
  263.  
  264.     return(dirp->entp[dirp->cur_ent++]);
  265. }
  266.  
  267.  
  268. long telldir(DIR *dirp)
  269. {
  270.     return((long) dirp->cur_ent);
  271. }
  272.  
  273.  
  274. void seekdir(DIR *dirp, long loc)
  275. {
  276.     dirp->cur_ent = (int) loc;
  277.     return;
  278. }
  279.  
  280.  
  281. void rewinddir(DIR *dirp)
  282. {
  283.     dirp->cur_ent = 0;
  284.     return;
  285. }
  286.  
  287.  
  288. void closedir(DIR *dirp)
  289. {
  290.     if (dirp)
  291.     {
  292.         if (dirp->dirname)
  293.             free(dirp->dirname);
  294.  
  295.         if (dirp->entp)
  296.         {
  297.             register int        i;
  298.  
  299.             for (i = 0; i < dirp->tot_ent; ++i)
  300.                 free(dirp->entp[i]);
  301.  
  302.             free(dirp->entp);
  303.         }
  304.     }
  305.  
  306.     return;
  307. }
  308.  
  309.  
  310. #endif
  311.