home *** CD-ROM | disk | FTP | other *** search
/ Geek Gadgets 1 / ADE-1.bin / ade-dist / cvs-1.8.7-src.tgz / tar.out / fsf / cvs / os2 / dirent.c < prev    next >
C/C++ Source or Header  |  1996-09-28  |  4KB  |  181 lines

  1. /*
  2.  *              Author:     Bob Withers
  3.  *              Copyright (c) 1993, All Rights Reserved
  4.  *
  5.  *                              NOTICE
  6.  *
  7.  * Permission to use, copy, modify, and distribute this software and
  8.  * its documentation for any purpose and without fee is hereby granted
  9.  * provided that the above copyright notice appears in all copies and
  10.  * that both the copyright notice and this permission notice appear in
  11.  * supporting documentation.
  12.  *
  13.  * The author makes no representations about the suitability of this
  14.  * software for any purpose.  This software is provided ``as is''
  15.  * without express or implied warranty.
  16.  */
  17.  
  18. #include <stdlib.h>
  19. #include <string.h>
  20.  
  21. #define INCL_DOSFILEMGR
  22. #define INCL_DOSERRORS
  23. #include <os2.h>
  24.  
  25. #include "dirent.h"
  26.  
  27.  
  28. #define DIRENT_INCR             25
  29.  
  30.  
  31. DIR *opendir(char *filename)
  32. {
  33.     auto     size_t             len;
  34.     auto     DIR               *dirp;
  35.     auto     char              *p;
  36.     auto     HDIR               hdir;
  37.  
  38. #ifdef OS2_16
  39.     auto     USHORT             rc;         /* for 16 bit OS/2          */
  40.     auto     FILEFINDBUF        ff;
  41.     auto     USHORT             cnt;
  42. #else
  43.     auto     APIRET             rc;         /* for 32 bit OS/2          */
  44.     auto     FILEFINDBUF3       ff;
  45.     auto     ULONG              cnt;
  46. #endif  /* OS2_16 */
  47.  
  48.     if (NULL == filename || '\0' == filename[0])
  49.         filename = ".";
  50.  
  51.     dirp = malloc(sizeof(*dirp));
  52.     if (NULL == dirp)
  53.         return(NULL);
  54.  
  55.     len = strlen(filename);
  56.     dirp->dirname = malloc(len + 5);
  57.     if (NULL == dirp->dirname)
  58.     {
  59.         free(dirp);
  60.         return(NULL);
  61.     }
  62.  
  63.     dirp->max_ent = 0;
  64.     dirp->tot_ent = 0;
  65.     dirp->cur_ent = 0;
  66.     dirp->entp    = NULL;
  67.     strcpy(dirp->dirname, filename);
  68.     for (p = dirp->dirname; *p; ++p)
  69.     {
  70.         if ('/' == *p)
  71.             *p = '\\';
  72.     }
  73.  
  74.     if ('\\' != dirp->dirname[len - 1])
  75.         strcat(dirp->dirname, "\\");
  76.  
  77.     strcat(dirp->dirname, "*.*");
  78.  
  79.     hdir = HDIR_SYSTEM;
  80.     cnt  = 1;
  81.     rc = DosFindFirst(dirp->dirname, &hdir,
  82.                       FILE_NORMAL | FILE_READONLY | FILE_HIDDEN |
  83.                       FILE_SYSTEM | FILE_DIRECTORY | FILE_ARCHIVED,
  84.                       &ff, sizeof(ff), &cnt, FIL_STANDARD);
  85.  
  86.     while (NO_ERROR == rc)
  87.     {
  88.         auto     struct dirent     *entp;
  89.  
  90.         if (dirp->tot_ent >= dirp->max_ent)
  91.         {
  92.             auto     struct dirent    **p;
  93.  
  94.             dirp->max_ent += DIRENT_INCR;
  95.             p = realloc(dirp->entp, dirp->max_ent * sizeof(entp));
  96.             if (NULL == p)
  97.             {
  98.                 rc = ERROR_NOT_ENOUGH_MEMORY;
  99.                 break;
  100.             }
  101.  
  102.             dirp->entp = p;
  103.         }
  104.  
  105.         entp = malloc(sizeof(*entp) + (size_t) ff.cchName);
  106.         if (NULL == entp)
  107.         {
  108.             rc = ERROR_NOT_ENOUGH_MEMORY;
  109.             break;
  110.         }
  111.  
  112.         entp->d_ino = 0;
  113.         entp->d_off = dirp->tot_ent;
  114.         entp->d_namlen = (unsigned short) ff.cchName;
  115.         memcpy(entp->d_name, ff.achName, entp->d_namlen);
  116.         entp->d_name[entp->d_namlen] = '\0';
  117.         dirp->entp[dirp->tot_ent++] = entp;
  118.  
  119.         cnt = 1;
  120.         rc = DosFindNext(hdir, &ff, sizeof(ff), &cnt);
  121.     }
  122.  
  123.     DosFindClose(hdir);
  124.     if (ERROR_NO_MORE_FILES == rc)
  125.         return(dirp);
  126.  
  127.     closedir(dirp);
  128.     return(NULL);
  129. }
  130.  
  131.  
  132. struct dirent *readdir(DIR *dirp)
  133. {
  134.     if (dirp->cur_ent < 0 || dirp->cur_ent >= dirp->tot_ent)
  135.         return(NULL);
  136.  
  137.     return(dirp->entp[dirp->cur_ent++]);
  138. }
  139.  
  140.  
  141. long telldir(DIR *dirp)
  142. {
  143.     return((long) dirp->cur_ent);
  144. }
  145.  
  146.  
  147. void seekdir(DIR *dirp, long loc)
  148. {
  149.     dirp->cur_ent = (int) loc;
  150.     return;
  151. }
  152.  
  153.  
  154. void rewinddir(DIR *dirp)
  155. {
  156.     dirp->cur_ent = 0;
  157.     return;
  158. }
  159.  
  160.  
  161. void closedir(DIR *dirp)
  162. {
  163.     if (dirp)
  164.     {
  165.         if (dirp->dirname)
  166.             free(dirp->dirname);
  167.  
  168.         if (dirp->entp)
  169.         {
  170.             register int        i;
  171.  
  172.             for (i = 0; i < dirp->tot_ent; ++i)
  173.                 free(dirp->entp[i]);
  174.  
  175.             free(dirp->entp);
  176.         }
  177.     }
  178.  
  179.     return;
  180. }
  181.