~ubuntu-branches/ubuntu/lucid/tuxtype/lucid-proposed

« back to all changes in this revision

Viewing changes to src/scandir.c

  • Committer: Bazaar Package Importer
  • Author(s): Holger Levsen
  • Date: 2009-11-25 13:17:11 UTC
  • mfrom: (2.1.6 squeeze)
  • Revision ID: james.westby@ubuntu.com-20091125131711-nhssnv6ewxj4ubrv
Tags: 1.8.0-1
* New upstream release, quoting from the upstream changelog:
  - new music files and backgrounds contributed by Caroline Ford,
    some old sounds (the ones with suboptimal free licensing) removed -
    Tux Typing is now 100% DFSG-compliant (Closes: #400924)
  - fixed a problem that was causing the wrong key to flash in the bottom
    row of keys
  - game Instructions - simplified and reactivated cascade and laser game
    instruction scripts, fixed scripting background image so that it scales
    properly in fullscreen
  - scripting - Added some basic scripts so that new users will have a
    complete lesson set out of the box. Added a howto in the docs.
  - Sarah Frisk's word list editor from GSoC 2009 has been merged in as
    a new, somewhat "beta" feature. (Closes: #94986)
* tuxtype.postinst: Make tuxtype binary and shared wordlist directory 
  setgid games, so that wordlists can be edited and shared. This is done
  with dpkg-statoverride, so local admins can override this decission.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
 
 
2
/* Replacement scandir implementations to be used if Autoconf does not find scandir on */
 
3
/* host platform - taken from Hatari project at Sourceforge - only modification is the */
 
4
/* #ifndef HAVE_SCANDIR.  */
 
5
 
 
6
/* We only need to compile this file if the host platform doesn't have scandir(): */
 
7
#include "config.h"
 
8
#ifndef HAVE_SCANDIR
 
9
 
 
10
/*
 
11
  Hatari - scandir.c
 
12
 
 
13
  This file is distributed under the GNU Public License, version 2 or at
 
14
  your option any later version. Read the file gpl.txt for details.
 
15
 
 
16
  scandir function for BEOS, SunOS etc..
 
17
*/
 
18
const char ScanDir_rcsid[] = "Hatari $Id: scandir.c,v 1.3 2007/01/16 18:42:59 thothy Exp $";
 
19
 
 
20
#include <stdlib.h>
 
21
#include <string.h>
 
22
#include <strings.h>
 
23
#include <stdio.h>
 
24
#include <sys/types.h>
 
25
#include <sys/stat.h>
 
26
#include <fcntl.h>
 
27
#include <unistd.h>
 
28
 
 
29
#include "scandir.h"
 
30
 
 
31
/*-----------------------------------------------------------------------
 
32
 * Here come alphasort and scandir for BeOS/Haiku and SunOS
 
33
 *-----------------------------------------------------------------------*/
 
34
#if defined(__BEOS__) || defined(__HAIKU__) || (defined(__sun) && defined(__SVR4))
 
35
 
 
36
#undef DIRSIZ
 
37
 
 
38
#define DIRSIZ(dp)                                          \
 
39
                ((sizeof(struct dirent) - sizeof(dp)->d_name) +     \
 
40
                (((dp)->d_reclen + 1 + 3) &~ 3))
 
41
 
 
42
#if defined(__sun) && defined(__SVR4)
 
43
# define dirfd(d) ((d)->dd_fd)
 
44
#elif defined(__BEOS__)
 
45
#ifndef (__HAIKU__)
 
46
#else
 
47
# define dirfd(d) ((d)->fd)
 
48
#endif
 
49
#endif
 
50
 
 
51
/
 
52
/*-----------------------------------------------------------------------*/
 
53
/**
 
54
 * Alphabetic order comparison routine.
 
55
 */
 
56
int alphasort(const void *d1, const void *d2)
 
57
{
 
58
  return strcmp((*(struct dirent * const *)d1)->d_name, (*(struct dirent * const *)d2)->d_name);
 
59
}
 
60
 
 
61
 
 
62
/*-----------------------------------------------------------------------*/
 
63
/**
 
64
 * Scan a directory for all its entries
 
65
 */
 
66
int scandir(const char *dirname, struct dirent ***namelist, int (*sdfilter)(struct dirent *), int (*dcomp)(const void *, const void *))
 
67
{
 
68
  struct dirent *d, *p, **names;
 
69
  struct stat stb;
 
70
  size_t nitems;
 
71
  size_t arraysz;
 
72
  DIR *dirp;
 
73
 
 
74
  if ((dirp = opendir(dirname)) == NULL)
 
75
    return(-1);
 
76
 
 
77
  if (fstat(dirfd(dirp), &stb) < 0)
 
78
    return(-1);
 
79
 
 
80
  /*
 
81
   * estimate the array size by taking the size of the directory file
 
82
   * and dividing it by a multiple of the minimum size entry.
 
83
   */
 
84
  arraysz = (stb.st_size / 24);
 
85
 
 
86
  names = (struct dirent **)malloc(arraysz * sizeof(struct dirent *));
 
87
  if (names == NULL)
 
88
    return(-1);
 
89
 
 
90
  nitems = 0;
 
91
 
 
92
  while ((d = readdir(dirp)) != NULL)
 
93
  {
 
94
 
 
95
    if (sdfilter != NULL && !(*sdfilter)(d))
 
96
      continue;       /* just selected names */
 
97
 
 
98
    /*
 
99
     * Make a minimum size copy of the data
 
100
     */
 
101
 
 
102
    p = (struct dirent *)malloc(DIRSIZ(d));
 
103
    if (p == NULL)
 
104
      return(-1);
 
105
 
 
106
    p->d_ino = d->d_ino;
 
107
    p->d_reclen = d->d_reclen;
 
108
    /*p->d_namlen = d->d_namlen;*/
 
109
    memcpy(p->d_name, d->d_name, p->d_reclen + 1);
 
110
 
 
111
    /*
 
112
     * Check to make sure the array has space left and
 
113
     * realloc the maximum size.
 
114
     */
 
115
 
 
116
    if (++nitems >= arraysz)
 
117
    {
 
118
 
 
119
      if (fstat(dirfd(dirp), &stb) < 0)
 
120
        return(-1);     /* just might have grown */
 
121
 
 
122
      arraysz = stb.st_size / 12;
 
123
 
 
124
      names = (struct dirent **)realloc((char *)names, arraysz * sizeof(struct dirent *));
 
125
      if (names == NULL)
 
126
        return(-1);
 
127
    }
 
128
 
 
129
    names[nitems-1] = p;
 
130
  }
 
131
 
 
132
  closedir(dirp);
 
133
 
 
134
  if (nitems && dcomp != NULL)
 
135
    qsort(names, nitems, sizeof(struct dirent *), dcomp);
 
136
 
 
137
  *namelist = names;
 
138
 
 
139
  return nitems;
 
140
}
 
141
 
 
142
 
 
143
#endif /* __BEOS__ || __sun */
 
144
 
 
145
 
 
146
/*-----------------------------------------------------------------------
 
147
* Here come alphasort and scandir for Windows
 
148
*-----------------------------------------------------------------------*/
 
149
#if defined(WIN32)
 
150
 
 
151
#undef DATADIR     // stupid windows.h defines DATADIR, too
 
152
#include <windows.h>
 
153
 
 
154
/*-----------------------------------------------------------------------*/
 
155
/**
 
156
* Alphabetic order comparison routine.
 
157
*/
 
158
int alphasort(const void *d1, const void *d2)
 
159
{
 
160
  return stricmp((*(struct dirent * const *)d1)->d_name, (*(struct dirent * const *)d2)->d_name);
 
161
}
 
162
 
 
163
/*-----------------------------------------------------------------------*/
 
164
/**
 
165
* Scan a directory for all its entries
 
166
*/
 
167
int scandir(const char *dirname, struct dirent ***namelist, int (*sdfilter)(struct dirent *), int (*dcomp)(const void *, const void *))
 
168
{
 
169
  int len;
 
170
  char *findIn, *d;
 
171
  WIN32_FIND_DATA find;
 
172
  HANDLE h;
 
173
  int nDir = 0, NDir = 0;
 
174
  struct dirent **dir = 0, *selectDir;
 
175
  unsigned long ret;
 
176
 
 
177
  len    = strlen(dirname);
 
178
  findIn = (char *)malloc(len+5);
 
179
  strcpy(findIn, dirname);
 
180
  printf("scandir : findIn orign=%s\n", findIn);
 
181
  for (d = findIn; *d; d++)
 
182
    if (*d=='/')
 
183
      *d='\\';
 
184
  if ((len==0))
 
185
  {
 
186
    strcpy(findIn, ".\\*");
 
187
  }
 
188
  if ((len==1)&& (d[-1]=='.'))
 
189
  {
 
190
    strcpy(findIn, ".\\*");
 
191
  }
 
192
  if ((len>0) && (d[-1]=='\\'))
 
193
  {
 
194
    *d++ = '*';
 
195
    *d = 0;
 
196
  }
 
197
  if ((len>1) && (d[-1]=='.') && (d[-2]=='\\'))
 
198
  {
 
199
    d[-1] = '*';
 
200
  }
 
201
  if ((len>1) && (d[-2]!='\\') && (d[-1]!='*'))
 
202
  {
 
203
    *d++ = '\\';
 
204
    *d++ = '*';
 
205
    *d = 0;
 
206
  }
 
207
 
 
208
  printf("scandir : findIn processed=%s\n", findIn);
 
209
  if ((h=FindFirstFile(findIn, &find))==INVALID_HANDLE_VALUE)
 
210
  {
 
211
    printf("scandir : FindFirstFile error\n");
 
212
    ret = GetLastError();
 
213
    if (ret != ERROR_NO_MORE_FILES)
 
214
    {
 
215
      // TODO: return some error code
 
216
    }
 
217
    *namelist = dir;
 
218
    return nDir;
 
219
  }
 
220
  do
 
221
  {
 
222
    printf("scandir : findFile=%s\n", find.cFileName);
 
223
    selectDir=(struct dirent*)malloc(sizeof(struct dirent)+strlen(find.cFileName));
 
224
    strcpy(selectDir->d_name, find.cFileName);
 
225
    if (!sdfilter || (*sdfilter)(selectDir))
 
226
    {
 
227
      if (nDir==NDir)
 
228
      {
 
229
        struct dirent **tempDir = (struct dirent **)calloc(sizeof(struct dirent*), NDir+33);
 
230
        if (NDir)
 
231
          memcpy(tempDir, dir, sizeof(struct dirent*)*NDir);
 
232
        if (dir)
 
233
          free(dir);
 
234
        dir = tempDir;
 
235
        NDir += 32;
 
236
      }
 
237
      dir[nDir] = selectDir;
 
238
      nDir++;
 
239
      dir[nDir] = 0;
 
240
    }
 
241
    else
 
242
    {
 
243
      free(selectDir);
 
244
    }
 
245
  }
 
246
  while (FindNextFile(h, &find));
 
247
  ret = GetLastError();
 
248
  if (ret != ERROR_NO_MORE_FILES)
 
249
  {
 
250
    // TODO: return some error code
 
251
  }
 
252
  FindClose(h);
 
253
 
 
254
  free (findIn);
 
255
 
 
256
  if (dcomp)
 
257
    qsort (dir, nDir, sizeof(*dir),dcomp);
 
258
 
 
259
  *namelist = dir;
 
260
  return nDir;
 
261
}
 
262
 
 
263
#endif /* WIN32 */
 
264
#endif /* HAVE_SCANDIR */