1 /*
2 *
3 * XASTIR, Amateur Station Tracking and Information Reporting
4 * Copyright (C) 1999,2000 Frank Giannandrea
5 * Copyright (C) 2000-2019 The Xastir Group
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 *
21 * Look at the README for more information on the program.
22 */
23
24 //====================================================================
25 // Canadian Callsign Lookup
26 // Richard Hagemeyer, VE3UNW
27 // GNU COPYLEFT applies
28 // 1999-11-08
29 //
30 // For use with XASTIR by Frank Giannandrea
31 //********************************************************************
32
33 #ifdef HAVE_CONFIG_H
34 #include "config.h"
35 #endif // HAVE_CONFIG_H
36
37 #include <stdio.h>
38 #include <fcntl.h>
39 #include <unistd.h>
40 #include <signal.h>
41 #include <stdio.h>
42 #include <stdlib.h>
43 #include <string.h>
44 #include <ctype.h>
45 #include <sys/types.h>
46
47 #if TIME_WITH_SYS_TIME
48 #include <sys/time.h>
49 #include <time.h>
50 #else // TIME_WITH_SYS_TIME
51 #if HAVE_SYS_TIME_H
52 #include <sys/time.h>
53 #else // HAVE_SYS_TIME_H
54 #include <time.h>
55 #endif // HAVE_SYS_TIME_H
56 #endif // TIME_WITH_SYS_TIME
57
58 #include <Xm/XmAll.h>
59
60 #include "xastir.h"
61 #include "rac_data.h"
62 #include "xa_config.h"
63 #include "main.h"
64 #include "snprintf.h"
65
66 // Must be last include file
67 #include "leak_detection.h"
68
69
70
71
72
73 /* ==================================================================== */
74 /* my version of chomp from perl, removes spaces and dashes */
75 /* */
76 /* ******************************************************************** */
chomp(char * input,unsigned int i)77 int chomp(char *input, unsigned int i)
78 {
79 unsigned int x;
80
81 for (x=i; input[x] == ' ' || input[x] == '-'; x--)
82 {
83 input[x] = '\0';
84 }
85
86 return ( (int)(i-x) );
87 }
88
89
90
91
92
93 /* ==================================================================== */
94 /* build a new (or newer if I check the file date) index file */
95 /* check for current ic index file */
96 /* FG: added a date check in case the RAC file has been updated. */
97 /* AMACALL.LST must have a time stamp newer than the index file */
98 /* time stamp. Use the touch command on the AMACALL.LST file to */
99 /* make the time current if necessary. */
100 /* ******************************************************************** */
build_rac_index(void)101 int build_rac_index(void)
102 {
103 FILE *fdb;
104 FILE *fndx;
105 unsigned long call_offset = 0;
106 unsigned long x = 0;
107 char racdata[RAC_DATA_LEN+8];
108 char amacall_path[MAX_VALUE];
109
110 get_user_base_dir("data/AMACALL.ndx", amacall_path, sizeof(amacall_path));
111
112 /* ==================================================================== */
113 /* If the index file is there, exit */
114 /* */
115 if (filethere(amacall_path))
116 {
117 /* if file is there make sure the index date is newer */
118 if(file_time(amacall_path)<=file_time(amacall_path))
119 {
120 return(1);
121 }
122 else
123 {
124
125 // RAC index old, rebuilding
126 statusline(langcode("STIFCC0103"), 1);
127
128 fprintf(stderr,"RAC index is old. Rebuilding index.\n");
129 // XmTextFieldSetString(text,"RAC Index old rebuilding");
130 // XtManageChild(text);
131 // XmUpdateDisplay(XtParent(text));
132 }
133 }
134 /* ==================================================================== */
135 /* Open the database and index file */
136 /* */
137 fdb=fopen(get_data_base_dir("fcc/AMACALL.LST"),"rb");
138 if (fdb==NULL)
139 {
140 fprintf(stderr,"Build:Could not open RAC data base: %s\n", get_data_base_dir("fcc/AMACALL.LST") );
141 return(0);
142 }
143
144 fndx=fopen(amacall_path,"w");
145 if (fndx==NULL)
146 {
147 fprintf(stderr,"Build:Could not open/create RAC data base index: %s\n", amacall_path );
148 (void)fclose(fdb);
149 return(0);
150 }
151 /* ==================================================================== */
152 /* Skip past the header to the first callsign (VA2AA) */
153 /* */
154 memset(racdata, 0, sizeof(racdata));
155 while (!feof(fdb) && strncmp(racdata,"VA",2))
156 {
157 call_offset = (unsigned long)ftell(fdb);
158 if (fgets(racdata, (int)sizeof(racdata), fdb)==NULL)
159 {
160 fprintf(stderr,"Build:header:Unable to read data base\n");
161 (void)fclose(fdb);
162 (void)fclose(fndx);
163 fprintf(stderr,"rc=0\n");
164 return (0);
165 }
166 }
167
168 /* ==================================================================== */
169 /* write out the current callsign and RBA of the db file */
170 /* skip 100 records and do it again until no more */
171 /* */
172 while (!feof(fdb))
173 {
174 fprintf(fndx,"%6.6s%li\n",racdata,(long)call_offset);
175 call_offset = (unsigned long)ftell(fdb);
176 for (x=0; x<=100 && !feof(fdb); x++)
177 if (fgets(racdata, (int)sizeof(racdata), fdb)==NULL)
178 {
179 break;
180 }
181 }
182 (void)fclose(fdb);
183 (void)fclose(fndx);
184
185 // XmTextFieldSetString(text,"");
186 // XtManageChild(text);
187
188 return(1);
189 }
190
191
192
193
194
195 /* ==================================================================== */
196 /* Check for ic data base file */
197 /* Check/build the index */
198 /* */
199 /* ******************************************************************** */
check_rac_data(void)200 int check_rac_data(void)
201 {
202 int rac_data_available = 0;
203 if( filethere( get_data_base_dir("fcc/AMACALL.LST") ) )
204 {
205 if (build_rac_index())
206 {
207 rac_data_available=1;
208 }
209 else
210 {
211 fprintf(stderr,"Check:Could not build ic data base index\n");
212 rac_data_available=0;
213 }
214 }
215 return(rac_data_available);
216 }
217
218
219
220
221
222 /* ==================================================================== */
223 /* The real work. Pass the callsign, get the info */
224 /* */
225 /* ******************************************************************** */
search_rac_data(char * callsign,rac_record * data)226 int search_rac_data(char *callsign, rac_record *data)
227 {
228 FILE *fdb;
229 FILE *fndx;
230 long call_offset = 0l;
231 char char_offset[16];
232 char index[32];
233 int found = 0;
234 rac_record racdata;
235 /*char filler[8];*/
236 char amacall_path[MAX_VALUE];
237
238 get_user_base_dir("data/AMACALL.ndx", amacall_path, sizeof(amacall_path));
239
240
241 xastir_snprintf(index, sizeof(index)," ");
242 xastir_snprintf(racdata.callsign, sizeof(racdata.callsign)," ");
243
244 /* ==================================================================== */
245 /* Search thru the index, get the RBA */
246 /* */
247
248 fndx = fopen(amacall_path, "r");
249 if(fndx != NULL)
250 {
251 if (fgets(index, (int)sizeof(index), fndx) == NULL)
252 {
253 // Error occurred
254 fprintf(stderr,
255 "Search:Could not read RAC data base index: %s\n",
256 amacall_path );
257 return (0);
258 }
259 memcpy(char_offset, &index[6], sizeof(char_offset));
260 char_offset[sizeof(char_offset)-1] = '\0'; // Terminate string
261 while (!feof(fndx) && strncmp(callsign, index, 6) > 0)
262 {
263 memcpy(char_offset, &index[6], sizeof(char_offset));
264 char_offset[sizeof(char_offset)-1] = '\0'; // Terminate string
265 if (fgets(index, (int)sizeof(index), fndx) == NULL)
266 {
267 // Error occurred
268 fprintf(stderr,
269 "Search:Could not read RAC data base index(2): %s\n",
270 amacall_path );
271 return (0);
272 }
273 }
274 }
275 else
276 {
277 fprintf(stderr,
278 "Search:Could not open RAC data base index: %s\n",
279 amacall_path );
280 return (0);
281 }
282 call_offset = atol(char_offset);
283
284 (void)fclose(fndx);
285
286 /* ==================================================================== */
287 /* Now we have our pointer into the main database (text) file. */
288 /* Start from there and linear search the data. */
289 /* This will take an avg of 1/2 of the # skipped making the index */
290 /* */
291
292 fdb = fopen(get_data_base_dir("fcc/AMACALL.LST"), "r");
293 if (fdb != NULL)
294 {
295 (void)fseek(fdb, call_offset, SEEK_SET);
296 if (callsign[5] == '-')
297 {
298 (void)chomp(callsign,5);
299 }
300
301 while (!feof(fdb) && strncmp((char *)&racdata, callsign, 6) < 0)
302
303 //WE7U
304 // Problem here: We're sticking 8 bytes too many into racdata!
305 if (fgets((char *)&racdata, sizeof(racdata), fdb) == NULL)
306 {
307 // Error occurred
308 fprintf(stderr,
309 "Search:Could not read RAC data base: %s\n",
310 amacall_path );
311 return (0);
312 }
313
314 }
315 else
316 {
317 fprintf(stderr,"Search:Could not open RAC data base: %s\n", get_data_base_dir("fcc/AMACALL.LST") );
318 }
319
320 /* || (callsign[5] == '-' && strncmp((char *)&racdata,callsign,5) < 0)) */
321 (void)chomp(racdata.callsign, 6);
322
323 if (!strncmp((char *)racdata.callsign, callsign, 6))
324 {
325 found = 1;
326
327 // Some of these cause problems on 64-bit processors, so commented
328 // them out for now.
329 // (void)chomp(racdata.first_name, 35);
330 // (void)chomp(racdata.last_name, 35);
331 // (void)chomp(racdata.address, 70);
332 // (void)chomp(racdata.city, 35);
333 // (void)chomp(racdata.province, 2);
334 // (void)chomp(racdata.postal_code, 10);
335 // (void)chomp(racdata.qual_a, 1);
336 // (void)chomp(racdata.qual_b, 1);
337 // (void)chomp(racdata.qual_c, 1);
338 // (void)chomp(racdata.qual_d, 1);
339 // (void)chomp(racdata.club_name, 141);
340 // (void)chomp(racdata.club_address, 70);
341 // (void)chomp(racdata.club_city, 35);
342 // (void)chomp(racdata.club_province, 2);
343 // (void)chomp(racdata.club_postal_code, 9);
344
345 xastir_snprintf(data->callsign,
346 sizeof(data->callsign),
347 "%s",
348 racdata.callsign);
349
350 xastir_snprintf(data->first_name,
351 sizeof(data->first_name),
352 "%s",
353 racdata.first_name);
354
355 xastir_snprintf(data->last_name,
356 sizeof(data->last_name),
357 "%s",
358 racdata.last_name);
359
360 xastir_snprintf(data->address,
361 sizeof(data->address),
362 "%s",
363 racdata.address);
364
365 xastir_snprintf(data->city,
366 sizeof(data->city),
367 "%s",
368 racdata.city);
369
370 xastir_snprintf(data->province,
371 sizeof(data->province),
372 "%s",
373 racdata.province);
374
375 xastir_snprintf(data->postal_code,
376 sizeof(data->postal_code),
377 "%s",
378 racdata.postal_code);
379
380 xastir_snprintf(data->qual_a,
381 sizeof(data->qual_a),
382 "%s",
383 racdata.qual_a);
384
385 xastir_snprintf(data->qual_b,
386 sizeof(data->qual_b),
387 "%s",
388 racdata.qual_b);
389
390 xastir_snprintf(data->qual_c,
391 sizeof(data->qual_c),
392 "%s",
393 racdata.qual_c);
394
395 xastir_snprintf(data->qual_d,
396 sizeof(data->qual_d),
397 "%s",
398 racdata.qual_d);
399
400 xastir_snprintf(data->club_name,
401 sizeof(data->club_name),
402 "%s",
403 racdata.club_name);
404
405 xastir_snprintf(data->club_address,
406 sizeof(data->club_address),
407 "%s",
408 racdata.club_address);
409
410 xastir_snprintf(data->club_city,
411 sizeof(data->club_city),
412 "%s",
413 racdata.club_city);
414
415 xastir_snprintf(data->club_province,
416 sizeof(data->club_province),
417 "%s",
418 racdata.club_province);
419
420 xastir_snprintf(data->club_postal_code,
421 sizeof(data->club_postal_code),
422 "%s",
423 racdata.club_postal_code);
424
425 }
426 (void)fclose(fdb);
427
428 if (!found)
429 {
430
431 // "Callsign Search", "Callsign Not Found!"
432 popup_message_always(langcode("STIFCC0101"),
433 langcode("STIFCC0102") );
434 }
435
436 return(found);
437 }
438
439
440