1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
|
/* ========================================================================
* Copyright 2008-2009 Mark Crispin
* ========================================================================
*/
/*
* Program: Scan directories
*
* Author: Mark Crispin
*
* Date: 1 August 1988
* Last Edited: 12 June 2009
*
* Previous versions of this file were:
*
* Copyright 1988-2006 University of Washington
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
*
* ========================================================================
*/
/* Emulator for BSD scandir() call
* Accepts: directory name
* destination pointer of names array
* selection function
* comparison function
* Returns: number of elements in the array or -1 if error
*/
int scandir (char *dirname,struct direct ***namelist,select_t select,
compar_t compar)
{
struct direct *p,*d,**names;
int nitems;
struct stat stb;
long nlmax;
DIR *dirp = opendir (dirname);/* open directory and get status poop */
if ((!dirp) || (fstat (dirp->dd_fd,&stb) < 0)) return -1;
/* guesstimate at number of files */
nlmax = max (stb.st_size / 24,32);
names = (struct direct **) fs_get (nlmax * sizeof (struct direct *));
nitems = 0; /* initially none found */
while (d = readdir (dirp)) { /* read directory item */
/* matches select criterion? */
if (select && !(*select) (d)) continue;
/* get size of direct record for this file */
p = (struct direct *) fs_get (DIR_SIZE (d));
p->d_ino = d->d_ino; /* copy the poop */
strcpy (p->d_name,d->d_name);
if (++nitems >= nlmax) { /* if out of space, try bigger guesstimate */
void *s = (void *) names; /* stupid language */
nlmax *= 2; /* double it */
fs_resize ((void **) &s,nlmax * sizeof (struct direct *));
names = (struct direct **) s;
}
names[nitems - 1] = p; /* store this file there */
}
closedir (dirp); /* done with directory */
/* sort if necessary */
if (nitems && compar) qsort (names,nitems,sizeof (struct direct *),compar);
*namelist = names; /* return directory */
return nitems; /* and size */
}
/* Alphabetic file name comparison
* Accepts: first candidate directory entry
* second candidate directory entry
* Returns: negative if d1 < d2, 0 if d1 == d2, positive if d1 > d2
*/
int alphasort (void *d1,void *d2)
{
return strcmp ((*(struct direct **) d1)->d_name,
(*(struct direct **) d2)->d_name);
}
|