HuntnGather – Diff between revs 26 and 27

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