home *** CD-ROM | disk | FTP | other *** search
/ The Pier Shareware 6 / The_Pier_Shareware_Number_6_(The_Pier_Exchange)_(1995).iso / 024 / psi110g.zip / CALLBOOK.C < prev    next >
C/C++ Source or Header  |  1994-04-17  |  15KB  |  594 lines

  1. #include <time.h>
  2. #include <sys/timeb.h>
  3. #include "global.h"
  4. #ifdef CALLBOOK
  5. #include "files.h"
  6.   
  7. #undef DEBUG 1
  8. #define TRUE 1
  9. #define FALSE 0
  10.   
  11. static int days_tbl[13] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
  12.   
  13.   
  14. struct callrec  {
  15.     char    *call;
  16.     char    *last_name;
  17.     char    *title;
  18.     char    *first_name;
  19.     char    *middle_name;
  20.     char    *birth_date;
  21.     char    *license_date;
  22.     char    *expire_date;
  23.     char    *mail_addr1;
  24.     char    *mail_city;
  25.     char    *mail_state;
  26.     char    *zip;
  27.     char    *location1;
  28.     char    *location2;
  29.     char    *location3;
  30.     char    *license_class;
  31.     char    *prev_call;
  32.     char    *prev_class;
  33.     char    *extra;
  34. };
  35.   
  36. typedef struct callrec CALLREC;
  37.   
  38. #define HIGHER 1
  39. #define LOWER 0
  40.   
  41.   
  42. extern char *get_field();
  43. extern fill_record();
  44. extern long calc_nxt_record();
  45. extern strnicmp();
  46.   
  47.   
  48. long    firstrec;       /* address of the end of the first record */
  49. char    cbuffer[256];
  50. CALLREC current_rec;
  51.   
  52.   
  53. struct tm st_time;
  54.   
  55. struct tm *ct_time;
  56. long    rtime;          /* time in secs since 70 */
  57.   
  58.   
  59. long    lasthi,lastlo,current;
  60.   
  61. cb_lookup(s,call)
  62. int s;
  63. char    *call;
  64. {
  65.     FILE    *fp;
  66.     char    *file;      /* derived file name */
  67.     long    pos = 0;
  68.     int sts;
  69.     int dir,srch;
  70.     char    search_call[10];
  71.     int srch_cnt = 0;
  72.     int srch_len= 0;
  73.     char    tmpstr[80];
  74.     unsigned    bdy,byr;
  75.     int yrs_old;
  76.     char    class;
  77.   
  78.     srch_len = strlen(call);
  79.     strcpy(search_call,"      ");
  80.     strncpy(search_call,call,srch_len);
  81. #ifdef notdef
  82.     file = (char *)pathname(CDBdir,"calldb");
  83.     tprintf("Opening database: %s\n",file);
  84.   
  85.     if((fp = fopen(file,READ_TEXT)) == NULLFILE)
  86. #endif
  87.         if((fp = fopen("/callbook/calldb",READ_TEXT)) == NULLFILE)
  88.         {
  89.             usputs(s,"Callbook Services unavailable.\n");
  90. #ifdef notdef
  91.             free(file);
  92. #endif
  93.             return(0);
  94.         }
  95. #ifdef notdef
  96.     free(file);     /* free up the filename string */
  97. #endif
  98.     /* position to end of file */
  99.     fseek(fp,0L,2L);
  100.     lasthi = ftell(fp);
  101.   
  102. #ifdef DEBUG
  103.     usprintf(s,"lasthi %ld\n",lasthi);
  104. #endif
  105.   
  106.     lastlo = 0;
  107.     current = lasthi/2;
  108.   
  109.     fgets(cbuffer,256,fp);
  110.     cbuffer[0] = '\0';
  111.   
  112.     firstrec = ftell(fp);
  113.   
  114.     while(current >= 0)
  115.     {
  116. #ifdef DEBUG
  117.         usprintf(s,"Position: %d\n",current);
  118. #endif
  119.         pwait(NULL);        /* give up the processor for others to run */
  120.   
  121.         sts = find_next_rec(fp,current,cbuffer);
  122.         if(sts)
  123.         {
  124.             usputs(s,"Error reading database\n");
  125.             fclose(fp);
  126.             return(0);
  127.         }
  128.   
  129.         srch_cnt++;
  130.   
  131.         srch = strnicmp(search_call,cbuffer,6);
  132.   
  133. #ifdef DEBUG
  134.         usprintf(s,"srch: %s    currec: %s\n",search_call,current_rec.call);
  135. #endif
  136.         if(srch== 0)
  137.         {
  138.             memset(¤t_rec,'\0',sizeof(struct callrec));
  139.   
  140.             sts = fill_record(cbuffer,¤t_rec);
  141.   
  142.             if(sts == 0)
  143.             {
  144.                 usprintf(s,"\n\nCallsign:  %s\n",current_rec.call);
  145.   
  146.                 /* License Class */
  147.                 usputs(s,"Class:     ");
  148.                 class = current_rec.license_class[0];
  149.                 switch(class)
  150.                 {
  151.                     case    'A':    usputs(s,"Advanced");
  152.                         break;
  153.                     case    'E':    usputs(s,"Extra");
  154.                         break;
  155.                     case    'G':    usputs(s,"General");
  156.                         break;
  157.                     case    'N':    usputs(s,"Novice");
  158.                         break;
  159.                     case    'T':    usputs(s,"Technician");
  160.                         break;
  161.                     default:    usputs(s,"Unknown");
  162.                 }
  163.                 usputc(s,'\n');
  164.   
  165.                 /* Expire Date */
  166.                 sprintf(tmpstr,"%.2s",current_rec.expire_date);
  167.   
  168.                 sscanf(tmpstr,"%d",&byr);
  169.                 sprintf(tmpstr,"%s",¤t_rec.expire_date[2]);
  170.                 sscanf(tmpstr,"%d",&bdy);
  171.   
  172.                 month_day_year(byr,bdy,&st_time);
  173.   
  174.                 format_date(&st_time,tmpstr);
  175.                 usprintf(s,"Expires:   %s\n",tmpstr);
  176.                 usputc(s,'\n');  /* blank line */
  177.   
  178.                 usprintf(s,"Owner:     %s ",current_rec.first_name);
  179.                 if(current_rec.middle_name != NULL)
  180.                     usprintf(s,"%s ",current_rec.middle_name);
  181.                 usprintf(s,"%s ",current_rec.last_name);
  182.                 if(current_rec.title != NULL)
  183.                     usputs(s,current_rec.title);
  184.   
  185.                 usputc(s,'\n');
  186.   
  187.   
  188.                 /* Address formatting */
  189.   
  190.                 usprintf(s,"           %s\n",current_rec.mail_addr1);
  191.   
  192.                 usputs(s,"           ");  /* line up nxt line */
  193.   
  194.                 if(current_rec.mail_city != NULL)
  195.                     usprintf(s,"%s ",current_rec.mail_city);
  196.                 if(current_rec.mail_state != NULL)
  197.                     usprintf(s,"%s ",current_rec.mail_state);
  198.                 if(current_rec.zip != NULL)
  199.                     usprintf(s,"%s ",current_rec.zip);
  200.                 usputc(s,'\n');
  201.   
  202.   
  203.                 /* Birth date */
  204.                 sprintf(tmpstr,"%.2s",current_rec.birth_date);
  205.   
  206.                 sscanf(tmpstr,"%d",&byr);
  207.                 sprintf(tmpstr,"%s",¤t_rec.birth_date[2]);
  208.                 sscanf(tmpstr,"%d",&bdy);
  209.   
  210.                 month_day_year(byr,bdy,&st_time);
  211.   
  212.   
  213.                 /* get current date and time */
  214.                 rtime = time((time_t *)0);
  215.                 ct_time = localtime(&rtime);
  216.   
  217.                 /* calculate age */
  218.                 yrs_old = ct_time->tm_year -  byr;
  219.   
  220.                 if((st_time.tm_mday > ct_time->tm_mday) &&
  221.                     (st_time.tm_mon >=  ct_time->tm_mon)) yrs_old--;
  222.   
  223.   
  224. /*
  225.                 format_date(&st_time,tmpstr);
  226.                 usprintf(s,"Birth date:      %s\n",tmpstr);
  227. */
  228.   
  229.   
  230.                 usputc(s,'\n'); /* blank line */
  231.   
  232.                 if(current_rec.prev_call != NULL)
  233.                     usprintf(s,"Prev Call: %s\n",current_rec.prev_call);
  234.                 usprintf(s,"Age:       %d\n",yrs_old);
  235.             }
  236.   
  237.             else
  238.             {
  239.                 usputs(s,"Internal Database Error!\n");
  240.             }
  241.   
  242.             usprintf(s,"\nSearch Count: %d\n\n",srch_cnt);
  243.   
  244.             free_record(¤t_rec);
  245.   
  246.             fclose(fp);
  247.             return(0);
  248.         }
  249.   
  250.         else
  251.         {
  252.             if(srch < 0)
  253.             {
  254.                 dir = LOWER;
  255. #ifdef DEBUG
  256.                 usprintf(s,"Nomatch: %s    TRY LOWER\n",current_rec.call);
  257. #endif
  258.             }
  259.             if(srch > 0)
  260.             {
  261.                 dir = HIGHER;
  262. #ifdef DEBUG
  263.                 usprintf(s,"Nomatch: %s    TRY HIGHER\n",current_rec.call);
  264. #endif
  265.             }
  266.             current = calc_nxt_record(dir);
  267.         }
  268.     }
  269.   
  270.     usputs(s,"Record not found!\n");
  271.     usprintf(s,"Search Count: %d\n",srch_cnt);
  272.     fclose(fp);
  273.   
  274. }
  275.   
  276. /* seek to file position "pos" then find start of next record */
  277.   
  278. find_next_rec(fp,pos,buffer)
  279. FILE    *fp;
  280. long pos;
  281. char    *buffer;
  282. {
  283.   
  284.     /* go to the right place in the file */
  285.     /* if error then exit */
  286.   
  287.     if(fseek(fp,pos,0L) != 0) return -1;
  288.   
  289.     /* get and toss any partial record */
  290.     if(pos != 0)fgets(buffer,256,fp);
  291.   
  292.     /* now get next complete record */
  293.     fgets(buffer,256,fp);
  294.   
  295.     return 0;
  296.   
  297. }
  298.   
  299.   
  300.   
  301. /* here disect an input string into it's component parts */
  302. fill_record(buffer,record)
  303. char    *buffer;
  304. CALLREC *record;
  305. {
  306.     char    fldbuf[256];
  307.     char    *tmpbuf;
  308.     int sts;
  309.   
  310.     sts = -1;       /* default to fail */
  311.     tmpbuf = buffer;
  312.   
  313.     while(1)
  314.     {
  315.   
  316.     /* get the data fields... and expand as neccessary */
  317.         if((tmpbuf = get_field(tmpbuf,fldbuf)) == NULL) break;
  318.   
  319.     /* get the callsign */
  320.         if(strlen(fldbuf))record->call = strdup(fldbuf);
  321.   
  322.         if((tmpbuf = get_field(tmpbuf,fldbuf)) == NULL) break;
  323.         if(strlen(fldbuf))record->last_name = strdup(fldbuf);
  324.   
  325.         if((tmpbuf = get_field(tmpbuf,fldbuf)) == NULL) break;
  326.         if(strlen(fldbuf))record->title = strdup(fldbuf);
  327.   
  328.         if((tmpbuf = get_field(tmpbuf,fldbuf)) == NULL) break;
  329.         if(strlen(fldbuf))record->first_name = strdup(fldbuf);
  330.   
  331.         if((tmpbuf = get_field(tmpbuf,fldbuf)) == NULL) break;
  332.         if(strlen(fldbuf))record->middle_name = strdup(fldbuf);
  333.   
  334.         if((tmpbuf = get_field(tmpbuf,fldbuf)) == NULL) break;
  335.         if(strlen(fldbuf))record->birth_date = strdup(fldbuf);
  336.   
  337.         if((tmpbuf = get_field(tmpbuf,fldbuf)) == NULL) break;
  338.         if(strlen(fldbuf))record->license_date = strdup(fldbuf);
  339.   
  340.         if((tmpbuf = get_field(tmpbuf,fldbuf)) == NULL) break;
  341.         if(strlen(fldbuf))record->expire_date = strdup(fldbuf);
  342.   
  343.         if((tmpbuf = get_field(tmpbuf,fldbuf)) == NULL) break;
  344.         if(strlen(fldbuf))record->mail_addr1 = strdup(fldbuf);
  345.   
  346.         if((tmpbuf = get_field(tmpbuf,fldbuf)) == NULL) break;
  347.         if(strlen(fldbuf))record->mail_city = strdup(fldbuf);
  348.   
  349.         if((tmpbuf = get_field(tmpbuf,fldbuf)) == NULL) break;
  350.         if(strlen(fldbuf))record->mail_state = strdup(fldbuf);
  351.   
  352.         if((tmpbuf = get_field(tmpbuf,fldbuf)) == NULL) break;
  353.         if(strlen(fldbuf))record->zip = strdup(fldbuf);
  354.   
  355.         if((tmpbuf = get_field(tmpbuf,fldbuf)) == NULL) break;
  356.         if(strlen(fldbuf))record->location1 = strdup(fldbuf);
  357.   
  358.         if((tmpbuf = get_field(tmpbuf,fldbuf)) == NULL) break;
  359.         if(strlen(fldbuf))record->location2 = strdup(fldbuf);
  360.   
  361.         if((tmpbuf = get_field(tmpbuf,fldbuf)) == NULL) break;
  362.         if(strlen(fldbuf))record->location3 = strdup(fldbuf);
  363.   
  364.         if((tmpbuf = get_field(tmpbuf,fldbuf)) == NULL) break;
  365.         if(strlen(fldbuf))record->license_class = strdup(fldbuf);
  366.   
  367.         if((tmpbuf = get_field(tmpbuf,fldbuf)) == NULL) break;
  368.         if(strlen(fldbuf))record->prev_call = strdup(fldbuf);
  369.   
  370.         if((tmpbuf = get_field(tmpbuf,fldbuf)) == NULL) break;
  371.         if(strlen(fldbuf))record->prev_class = strdup(fldbuf);
  372.   
  373.         get_field(tmpbuf,fldbuf);
  374.         if(strlen(fldbuf)) record->extra = strdup(fldbuf);
  375.         sts = 0;
  376.     }
  377.   
  378.   
  379.     return sts;
  380.   
  381. }
  382.   
  383.   
  384. /* given input buffer, pull out the next field, copying data into specified */
  385. /* field, and return pointer to beginning of next field... skipping over */
  386. /* the "BAR".  Return NULL for no more fields */
  387.   
  388. char *
  389. get_field(buffer,field)
  390. char    *buffer;
  391. char    *field;
  392. {
  393.   
  394.     char    *bar;
  395.     int field_len;
  396.     int blnklen = 0;
  397.   
  398.     field[0] = '\0';    /* initially null terminate the string */
  399.   
  400.     /* find the "BAR" separator field */
  401.     bar = strchr(buffer,'|');
  402.   
  403.     if(bar != NULL)
  404.     {
  405.         field_len = (int)(bar - buffer);
  406.   
  407.         if(field_len)
  408.         {
  409.             blnklen = strspn(buffer," ");
  410.             strncpy(field,buffer+blnklen,field_len-blnklen);
  411.   
  412.             field[field_len-blnklen] = '\0';    /* terminate the string */
  413.         }
  414.   
  415.         /* bump pointer past the "BAR" */
  416.         bar +=1;
  417.     }
  418.     else
  419.     {
  420.         field_len = strlen(buffer);
  421.         blnklen = strspn(buffer," ");
  422.         strncpy(field,buffer+blnklen,field_len-blnklen);
  423.         field[field_len-blnklen] = '\0';   /* terminate the string */
  424.     }
  425.     return bar;
  426. }
  427.   
  428. long
  429. calc_nxt_record(dir)
  430. int dir;
  431. {
  432.     long    new;
  433.   
  434.     if(dir == LOWER)
  435.     {
  436.         lasthi = current;
  437.         if(current == 1 )new = 0;
  438.         else new = current - ((current - lastlo)/2);
  439.     }
  440.   
  441.     if(dir == HIGHER)
  442.     {
  443.         lastlo = current;
  444.         new = current + ((lasthi-current)/2);
  445.     }
  446.   
  447.     if(new == current)new = -1;
  448.   
  449.     return new;
  450. }
  451.   
  452.   
  453. #ifdef BSD
  454.   
  455. /* Case-insensitive string comparison */
  456. strnicmp(a,b,n)
  457. register char *a,*b;
  458. register int n;
  459. {
  460.     char a1,b1;
  461.   
  462.     while(n-- != 0 && (a1 = *a++) != '\0' && (b1 = *b++) != '\0'){
  463.         if(a1 == b1)
  464.             continue;   /* No need to convert */
  465.         a1 = tolower(a1);
  466.         b1 = tolower(b1);
  467.         if(a1 == b1)
  468.             continue;   /* NOW they match! */
  469.         if(a1 > b1)
  470.             return 1;
  471.         if(a1 < b1)
  472.             return -1;
  473.     }
  474.     return 0;
  475. }
  476.   
  477. #endif
  478.   
  479.   
  480.   
  481.   
  482. format_date(st_time,day_str)
  483. struct  tm  *st_time;
  484. char    *day_str;
  485. {
  486.     sprintf(day_str,"%1d/%1d/%2d",
  487.     st_time->tm_mon,
  488.     st_time->tm_mday,
  489.     st_time->tm_year);
  490. }
  491.   
  492.   
  493.   
  494. /*
  495.  * Fills the  time/date structure from supplied DAY of YEAR
  496.  */
  497. month_day_year(year,dayno,st_time)
  498. unsigned year,dayno;
  499. struct tm *st_time;
  500. {
  501.     int i;
  502.     unsigned leap,days;
  503.     unsigned month;
  504.     unsigned days_in_year, cur_days_in_cur_month;
  505.   
  506.   
  507.     days = dayno;
  508.   
  509.     if ((year % 4) == 0)
  510.         leap = TRUE;
  511.     else
  512.         leap = FALSE;
  513.   
  514.     month = 1;
  515.   
  516.     cur_days_in_cur_month = days_tbl[1];
  517.   
  518.     /* now add in the days for previous months in this year */
  519.     while ( days > cur_days_in_cur_month )
  520.     {
  521.         /* next month */
  522.         month++;
  523.   
  524.         /* remaining days in year */
  525.         days -= cur_days_in_cur_month;
  526.   
  527.         /* get current month's days */
  528.         cur_days_in_cur_month = days_tbl[month];
  529.   
  530.         if ( (month == 2) && (leap) )
  531.             cur_days_in_cur_month++;
  532.     }
  533.   
  534.     if ( days == 0 )
  535.         st_time->tm_mday = 1;
  536.     else
  537.         st_time->tm_mday = days;
  538.   
  539.     st_time->tm_mon = month;
  540.     st_time->tm_year = year;
  541.     st_time->tm_sec = 0;
  542.     st_time->tm_min = 0;
  543.     st_time->tm_hour = 0;
  544.   
  545.     return;
  546. }
  547.   
  548. free_record(record)
  549. CALLREC *record;
  550. {
  551.   
  552.     if(record->call != NULL) free(record->call);
  553.   
  554.     if(record->last_name != NULL) free(record->last_name);
  555.   
  556.     if(record->title != NULL) free(record->title);
  557.   
  558.     if(record->first_name != NULL) free(record->first_name);
  559.   
  560.     if(record->middle_name != NULL) free(record->middle_name);
  561.   
  562.     if(record->birth_date != NULL) free(record->birth_date);
  563.   
  564.     if(record->license_date != NULL) free(record->license_date);
  565.   
  566.     if(record->expire_date != NULL) free(record->expire_date);
  567.   
  568.     if(record->mail_addr1 != NULL) free(record->mail_addr1);
  569.   
  570.     if(record->mail_city != NULL) free(record->mail_city);
  571.   
  572.     if(record->mail_state != NULL) free(record->mail_state);
  573.   
  574.     if(record->zip != NULL) free(record->zip);
  575.   
  576.     if(record->location1 != NULL) free(record->location1);
  577.   
  578.     if(record->location2 != NULL) free(record->location2);
  579.   
  580.     if(record->location3 != NULL) free(record->location3);
  581.   
  582.     if(record->license_class != NULL) free(record->license_class);
  583.   
  584.     if(record->prev_call != NULL) free(record->prev_call);
  585.   
  586.     if(record->prev_class != NULL) free(record->prev_class);
  587.   
  588.     if( record->extra != NULL) free(record->extra);
  589.   
  590.   
  591. }
  592. #endif /* CALLBOOK */
  593.   
  594.