HuntnGather – Blame information for rev 27

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