00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #if HAVE_CONFIG_H
00021 #include "config.h"
00022 #endif
00023
00024 #include "file.h"
00025 #include "file_mythiowrapper.h"
00026 #include "util/macro.h"
00027 #include "util/logging.h"
00028 #include "util/strutl.h"
00029
00030 #include <stdlib.h>
00031 #include <string.h>
00032 #if defined(HAVE_DIRENT_H)
00033 # include <dirent.h>
00034 #endif
00035 #if defined(_WIN32)
00036 # include <io.h>
00037 #endif
00038
00039 #if defined(_WIN32)
00040 typedef struct {
00041 long handle;
00042 struct _finddata_t info;
00043 } dir_data_t;
00044 #endif
00045
00046 static void dir_close_posix(BD_DIR_H *dir)
00047 {
00048 if (dir) {
00049 #if defined(_WIN32)
00050 dir_data_t *priv = dir->internal;
00051 _findclose(priv->handle);
00052 X_FREE(dir->internal);
00053 #else
00054 closedir((DIR *)dir->internal);
00055 #endif
00056
00057 BD_DEBUG(DBG_DIR, "Closed POSIX dir (%p)\n", dir);
00058
00059 X_FREE(dir);
00060 }
00061 }
00062
00063 static int dir_read_posix(BD_DIR_H *dir, BD_DIRENT *entry)
00064 {
00065 #if defined(_WIN32)
00066 dir_data_t *priv = dir->internal;
00067
00068 if (!priv->info.name[0]) {
00069 return 1;
00070 }
00071 strncpy(entry->d_name, priv->info.name, sizeof(entry->d_name));
00072
00073 priv->info.name[0] = 0;
00074 _findnext(priv->handle, &priv->info);
00075
00076 #else
00077 struct dirent e, *p_e;
00078 int result;
00079
00080 result = readdir_r((DIR*)dir->internal, &e, &p_e);
00081 if (result) {
00082 return -result;
00083 } else if (p_e == NULL) {
00084 return 1;
00085 }
00086 strncpy(entry->d_name, e.d_name, 256);
00087 #endif
00088
00089 return 0;
00090 }
00091
00092 static BD_DIR_H *dir_open_posix(const char* dirname)
00093 {
00094 if (strncmp(dirname, "myth://", 7) == 0)
00095 return dir_open_mythiowrapper(dirname);
00096
00097 BD_DIR_H *dir = malloc(sizeof(BD_DIR_H));
00098
00099 BD_DEBUG(DBG_DIR, "Opening POSIX dir %s... (%p)\n", dirname, dir);
00100 dir->close = dir_close_posix;
00101 dir->read = dir_read_posix;
00102
00103 #if defined(_WIN32)
00104 char *filespec = str_printf("%s/*", dirname);
00105 dir_data_t *priv = calloc(1, sizeof(dir_data_t));
00106
00107 dir->internal = priv;
00108
00109 priv->handle = _findfirst(filespec, &priv->info);
00110
00111 X_FREE(filespec);
00112
00113 if (priv->handle != -1) {
00114 return dir;
00115 }
00116
00117 X_FREE(dir->internal);
00118
00119 #else
00120 DIR *dp = NULL;
00121
00122 if ((dp = opendir(dirname))) {
00123 dir->internal = dp;
00124
00125 return dir;
00126 }
00127 #endif
00128
00129 BD_DEBUG(DBG_DIR, "Error opening dir! (%p)\n", dir);
00130
00131 X_FREE(dir);
00132
00133 return NULL;
00134 }
00135
00136 BD_DIR_H* (*dir_open)(const char* dirname) = dir_open_posix;