HuntnGather – Blame information for rev 24

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