1 /* (PD) 2001 The Bitzi Corporation
2 * Please see file COPYING or http://bitzi.com/publicdomain
3 * for more info.
4 *
5 * $Id: dirsearch.c,v 1.4 2001/06/16 03:28:43 mayhemchaos Exp $
6 */
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <string.h>
10 #include "bitcollider.h"
11 #include "dirsearch.h"
12
13 #ifdef _WIN32
14 #include <windows.h>
15 #else
16 #include <sys/stat.h>
17 #include <unistd.h>
18 #include <sys/types.h>
19 #include <dirent.h>
20 #endif
21
22 #ifndef WIN32
23 // check the type and do the long name lookup on the file
check_file_type(const char * path)24 FileType check_file_type(const char *path)
25 {
26 struct stat sbuf;
27
28 if (lstat(path, &sbuf) == 0)
29 {
30 if (S_ISCHR(sbuf.st_mode) || S_ISBLK(sbuf.st_mode) ||
31 S_ISFIFO(sbuf.st_mode) || S_ISSOCK(sbuf.st_mode))
32 return eOther;
33
34 if (S_ISREG(sbuf.st_mode))
35 return eFile;
36 else
37 if (S_ISDIR(sbuf.st_mode) && !S_ISLNK(sbuf.st_mode))
38 return eDir;
39 else
40 return eOther;
41 }
42 else
43 return eNotFound;
44 }
45
recurse_dir(BitcolliderSubmission * sub,const char * path,b_bool analyzeAll,b_bool recurseDeep)46 int recurse_dir(BitcolliderSubmission *sub,
47 const char *path,
48 b_bool analyzeAll,
49 b_bool recurseDeep)
50 {
51 DIR *dir;
52 struct dirent *entry;
53 char newPath[MAX_PATH];
54 int count = 0;
55 struct stat sbuf;
56
57 dir = opendir(path);
58 if (dir == NULL)
59 {
60 return 0;
61 }
62
63 for(;;)
64 {
65 if (sub->bc->exitNow)
66 break;
67
68 /* Scan the given dir for plugins */
69 entry = readdir(dir);
70 if (!entry)
71 break;
72
73 /* Skip the . and .. dirs */
74 if (strcmp(entry->d_name, ".") == 0 ||
75 strcmp(entry->d_name, "..") == 0)
76 continue;
77
78 sprintf(newPath, "%s/%s", path, entry->d_name);
79 if (lstat(newPath, &sbuf) == 0)
80 {
81 if (S_ISDIR(sbuf.st_mode) && !S_ISLNK(sbuf.st_mode) && recurseDeep)
82 {
83 count += recurse_dir(sub, newPath, analyzeAll, recurseDeep);
84 }
85 else
86 if (S_ISREG(sbuf.st_mode))
87 {
88 fflush(stdout);
89
90 if (analyze_file(sub, newPath, !analyzeAll))
91 {
92 count++;
93 }
94 }
95 else
96 {
97 if (sub->bc->progressCallback)
98 sub->bc->progressCallback(0, newPath,
99 "skipped. (not a regular file)");
100 }
101 }
102 }
103 closedir(dir);
104
105 return count;
106 }
107
108 #else
109
110 // check the type and do the long name lookup on the file
check_file_type(const char * path)111 FileType check_file_type(const char *path)
112 {
113 DWORD type;
114
115 type = (int)GetFileAttributes(path);
116 if ((int)type < 0)
117 return eNotFound;
118
119 if (type & FILE_ATTRIBUTE_DIRECTORY)
120 return eDir;
121
122 if ((type & FILE_ATTRIBUTE_HIDDEN) ||
123 (type & FILE_ATTRIBUTE_OFFLINE) ||
124 (type & FILE_ATTRIBUTE_TEMPORARY))
125 return eOther;
126
127 return eFile;
128 }
129
recurse_dir(BitcolliderSubmission * sub,const char * path,b_bool analyzeAll,b_bool recurseDeep)130 int recurse_dir(BitcolliderSubmission *sub,
131 const char *path,
132 b_bool analyzeAll,
133 b_bool recurseDeep)
134 {
135 WIN32_FIND_DATA find;
136 HANDLE hFind;
137 int count = 0, j;
138 char newPath[MAX_PATH], newFile[MAX_PATH], savedPath[MAX_PATH];
139 FileType type;
140
141 strcpy(newPath, path);
142 if (newPath[strlen(newPath) - 1] == '\\')
143 newPath[strlen(newPath) - 1] = 0;
144
145 strcpy(savedPath, newPath);
146
147 /* if a path was specified, then add a \*.* */
148 if ((GetFileAttributes(newPath) & FILE_ATTRIBUTE_DIRECTORY) != 0)
149 strcat(newPath, "\\*.*");
150
151 hFind = FindFirstFile(newPath, &find);
152 if (hFind == INVALID_HANDLE_VALUE)
153 return -1;
154
155 /* If its not a directory, then remove everything after the last slash */
156 if ((GetFileAttributes(savedPath) & FILE_ATTRIBUTE_DIRECTORY) == 0)
157 {
158 char *ptr;
159
160 ptr = strrchr(savedPath, '\\');
161 if (ptr)
162 *ptr = 0;
163 }
164
165 for(j = 0;; j++)
166 {
167 if (sub->bc->exitNow)
168 break;
169
170 if (j > 0)
171 if (!FindNextFile(hFind, &find))
172 break;
173
174 /* Skip the . and .. dirs */
175 if (strcmp(find.cFileName, ".") == 0 ||
176 strcmp(find.cFileName, "..") == 0)
177 continue;
178
179 sprintf(newPath, "%s\\%s", savedPath, find.cFileName);
180 type = check_file_type(newPath);
181 if (type == eDir && recurseDeep)
182 {
183 count += recurse_dir(sub, newPath, analyzeAll, recurseDeep);
184 }
185 if (type == eFile)
186 {
187 getLongPathName(newPath, MAX_PATH, newFile);
188 if (analyze_file(sub, newFile, !analyzeAll))
189 count++;
190 }
191 else
192 {
193 if (sub->bc->progressCallback)
194 sub->bc->progressCallback(0, newPath,
195 "skipped. (not a regular file)");
196 }
197 }
198 FindClose(hFind);
199
200 return count;
201
202 }
203
204 #endif
205