home *** CD-ROM | disk | FTP | other *** search
/ The Pier Shareware 6 / The_Pier_Shareware_Number_6_(The_Pier_Exchange)_(1995).iso / 024 / psi110g.zip / QRZ.C < prev    next >
Text File  |  1994-07-05  |  15KB  |  542 lines

  1. // June 15, 1994 - KF5MG - Jack Snodgrass
  2. //
  3. // This code was adapted/copied from the SAM.C code. The code to process
  4. // the QRZ disk was taken from the QRZ CD-ROM. This code could work
  5. // with the name and zipcode versions of the Callbook data, but as-is, it
  6. // only processes callsigns.
  7. //
  8. #include <ctype.h>
  9. #include <stdio.h>
  10. #include <string.h>
  11. #include <stdlib.h>
  12. #include <io.h>
  13. #include <fcntl.h>
  14.  
  15. #define reclen 160
  16. #include "global.h"
  17. #ifdef QRZCALLB
  18. #include "mbuf.h"
  19. #include "socket.h"
  20. #include "session.h"
  21. #include "proc.h"
  22. #include "netuser.h"
  23. #include "commands.h"
  24. #include "tty.h"
  25. #include "config.h"
  26.  
  27. extern char *Callserver;                                   /* buckbook.c */
  28. int cb_lookup __ARGS((int s,char *,FILE *));
  29.  
  30. /* does the actual lookup.   */
  31. int  qrzfind(char *,int s, FILE *);
  32. /* Parse QRZ data record.    */
  33. void parse_record(char *, int s);
  34. /* Format QRZ Database Date. */
  35. void formatdate(char *);
  36.  
  37. /* Gobal variables. */
  38. char pretty_date[12];
  39. char prettycall[7];
  40. char *qrzdir;
  41. char *qrzdrv;
  42.  
  43. /*     Taken from the QRZ CD-ROM disk.
  44.  *     This block is located at the start of each index
  45.  */
  46. /*
  47.  *     New Index Header Block Definition
  48.  */
  49. typedef struct {
  50.   char  dataname[16];    /* Name of the data file            */
  51.   char  bytesperkey[8];  /* Data Bytes per Index Item        */
  52.   char  numkeys[8];      /* Number of items in this index    */
  53.   char  keylen[8];       /* Length of each key item in bytes */
  54.   char  version[8];      /* Database Version ID              */
  55. } index_header;
  56.  
  57. /*
  58.  *     Old Index Header Block Definition
  59.  */
  60. typedef struct {
  61.   char  dataname[13];    /* Name of the data file            */
  62.   long  bytesperkey;     /* Data Bytes per Index Item        */
  63.   int   numkeys;         /* Number of items in this index    */
  64.   int   keylen;          /* Length of each key item in bytes */
  65. } old_index_header ;
  66.  
  67. /* return values - 2= Callbook Error 1= not found, 0= okay */
  68. int cb_lookup(s, str, fp)
  69. int s;
  70. char *str;
  71. FILE *fp;
  72. {
  73.    if(qrzfind(str,s,fp))
  74.       return 0;
  75.    else
  76.       return 1;
  77. }
  78.  
  79. int qrzfind(char *call_in, int s, FILE *fpout)
  80. {
  81. index_header     idxhdr;
  82. old_index_header oldidxhdr;
  83.  
  84. FILE         *fp;
  85. char         *buf;
  86. char         *bufptr;
  87. char         IndexFile[] = "callbkc.idx";
  88. int          size;
  89. int          bytesperkey;     /* Data Bytes per Index Item        */
  90. int          numkeys;         /* Number of items in this index    */
  91. int          keylen;          /* Length of each key item in bytes */
  92. int          slots;
  93. int          i,j,k,found,slotcnt;
  94. long         fpos;
  95. long         frc;
  96. char         temp[255];
  97. char         *cp;
  98. char         *cp2;
  99. char         call[8];
  100.  
  101.  
  102.    /* call needs to be blank filled. */
  103.    strcpy(call,"       ");
  104.  
  105.    /* Pretty call holds the original, un-qrz-formatted callsign. */
  106.    strcpy(prettycall, call_in);
  107.    strupr(prettycall);
  108.  
  109.  
  110.    k = strlen(call_in);
  111.    if (k>6) {
  112.       usprintf(s,"Callsign too long.\n");
  113.       return 0;
  114.    }
  115.  
  116.    /* Callsigns in the QRZ Index are stored in a weird format. They are */
  117.    /* 6 characters in length ( padded with spaces ), in the format of   */
  118.    /* ccdccc where the digit is always in the 3rd posistion. If the     */
  119.    /* callsign is a 1-by-something callsign, the 2nd posistion will be  */
  120.    /* blank. KF5MG will be stored as KF5MGb. N5VGC will be stored as    */
  121.    /* Nb5VGC. ( the b are spaces )                                      */
  122.    /*                                                                   */
  123.    i = 1;
  124.    j = 1;
  125.    call[0] = call_in[0];
  126.    if(!isdigit(call_in[j]))
  127.       call[i++] = call_in[j++];
  128.    else
  129.       call[i++] = ' ';
  130.    if(isdigit(call_in[j])) {
  131.       call[i++] = call_in[j++];
  132.    } else {
  133.       /* No digit found in posistion 2 or 3. */
  134.       usprintf(s,"Error parsing callsign... %s\n", call_in);
  135.       return 0;
  136.    }
  137.    if(isalpha(call_in[j]))
  138.       call[i++] = call_in[j];
  139.    else
  140.       call[i++] = ' ';
  141.    j++;
  142.    if(isalpha(call_in[j]))
  143.       call[i++] = call_in[j];
  144.    else
  145.       call[i++] = ' ';
  146.    j++;
  147.    if(isalpha(call_in[j]))
  148.       call[i++] = call_in[j];
  149.    else
  150.       call[i++] = ' ';
  151.  
  152.  
  153.    call[6]   = 0;
  154.    strupr(call);
  155.  
  156.  
  157.    qrzdir = strdup(getenv("QRZPATH"));
  158.    qrzdrv = strdup(getenv("QRZDRV"));
  159.  
  160.    if(qrzdir == NULLCHAR)
  161.       qrzdir =  strdup("\\callbk");
  162.  
  163.    if(qrzdrv == NULLCHAR)
  164.       qrzdrv =  strdup("C:");
  165.  
  166.    /* Open the index file.  We'll use it to tell us the name of the     */
  167.    /* database file. We'll also find the database version and some      */
  168.    /* other useful info.                                                */
  169.    /*                                                                   */
  170.    sprintf(temp,"%s%s\\%s",qrzdrv,qrzdir,IndexFile);
  171.    if((fp = fopen(temp,"rt"))==NULL) {
  172.       usprintf(s,"Error opening Index: %s\n",temp);
  173.       free(qrzdir);
  174.       free(qrzdrv);
  175.       return 0;
  176.    }
  177.  
  178.    size = fread(&idxhdr,sizeof(idxhdr),1,fp);
  179.    if(size != 1) {
  180.       usprintf(s,"Error reading Index Header.\n");
  181.       free(qrzdir);
  182.       free(qrzdrv);
  183.       return 0;
  184.    }
  185.  
  186.    // Old Style Index has a '0' at pos 16 and 17.
  187.    if((int)idxhdr.dataname[16] != 0) {
  188.       // This is a 'new' style index
  189.       bytesperkey = atoi(idxhdr.bytesperkey);   /* size of data area.   */
  190.       numkeys     = atoi(idxhdr.numkeys);       /* # of keys in file.   */
  191.       keylen      = atoi(idxhdr.keylen);        /* length of each key.  */
  192.    } else {
  193.       // This is an 'old' style index.
  194.       // rewind the file and read the header using the old_index_header struct.
  195.       rewind(fp);
  196.  
  197.       size = fread(&oldidxhdr,sizeof(oldidxhdr),1,fp);
  198.       if(size != 1) {
  199.          usprintf(s,"Error reading Index Header.\n");
  200.          free(qrzdir);
  201.          free(qrzdrv);
  202.          return 0;
  203.       }
  204.       bytesperkey = oldidxhdr.bytesperkey;      /* size of data area.   */
  205.       numkeys     = oldidxhdr.numkeys;          /* # of keys in file.   */
  206.       keylen      = oldidxhdr.keylen;           /* length of each key.  */
  207.    }
  208.  
  209.    /* This is a 10K ish buffer. Each 'key' in the index covers almost   */
  210.    /* 10K of data. Once you find the correct key, you have to read the  */
  211.    /* 10K chunk of data from the data file. You then start searching    */
  212.    /* for the correct callsign. This code uses the same 10k buffer to   */
  213.    /* scan the index file ( typically 40K so you might do 4 reads ) to  */
  214.    /* save memory. Once you've found the correct key, you calculate the */
  215.    /* offset into the database. You then read the data base into your   */
  216.    /* 10K buffer.
  217.    /*                                                                   */
  218.    bufptr      = malloc(bytesperkey+400);       /* Get space for buffer */
  219.    slots       = bytesperkey / keylen;          /* Calculate # of slots */
  220.    found       = 0;
  221.    slotcnt     = 0;
  222.  
  223.    do {
  224.       /* Point floating buf pointer to start of big buffer.   */
  225.       buf      = bufptr;
  226.       /* Read slots number of entries that are keylen in size */
  227.       size = fread(buf,keylen,slots,fp);
  228.       if(size == 0) {
  229.          usprintf(s,"Error reading Index file.\n");
  230.          found = 2;
  231.       }
  232.  
  233.       /* Start scanning Index buffer. If the data is less than your search */
  234.       /* Value... keep going. If the Data is greater, then your done. You  */
  235.       /* then subtract one from your slotcnt (unless it's an exact match)  */
  236.       /* and that's the closet record to your data.                        */
  237.       /*                                                                   */
  238.       for(i=0;i<size;i++) {
  239.         slotcnt++;
  240.         strncpy(temp,(char *)buf,keylen);
  241.         temp[keylen] = 0;
  242.         if(strncmp(&temp[3],&call[3],3) >= 0) {
  243.            if(strncmp(&temp[3],&call[3],3) > 0) {
  244.            found = 1;
  245.               slotcnt--;
  246.            }
  247.            else
  248.               if(strncmp(&temp[2],&call[2],4) > 0) {
  249.                  slotcnt--;
  250.                  found = 1;
  251.               }
  252.         }
  253.         if(found)
  254.            break;
  255.         /*
  256.         *buf++;
  257.         *buf++;
  258.         *buf++;
  259.         *buf++;
  260.         *buf++;
  261.         *buf++;
  262.         */
  263.         buf += 6;
  264.       }
  265.    } while(!found); /* enddo */
  266.  
  267.    slotcnt--;
  268.  
  269.    /* We're done with the Index so we can close it. */
  270.    fclose(fp);
  271.  
  272.    /* If we found a match, the calculate the offset and read the data. */
  273.    if(found == 1) {
  274.       buf      = bufptr;
  275.       sprintf(temp,"%s%s\\%s",qrzdrv,qrzdir,idxhdr.dataname);
  276.       if((fp = fopen(temp,"rt"))==NULL) {
  277.          usprintf(s,"Error opening Database: %s\n",temp);
  278.          free(bufptr);
  279.          free(qrzdir);
  280.          free(qrzdrv);
  281.          return 0;
  282.       }
  283.  
  284.       /* Just to to be save, we read 200 bytes before and after so we  */
  285.       /* don't miss anything.                                          */
  286.       /* seek to correct posistion in file .                           */
  287.       fpos = (long) bytesperkey*slotcnt;
  288.       fpos -= 200;
  289.  
  290.       frc = lseek(fileno(fp),(long) fpos,SEEK_SET);
  291.       if(frc < 1) {
  292.          usprintf(s,"Error seeking Database file.\n");
  293.          free(bufptr);
  294.          free(qrzdir);
  295.          free(qrzdrv);
  296.          return 0;
  297.       }
  298.  
  299.       /* Read slot from callbk file. */
  300.       size = fread(buf,bytesperkey+400,1,fp);
  301.       if(size < 1) {
  302.          usprintf(s,"Error reading Database file.\n");
  303.          free(bufptr);
  304.          free(qrzdir);
  305.          free(qrzdrv);
  306.          return 0;
  307.       }
  308.  
  309.       /* Done with data file. Now we can close it too. Our users is either */
  310.       /* in our buffer or doesn't exist.                                   */
  311.       fclose(fp);
  312.  
  313.       i = 0;
  314.       for(;;) {
  315.          if(i>bytesperkey+400)
  316.             break;
  317.          k = strcspn(buf,"\n");
  318.          strncpy(temp,buf,k);
  319.          temp[k] = 0;
  320.          for(j=0;j<=k;j++)
  321.             /*
  322.             *buf++;
  323.             */
  324.             buf += 1;
  325.  
  326.          /* Find our user. */
  327.          if(strncmp(temp,call,6) == 0) {
  328.             /* Found it. Now read and format the data. */
  329.             parse_record(temp,s);
  330.             break;
  331.          }
  332.          i+=k;
  333.       }
  334.    }
  335.    /* Done with the buffer. */
  336.    free(bufptr);
  337.    free(qrzdir);
  338.    free(qrzdrv);
  339.    return found;
  340. }
  341.  
  342. void parse_record(char *record, int s) {
  343. /*
  344.  *    Standard Record Format
  345.  */
  346. char callsign[7];         /* Call Sign Decoded      */
  347. char lastname[33];        /* Last Name              */
  348. char namesuffix[3];       /* Name Suffix            */
  349. char frstname[33];        /* First Name             */
  350. char middleinit[3];       /* Middle Initial         */
  351. char datelicensed[6];     /* Date Licensed mm/dd/yy */
  352. char dateborn[6];         /* Date Born              */
  353. char dateexpires[6];         /* Date Born              */
  354. char streetaddr[33];      /* Street Address         */
  355. char city[33];            /* City                   */
  356. char state[3];            /* State Code             */
  357. char zipcode[6];          /* Zip Code               */
  358. char license_class[3];    /* License Class          */
  359. char prevcall[7];         /* Previous Call          */
  360. char prevclass[3];        /* Previous Class         */
  361.  
  362. char *cp;
  363. char fullname[80];
  364. char address[80];
  365. char temp[255];
  366. char temp2[255];
  367. int  i,j,k;
  368.  
  369.   strcpy(temp2,record);
  370.   cp = temp2;
  371.  
  372.   k = strcspn(cp,",");
  373.   strncpy(temp,cp,k);
  374.   temp[k] = 0;
  375.   for(j=0;j<=k;j++)
  376.      cp += 1;
  377.   strcpy(callsign,temp);
  378.  
  379.   if(strlen(record) < 16) {
  380.      usprintf(s,"%s is an old call for %s\n", prettycall, cp);
  381.      return;
  382.   }
  383.  
  384.   k = strcspn(cp,",");
  385.   strncpy(temp,cp,k);
  386.   temp[k] = 0;
  387.   for(j=0;j<=k;j++)
  388.      cp += 1;
  389.   strcpy(lastname,temp);
  390.  
  391.  
  392.   k = strcspn(cp,",");
  393.   strncpy(temp,cp,k);
  394.   temp[k] = 0;
  395.   for(j=0;j<=k;j++)
  396.      cp += 1;
  397.   strcpy(namesuffix,temp);
  398.  
  399.   k = strcspn(cp,",");
  400.   strncpy(temp,cp,k);
  401.   temp[k] = 0;
  402.   for(j=0;j<=k;j++)
  403.      cp += 1;
  404.   strcpy(frstname,temp);
  405.  
  406.   k = strcspn(cp,",");
  407.   strncpy(temp,cp,k);
  408.   temp[k] = 0;
  409.   for(j=0;j<=k;j++)
  410.      cp += 1;
  411.   strcpy(middleinit,temp);
  412.  
  413.   k = strcspn(cp,",");
  414.   strncpy(temp,cp,k);
  415.   temp[k] = 0;
  416.   for(j=0;j<=k;j++)
  417.      cp += 1;
  418.   strcpy(dateborn,temp);
  419.  
  420.   k = strcspn(cp,",");
  421.   strncpy(temp,cp,k);
  422.   temp[k] = 0;
  423.   for(j=0;j<=k;j++)
  424.      cp += 1;
  425.   strcpy(datelicensed, temp);
  426.  
  427.   k = strcspn(cp,",");
  428.   strncpy(temp,cp,k);
  429.   temp[k] = 0;
  430.   for(j=0;j<=k;j++)
  431.      cp += 1;
  432.   strcpy(dateexpires,temp);
  433.  
  434.   k = strcspn(cp,",");
  435.   strncpy(temp,cp,k);
  436.   temp[k] = 0;
  437.   for(j=0;j<=k;j++)
  438.      cp += 1;
  439.   strcpy(streetaddr,temp);
  440.  
  441.   k = strcspn(cp,",");
  442.   strncpy(temp,cp,k);
  443.   temp[k] = 0;
  444.   for(j=0;j<=k;j++)
  445.      cp += 1;
  446.   strcpy(city,temp);
  447.  
  448.   k = strcspn(cp,",");
  449.   strncpy(temp,cp,k);
  450.   temp[k] = 0;
  451.   for(j=0;j<=k;j++)
  452.      cp += 1;
  453.   strcpy(state,temp);
  454.  
  455.   k = strcspn(cp,",");
  456.   strncpy(temp,cp,k);
  457.   temp[k] = 0;
  458.   for(j=0;j<=k;j++)
  459.      cp += 1;
  460.   strcpy(zipcode,temp);
  461.  
  462.   k = strcspn(cp,",");
  463.   strncpy(temp,cp,k);
  464.   temp[k] = 0;
  465.   for(j=0;j<=k;j++)
  466.      cp += 1;
  467.   strcpy(license_class,temp);
  468.  
  469.   k = strcspn(cp,",");
  470.   strncpy(temp,cp,k);
  471.   temp[k] = 0;
  472.   for(j=0;j<=k;j++)
  473.      cp += 1;
  474.   strcpy(prevcall,temp);
  475.  
  476.   k = strcspn(cp,",");
  477.   strncpy(temp,cp,k);
  478.   temp[k] = 0;
  479.   for(j=0;j<=k;j++)
  480.      cp += 1;
  481.   strcpy(prevclass,temp);
  482.  
  483.   sprintf(fullname,"%s %s. %s, %s",frstname, middleinit, lastname, namesuffix);
  484.   sprintf(address, "%s, %s, %s", city, state, zipcode);
  485.  
  486.   usprintf(s,"\n%-8s", prettycall);
  487.   usprintf(s,"%-45s", fullname);
  488.   formatdate(dateborn);
  489.   usprintf(s,"Born:    %s\n", pretty_date);
  490.  
  491.   usprintf(s,"%-8s%-45s","", streetaddr);
  492.   formatdate(datelicensed);
  493.   usprintf(s,"Class: %s %s\n", license_class, pretty_date);
  494.  
  495.   usprintf(s,"%-8s%-45s", "", address);
  496.   usprintf(s,"Prev:  %s %s\n", prevclass, prevcall);
  497.  
  498.   formatdate(dateexpires);
  499.   usprintf(s,"%52s Expir:   %s\n", "", pretty_date);
  500.  
  501.   return;
  502. }
  503.  
  504. void formatdate(char *date){
  505. char year[5];
  506. char rest[4];
  507. int  mon;
  508. int  day;
  509. int  days;
  510. int  years;
  511. int  i;
  512.  
  513. int  dayarray[12] = { 31,  60,  91, 121, 152, 182,
  514.                      213, 244, 274, 305, 335, 366 };
  515.  
  516.    strncpy(year,date,2);
  517.    year[2]  = 0;
  518.    years    = atoi(year);
  519.    if(years < 20)
  520.       years += 2000;
  521.    else
  522.       years += 1900;
  523.  
  524.    strncpy(rest,&date[2],3);
  525.    rest[3]  = 0;
  526.    days     = atoi(rest);
  527.  
  528.    if((years % 4) != 0)
  529.       if(days > 59)
  530.          days++;
  531.  
  532.    for(i=0;i<12;i++){
  533.       if(days <= dayarray[i]) {
  534.          mon = i;
  535.          day = days - dayarray[i-1];
  536.          break;
  537.       }
  538.    }
  539.    sprintf(pretty_date, "%02d/%02d/%04d", mon+1,day,years);
  540. }
  541. #endif
  542.