HuntnGather – Blame information for rev 26

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