#include <exec/types.h>
#include <dos.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <exec/memory.h>
#include <proto/intuition.h>
#include <proto/dlg.h>
#include <libraries/dos.h>

//#include "header.h"
#include "protos.h"

#include <DLG/globalconfig.h>

#define MyDEBUG 0

char *e1,*e2;



struct nodenum *create_nodenum_on_end5(struct nodenum **n,char *org,short zone,short net,
             short node,short point)
{
  n=get_last_nodenum_ptr(n);
  *n=create_nodenum5(org,zone,net,node,point);
  return *n;
}

struct nodenum *create_nodenum_in_order(struct nodenum **n,short net,short node)
{
  struct nodenum *nn;
  for(;;)
    {
      if(*n==0)
   {
     *n=create_nodenum(net,node);
     return *n;
   }
      if(net>((*n)->net) || net==((*n)->net) && node>((*n)->node))
   {
     n=&((*n)->next_nodenum);
     continue;
   }
      if(net==((*n)->net) && node==((*n)->node))
   {
     /* printf("Net and Node are already in list!\n"); */
     return *n;
   }
      /* At this point, we are ready to insert... */
      nn=create_nodenum(net,node);
      if(nn)
   {
     nn->next_nodenum=*n;
     *n=nn;
     return *n;
   }
      else
   {
     return 0;
   }
    }
}

void print_areas(struct area *a)
{
  FILE *fp;

  int passthru;
  int link;
  int alias;
  char *passthrustring[]={"NOPASSTHRU","PASSTHRU"};
  char *linkstring[]={"NOLINK","LINK"};
  char *aliasstring[]={"NOALIASES","ALIASES"};

   fp=fopen("logs:zareas.rpt","w");
   if(fp)
   {

   fprintf(fp,"*****  List of Known Areas *****");
   for(;a;a=get_next_area(a))
      {
            passthru=a->passthru;
            link=a->link;
      alias=a->alias;

            if(passthru)
        passthru=1;
            if(link)
        link=1;
      if(alias)
        alias=1;

            fprintf(fp,"\n*\n* Area %s Path %s Area Number %d Class %d %s %s %s\n",
            a->name,a->path,a->areanum,a->class,passthrustring[passthru],linkstring[link],aliasstring[alias]);
      if(a->description)
        fprintf(fp,"Description: %s\n");
      fprintf(fp,"*\n");
            fprint_netnodes(a->first_nodenum,fp);
      }
   fclose(fp);
   }
}

void print_netnodes(struct nodenum *n)
{
  char *stripstring[]={"","SEENBY'S-STRIPPED"};
  int strip;

  for(;n;n=get_next_nodenum(n))
    {
      strip=n->strip;
      if(strip)
   strip=1;
      printf("* Remote: %s!%d:%d/%d.%d  Me: %s!%d:%d/%d.%d %s\n",
        n->organization,n->zone,n->net,n->node,n->point,
        n->from_organization,n->from_zone,n->from_net,n->from_node,
        n->from_point,stripstring[strip]);
    }
    printf("*\n");
}
void fprint_netnodes(struct nodenum *n,FILE *fp)
{
  char *stripstring[]={"","SEENBY'S-STRIPPED"};
  int strip;

  for(;n;n=get_next_nodenum(n))
    {
      strip=n->strip;
      if(strip)
   strip=1;
      fprintf(fp,"* Remote: %s!%d:%d/%d.%d  Me: %s!%d:%d/%d.%d %s\n",
        n->organization,n->zone,n->net,n->node,n->point,
        n->from_organization,n->from_zone,n->from_net,n->from_node,
        n->from_point,stripstring[strip]);
    }
    fprintf(fp,"*\n");
}

void delete_areas(struct areas *a)
{
   printf(":-)\n");
}

void new_delete_areas(struct areas *a)
{
  if(a==0 || _MYREMEMBER==0)
    return;
  FreeRemember(&_MYREMEMBER,TRUE);
  a=0;
  _MYREMEMBER=0;
  //delete_all_area(get_area(a,1));
  //delete(a);
}

/****
void delete_all_area(struct area *a)
{
  if(a==0)
    return;
  delete_all_area(get_next_area(a));
  delete_all_nodenum(get_nodenum(a,1));
  if(a->description)
    delete(a->description);
  delete(a);
}
*****/

/****
void delete_all_nodenum(struct nodenum *n)
{
  if(n==0)
    return;
  delete_all_nodenum(get_next_nodenum(n));
  delete(n);
}
*****/

struct area *add_area(struct areas *a,char *string,char *name)
{
  struct area *aa;
  aa=create_area(string,name);
  if(aa==0)
    return 0;
  aa->next_area=a->first_area;
  a->first_area=aa;
  return aa;
}

struct area **get_last_area_ptr(struct areas *a)
{
  struct area **aa;
  aa=&a->first_area;
  while(*aa)
    aa=&((*aa)->next_area);
  return aa;
}

struct area *add_area_on_end(struct areas *a,char *string,char *name)
{
  struct area **aa;
  aa=get_last_area_ptr(a);
  *aa=create_area(string,name);
  return *aa;
}

struct nodenum *add_nodenum(struct area *a,short net,short node)
{
  struct nodenum *n;
  n=create_nodenum(net,node);
  if(n==0)
    return 0;
  n->next_nodenum=a->first_nodenum;
  a->first_nodenum=n;
  return n;
}

struct nodenum *add_nodenum5(struct area *a,char *org,short zone,short net,
              short node,short point)
{
  struct nodenum *n;
  n=create_nodenum5(org,zone,net,node,point);
  if(n==0)
    return 0;
  n->next_nodenum=a->first_nodenum;
  a->first_nodenum=n;
  return n;
}

struct nodenum *add_nodenum_on_end5(struct area *a,char *org,short zone,
                short net,short node,short point)
{
  struct nodenum *n;
  n=create_nodenum_on_end5(&a->first_nodenum,org,zone,net,node,point);
  return n;
}

int translate_line_token(char *word)
{
int i;
for(i=0;;i++)
  {
    if(!linetokenlist[i])
   break;
    if(!strcmpi(linetokenlist[i],word))
      return i;
  }
return -1;
}

int translate_entry_token(char *word)
{
int i;
for(i=0;;i++)
  {
    if(!entrytokenlist[i])
   break;
    if(!strcmpi(entrytokenlist[i],word))
      return i;
  }
return -1;
}

int skip_to_line_token(FILE *fp)
{
  int c;
  for(;;)
    {
      c=skipchars(fp," \t\n\r");
      if(c==EOF)
   return 1;
      if(c!=';')
   {
     return 0;
   }
      skipuntilterm(fp,"\n");
    }
}

int skip_to_entry_token(FILE *fp)
{
  int c;
  for(;;)
    {
      c=skipchars(fp," \t\r");
      if(c==EOF)
   return 1;
      if(c==';')
   {
     c=skipuntilterm(fp,"\n");  /* c will be '\n' on return. */
     ungetc(c,fp);
   }
      return 0;
    }
}

int read_address(FILE *fp,char *org,short *zone,short *net,short *node,
       short *point)
{
  int c;
  char t1[100];
  char *numbers="0123456789";

  skipchars(fp," \t");

  *point=0;
  c=readuntilterm(fp,t1,"!:/. ;\t\n\r");
  if(c=='.' && strlen(t1)==0)
    {
      if(!string1subsetstring2(t1,numbers))
   return 1; /* Fields not Numeric; return error. */
      c=readuntilterm(fp,t1,"!:/. ;\t\n\r");
      if(!string1subsetstring2(t1,numbers))
   return 1; /* Fields not Numeric; return error. */
      if(charisinstring(c," ;\t\n\r"))
   {
     *point=atoi(t1);
     ungetc(c,fp);
     return 0;
   }
      else
   {
     return 1;
   }
    }
  if(c=='!')
    {
      stccpy(org,t1,MAX_STR);
      c=readuntilterm(fp,t1,"!:/. ;\t\n\r");
      if(c!=':')
   {
     return 1;
   }
    }
  if(!string1subsetstring2(t1,numbers))
    return 1; /* Fields not Numeric; return error. */
  if(c==':')
    {
      *zone=atoi(t1);
      c=readuntilterm(fp,t1,"!:/. ;\t\n\r");
      if(!string1subsetstring2(t1,numbers))
   return 1; /* Fields not Numeric; return error. */
      if(c!='/')
   {
     return 1;
   }
    }
  if(c=='/')
    {
      *net=atoi(t1);
      c=readuntilterm(fp,t1,"!:/. ;\t\n\r");
      if(!string1subsetstring2(t1,numbers))
   return 1; /* Fields not Numeric; return error. */
      if(c!='.')
   {
     if(charisinstring(c," ;\t\n\r"))
       {
         *node=atoi(t1);
         ungetc(c,fp);
         return 0;
       }
     else
       {
         return 1;
       }
   }
    }
  if(c=='.')
    {
      *node=atoi(t1);
      c=readuntilterm(fp,t1,"!:/. ;\t\n\r");
      if(!string1subsetstring2(t1,numbers))
   return 1; /* Fields not Numeric; return error. */
      if(charisinstring(c," ;\t\n\r"))
   {
     *point=atoi(t1);
     ungetc(c,fp);
     return 0;
   }
      else
   {
     return 1;
   }
    }
  ungetc(c,fp);
  *node=atoi(t1);
  return 0;
}

void read_entry_token(FILE *fp,char *token)
{
  int c;
  long position;
  position=ftell(fp);
  c=fgetc(fp);
  if(c!='\n')
    {
      fseek(fp,position,0);
      c=readuntilterm(fp,token," ;\n\r\t");
      ungetc(c,fp);
      return;
    }
  if(charisinstring(fgetc(fp),"cC") &&
     charisinstring(fgetc(fp),"oO") &&
     charisinstring(fgetc(fp),"nN") &&
     charisinstring(fgetc(fp),"tT") )
    {
      strcpy(token,"\nCONT");
    }
  else
    {
      fseek(fp,position+1,0);
      strcpy(token,"\n");
    }
  return;
}


#define FBUFSIZE 10000


struct areas *read_areas(char *fname)
{
   printf(":-(\n");
   return 0;
}

struct areas *new_read_areas(char *fname, char *errline1, char *errline2)
{
  struct areas *Areas;
  char t1[100],t2[100];
  char token[100];
  int tokennum;
  struct area *current_area;
  char organization[MAX_STR];
  short zone,net,node,point;
  int c,loop,error,size;
  FILE *fp;
  long position;

   e1=errline1;
   e2=errline2;

   default_class=0;
   default_passthru=FALSE;
   default_link=TRUE;
   default_alias=FALSE;
   *default_from_organization=0;

   set_error_code(NO_ERROR,"DLGMail.ARE: No Error Occurred.","");

   fp=fopen(fname,"r");
   if(!fp)
      {
            set_error_code(FILE_ACCESS,"DLGMail.ARE: Can't open areas file: ",fname);
            return 0;
      }

   skip_to_line_token(fp);
   readuntilterm(fp,token," ;\t\n\r");  /* Read in Token. */
   if(translate_line_token(token)!=MYADDRESS)
      {
            set_error_code(PARSE_ERROR,"DLGMail.ARE: First keyword in file must be",
           linetokenlist[MYADDRESS]);
            fclose(fp);
            return 0;
      }
   position=ftell(fp); /* record position of start of address. */
   error=read_address(fp,default_from_organization,(short *)&default_from_zone,
           (short *)&default_from_net,(short *)&default_from_node,
           (short *)&default_from_point);
   if(error)
      {
            fseek(fp,position,0);
            read_entry_token(fp,token);
            set_error_code(PARSE_ERROR,"DLGMail.ARE: Illegal MYADDRESS address: ",
           token);
            fclose(fp);
            return 0;
      }
   if(!*default_from_organization)
      {
            fseek(fp,position,0);
            skipchars(fp," \t");
            read_entry_token(fp,token);
            set_error_code(PARSE_ERROR,
            "DLGMail.ARE: MYADDRESS must be 5d address:",
            token);
            fclose(fp);
            return 0;
      }

   Areas = create_areas();
   if(Areas==0)
      {
            set_error_code(MEM_ALLOC,
         "DLGMail.ARE: Couldn't allocate memory","for areas structure");
            fclose(fp);
            return 0;
      }

   for(;;)
      {
            /* At this point, we are at the beginning of a line (or the file) */
            error=skip_to_line_token(fp); /* Find start of first line token. */
            if(error)
         break;
            readuntilterm(fp,token," ;\t\n\r");  /* Read in token. */
            tokennum=translate_line_token(token);
            switch(tokennum)
      {
         case MYADDRESS:
         position=ftell(fp); /* record position of start of address. */
         error=read_address(fp,default_from_organization,(short *)&default_from_zone,
              (short *)&default_from_net,(short *)&default_from_node,
              (short *)&default_from_point);
         if(error)
            {
                  fseek(fp,position,0);
                  skipchars(fp," \t");
                  read_entry_token(fp,token);
            set_error_code(PARSE_ERROR,"DLGMail.ARE: Illegal MYADDRESS address:",
               token);
/* ==> */                  new_delete_areas(Areas);
                  fclose(fp);
                  return 0;
            }
         break;
   
         case LINK:
         default_link=TRUE;
         break;
   
         case NOLINK:
         default_link=FALSE;
         break;
   
         case ALIAS:
         default_alias=TRUE;
         break;
   
         case NOALIAS:
         default_alias=FALSE;
         break;
   
         case PASSTHRU:
         default_passthru=TRUE;
         break;
   
         case NOPASSTHRU:
         default_passthru=FALSE;
         break;
   
         case CLASS:
         skipchars(fp," \t");
         readuntilterm(fp,t1," ;\t\n\r");
         if(!string1subsetstring2(t1,"0123456789"))
            {
                  set_error_code(PARSE_ERROR,"DLGMail.ARE: CLASS keyword followed by:",t1);
/* ==> */               new_delete_areas(Areas);
                  fclose(fp);
                  return 0;
            }
         default_class=atoi(t1);
         break;
   
         case TAG:
         case AREA:
         skipchars(fp," \t");
         c=readuntilterm(fp,t1," ;\t\n\r");
         if(charisinstring(c,"\n\r;"))
            {
                  set_error_code(PARSE_ERROR,"DLGMail.ARE: TAG/AREA keyword followed by:",t1);
/* ==> */               new_delete_areas(Areas);
                  fclose(fp);
                  return 0;
            }
         skipchars(fp," \t");
         c=readuntilterm(fp,t2," ;\t\n\r");
         ungetc(c,fp);




         current_area = add_area_on_end(Areas,t2,t1);

         if(current_area==0)
            {
                  set_error_code(MEM_ALLOC,"DLGMail.ARE: Can't allocate enough memory","to handle all the configured areas.");
/* ==> */               new_delete_areas(Areas);
                  fclose(fp);
                  return 0;
         }

         stccpy(current_from_organization,default_from_organization,MAX_STR);
         current_from_zone=default_from_zone;
         current_from_net=default_from_net;
         current_from_node=default_from_node;
         current_from_point=default_from_point;
         current_strip=FALSE;

         stccpy(organization,current_from_organization,MAX_STR);
         zone=current_from_zone;
         net=current_from_net;

         /* Now we are reading entries for an area. */
         loop=TRUE;
         while(loop)
            {     
                  error=skip_to_entry_token(fp);
                  /* Find start of first entry token. */
                  if(error)
            {
               set_error_code(PARSE_ERROR,
                  "DLGMail.ARE: Abnormal End Of File","Check last area for structure and carriage returns");
               fclose(fp);
/* ==> */            new_delete_areas(Areas);
               return 0;
            }
                  position=ftell(fp); /* record position of start of token. */
                  read_entry_token(fp,token);  /* Read in token. */
                  tokennum=translate_entry_token(token);
                  switch(tokennum)
            {
               case CONT:
               break;
               
               case NEWLINE:
               loop=FALSE;
               break;
      
               case USEADDRESS:
               position=ftell(fp); /* record position of start of address. */
               error=read_address(fp,current_from_organization,
                     (short *)&current_from_zone,
                     (short *)&current_from_net,(short *)&current_from_node,
                     (short *)&current_from_point);
               if(error)
                  {
                        fseek(fp,position,0);
                        skipchars(fp," \t");
                        read_entry_token(fp,token);
                  set_error_code(PARSE_ERROR,"DLGMail.ARE: Illegal USEADDRESS address:",
                     token);
/* ==> */                     new_delete_areas(Areas);
                        fclose(fp);
                        return 0;
                  }
               stccpy(organization,current_from_organization,MAX_STR);
               zone=current_from_zone;
               net=current_from_net;
               break;
      
               case STRIP:
               current_strip=TRUE;
               break;
      
               case NOSTRIP:
               current_strip=FALSE;
               break;
      
               case DESC:
               if(current_area->description)
                  {
                        set_error_code(PARSE_ERROR,"DLGMail.ARE: Two area descriptions given for area",current_area->name);
/* ==> */                     new_delete_areas(Areas);
                        fclose(fp);
                        return 0;
                  }
               skipchars(fp," \t");
               c=readuntilterm(fp,token,"\n\r");
               ungetc(c,fp);
               size=strlen(token)+1;
               if(size>DESC_MAX)
                     size=DESC_MAX;
               current_area->description=new(size);
               if(current_area->description==0)
                  {
                        set_error_code(MEM_ALLOC,"DLGMail.ARE: Couldn't allocate memory","for a bitty string!");
/* ==> */                     new_delete_areas(Areas);
                        fclose(fp);
                        return 0;
                  }
//here
               strncpy(current_area->description,token,size);
               current_area->description[size-1]=0;
               break;
      
               default:
               /* Default is a new address to add to area. */
               /* rewind to start of this token. */
               fseek(fp,position,0);
               error=read_address(fp,organization,&zone,&net,&node,&point);
               if(error)
                  {
                  set_error_code(PARSE_ERROR,"DLGMail.ARE: Entry on line not keyword or valid address:",
                     token);
/* ==> */                     new_delete_areas(Areas);
                        fclose(fp);
                        return 0;
                  }
               error=!add_nodenum_on_end5(current_area,organization,zone,
                        net,node,point);
               if(error)
                  {
                  set_error_code(MEM_ALLOC,"DLGMail.ARE: Not enough memory","to parse areas file.");
/* ==> */                     new_delete_areas(Areas);
                        fclose(fp);
                        return 0;
                  }

               break;
            }
            }
         break;
      
         default:
         /* Default line token at line start is an error. */
         set_error_code(PARSE_ERROR,"DLGMail.ARE: Illegal token in input:",
            token);
/* ==> */      new_delete_areas(Areas);
         fclose(fp);
         return 0;
      }
      }
   fclose(fp);
   return Areas;
}

void *new(int size)
{
  void *v;
  v=(void *)AllocRemember(&_MYREMEMBER,size,MEMF_PUBLIC | MEMF_CLEAR);
  return v;
}

void delete(void *v)
{
   printf(":-)");
  //free(v);
}

/*  OLD CODE
 *
 * int Log(char *s1,char *s2);
 * Log(char *s1,char *s2)
 * {
 * return 0;
 * }
 *
 * int QuietExit(void);
 * QuietExit()
 * {
 * return 0;
 * }
 *
 * void myexit(int i)
 * {
 *
 *  Log("*-----","ERROR FOUND BY ROSS' CODE - QUITTING\n");
 *  printf("ERROR FOUND BY ROSS' CODE - QUITTING\n");
 *
 *  QuietExit();
 * }
 *
 */

void set_error_code(int code,char *str1,char *str2)
{
if(code)
{
   //here
   strncpy(e1,str1,50);
   strncpy(e2,str2,50);

 //printf(" [33m## Z_ROSS.C Error\n");
 //printf("        ##      Error code: %d\n",code);
 //printf("        ## Verbose message: %s\n",str1);
 //printf("        ##                  %s\n[0m",str2);
 //Delay(500);
}

global_error_code=code;
stccpy(global_error_string1,str1,MAX_LONG_STR);
stccpy(global_error_string2,str2,MAX_LONG_STR);
}

/* Global Variable Definitions: */

short current_strip;
char  current_from_organization[MAX_STR];
unsigned short current_from_zone;
unsigned short current_from_net;
unsigned short current_from_node;
unsigned short current_from_point;

char  default_from_organization[MAX_STR];
unsigned short default_from_zone;
unsigned short default_from_net;
unsigned short default_from_node;
unsigned short default_from_point;

short default_class;
short default_passthru;
short default_link;
short default_alias;


/* order here must correspond to definitions in header.h */
char *linetokenlist[]=
{
"MYADDRESS",
"PASSTHRU",
"NOPASSTHRU",
"CLASS",
"TAG",
"AREA",
"LINK",
"NOLINK",
"ALIAS",
"NOALIAS",
(char *)0
};

char *entrytokenlist[]=
{
"\nCONT",
"\n",
"USEADDRESS",
"STRIP",
"NOSTRIP",
"DESC",
(char *)0
};

int global_error_code=0;
char global_error_string1[MAX_LONG_STR];
char global_error_string2[MAX_LONG_STR];



SteveAreaTest(char *filename,char *comment,struct areas *x)
{
   int rc=1;
   struct area *as;
   FILE *fp;
   int i=0;

   fp=fopen(filename,"a");
   if(fp)
   {
      fprintf(fp,"========\nDebugging comment: %s\n",comment);

      for(as=x->first_area;;as=as->next_area)
      {
         i++;

         fprintf(fp,"%3d  [%20.20s] [%25.25s] %4d %3d %d %d %d\n",
            i,
            as->name,
            as->path,
            as->areanum,
            as->class,
            as->passthru,
            as->link,
            as->alias);

         if(*as->path==NULL) rc=0;

         if(as->next_area==NULL) break;
      }
      fprintf(fp,"=========\n");
      fclose(fp);
   }
   return rc;
}

