HuntnGather – Diff between revs 27 and 29

Subversion Repositories:
Rev:
Only display areas with differencesIgnore whitespace
Rev 27 Rev 29
1 /////////////////////////////////////////////////////////////////////////// 1 ///////////////////////////////////////////////////////////////////////////
2 // Copyright (C) 2021 Wizardry and Steamworks - License: MIT // 2 // Copyright (C) 2021 Wizardry and Steamworks - License: MIT //
3 /////////////////////////////////////////////////////////////////////////// 3 ///////////////////////////////////////////////////////////////////////////
4   4  
5 #include <stdio.h> 5 #include <stdio.h>
6 #include <stdlib.h> 6 #include <stdlib.h>
7 #include <string.h> 7 #include <string.h>
8 #include <dirent.h> -  
9 #include <ctype.h> 8 #include <ctype.h>
10 #if !defined ___AmigaOS___ 9 #if !defined ___AmigaOS___
11 #include <signal.h> 10 #include <signal.h>
-   11 #include <dirent.h>
-   12 #include <sys/stat.h>
12 #endif 13 #endif
13   -  
14   14  
15 #include <sys/types.h> -  
16 #include <sys/stat.h> 15 #include <sys/types.h>
17   16  
18 #if defined ___AmigaOS___ 17 #if defined ___AmigaOS___
19 #include <proto/dos.h> 18 #include <proto/dos.h>
20 #include <proto/exec.h> 19 #include <proto/exec.h>
21 #include <proto/utility.h> 20 #include <proto/utility.h>
22 #endif 21 #endif
23   22  
24 #if defined ___AsyncIO___ 23 #if defined ___AsyncIO___
25 #include <asyncio.h> 24 #include <asyncio.h>
26 #endif 25 #endif
27   26  
28 #if !defined ___HAVE_GETOPT___ 27 #if !defined ___HAVE_GETOPT___
29 #include "getopt.h" 28 #include "getopt.h"
30 #endif 29 #endif
31   30  
32 #define PROGRAM_VERSION "1.7.4" 31 #define PROGRAM_VERSION "1.7.4"
33   32  
34 #if defined ___AmigaOS___ 33 #if defined ___AmigaOS___
35 /*************************************************************************/ 34 /*************************************************************************/
36 /* Version string used for querrying the program version. */ 35 /* Version string used for querrying the program version. */
37 /*************************************************************************/ 36 /*************************************************************************/
38 TEXT version_string[] = 37 TEXT version_string[] =
39 "\0$VER: Hunt " PROGRAM_VERSION " "__DATE__" by Wizardry and Steamworks"; 38 "\0$VER: Hunt " PROGRAM_VERSION " "__DATE__" by Wizardry and Steamworks";
40 #endif 39 #endif
41   40  
42 #if !defined TRUE 41 #if !defined TRUE
43 #define TRUE 1; 42 #define TRUE 1;
44 #endif 43 #endif
45   44  
46 #if !defined FALSE 45 #if !defined FALSE
47 #define FALSE 0; 46 #define FALSE 0;
48 #endif 47 #endif
49   48  
50 #define ASYNC_BUF 8192 49 #define ASYNC_BUF 8192
51 #define NAME_BUF 32 50 #define NAME_BUF 32
52 #define PATH_BUF 128 51 #define PATH_BUF 128
53 #define DEFAULT_DATABASE_FILE "S:gather.db" 52 #define DEFAULT_DATABASE_FILE "S:gather.db"
54   53  
55 int run = TRUE; 54 int run = TRUE;
56   55  
57 void SignalHandler(int sig) { 56 void SignalHandler(int sig) {
58 // Toggle the run flag to stop execution. 57 // Toggle the run flag to stop execution.
59 run = FALSE; 58 run = FALSE;
60 } 59 }
61   60  
62 /* 61 /*
63 * 62 *
64 * Returns largest of strings. 63 * Returns largest of strings.
65 */ 64 */
66 #if defined ___AmigaOS___ 65 #if defined ___AmigaOS___
67 LONG StringLenMax(char *a, char *b) { 66 LONG StringLenMax(char *a, char *b) {
68 LONG p = strlen(a); 67 LONG p = strlen(a);
69 LONG q = strlen(b); 68 LONG q = strlen(b);
70 #else 69 #else
71 int StrlenMax(char *a, char *b) { 70 int StrlenMax(char *a, char *b) {
72 int q = strlen(a); 71 int q = strlen(a);
73 int p = strien(b); 72 int p = strien(b);
74 #endif 73 #endif
75 return p > q ? p : q; 74 return p > q ? p : q;
76 } 75 }
77   76  
78 /* 77 /*
79 * Compare two strings. 78 * Compare two strings.
80 */ 79 */
81 #if defined ___AmigaOS___ 80 #if defined ___AmigaOS___
82 BOOL compare(char *a, char *b) { 81 BOOL compare(char *a, char *b) {
83 #else 82 #else
84 int compare(char *a, char *b) { 83 int compare(char *a, char *b) {
85 #endif 84 #endif
86 #if defined ___AmigaOS___ 85 #if defined ___AmigaOS___
87 ULONG size; 86 ULONG size;
88 BOOL success; 87 BOOL success;
89 UBYTE *pattern; 88 UBYTE *pattern;
90   89  
91 // "must be at least 2 times as large plus 2 bytes" 90 // "must be at least 2 times as large plus 2 bytes"
92 size = strlen(b) * 2 + 2; 91 size = strlen(b) * 2 + 2;
93   92  
94 success = FALSE; 93 success = FALSE;
95   94  
96 if(pattern = AllocVec(size, MEMF_ANY|MEMF_CLEAR)) { 95 if(pattern = AllocVec(size, MEMF_ANY|MEMF_CLEAR)) {
97 switch(ParsePatternNoCase(b, pattern, (LONG)size)) { 96 switch(ParsePatternNoCase(b, pattern, (LONG)size)) {
98 case 1: // the pattern contains wildcards 97 case 1: // the pattern contains wildcards
99 success = MatchPatternNoCase(pattern, a); 98 success = MatchPatternNoCase(pattern, a);
100   99  
101 break; 100 break;
102 case 0: // no wildcards so fall back to exact name match 101 case 0: // no wildcards so fall back to exact name match
103 #if defined ___NOCASE_FS___ 102 #if defined ___NOCASE_FS___
104 success = (Strnicmp(a, b, StringLenMax(a, b)) == 0); 103 success = (Strnicmp(a, b, StringLenMax(a, b)) == 0);
105 #else 104 #else
106 success = (StrnCmp(a, b, StringLenMax(a, b)) == 0); 105 success = (StrnCmp(a, b, StringLenMax(a, b)) == 0);
107 #endif 106 #endif
108   107  
109 break; 108 break;
110 } 109 }
111   110  
112 FreeVec(pattern); 111 FreeVec(pattern);
113 } 112 }
114   113  
115 return success; 114 return success;
116 #else 115 #else
117 int success; 116 int success;
118 char *e = a; 117 char *e = a;
119 char *n = b; 118 char *n = b;
120   119  
121 success = FALSE; 120 success = FALSE;
122   121  
123 #if defined ___NOCASE_FS___ 122 #if defined ___NOCASE_FS___
124 e = strupr(e); 123 e = strupr(e);
125 n = strupr(n); 124 n = strupr(n);
126 #endif 125 #endif
127   126  
128 // search for substring 127 // search for substring
129 success = strstr(e, n) != NULL; 128 success = strstr(e, n) != NULL;
130   129  
131 return success; 130 return success;
132 #endif 131 #endif
133 } 132 }
134   133  
135   134  
136 /* 135 /*
137 * 136 *
138 * Search the database for a matching string. 137 * Search the database for a matching string.
139 */ 138 */
140 void SearchDatabase(char *dbFile, char* needle) { 139 void SearchDatabase(char *dbFile, char* needle) {
141 #if defined ___AsyncIO___ 140 #if defined ___AsyncIO___
142 struct AsyncFile *fp; 141 struct AsyncFile *fp;
143 LONG c; 142 LONG c;
144 #else 143 #else
145 FILE *fp; 144 FILE *fp;
146 char c; 145 char c;
147 #endif 146 #endif
148 char *name; 147 char *name;
149 int name_size; 148 int name_size;
150 char *path; 149 char *path;
151 int path_size; 150 int path_size;
152 int i; 151 int i;
153 int side; 152 int side;
154 int match; 153 int match;
155 int total; 154 int total;
156   155  
157 #if defined ___AsyncIO___ 156 #if defined ___AsyncIO___
158 if((fp = OpenAsync(dbFile, MODE_READ, ASYNC_BUF)) == NULL) { 157 if((fp = OpenAsync(dbFile, MODE_READ, ASYNC_BUF)) == NULL) {
159 #else 158 #else
160 if((fp = fopen(dbFile, "r")) == NULL) { 159 if((fp = fopen(dbFile, "r")) == NULL) {
161 #endif 160 #endif
162 fprintf(stderr, "Unable to open '%s' for reading.\n", dbFile); 161 fprintf(stderr, "Unable to open '%s' for reading.\n", dbFile);
163 return; 162 return;
164 } 163 }
165   164  
166 name_size = NAME_BUF; 165 name_size = NAME_BUF;
167 name = malloc(name_size * sizeof(*name)); 166 name = malloc(name_size * sizeof(*name));
168 path_size = PATH_BUF; 167 path_size = PATH_BUF;
169 path = malloc(path_size * sizeof(*path)); 168 path = malloc(path_size * sizeof(*path));
170   169  
171 i = 0; 170 i = 0;
172 side = 0; 171 side = 0;
173 match = FALSE; 172 match = FALSE;
174 total = 0; 173 total = 0;
175   174  
176 #if defined ___AsyncIO___ 175 #if defined ___AsyncIO___
177 while(run && (c = ReadCharAsync(fp)) != -1) { 176 while(run && (c = ReadCharAsync(fp)) != -1) {
178 #else 177 #else
179 while(run && fscanf(fp, "%c", &c) == 1) { 178 while(run && fscanf(fp, "%c", &c) == 1) {
180 #endif 179 #endif
181 #if defined ___AmigaOS___ 180 #if defined ___AmigaOS___
182 // Check if CTRL+C was pressed and abort the program. 181 // Check if CTRL+C was pressed and abort the program.
183 if(SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) { 182 if(SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) {
184 run = FALSE; 183 run = FALSE;
185 continue; 184 continue;
186 } 185 }
187 #endif 186 #endif
188   187  
189 switch(c) { 188 switch(c) {
190 case '\n': 189 case '\n':
191 ++total; 190 ++total;
192 if(match) { 191 if(match) {
193 fprintf(stdout, "%s\n", path); 192 fprintf(stdout, "%s\n", path);
194 match = FALSE; 193 match = FALSE;
195 } 194 }
196 if(name != NULL) { 195 if(name != NULL) {
197 free(name); 196 free(name);
198 name_size = NAME_BUF; 197 name_size = NAME_BUF;
199 name = malloc(name_size * sizeof(*name)); 198 name = malloc(name_size * sizeof(*name));
200 } 199 }
201 --side; 200 --side;
202 i = 0; 201 i = 0;
203 break; 202 break;
204 case '\t': 203 case '\t':
205 // Case insensitive match. 204 // Case insensitive match.
206 if(compare(name, needle)) { 205 if(compare(name, needle)) {
207 match = TRUE; 206 match = TRUE;
208 } 207 }
209 if(path != NULL) { 208 if(path != NULL) {
210 free(path); 209 free(path);
211 path_size = PATH_BUF; 210 path_size = PATH_BUF;
212 path = malloc(path_size * sizeof(*name)); 211 path = malloc(path_size * sizeof(*name));
213 } 212 }
214 ++side; 213 ++side;
215 i = 0; 214 i = 0;
216 break; 215 break;
217 default: 216 default:
218 switch(side) { 217 switch(side) {
219 case 0: 218 case 0:
220 if(strlen(name) == name_size) { 219 if(strlen(name) == name_size) {
221 name_size = 1.5 * name_size; 220 name_size = 1.5 * name_size;
222 name = realloc(name, name_size * sizeof(*name)); 221 name = realloc(name, name_size * sizeof(*name));
223 } 222 }
224 name[i] = c; 223 name[i] = c;
225 name[i + 1] = '\0'; 224 name[i + 1] = '\0';
226 break; 225 break;
227 case 1: 226 case 1:
228 if(strlen(path) == path_size) { 227 if(strlen(path) == path_size) {
229 path_size = 1.5 * path_size; 228 path_size = 1.5 * path_size;
230 path = realloc(path, path_size * sizeof(*path)); 229 path = realloc(path, path_size * sizeof(*path));
231 } 230 }
232 path[i] = c; 231 path[i] = c;
233 path[i + 1] = '\0'; 232 path[i + 1] = '\0';
234 break; 233 break;
235 default: 234 default:
236 fprintf(stderr, "Database corrupted.\n"); 235 fprintf(stderr, "Database corrupted.\n");
237 break; 236 break;
238 } 237 }
239 ++i; 238 ++i;
240 break; 239 break;
241 } 240 }
242 } 241 }
243   242  
244 free(name); 243 free(name);
245 free(path); 244 free(path);
246   245  
247 #if defined ___AsyncIO___ 246 #if defined ___AsyncIO___
248 CloseAsync(fp); 247 CloseAsync(fp);
249 #else 248 #else
250 fclose(fp); 249 fclose(fp);
251 #endif 250 #endif
252 } 251 }
253   252  
254 /* 253 /*
255 * 254 *
256 * Search the database for the matching string. 255 * Search the database for the matching string.
257 */ 256 */
258 void Hunt(char *dbFile, char *needle) { 257 void Hunt(char *dbFile, char *needle) {
259 // Search the database for the matching string. 258 // Search the database for the matching string.
260 SearchDatabase(dbFile, needle); 259 SearchDatabase(dbFile, needle);
261 } 260 }
262   261  
263 void usage(char *name) { 262 void usage(char *name) {
264 fprintf(stdout, "Hunt & Gather - %s, a file index search tool. \n", name); 263 fprintf(stdout, "Hunt & Gather - %s, a file index search tool. \n", name);
265 fprintf(stdout, "Version: %s \n", PROGRAM_VERSION); 264 fprintf(stdout, "Version: %s \n", PROGRAM_VERSION);
266 fprintf(stdout, " \n"); 265 fprintf(stdout, " \n");
267 fprintf(stdout, "SYNTAX: %s [-d DATABASE] PATTERN \n", name); 266 fprintf(stdout, "SYNTAX: %s [-d DATABASE] PATTERN \n", name);
268 fprintf(stdout, " \n"); 267 fprintf(stdout, " \n");
269 fprintf(stdout, " -d DATABASE A path to a database generated by the \n"); 268 fprintf(stdout, " -d DATABASE A path to a database generated by the \n");
270 fprintf(stdout, " Gather tool that should be searched. \n"); 269 fprintf(stdout, " Gather tool that should be searched. \n");
271 fprintf(stdout, " \n"); 270 fprintf(stdout, " \n");
272 fprintf(stdout, "PATTERN is an AmigaOS DOS pattern to match file names. \n"); 271 fprintf(stdout, "PATTERN is an AmigaOS DOS pattern to match file names. \n");
273 fprintf(stdout, " \n"); 272 fprintf(stdout, " \n");
274 fprintf(stdout, "(c) 2021 Wizardry and Steamworks, MIT. \n"); 273 fprintf(stdout, "(c) 2021 Wizardry and Steamworks, MIT. \n");
275 } 274 }
276   275  
277 int main(int argc, char **argv) { 276 int main(int argc, char **argv) {
-   277 #if defined ___AmigaOS___
-   278 struct FileInfoBlock *FIB;
-   279 BPTR lock;
-   280 #else
-   281 struct stat dirStat;
-   282 #endif
278 int option; 283 int option;
279 char *dbFile; 284 char *dbFile;
280 struct stat path; -  
281   285  
282 // Bind handler to SIGINT. 286 // Bind handler to SIGINT.
283 #if !defined ___AmigaOS___ 287 #if !defined ___AmigaOS___
284 signal(SIGINT, SignalHandler); 288 signal(SIGINT, SignalHandler);
285 #endif 289 #endif
286   290  
287 dbFile = DEFAULT_DATABASE_FILE; 291 dbFile = DEFAULT_DATABASE_FILE;
288 while((option = getopt(argc, argv, "hd:")) != -1) { 292 while((option = getopt(argc, argv, "hd:")) != -1) {
289 switch(option) { 293 switch(option) {
290 case 'd': 294 case 'd':
291 dbFile = optarg; 295 dbFile = optarg;
292 break; 296 break;
293 case 'h': 297 case 'h':
294 usage(argv[0]); 298 usage(argv[0]);
295 return 0; 299 return 0;
296 case '?': 300 case '?':
297 fprintf(stderr, "Invalid option %c.\n", optopt);; 301 fprintf(stderr, "Invalid option %c.\n", optopt);;
298 return 1; 302 return 1;
299 } 303 }
300 } 304 }
301   305  
302 if(optind >= argc) { 306 if(optind >= argc) {
303 usage(argv[0]); 307 usage(argv[0]);
304 return 1; 308 return 1;
305 } 309 }
-   310  
-   311 #if defined ___AmigaOS___
-   312 if((lock = Lock(dbFile, ACCESS_READ)) == NULL) {
-   313 fprintf(stderr, "Path '%s' is not accessible.\n", dbFile);
-   314 return 1;
-   315 }
-   316  
-   317 if((FIB = AllocDosObject(DOS_FIB, NULL)) == NULL) {
-   318 fprintf(stderr, "Path '%s' file information block not accessible.\n", dbFile);
-   319 UnLock(lock);
-   320 return 1;
-   321 }
-   322  
-   323 if(Examine(lock, FIB) == FALSE) {
-   324 fprintf(stderr, "Path '%s' information unexaminable.\n", dbFile);
-   325 FreeDosObject(DOS_FIB, FIB);
-   326 UnLock(lock);
-   327 return 1;
-   328 }
-   329  
-   330 if(FIB->fib_DirEntryType > 0) {
306   331 #else
307 stat(dbFile, &path); 332 stat(dbFile, &dirStat);
-   333 if(!S_ISREG(dirStat.st_mode)) {
308 if(!S_ISREG(path.st_mode)) { 334 #endif
309 fprintf(stderr, "'%s' is not a file.\n", dbFile); 335 fprintf(stderr, "'%s' is not a file.\n", dbFile);
310 return 1; 336 return 1;
311 } 337 }
-   338  
-   339 #if defined ___AmigaOS___
-   340 FreeDosObject(DOS_FIB, FIB);
-   341 UnLock(lock);
-   342 #endif
312   343  
313 Hunt(dbFile, argv[optind]); 344 Hunt(dbFile, argv[optind]);
314   345  
315 return 0; 346 return 0;
316 } 347 }
317   348