home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / streamva.zip / direct.c next >
Text File  |  2002-07-15  |  9KB  |  373 lines

  1. /*-----------------------------------------------------------------------*
  2.  * filename - direct.c
  3.  *
  4.  * functions:
  5.  *        diropen       - opens a directory stream
  6.  *        readdir       - read entry from directory stream
  7.  *        rewinddir     - position directory stream at first entry
  8.  *        closedir      - close directory stream
  9.  *-----------------------------------------------------------------------*/
  10. #define INCL_DOSERRORS
  11. #include <os2.h>
  12. #include <dirent.h>
  13. #include <errno.h>
  14. #include <stdlib.h>
  15. #include <string.h>
  16. #define DIRMAGIC 0xddaa
  17. #define SEARCH_ATTR (FILE_HIDDEN|FILE_SYSTEM|FILE_DIRECTORY)
  18.  
  19. /*----------------------------------------------------------------------
  20.  
  21. Name            opendir - open a directory stream
  22.  
  23. Usage           #include <dirent.h>
  24.  
  25.                 DIR *opendir(const char *dirname);
  26.  
  27. Related
  28.  
  29. functions usage struct dirent *readdir(DIR *dirp);
  30.  
  31.                 void rewinddir(DIR *dirp);
  32.  
  33.                 int closedir(DIR *dirp);
  34.  
  35. Prototype in    dirent.h
  36.  
  37. Description     The opendir() function opens a directory stream for reading
  38.  
  39.                 The name of the directory to read is dirname.  The stream
  40.  
  41.                 is set to read the first entry in the directory.
  42.  
  43. Return value    On a successful open, opendir() returns a pointer to
  44.  
  45.                 an object of type DIR.  On an error, opendir() returns
  46.  
  47.                 NULL and sets errno as follows:
  48.  
  49.                 ENOENT  The directory does not exist.
  50.  
  51.                 ENOMEM  Not enough memory to allocate a DIR object.
  52.  
  53. *---------------------------------------------------------------------*/
  54.  
  55. DIR * opendir(const char *dirname)
  56.  
  57. {
  58.     char *name;
  59.     int len;
  60.     DIR *dir;
  61.     ULONG nfiles;
  62.     APIRET apiret;
  63.  
  64.     /* Allocate space for a copy of the directory name, plus
  65.      * room for the "*.*" we will concatenate to the end.
  66.      */
  67.  
  68.     len = strlen(dirname);
  69.  
  70.     if ((name = (char*)malloc(len+5)) == NULL)
  71.  
  72.     {
  73.         errno = ENOMEM;
  74.         return (NULL);
  75.     }
  76.  
  77.     strcpy(name,dirname);
  78.  
  79.     if (len-- && name[len] != ':' && name[len] != '\\' && name[len] != '/')
  80.  
  81.         strcat(name,"\\*.*");
  82.  
  83.     else
  84.  
  85.         strcat(name,"*.*");
  86.  
  87.     /* Allocate space for a DIR structure.
  88.      */
  89.  
  90.     if ((dir = (DIR*)malloc(sizeof(DIR))) == NULL)
  91.  
  92.     {
  93.         errno = ENOMEM;
  94.         free(name);
  95.         return (NULL);
  96.     }
  97.  
  98.     /* Search for the first few files to see if the directory exists,
  99.      * and to obtain directory handle for future DosFindNext() calls.
  100.      */
  101.  
  102.     dir->_d_hdir = HDIR_CREATE;
  103.  
  104.     nfiles = 256;
  105.  
  106.     if ((apiret = DosFindFirst((PSZ)name, &dir->_d_hdir, SEARCH_ATTR,
  107.  
  108.             (PVOID)&dir->_d_buf[0], sizeof(dir->_d_buf),
  109.  
  110.             &nfiles,FIL_STANDARD)) != 0)
  111.  
  112.     {
  113.         free(name);
  114.         free(dir);
  115.  
  116.         /* set errno */
  117.  
  118.         if ( apiret == ERROR_PATH_NOT_FOUND || apiret == ERROR_FILE_NOT_FOUND )
  119.  
  120.             errno = ENOENT;
  121.  
  122.         else
  123.  
  124.             errno = EOS2ERR;
  125.  
  126.         _doserrno = (int)apiret;
  127.  
  128.         return (NULL);
  129.  
  130.     }
  131.  
  132.  
  133.  
  134.     /* Everything is OK.  Save information in the DIR structure, return it.
  135.      */
  136.  
  137.     dir->_d_dirname = name;
  138.  
  139.     dir->_d_magic = DIRMAGIC;
  140.  
  141.     dir->_d_nfiles = (unsigned)nfiles;
  142.  
  143.     dir->_d_bufp = &dir->_d_buf[0];
  144.  
  145.     return dir;
  146.  
  147. }
  148.  
  149.  
  150.  
  151. /*----------------------------------------------------------------------
  152. Name            rewinddir - rewind a directory stream
  153. Usage           #include <dirent.h>
  154.                 void rewinddir(DIR *dirp);
  155. Related
  156.  
  157. functions usage struct dirent *readdir(DIR *dirp);
  158.  
  159.                 DIR *opendir(const char *dirname);
  160.  
  161.                 int closedir(DIR *dirp);
  162.  
  163. Prototype in    dirent.h
  164.  
  165. Description     The rewinddir() function resets the directory stream dirp to the
  166.  
  167.                 first entry in the directory.
  168.  
  169. Return value    The rewinddir() function does not return a value.
  170. *---------------------------------------------------------------------*/
  171. void rewinddir(DIR *dir)
  172.  
  173. {
  174.     ULONG nfiles;
  175.  
  176.     /* Verify the handle.
  177.      */
  178.  
  179.     if (dir->_d_magic != DIRMAGIC)
  180.  
  181.             return;
  182.  
  183.  
  184.  
  185.     /* Search for the first few files.
  186.      */
  187.  
  188.     nfiles = 256;
  189.  
  190.     if (DosFindFirst((PSZ)dir->_d_dirname, &dir->_d_hdir, SEARCH_ATTR,
  191.  
  192.             (PVOID)&dir->_d_buf[0], sizeof(dir->_d_buf),
  193.  
  194.             &nfiles, FIL_STANDARD) == 0)
  195.  
  196.     {
  197.  
  198.         dir->_d_nfiles = (unsigned)nfiles;
  199.  
  200.         dir->_d_bufp = &dir->_d_buf[0];
  201.  
  202.     }
  203.  
  204. }
  205. /*----------------------------------------------------------------------
  206. Name            readdir - read directory entry from a directory stream
  207. Usage           #include <dirent.h>
  208.                 struct dirent *readdir(DIR *dirp);
  209. Related
  210. functions usage void rewinddir(DIR *dirp);
  211.                 DIR *opendir(const char *dirname);
  212.                 int closedir(DIR *dirp);
  213.  
  214. Prototype in    dirent.h
  215. Description     The readdir() function reads the directory entry at the
  216.  
  217.                 current position in the directory stream dirp, and
  218.  
  219.                 advances the directory stream position to the next entry.
  220.  
  221.                 The directory entry is an object of type 'struct dirent'
  222.  
  223.                 that contains the member
  224.  
  225.                         char d_name[]
  226.  
  227.                 which is an array of characters containing the null-terminated
  228.  
  229.                 filename.
  230.                 The readdir() function reads directory entries for all files,
  231.  
  232.                 including directories.  On DOS, it also reads directory
  233.  
  234.                 entries for system and hidden files.  It does not read
  235.  
  236.                 volume labels or unused directory entries.
  237.  
  238. Return value    On a successful read, readdir() returns a pointer
  239.  
  240.                 to an object of type 'struct direct'.  This structure
  241.  
  242.                 will be overwritten by subsequent operations on the
  243.  
  244.                 same directory stream.  It will not be overwritten
  245.  
  246.                 by operations on other directory streams.
  247.  
  248.                 When the end of the directory is reached, readdir()
  249.  
  250.                 returns NULL but does not set errno.
  251.  
  252.                 On an error, readdir() returns NULL and sets errno:
  253.  
  254.                 EBADF   The dirp parameter does not point to a valid
  255.  
  256.                         open directory stream.
  257. *---------------------------------------------------------------------*/
  258.  
  259. struct dirent * readdir(DIR *dir)
  260.  
  261. {
  262.  
  263.     ULONG nfiles;
  264.  
  265.     FILEFINDBUF3 *ff;
  266.  
  267.     /* Verify the handle.
  268.      */
  269.  
  270.     if (dir->_d_magic != DIRMAGIC)
  271.  
  272.     {
  273.         errno = EBADF;
  274.         return (NULL);
  275.     }
  276.  
  277.     /* If all files in the buffer have been returned, find some more files.
  278.      */
  279.  
  280.     if (dir->_d_nfiles == 0)
  281.  
  282.     {
  283.  
  284.         nfiles = 256;
  285.  
  286.         if (DosFindNext(dir->_d_hdir,(PFILEFINDBUF)&dir->_d_buf[0],
  287.  
  288.                 sizeof(dir->_d_buf), &nfiles) != 0)
  289.  
  290.             return (NULL);
  291.  
  292.         dir->_d_nfiles = (unsigned)nfiles;
  293.  
  294.         dir->_d_bufp = &dir->_d_buf[0];
  295.  
  296.     }
  297.  
  298.     /* Return the filename of the current file in the buffer,
  299.      * advance the buffer pointer.
  300.      */
  301.  
  302.     ff = (FILEFINDBUF3 *)(dir->_d_bufp);
  303.  
  304.     dir->_d_bufp += (int)ff->oNextEntryOffset;
  305.  
  306.     dir->_d_nfiles--;
  307.  
  308.     return ((struct dirent *)&ff->achName[0]);
  309.  
  310. }
  311.  
  312. /*----------------------------------------------------------------------
  313.  
  314. Name            closedir - close directory stream
  315.  
  316. Usage           #include <dirent.h>
  317.  
  318.                 int closedir(DIR *dirp);
  319.  
  320. Related
  321.  
  322. functions usage void rewinddir(DIR *dirp);
  323.  
  324.                 struct dirent *readdir(DIR *dirp);
  325.  
  326.                 DIR *opendir(const char *dirname);
  327.  
  328. Prototype in    dirent.h
  329.  
  330. Description     The closedir() function closes the directory stream dirp.
  331.  
  332.                 Subsequently, dirp will not refer to a valid directory
  333.  
  334.                 stream.
  335.  
  336. Return value    On a successful close, closedir() returns 0.
  337.  
  338.                 On an error, closedir() returns -1 and sets errno:
  339.  
  340.                 EBADF   The dirp parameter does not point to a valid
  341.  
  342.                         open directory stream.
  343. *---------------------------------------------------------------------*/
  344.  
  345. int closedir(DIR *dir)
  346.  
  347. {
  348.  
  349.     /* Verify the handle.
  350.      */
  351.  
  352.     if (dir == NULL || dir->_d_magic != DIRMAGIC)
  353.  
  354.     {
  355.         errno = EBADF;
  356.         return (-1);
  357.     }
  358.  
  359.  
  360.  
  361.     dir->_d_magic = 0;          /* prevent accidental use after closing */
  362.  
  363.     DosFindClose(dir->_d_hdir); /* close directory handle */
  364.  
  365.     free(dir->_d_dirname);      /* free directory name */
  366.  
  367.     free(dir);                  /* free directory structure */
  368.  
  369.     return 0;
  370.  
  371. }
  372.  
  373.