HuntnGather – Diff between revs 22 and 24

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