// StatConv.C - Converting STATIONS.59 to STATIONS.DBF
// Written by Stefan Pfeiffer, DL1ELY, 951027
// Last Modification: 951220
// (C) 1995 by Stefan Pfeiffer, DL1ELY

#include "dbase.h"
#include <stdio.h>
#include <string.h>
#include <mem.h>
#include <dos.h>

#define OLD_NAME  "\STATIONS.59"
#define NEW_NAME  "\STATIONS.DBF"
#define NEW_NAME2 "\STATIONS.NFO"

#define STATION_HEADER "STATIONS0\r\nStation-Database for FiveNine\r\n(C) 1994-95 by Stefan Pfeiffer, DL1ELY\r\n\x1A"

#define TITLE "Stations-Convert v1.00 by Stefan Pfeiffer, DL1ELY"

typedef struct callinfo
{
  unsigned char call[13];
  unsigned char locator[7];
  unsigned char mon;
  unsigned char year;
  unsigned char info[80];
};


// Format der Datenfelder in STATIONS.DBF:
// CALL         ZEICHEN 12
// INFO_IDX     NUMMER   7
// QRV_ON       ZEICHEN 15
// LOCATORS     ZEICHEN 34
// LOC_DATE     NUMMER   4
// MULTI_INFO   ZEICHEN  6
// MULTI_DATE   NUMMER   4


void write_dbf_header(FILE *dbf)
{
   struct db_header header;
   struct db_rec_def def;
   unsigned char i;
   struct date d;

   getdate(&d);

   header.version = 0x03;
   header.last_access[2] = d.da_day;
   header.last_access[1] = d.da_mon;
   header.last_access[0] = (unsigned char)(d.da_year%100);
   header.rec_count = 0;
   header.header_len = sizeof(header)+(sizeof(def)*7)+1;
   header.rec_len = 83;
   memset(&header.reserved,0,20);
   fwrite(&header,1,sizeof(header),dbf);

   memset(&def.name,0,11);
   strcpy(def.name,"CALL");
   def.type = 'C';
   def.address = 0L;
   def.len = 12;
   def.decimals = 0;
   memset(&def.reserved,0,14);
   fwrite(&def,1,sizeof(struct db_rec_def),dbf);

   memset(&def.name,0,11);
   strcpy(def.name,"INFO_IDX");
   def.type = 'N';
   def.address = 0L;
   def.len = 7;
   def.decimals = 0;
   memset(&def.reserved,0,14);
   fwrite(&def,1,sizeof(struct db_rec_def),dbf);

   memset(&def.name,0,11);
   strcpy(def.name,"QRV_ON");
   def.type = 'C';
   def.address = 0L;
   def.len = 15;
   def.decimals = 0;
   memset(&def.reserved,0,14);
   fwrite(&def,1,sizeof(struct db_rec_def),dbf);

   memset(&def.name,0,11);
   strcpy(def.name,"LOCATORS");
   def.type = 'C';
   def.address = 0L;
   def.len = 34;
   def.decimals = 0;
   memset(&def.reserved,0,14);
   fwrite(&def,1,sizeof(struct db_rec_def),dbf);

   memset(&def.name,0,11);
   strcpy(def.name,"LOC_DATE");
   def.type = 'N';
   def.address = 0L;
   def.len = 4;
   def.decimals = 0;
   memset(&def.reserved,0,14);
   fwrite(&def,1,sizeof(struct db_rec_def),dbf);

   memset(&def.name,0,11);
   strcpy(def.name,"MULTI");
   def.type = 'C';
   def.address = 0L;
   def.len = 6;
   def.decimals = 0;
   memset(&def.reserved,0,14);
   fwrite(&def,1,sizeof(struct db_rec_def),dbf);

   memset(&def.name,0,11);
   strcpy(def.name,"MULTI_DATE");
   def.type = 'N';
   def.address = 0L;
   def.len = 4;
   def.decimals = 0;
   memset(def.reserved,0,14);
   fwrite(&def,1,sizeof(struct db_rec_def),dbf);

   i = FIELD_TERMINATOR;
   fwrite(&i,1,1,dbf);
};

char check_59_header(FILE *f)
{
   char s[130];
   unsigned i;

   fread(s,1,128,f);
   fread(&i,1,2,f);
   fread(&i,1,2,f);

   return(!strncmp(s,STATION_HEADER,9));
};

void read_entry(FILE *f, struct callinfo *info)
{
  unsigned char len;

  fread(info->call,1,12,f);
  info->call[12] = 0;
  fread(info->locator,1,6,f);
  info->locator[6] = 0;
  fread(&info->mon,1,1,f);
  fread(&info->year,1,1,f);
  fread(&len,1,1,f);
  info->info[len] = 0;
  if(len) fread(info->info,1,len,f);
  return;
};

unsigned long write_dbf_info(FILE *f,char *cp)
{
   unsigned long pos;

   pos = ftell(f);
   fwrite(cp,1,strlen(cp)+1,f);
   return(pos);
};

void write_dbf_rec(FILE *f, struct callinfo rec, unsigned long pos)
{
   char s[40];
   char i;
   unsigned j;

   i = ' ';
   fwrite(&i,1,1,f);

   memset(s,0,40);
   strcpy(s,rec.call);
   fwrite(s,1,12,f);

   sprintf(s,"%07ld",pos);
   fwrite(s,1,7,f);
 
   strcpy(s,"NNNNNNNNNNNNNNN");
   fwrite(s,1,15,f);

   memset(s,0,35);
   strcpy(s,rec.locator);
   fwrite(s,1,34,f);
 
   memset(s,0,40);
   j = (rec.year*100)+rec.mon;
   sprintf(s,"%04d",j);
   fwrite(s,1,4,f);

   memset(s,0,40);
   fwrite(s,1,6,f);

   memset(s,0,40);
   sprintf(s,"%04d",0);
   fwrite(s,1,4,f);
};

void adjust_dbf_header(FILE *f, unsigned cnt)
{
   unsigned long c = 0;

   c = cnt;
   fseek(f,4,SEEK_SET);
   fwrite(&c,1,4,f);
   return;
};


void main(int argc, char **argv)
{
   FILE *inf, *outf, *outf2;
   char infile[128];
   char outfile[128];
   char outfile2[128];
   unsigned long infopos;
   unsigned rec_cnt = 0;
   struct callinfo fn_rec;
   char s[10];

   infile[0] = 0;
   outfile[0] = 0;
   outfile2[0] = 0;

   printf("\n%s\n",TITLE);

   if(argc>1)
   {
      strcpy(infile,argv[1]);
      strupr(infile);
      if(infile[strlen(infile)-1] == '\\')
         infile[strlen(infile)-1] = 0;

      strcpy(outfile, infile);
      strcpy(outfile2,infile);
   };

   strcat(infile,OLD_NAME);
   strcat(outfile,NEW_NAME);
   strcat(outfile2,NEW_NAME2);

   if((inf = fopen(infile,"rb")) == NULL)
   {
      printf("\nFile %s not found!\n",infile);
      return;
   };

   if((outf = fopen(outfile,"wb")) == NULL)
   {
      printf("\nCould not open file %s!\n",outfile);
      fclose(inf);
      return;
   };

   if((outf2 = fopen(outfile2,"wb")) == NULL)
   {
      printf("\nCould not open file %s!\n",outfile2);
      fclose(inf);
      fclose(outf);
      return;
   };

   strcpy(s,"INFO     ");
   fwrite(s,1,8,outf2);

   if(!check_59_header(inf))
   {
      printf("\nHeader of file %s is destroyed!\n",infile);
      fclose(inf);
      fclose(outf);
      return;
   };

   write_dbf_header(outf);

   while(!feof(inf))
   {
      read_entry(inf,&fn_rec);
      infopos = 0;

      if(fn_rec.call[0])
      {
         if(fn_rec.info[0])
            infopos = write_dbf_info(outf2,fn_rec.info);
         write_dbf_rec(outf,fn_rec,infopos);
         if(!(rec_cnt%100)) printf("%5d\r",rec_cnt);
         rec_cnt++;
      };
   };

   printf("%5d",rec_cnt);
   adjust_dbf_header(outf, rec_cnt);

   fclose(inf);
   fclose(outf);
   fclose(outf2);

   printf("\nConversion completed!\n");
   return;
};

 
