1 // ----------------------------------------------------------------------------
2 // qrzlib.cc
3 //
4 // Interface library to the QRZ database distributed by AA7BQ
5 //
6 // Copyright (C) 1999-2009 David Freese
7 //
8 // This file is part of fldigi.
9 //
10 // Fldigi is free software: you can redistribute it and/or modify
11 // it under the terms of the GNU General Public License as published by
12 // the Free Software Foundation, either version 3 of the License, or
13 // (at your option) any later version.
14 //
15 // Fldigi is distributed in the hope that it will be useful,
16 // but WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU General Public License for more details.
19 //
20 // You should have received a copy of the GNU General Public License
21 // along with fldigi. If not, see <http://www.gnu.org/licenses/>.
22 // ----------------------------------------------------------------------------
23
24 #include <config.h>
25
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include <ctype.h>
30 #include <stdlib.h>
31 #include <unistd.h>
32 #include <string>
33
34 #include <iostream>
35 //using namespace std;
36
37 #include "qrzlib.h"
38 #include "configuration.h"
39 #include "debug.h"
40
41 static char QRZdir[256] = "";
42
43 static const char *QRZpath;
44 static const char *QRZtry[] = {
45 #ifdef __WOE32__
46 "C:/CALLBK/", // look on C: drive first
47 "D:/CALLBK/",
48 "E:/CALLBK/",
49 "F:/CALLBK/",
50 "G:/CALLBK/",
51 #else
52 "~/callbk/",
53 "/cdrom/callbk/",
54 "/mnt/cdrom/callbk/", "/mnt/cdrom0/callbk/", "/mnt/cdrom1/callbk/",
55 "/media/cdrom/callbk/", "/media/cdrom0/callbk/", "/media/cdrom1/callbk/",
56 #endif
57 0 };
58
59 FILE *imagefile = NULL;
60
61 #define isdirsep(c) ((c)=='/')
62
filename_expand(char * to,int tolen,const char * from)63 int filename_expand(char *to,int tolen, const char *from) {
64
65 char temp[tolen];
66 strlcpy(temp,from, tolen);
67 char *start = temp;
68 char *end = temp+strlen(temp);
69
70 int ret = 0;
71
72 for (char *a=temp; a<end; ) { // for each slash component
73 char *e; for (e=a; e<end && !isdirsep(*e); e++); // find next slash
74 const char *value = 0; // this will point at substitute value
75 switch (*a) {
76 case '~': // a home directory name
77 if (e <= a+1) { // current user's directory
78 value = getenv("HOME");
79 }
80 break;
81 case '$': /* an environment variable */
82 {char t = *e; *(char *)e = 0; value = getenv(a+1); *(char *)e = t;}
83 break;
84 }
85 if (value) {
86 // substitutions that start with slash delete everything before them:
87 if (isdirsep(value[0])) start = a;
88 int t = strlen(value); if (isdirsep(value[t-1])) t--;
89 if ((end+1-e+t) >= tolen) end += tolen - (end+1-e+t);
90 memmove(a+t, e, end+1-e);
91 end = a+t+(end-e);
92 *end = '\0';
93 memcpy(a, value, t);
94 ret++;
95 } else {
96 a = e+1;
97 }
98 }
99
100 strlcpy(to, start, tolen);
101
102 return ret;
103 }
104
105
QRZImageFilename(char * call)106 char *QRZImageFilename (char *call)
107 {
108 static char fname[80], *p, imgcall[12];
109 FILE *f;
110 strcpy(imgcall, call);
111 p = imgcall;
112 while (*p) {*p = tolower (*p); p++; }
113 strcpy (fname, QRZdir);
114 strcat (fname, "images/");
115 strcat (fname, &imgcall[strlen(imgcall)-1]);
116 strcat (fname, "/");
117 strcat (fname, imgcall);
118 while (fname[strlen(fname)-1] == ' ') fname[strlen(fname)-1] = 0;
119 strcat (fname, ".jpg");
120 f = fl_fopen(fname, "r");
121 if (f != NULL) {
122 fclose (f);
123 return fname;
124 }
125 return NULL;
126 }
127
checkPath(const char * filename)128 int checkPath( const char *filename )
129 {
130 char fname[120];
131 FILE *f;
132 bool notfound = false;
133 if (!progdefaults.QRZpathname.empty()) {
134 strcpy ( fname, progdefaults.QRZpathname.c_str());
135 for (size_t i = 0; i < strlen(fname); i++)
136 if (fname[i] == '\\') fname[i] = '/'; // fix for DOS path convention
137
138 strcat( fname, filename );
139 strcat( fname, ".dat" );
140 if (fname[0] == '~' || fname[0] == '$') {
141 char f2name[80];
142 filename_expand(f2name, 79, fname);
143 strcpy (fname, f2name);
144 }
145 f = fl_fopen(fname, "r" );
146 if( f != NULL ) {
147 fclose( f );
148 char pathname[120];
149 strcpy( pathname, progdefaults.QRZpathname.c_str());
150 if (pathname[0] == '~' || pathname[0] == '$')
151 filename_expand(QRZdir, 79, pathname);
152 else
153 strcpy (QRZdir, pathname);
154 return 1;
155 }
156 std::string err = fname;
157 err.append(" not found, performing search");
158 LOG_WARN("%s", err.c_str());
159 notfound = true;
160 }
161 // not specified, perform a search
162 const char **pQRZpath = QRZtry;
163 while (*pQRZpath) {
164 strcpy( fname, *pQRZpath );
165 strcat( fname, filename );
166 strcat( fname, ".dat" );
167 if (fname[0] == '~' || fname[0] == '$') {
168 char f2name[80];
169 filename_expand(f2name, 79, fname);
170 strcpy (fname, f2name);
171 }
172 f = fl_fopen(fname, "r" );
173 if( f != NULL ) {
174 fclose( f );
175 QRZpath = *pQRZpath;
176 if (QRZpath[0] == '~' || QRZpath[0] == '$')
177 filename_expand(QRZdir, 79, QRZpath);
178 else
179 strcpy (QRZdir, QRZpath);
180 if (notfound) {
181 std::string err = "Using ";
182 err.append(fname);
183 LOG_WARN("%s", err.c_str());
184 }
185 return 1;
186 }
187 pQRZpath++;
188 }
189 QRZpath = QRZtry[0];
190 LOG_WARN("QRZ data base not found");
191 return 0;
192 }
193
SetQRZdirectory(char * dir)194 void SetQRZdirectory(char *dir)
195 {
196 strcpy(QRZdir, dir);
197 strcat(QRZdir, "/");
198 }
199
ImageExists()200 bool QRZ::ImageExists() {
201 if (Qimagefname == NULL)
202 return (hasImage = false);
203 imagefile = fl_fopen(Qimagefname, "r");
204 if (imagefile) {
205 fclose (imagefile);
206 return (hasImage = true);
207 }
208 return (hasImage = false);
209 }
210
OpenQRZFiles(const char * fname)211 void QRZ::OpenQRZFiles( const char *fname )
212 {
213 long fsize;
214 char dfname[64];
215 char idxname[64];
216 int num1;
217 int num2;
218 num1 = 0;
219 num2 = 0;
220
221 if( fname[0] == 0 ) {
222 QRZvalid = 0;
223 return;
224 }
225
226 QRZvalid = 1;
227
228 if (*QRZdir == 0)
229 if( checkPath( fname ) == 0 ) {
230 QRZvalid = 0;
231 return;
232 }
233
234 strcpy( dfname, QRZdir );
235 strcpy( idxname, QRZdir );
236
237 strcat( idxname, fname );
238 strcat( idxname, ".idx" );
239 strcat( dfname, fname );
240 strcat( dfname, ".dat" );
241
242 idxfile = fl_fopen( idxname, "r" );
243 if( idxfile == NULL ) {
244 QRZvalid = 0;
245 return;
246 }
247
248 fseek( idxfile, 0, SEEK_END );
249 fsize = ftell( idxfile );
250 rewind( idxfile );
251
252 idxsize = fsize - 48;
253
254 index = new char[idxsize];
255
256 if( index == NULL ) {
257 fclose( idxfile );
258 QRZvalid = 0;
259 return;
260 }
261 memset( index, 0, idxsize );
262
263 num1 = fread( &idxhdr.dataname, 48, 1, idxfile );
264 num2 = fread( index, idxsize, 1, idxfile );
265
266 if (num1 != 1 || num2 != 1) {
267 fclose( idxfile );
268 delete [] index;
269 QRZvalid = 0;
270 return;
271 }
272
273 fflush( stdout );
274
275 fclose( idxfile );
276
277 datafile = fl_fopen( dfname, "r" );
278 if( datafile == NULL ) {
279 delete [] index;
280 QRZvalid = 0;
281 return;
282 }
283
284 sscanf( idxhdr.bytesperkey, "%d", &datarecsize );
285 if( datarecsize == 0 || datarecsize > 32767 ) {
286 delete [] index;
287 QRZvalid = 0;
288 return;
289 }
290
291 // allocate sufficient data buffer for file read over key boundary
292
293 if (data) delete [] data;
294 data = new char[datarecsize + 512];
295
296 if( data == NULL ) {
297 delete [] index;
298 QRZvalid = 0;
299 return;
300 }
301 // fill buffer with new-lines to insure not reading past end of
302 // the buffer
303 memset( data, '\n', datarecsize + 512 );
304
305 sscanf( idxhdr.keylen, "%d", &keylen );
306 sscanf( idxhdr.numkeys, "%ld", &numkeys );
307 top = index + idxsize - keylen;
308
309 }
310
311
QRZ(const char * fname)312 QRZ::QRZ( const char *fname )
313 {
314 int len = strlen(fname);
315 criteria = fname[ len - 1 ];
316 OpenQRZFiles( fname );
317 }
318
QRZ(const char * fname,char c)319 QRZ::QRZ( const char *fname, char c )
320 {
321 criteria = c;
322 OpenQRZFiles( fname );
323 }
324
NewDBpath(const char * fname)325 void QRZ::NewDBpath( const char *fname )
326 {
327 int len = strlen(fname);
328 criteria = fname[ len - 1 ];
329 *QRZdir = 0;
330 OpenQRZFiles( fname );
331 }
332
333
~QRZ()334 QRZ::~QRZ()
335 {
336 if (index) delete [] index;
337 if (data) delete [] data;
338 if( datafile != NULL ) fclose( datafile );
339 return;
340 }
341
CallComp(char * s1,char * s2)342 int QRZ::CallComp( char *s1, char *s2 )
343 {
344 static char sa[7], sb[7];
345 strncpy( sb, s2, 6 );
346 strncpy( sa, s1, 6 );
347 sa[6] = 0;
348 sb[6] = 0;
349
350 int stest = strncasecmp( sa + 3, sb + 3, 3 );
351 if( stest < 0 )
352 return -1;
353 if( stest > 0 )
354 return 1;
355 // suffix are equal
356 int atest = strncasecmp( sa + 2, sb + 2, 1 );
357 if( atest < 0 )
358 return -1;
359 if( atest > 0 )
360 return 1;
361 // suffix & call area are equal
362 int ptest = strncasecmp( sa, sb, 2 );
363 if( ptest < 0 )
364 return -1;
365 if( ptest > 0 )
366 return 1;
367 // total match of calls
368 return 0;
369 }
370
Composite(char * s)371 char *Composite( char *s )
372 {
373 static char newstr[7];
374 int ccount = strlen(s) < 7 ? strlen(s) : 6;
375 memset(newstr, ' ', 6 );
376 newstr[6] = 0;
377 if( isdigit( s[2] ) ) {
378 for( int i = 0; i < ccount; i++ )
379 newstr[i] = s[i];
380 } else {
381 newstr[0] = s[0];
382 newstr[2] = s[1];
383 for( int i = 2; i < ccount; i++ )
384 newstr[i+1] = s[i];
385 }
386 return( newstr );
387 }
388
ReadDataBlock(long p)389 int QRZ::ReadDataBlock( long p )
390 {
391 rewind( datafile );
392
393 if ( p < 0 ) p = 0;
394
395 if( fseek( datafile, p, SEEK_SET ) != 0 ) {
396 return 1;
397 }
398
399 databytesread = fread( data, 1, datarecsize + 512, datafile );
400 dataoffset = p;
401
402 fflush( stdout);
403 return 0;
404 }
405
FindCallsign(char * field)406 int QRZ::FindCallsign( char *field )
407 {
408 char composite[7], testcall[7];
409 char *endofdata;
410 int matched = 0, iOffset;
411
412 memset( composite, 0, 6 );
413 memset( testcall, 0, 6 );
414 found = 0;
415 idxptr = index;
416
417 if( strlen( field ) < 3 ) // must be a valid callsign
418 return 0;
419
420 if ( !(isdigit( field[1] ) || isdigit( field[2] ) ) )
421 return 0;
422
423 strcpy( composite, Composite( field ) );
424
425 for( iOffset = 0; iOffset < numkeys; iOffset++, idxptr += keylen )
426 if( CallComp( composite, idxptr) <= 0 )
427 break;
428
429 iOffset--;
430 if (iOffset < 0) iOffset = 0;
431
432 ReadDataBlock( datarecsize * iOffset );
433
434 dfptr = data;
435 endofdata = data + databytesread;
436
437 endofline = strchr( dfptr, '\n' );
438
439 if( idxptr != index ) {
440 endofline = strchr( dfptr, '\n' );
441 if (endofline != NULL )
442 dfptr = endofline + 1;
443 }
444
445 found = 0;
446
447 while ( !found && (dfptr < endofdata ) ) {
448 memcpy( testcall, dfptr, 6 );
449 if( (matched = CallComp( composite, Composite(testcall) ) ) <= 0 )
450 found = 1;
451 else {
452 endofline = strchr( dfptr, '\n' );
453 dfptr = endofline + 1;
454 }
455 }
456
457 if ( matched == 0 ) {
458 endofline = strchr( dfptr, '\n' );
459 *endofline = 0;
460 strcpy( recbuffer, dfptr );
461 // check for old call referencing new call
462 if (strlen(recbuffer) < 15 ) {
463 dfptr = strchr( dfptr, ',' ) + 1;
464 strcpy( recbuffer, dfptr );
465 // Qcall = recbuffer;
466 found = -1;
467 } else {
468 found = 1;
469 dfptr = endofline + 1; // point to next record
470 }
471 return (found);
472 }
473 found = 0;
474 return 0;
475 }
476
nextrec()477 int QRZ::nextrec()
478 {
479 if( dfptr > data + datarecsize ) {
480 if( ReadDataBlock( dataoffset + (dfptr - data) ) != 0)
481 return 0;
482 dfptr = data;
483 }
484
485 endofline = strchr( dfptr, '\n' );
486 *endofline = 0;
487 strcpy( recbuffer, dfptr );
488 dfptr = endofline + 1;
489 if (strlen(recbuffer) < 15 ) {
490 nextrec();
491 }
492 return 1;
493 }
494
NextRecord()495 int QRZ::NextRecord()
496 {
497 if( nextrec() == 1 )
498 return( ReadRec() );
499 return 0;
500 }
501
FindName(char * field)502 int QRZ::FindName( char *field )
503 {
504 char *endofdata;
505 int matched = 0, iOffset;
506 char *Lname, *Fname;
507 char sFname[17];
508 char sLname[17];
509 char sIdxName[33];
510 char *cptr;
511
512 memset( sFname, 0, 17 );
513 memset( sLname, 0, 17 );
514 memset( sIdxName, 0, 33 );
515
516 if ( (cptr = strchr( field, ',' ) ) != NULL ) {
517 strncpy( sLname, field, cptr - field );
518 strcpy( sFname, cptr + 1 );
519 } else
520 strcpy( sLname, field );
521
522 strcpy( sIdxName, sLname );
523 if( strlen( sFname ) > 0 ) {
524 strcat( sIdxName, " " );
525 strcat( sIdxName, sFname );
526 }
527
528 found = 0;
529 idxptr = index;
530
531 for( iOffset = 0; iOffset < numkeys; iOffset++, idxptr += keylen )
532 if( strncasecmp( sIdxName, idxptr, keylen ) <= 0 )
533 break;
534
535 iOffset--;
536 if (iOffset < 0) iOffset = 0;
537
538 ReadDataBlock( datarecsize * iOffset );
539
540 dfptr = data;
541 endofdata = data + databytesread;
542
543 if( idxptr != index ) {
544 endofline = strchr( dfptr, '\n' );
545 if (endofline != NULL )
546 dfptr = endofline + 1;
547 }
548
549 found = 0;
550 while ( !found && (dfptr < endofdata ) ) {
551 endofline = strchr( dfptr, '\n' );
552 if( endofline == NULL || endofline > endofdata )
553 break;
554 if( endofline - dfptr > 14 ) { // valid racord
555 Lname = strchr( dfptr, ',' ) + 1; // locate Lname element
556 Fname = strchr( Lname, ',' ) + 1; // locate Fname element
557 if( *Fname == ',' )
558 Fname++;
559 else
560 Fname = strchr( Fname, ',' ) + 1;
561 if( (matched = strncasecmp( sLname, Lname, strlen(sLname) ) ) == 0 ) {
562 if( sFname[0] == 0 )
563 found = 1;
564 else
565 if( ( matched = strncasecmp( sFname, Fname, strlen(sFname) ) ) <= 0 )
566 found = 1;
567 }
568 }
569 if (!found && (dfptr < endofdata ) )
570 dfptr = strchr( dfptr, '\n' ) + 1; // move to next record
571 }
572
573 if ( matched == 0 ) {
574 endofline = strchr( dfptr, '\n' );
575 *endofline = 0;
576 strcpy( recbuffer, dfptr );
577 found = 1;
578 dfptr = endofline + 1; // point to next record
579 return (found);
580 }
581 found = 0;
582 return 0;
583 }
584
CompState(const char * field,const char * state,const char * city)585 int QRZ::CompState( const char *field, const char *state, const char *city )
586 {
587 int compsize = strlen(field+2),
588 chk;
589 if (compsize > keylen) compsize = keylen;
590
591 if(strlen( field ) == 2)
592 return ( strncasecmp( field, state, 2 ) );
593
594 if( (chk = strncasecmp( field, state, 2 ) ) < 0 )
595 return -1;
596 if( chk > 0 )
597 return 1;
598 chk = strncasecmp( field + 2, city, compsize);
599 if (chk < 0)
600 return -1;
601 if (chk > 0)
602 return 1;
603 return 0;
604 }
605
FindState(char * field)606 int QRZ::FindState( char *field )
607 {
608 char *endofdata;
609 int matched = 0, iOffset;
610 char *state;
611 char *city;
612 int compsize = strlen(field);
613
614 if (compsize > keylen) compsize = keylen;
615
616 found = 0;
617 idxptr = index;
618
619 for( iOffset = 0; iOffset < numkeys; iOffset++, idxptr += keylen )
620 if( strncasecmp( field, idxptr, compsize ) <= 0 )
621 break;
622
623 iOffset--;
624 if (iOffset < 0) iOffset = 0;
625
626 ReadDataBlock( datarecsize * iOffset );
627
628 dfptr = data;
629 endofdata = data + datarecsize;
630
631 if( idxptr != index ) {
632 endofline = strchr( dfptr, '\n' );
633 if (endofline != NULL )
634 dfptr = endofline + 1;
635 }
636
637 found = 0;
638 while ( !found && (dfptr < endofdata ) ) {
639 endofline = strchr( dfptr, '\n' );
640 if( endofline - dfptr > 14 ) { // valid record
641
642 city = dfptr;
643 for( int i = 0; i < 9; i++ ) // move to city element
644 city = strchr( city, ',' ) + 1;
645 state = strchr( city, ',' ) + 1; // move to state element
646 matched = CompState( field, state, city );
647
648 if( matched == 0)
649 found = 1;
650 else {
651 endofline = strchr( dfptr, '\n' ); // no match, move to next
652 dfptr = endofline + 1;
653 }
654 } else {
655 endofline = strchr( dfptr, '\n' ); // invalid record, move to next
656 dfptr = endofline + 1;
657 }
658 }
659
660 if ( matched == 0 ) {
661 endofline = strchr( dfptr, '\n' );
662 *endofline = 0;
663 strcpy( recbuffer, dfptr );
664 found = 1;
665 dfptr = endofline + 1; // point to next record
666 return (found);
667 }
668 found = 0;
669 return 0;
670 }
671
FindZip(char * field)672 int QRZ::FindZip( char *field )
673 {
674 char *endofdata;
675 int matched = 0, iOffset;
676 char *zip;
677
678 found = 0;
679 idxptr = index;
680
681 for( iOffset = 0; iOffset < numkeys; iOffset++, idxptr += keylen )
682 if( strncasecmp( field, idxptr, 5 ) <= 0 )
683 break;
684
685 iOffset--;
686 if (iOffset < 0) iOffset = 0;
687
688 ReadDataBlock( datarecsize * iOffset );
689
690 dfptr = data;
691 endofdata = data + datarecsize;
692
693 if( idxptr != index ) {
694 endofline = strchr( dfptr, '\n' );
695 if (endofline != NULL )
696 dfptr = endofline + 1;
697 }
698
699 found = 0;
700 while ( !found && (dfptr < endofdata ) ) {
701 endofline = strchr( dfptr, '\n' );
702
703 if( endofline - dfptr > 14 ) { // valid record
704 zip = dfptr;
705 for( int i = 0; i < 11; i++ ) // move to Zip element
706 zip = strchr( zip, ',' ) + 1;
707 if( (matched = strncasecmp( field, zip, 5 ) ) <= 0 )
708 found = 1;
709 else {
710 endofline = strchr( dfptr, '\n' ); // no match, move to next
711 dfptr = endofline + 1;
712 }
713 } else {
714 endofline = strchr( dfptr, '\n' ); // invalid record, move to next
715 dfptr = endofline + 1;
716 }
717 }
718
719 if ( matched == 0 ) {
720 endofline = strchr( dfptr, '\n' );
721 *endofline = 0;
722 strcpy( recbuffer, dfptr );
723 found = 1;
724 dfptr = endofline + 1; // point to next record
725 return (found);
726 }
727 found = 0;
728 return 0;
729 }
730
FindRecord(char * field)731 int QRZ::FindRecord( char *field )
732 {
733 if (QRZvalid == 0 ) return 0;
734
735 switch (criteria) {
736 case 'c' :
737 FindCallsign( field );
738 break;
739 case 'n' :
740 FindName( field );
741 break;
742 case 's' :
743 FindState( field );
744 break;
745 case 'z' :
746 FindZip( field );
747 }
748 return( ReadRec() );
749 }
750
751
752
ReadRec()753 int QRZ::ReadRec()
754 {
755 char *comma;
756 static char empty[] = { '\0' };
757
758 if( found == 1 ) {
759 Qcall = recbuffer;
760 comma = strchr( Qcall, ',' );
761 *comma = 0;
762 Qlname = comma + 1;
763 comma = strchr( Qlname, ',' );
764 *comma = 0;
765 Qfname = comma + 1;
766 comma = strchr( Qfname, ',' );
767 Qfname = comma + 1; // skip JR field
768 comma = strchr( Qfname, ',' );
769 *comma = 0;
770 Qdob = comma + 1;
771 comma = strchr( Qdob, ',' );
772 Qdob = comma + 1; // skip MI field
773 comma = strchr( Qdob, ',' );
774 *comma = 0;
775 Qefdate = comma + 1;
776 comma = strchr( Qefdate, ',' );
777 *comma = 0;
778 Qexpdate = comma + 1;
779 comma = strchr( Qexpdate, ',' );
780 *comma = 0;
781 Qmail_str = comma + 1;
782 comma = strchr( Qmail_str, ',' );
783 *comma = 0;
784 Qmail_city = comma + 1;
785 comma = strchr( Qmail_city, ',' );
786 *comma = 0;
787 Qmail_st = comma + 1;
788 comma = strchr( Qmail_st, ',' );
789 *comma = 0;
790 Qmail_zip = comma + 1;
791 comma = strchr( Qmail_zip, ',' );
792 *comma = 0;
793 Qopclass = comma + 1;
794 comma = strchr( Qopclass, ',' );
795 *comma = 0;
796 Qp_call = comma + 1;
797 comma = strchr( Qp_call, ',' );
798 *comma = 0;
799 Qp_class = comma + 1;
800 //Qp_class[1] = 0;
801 *(comma + 2) = 0;
802 Qimagefname = QRZImageFilename (GetCall());
803 return( 1 );
804 } else {
805 Qcall = empty;
806 Qlname = empty;
807 Qfname = empty;
808 Qdob = empty;
809 Qefdate = empty;
810 Qexpdate = empty;
811 Qmail_str = empty;
812 Qmail_city = empty;
813 Qmail_st = empty;
814 Qmail_zip = empty;
815 Qopclass = empty;
816 Qp_call = empty;
817 Qp_class = empty;
818 Qimagefname = NULL;
819 return( 0 );
820 }
821 }
822
GetCount(char * unknown)823 int QRZ::GetCount( char *unknown )
824 {
825 int matched, cnt = 0;
826 char temp[40];
827
828 if( FindRecord( unknown ) != 1 )
829 return(0);
830 matched = 0;
831 while (matched == 0) {
832 cnt++;
833 NextRecord();
834 switch (criteria) {
835 case 'c' :
836 matched = 1;
837 break;
838 case 'n' :
839 if( strchr( unknown, ',' ) == 0 )
840 matched = strcasecmp( unknown, GetLname() );
841 else {
842 strcpy( temp, GetLname() );
843 strcat( temp, "," );
844 strcat( temp, GetFname() );
845 matched = strncasecmp( unknown, temp, strlen(unknown) );
846 }
847 break;
848 case 'z' :
849 matched = strncmp( unknown, GetZIP(), 5 );
850 break;
851 case 's' :
852 matched = CompState( unknown, GetState(), GetCity() );
853 break;
854 default :
855 matched = 1;
856 }
857 }
858 return cnt;
859 }
860
GetCall()861 char * QRZ::GetCall()
862 {
863 static char call[15];
864 char *p = call;
865 strcpy (call, Qcall);
866 while (*p) {
867 if (*p == ' ') strcpy (p, p+1);
868 if (*p != ' ') p++;
869 }
870 return( call );
871 };
872
GetLname()873 const char * QRZ::GetLname()
874 {
875 return( Qlname );
876 };
877
GetFname()878 const char * QRZ::GetFname()
879 {
880 return( Qfname );
881 };
882
GetDOB()883 const char * QRZ::GetDOB()
884 {
885 return( Qdob );
886 };
887
GetEFdate()888 const char * QRZ::GetEFdate()
889 {
890 return( Qefdate );
891 };
892
GetEXPdate()893 const char * QRZ::GetEXPdate()
894 {
895 return( Qexpdate );
896 };
897
GetStreet()898 const char * QRZ::GetStreet()
899 {
900 return( Qmail_str );
901 };
902
GetCity()903 const char * QRZ::GetCity()
904 {
905 return( Qmail_city );
906 };
907
GetState()908 const char * QRZ::GetState()
909 {
910 return( Qmail_st );
911 };
912
GetZIP()913 const char * QRZ::GetZIP()
914 {
915 return( Qmail_zip );
916 };
917
GetOPclass()918 const char * QRZ::GetOPclass()
919 {
920 return( Qopclass );
921 };
922
GetPriorCall()923 const char * QRZ::GetPriorCall()
924 {
925 return( Qp_call );
926 };
927
GetPriorClass()928 const char * QRZ::GetPriorClass()
929 {
930 return( Qp_class );
931 };
932
getQRZvalid()933 int QRZ::getQRZvalid()
934 {
935 return( QRZvalid );
936 }
937
GetImageFileName()938 const char * QRZ::GetImageFileName ()
939 {
940 return (Qimagefname);
941 }
942
CSV_Record()943 char * QRZ::CSV_Record()
944 {
945 static char info[256];
946 memset( info, 0, 256 );
947 snprintf( info, sizeof(info) - 1, "%s,%s,%s,%s,%s,%s,%s,%s,%s",
948 GetCall(), Qopclass, Qefdate,
949 Qlname, Qfname, Qmail_str, Qmail_city, Qmail_st, Qmail_zip );
950 return info;
951 }
952
Fmt_Record()953 char *QRZ::Fmt_Record()
954 {
955 static char info[256];
956 memset( info, 0, 256 );
957 snprintf( info, sizeof(info) - 1, "%s %s : %s\n%s %s\n%s\n%s, %s %s\n",
958 GetCall(), Qopclass, Qefdate,
959 Qfname, Qlname,
960 Qmail_str,
961 Qmail_city, Qmail_st, Qmail_zip
962 );
963 return info;
964 }
965
966
967