dirent.c
上传用户:kjfoods
上传日期:2020-07-06
资源大小:29949k
文件大小:7k
源码类别:

midi

开发平台:

Unix_Linux

  1. /*
  2.  * dirent.c
  3.  *
  4.  * Derived from DIRLIB.C by Matt J. Weinstein
  5.  * This note appears in the DIRLIB.H
  6.  * DIRLIB.H by M. J. Weinstein   Released to public domain 1-Jan-89
  7.  *
  8.  * Updated by Jeremy Bettis <jeremy@hksys.com>
  9.  * Significantly revised and rewinddir, seekdir and telldir added by Colin
  10.  * Peters <colin@fu.is.saga-u.ac.jp>
  11.  *
  12.  * $Revision: 1.6 $
  13.  * $Author: sam $
  14.  * $Date: 2002/11/13 20:51:04 $
  15.  *
  16.  */
  17. #include "config.h"
  18. #include <stdlib.h>
  19. #include <stdio.h>
  20. #include <errno.h>
  21. #include <string.h>
  22. #ifndef UNDER_CE
  23. #   include <io.h>
  24. #   include <direct.h>
  25. #else
  26. #   define FILENAME_MAX (260)
  27. #endif
  28. #define WIN32_LEAN_AND_MEAN
  29. #include <windows.h> /* for GetFileAttributes */
  30. #include <tchar.h>
  31. #define SUFFIX  "*"
  32. #define SLASH   "\"
  33. struct dirent
  34. {
  35.     long        d_ino;        /* Always zero. */
  36.     unsigned short    d_reclen;    /* Always zero. */
  37.     unsigned short    d_namlen;    /* Length of name in d_name. */
  38.     char            d_name[FILENAME_MAX]; /* File name. */
  39. };
  40. typedef struct
  41. {
  42.     /* disk transfer area for this dir */
  43.     WIN32_FIND_DATA        dd_dta;
  44.     /* dirent struct to return from dir (NOTE: this makes this thread
  45.      * safe as long as only one thread uses a particular DIR struct at
  46.      * a time) */
  47.     struct dirent        dd_dir;
  48.     /* findnext handle */
  49.     HANDLE            dd_handle;
  50.     /*
  51.          * Status of search:
  52.      *   0 = not started yet (next entry to read is first entry)
  53.      *  -1 = off the end
  54.      *   positive = 0 based index of next entry
  55.      */
  56.     int            dd_stat;
  57.     /* given path for dir with search pattern (struct is extended) */
  58.     char            dd_name[1];
  59. } DIR;
  60. /*
  61.  * opendir
  62.  *
  63.  * Returns a pointer to a DIR structure appropriately filled in to begin
  64.  * searching a directory.
  65.  */
  66. DIR *
  67. vlc_opendir (const CHAR *szPath)
  68. {
  69.   DIR *nd;
  70.   unsigned int rc;
  71.   CHAR szFullPath[MAX_PATH];
  72.   errno = 0;
  73.   if (!szPath)
  74.     {
  75.       errno = EFAULT;
  76.       return (DIR *) 0;
  77.     }
  78.   if (szPath[0] == '')
  79.     {
  80.       errno = ENOTDIR;
  81.       return (DIR *) 0;
  82.     }
  83.   /* Attempt to determine if the given path really is a directory. */
  84. #ifdef UNICODE
  85.   {
  86.     wchar_t szPathTmp[MAX_PATH];
  87.     mbstowcs( szPathTmp, szPath, MAX_PATH );
  88.     szPathTmp[MAX_PATH-1] = 0;
  89.     rc = GetFileAttributes (szPathTmp);
  90.   }
  91. #else
  92.   rc = GetFileAttributes (szPath);
  93. #endif
  94.   if (rc == (unsigned int)-1)
  95.     {
  96.       /* call GetLastError for more error info */
  97.       errno = ENOENT;
  98.       return (DIR *) 0;
  99.     }
  100.   if (!(rc & FILE_ATTRIBUTE_DIRECTORY))
  101.     {
  102.       /* Error, entry exists but not a directory. */
  103.       errno = ENOTDIR;
  104.       return (DIR *) 0;
  105.     }
  106.   /* Make an absolute pathname.  */
  107. #if defined( UNDER_CE )
  108.   if (szPath[0] == '\' || szPath[0] == '/')
  109.     {
  110.       sprintf (szFullPath, "%s", szPath);
  111.       szFullPath[0] = '\';
  112.     }
  113.   else
  114.     {
  115.       wchar_t szFullPathTmp[MAX_PATH];
  116.       if (GetModuleFileName( NULL, szFullPathTmp, MAX_PATH ) )
  117.         {
  118.           wcstombs( szFullPath, szFullPathTmp, MAX_PATH );
  119.           szFullPath[MAX_PATH-1] = 0;
  120.         }
  121.       else
  122.         {
  123.           /* FIXME: if I wasn't lazy, I'd check for overflows here. */
  124.           sprintf (szFullPath, "\%s", szPath );
  125.         }
  126.     }
  127. #else
  128.   _fullpath (szFullPath, szPath, MAX_PATH);
  129. #endif
  130.   /* Allocate enough space to store DIR structure and the complete
  131.    * directory path given. */
  132.   nd = (DIR *) malloc (sizeof (DIR) + strlen (szFullPath) + sizeof (SLASH) +
  133.                        sizeof (SUFFIX));
  134.   if (!nd)
  135.     {
  136.       /* Error, out of memory. */
  137.       errno = ENOMEM;
  138.       return (DIR *) 0;
  139.     }
  140.   /* Create the search expression. */
  141.   strcpy (nd->dd_name, szFullPath);
  142.   /* Add on a slash if the path does not end with one. */
  143.   if (nd->dd_name[0] != '' &&
  144.       nd->dd_name[strlen (nd->dd_name) - 1] != '/' &&
  145.       nd->dd_name[strlen (nd->dd_name) - 1] != '\')
  146.     {
  147.       strcat (nd->dd_name, SLASH);
  148.     }
  149.   /* Add on the search pattern */
  150.   strcat (nd->dd_name, SUFFIX);
  151.   /* Initialize handle so that a premature closedir doesn't try
  152.    * to call FindClose on it. */
  153.   nd->dd_handle = INVALID_HANDLE_VALUE;
  154.   /* Initialize the status. */
  155.   nd->dd_stat = 0;
  156.   /* Initialize the dirent structure. ino and reclen are invalid under
  157.    * Win32, and name simply points at the appropriate part of the
  158.    * findfirst_t structure. */
  159.   nd->dd_dir.d_ino = 0;
  160.   nd->dd_dir.d_reclen = 0;
  161.   nd->dd_dir.d_namlen = 0;
  162.   memset (nd->dd_dir.d_name, 0, FILENAME_MAX);
  163.   return nd;
  164. }
  165. /*
  166.  * readdir
  167.  *
  168.  * Return a pointer to a dirent structure filled with the information on the
  169.  * next entry in the directory.
  170.  */
  171. struct dirent *
  172. vlc_readdir (DIR * dirp)
  173. {
  174.   errno = 0;
  175.   /* Check for valid DIR struct. */
  176.   if (!dirp)
  177.     {
  178.       errno = EFAULT;
  179.       return (struct dirent *) 0;
  180.     }
  181.   if (dirp->dd_stat < 0)
  182.     {
  183.       /* We have already returned all files in the directory
  184.        * (or the structure has an invalid dd_stat). */
  185.       return (struct dirent *) 0;
  186.     }
  187.   else if (dirp->dd_stat == 0)
  188.     {
  189. #ifdef UNICODE
  190.         wchar_t dd_name[MAX_PATH];
  191.         mbstowcs( dd_name, dirp->dd_name, MAX_PATH );
  192.         dd_name[MAX_PATH-1] = 0;
  193. #else
  194.         char *dd_name = dirp->dd_name;
  195. #endif
  196.       /* We haven't started the search yet. */
  197.       /* Start the search */
  198.       dirp->dd_handle = FindFirstFile (dd_name, &(dirp->dd_dta));
  199.           if (dirp->dd_handle == INVALID_HANDLE_VALUE)
  200.         {
  201.           /* Whoops! Seems there are no files in that
  202.            * directory. */
  203.           dirp->dd_stat = -1;
  204.         }
  205.       else
  206.         {
  207.           dirp->dd_stat = 1;
  208.         }
  209.     }
  210.   else
  211.     {
  212.       /* Get the next search entry. */
  213.       if (!FindNextFile ((HANDLE)dirp->dd_handle, &(dirp->dd_dta)))
  214.         {
  215.           /* We are off the end or otherwise error. */
  216.           FindClose ((HANDLE)dirp->dd_handle);
  217.           dirp->dd_handle = INVALID_HANDLE_VALUE;
  218.           dirp->dd_stat = -1;
  219.         }
  220.       else
  221.         {
  222.           /* Update the status to indicate the correct
  223.            * number. */
  224.           dirp->dd_stat++;
  225.         }
  226.     }
  227.   if (dirp->dd_stat > 0)
  228.     {
  229.       /* Successfully got an entry */
  230. #ifdef UNICODE
  231.       char d_name[MAX_PATH];
  232.       wcstombs( d_name, dirp->dd_dta.cFileName, MAX_PATH );
  233.       d_name[MAX_PATH-1] = 0;
  234. #else
  235.       char *d_name = dirp->dd_dta.cFileName;
  236. #endif
  237.       strcpy (dirp->dd_dir.d_name, d_name);
  238.       dirp->dd_dir.d_namlen = strlen (dirp->dd_dir.d_name);
  239.       return &dirp->dd_dir;
  240.     }
  241.   return (struct dirent *) 0;
  242. }
  243. /*
  244.  * closedir
  245.  *
  246.  * Frees up resources allocated by opendir.
  247.  */
  248. int
  249. vlc_closedir (DIR * dirp)
  250. {
  251.   int rc;
  252.   errno = 0;
  253.   rc = 0;
  254.   if (!dirp)
  255.     {
  256.       errno = EFAULT;
  257.       return -1;
  258.     }
  259.   if (dirp->dd_handle != INVALID_HANDLE_VALUE)
  260.     {
  261.       rc = FindClose ((HANDLE)dirp->dd_handle);
  262.     }
  263.   /* Delete the dir structure. */
  264.   free (dirp);
  265.   return rc;
  266. }
  267. /*
  268.  * rewinddir
  269.  *
  270.  * Return to the beginning of the directory "stream". We simply call findclose
  271.  * and then reset things like an opendir.
  272.  */
  273. void
  274. vlc_rewinddir (DIR * dirp)
  275. {
  276.   errno = 0;
  277.   if (!dirp)
  278.     {
  279.       errno = EFAULT;
  280.       return;
  281.     }
  282.   if (dirp->dd_handle != INVALID_HANDLE_VALUE)
  283.     {
  284.       FindClose ((HANDLE)dirp->dd_handle);
  285.     }
  286.   dirp->dd_handle = INVALID_HANDLE_VALUE;
  287.   dirp->dd_stat = 0;
  288. }