HuntnGather – Blame information for rev 29

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