1 /*
2 TiMidity++ -- MIDI to WAVE converter and player
3 Copyright (C) 1999-2002 Masanao Izumo <mo@goice.co.jp>
4 Copyright (C) 1995 Tuukka Toivonen <tt@cgs.fi>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
20 readdir.c
21 */
22
23 #ifdef HAVE_CONFIG_H
24 #include "config.h"
25 #endif /* HAVE_CONFIG_H */
26
27 #ifdef HAVE_STDLIB_H
28 #include <stdlib.h>
29 #else
30 #ifdef HAVE_MALLOC_H
31 #include <malloc.h>
32 #endif
33 #endif
34
35 #ifndef NO_STRING_H
36 #include <string.h>
37 #else
38 #include <strings.h>
39 #endif
40
41 #include "timidity.h"
42 #include "common.h"
43
44 #ifdef __W32__
45 #include "readdir.h"
46
47 /**********************************************************************
48 * Implement dirent-style opendir/readdir/closedir on Window 95/NT
49 *
50 * Functions defined are opendir(), readdir() and closedir() with the
51 * same prototypes as the normal dirent.h implementation.
52 *
53 * Does not implement telldir(), seekdir(), rewinddir() or scandir().
54 * The dirent struct is compatible with Unix, except that d_ino is
55 * always 1 and d_off is made up as we go along.
56 *
57 * The DIR typedef is not compatible with Unix.
58 **********************************************************************/
59
opendir(const char * dir)60 API_EXPORT(DIR *) opendir(const char *dir)
61 {
62 DIR *dp;
63 char *filespec;
64 long handle;
65 int index;
66
67 filespec = safe_malloc(strlen(dir) + 2 + 1);
68 strcpy(filespec, dir);
69 index = strlen(filespec) - 1;
70 if (index >= 0 && (filespec[index] == '/' || filespec[index] == '\\'))
71 filespec[index] = '\0';
72 strcat(filespec, "/*");
73
74 dp = (DIR *)safe_malloc(sizeof(DIR));
75 dp->offset = 0;
76 dp->finished = 0;
77 dp->dir = safe_strdup(dir);
78
79 if ((handle = _findfirst(filespec, &(dp->fileinfo))) < 0) {
80 if (errno == ENOENT)
81 dp->finished = 1;
82 else
83 return NULL;
84 }
85
86 dp->handle = handle;
87 free(filespec);
88
89 return dp;
90 }
91
readdir(DIR * dp)92 API_EXPORT(struct dirent *) readdir(DIR *dp)
93 {
94 if (!dp || dp->finished) return NULL;
95
96 if (dp->offset != 0) {
97 if (_findnext(dp->handle, &(dp->fileinfo)) < 0) {
98 dp->finished = 1;
99 return NULL;
100 }
101 }
102 dp->offset++;
103
104 #ifdef __BORLANDC__
105 /* Borland C++ */
106 strncpy(dp->dent.d_name, dp->fileinfo.ff_name, _MAX_FNAME);
107 #else
108 strncpy(dp->dent.d_name, dp->fileinfo.name, _MAX_FNAME);
109 #endif /* __BORLANDC__ */
110
111 dp->dent.d_name[_MAX_FNAME] = '\0';
112 dp->dent.d_ino = 1;
113 dp->dent.d_reclen = strlen(dp->dent.d_name);
114 dp->dent.d_off = dp->offset;
115
116 return &(dp->dent);
117 }
118
closedir(DIR * dp)119 API_EXPORT(int) closedir(DIR *dp)
120 {
121 if (!dp) return 0;
122
123 #ifndef __BORLANDC__
124 _findclose(dp->handle);
125 #endif
126 if (dp->dir) free(dp->dir);
127 if (dp) free(dp);
128
129 return 0;
130 }
131 #endif /* __W32__ */
132