/* modified for unpadded names! */

#include <exec/types.h>
#include <stdio.h>
#include <string.h>
#include <dos.h>

#include <link/io.h>

#include <proto/dos.h>
#include <proto/dlg.h>

#include <pragmas/dlg.h>

#include <stdlib.h>
#include "flavor.h"
#include <DLG/globalconfig.h>
#include "flavorproto.h"

extern struct Library *DLGBase;

extern BPTR sout;

/* EvaluateFilename() takes any filename found in the newstyle outbound dir
   and returns the address that it is to, along with the type. Supply
   it with both the filename and filenote for evaluative purposes */

int EvaluateFilename(char *s,char *p,int *zone,int *net,int *node,int *point,ULONG *type)

/* s is either oldstyle .pkt or newstyle any
   if s is oldstyle, p should contain z:n/n/p address */

{
   char string0[40];
   char string1[40];
   char string2[40];
   char string3[40];
   char string4[40];

   char a[40],b[40],c[40],d[40],e[40];

   *zone=0;
   *net=0;
   *node=0;
   *point=0;
   *type=0;

   strcpy(a,"");
   strcpy(b,"");
   strcpy(c,"");
   strcpy(d,"");
   strcpy(e,"");

   NFComponents(s,a,b,c,d,e);

   if(*c && *d && *e)
   {
      *zone=atoi(a);
      *net=atoi(b);
      *node=atoi(c);
      *point=atoi(d);
   
      if(!Stricmp(e,"CLO")) *type=flavor_CLO;
      if(!Stricmp(e,"FLO")) *type=flavor_FLO;
      if(!Stricmp(e,"DLO")) *type=flavor_DLO;
      if(!Stricmp(e,"HLO")) *type=flavor_HLO;
      if(!Stricmp(e,"NLO")) *type=flavor_NLO;
   
      if(!Stricmp(e,"CUT")) *type=flavor_CUT;
      if(!Stricmp(e,"OUT")) *type=flavor_OUT;
      if(!Stricmp(e,"DUT")) *type=flavor_DUT;
      if(!Stricmp(e,"HUT")) *type=flavor_HUT;
      if(!Stricmp(e,"NUT")) *type=flavor_NUT;
      if(!Stricmp(e,"PKT")) *type=flavor_PKTFILE;

      if(!Strnicmp(e,"SU",2)) *type=flavor_SU;
      if(!Strnicmp(e,"MO",2)) *type=flavor_MO;
      if(!Strnicmp(e,"TU",2)) *type=flavor_TU;
      if(!Strnicmp(e,"WE",2)) *type=flavor_WE;
      if(!Strnicmp(e,"TH",2)) *type=flavor_TH;
      if(!Strnicmp(e,"FR",2)) *type=flavor_FR;
      if(!Strnicmp(e,"SA",2)) *type=flavor_SA;

      if(*type & flavor_BUNDLE)
      {
         *type=*type+atoi(e+2);
      }
   
      if(*type)
         return(1);
      else
         return(0);
   }
   else
   {
      if(strlen(s)!=12) return(0);
      if(s[8] != '.') return(0);
      if(Stricmp(s+9,"PKT")) return(0);

      mystrsfn(p,string0,string1,string2,string3,string4);

      *zone=atoi(string0);
      *net=atoi(string1);
      *node=atoi(string2);
      *point=atoi(string3);

      if(0==Stricmp("PKT",string4))
      {
         *type=flavor_PKTFILE;
         return(1);
      }
      else
         return(0);

   }
}

/* AddToWild() takes a wildcardable z:n/n.p address and converts it into
   a newstyle flow or packet name with wildcards, suitable for use with
   the lattice pattern matching functions (or possibly Lock()). This
   will not produce a pattern to find oldstyle .pkt's */

int AddToWild(char *in,char *out,ULONG type)
{
   char a[40],b[40],c[40],d[40],e[40];

   int daynum;

   mystrsfn(in,a,b,c,d,e);

   strcpy(e,"");

   if(*a=='*')
   {
      strcpy(a,"*");
      strcpy(b,"*");
      strcpy(c,"*");
      strcpy(d,"*");
   }

   if(*b=='*')
   {
      strcpy(b,"*");
      strcpy(c,"*");
      strcpy(d,"*");

   }

   if(*c=='*')
   {
      strcpy(c,"*");
      strcpy(d,"*");

   }

   if(*d=='*')
   {
      strcpy(d,"*");
   }

   if(type & flavor_PKTFILE)
   {
/*    printf("bug: pktfile\n");
*/    if(type & flavor_CRASH) strcpy(e,"CUT");
      if(type & flavor_NORMAL) strcpy(e,"OUT");
      if(type & flavor_DIRECT) strcpy(e,"DUT");
      if(type & flavor_HOLD) strcpy(e,"HUT");
      if(type & flavor_NONE) strcpy(e,"NUT");
      if(type & flavor_ANY) strcpy(e,"?UT");
   }
   if(type & flavor_FLOWFILE)
   {
/*    printf("bug: flowfile\n");
*/    if(type & flavor_CRASH) strcpy(e,"CLO");
      if(type & flavor_NORMAL) strcpy(e,"FLO");
      if(type & flavor_DIRECT) strcpy(e,"DLO");
      if(type & flavor_HOLD) strcpy(e,"HLO");
      if(type & flavor_NONE) strcpy(e,"NLO");
      if(type & flavor_ANY) strcpy(e,"?LO");
   }
   if(type & flavor_BUNDLE)
   {
/*    printf("bug: bundle\n");
*/    if(type & flavor_SUNDAY)   strcpy(e,"SU");
      if(type & flavor_MONDAY)   strcpy(e,"MO");
      if(type & flavor_TUESDAY)  strcpy(e,"TU");
      if(type & flavor_WEDNESDAY)   strcpy(e,"WE");
      if(type & flavor_THURSDAY) strcpy(e,"TH");
      if(type & flavor_FRIDAY)   strcpy(e,"FR");
      if(type & flavor_SATURDAY) strcpy(e,"SA");
      if(type & flavor_ANY)   strcpy(e,"??");

      if(!(type & flavor_ANY))
      {
         daynum=type&15;

         if(daynum>9) daynum=0;

         if(daynum==0) strcat(e,"0");
         if(daynum==1) strcat(e,"1");
         if(daynum==2) strcat(e,"2");
         if(daynum==3) strcat(e,"3");
         if(daynum==4) strcat(e,"4");
         if(daynum==5) strcat(e,"5");
         if(daynum==6) strcat(e,"6");
         if(daynum==7) strcat(e,"7");
         if(daynum==8) strcat(e,"8");
         if(daynum==9) strcat(e,"9");
      }
      if(type & flavor_ANY) strcat(e,"?");
   }

   ASPrintf(NULL,out,"%s.%s.%s.%s.%s",a,b,c,d,e);
   Upper(out);
   return(1);
}

/* mystrsfn is sort of an extension of lattice's version. it picks the
   address apart and allows wildcards in it. in addition, it returns
   the filename extension in the sixth argument */

int mystrsfn(char *in, char *a, char *b, char *c, char *d, char *e)
{
   char *s;

   *a=NULL;
   *b=NULL;
   *c=NULL;
   *d=NULL;
   *e=NULL;

   s=in;

   while(*s!=':' && *s!=NULL)
   {
      *a++=*s++;
      *a=NULL;
   }
   if(*s==NULL) return(1);



   s++;

   while(*s!='/' && *s!=NULL)
   {
      *b++=*s++;
      *b=NULL;
   }
   if(*s==NULL) return(2);



   s++;

   while(*s!='.' && *s!=NULL)
   {
      *c++=*s++;
      *c=NULL;
   }
   if(*s==NULL) return(3);



   s++;

   while(*s!='.' && *s!=NULL)
   {
      *d++=*s++;
      *d=NULL;
   }
   if(*s==NULL) return(4);



   s++;

   while(*s!=NULL)
   {
      *e++=*s++;
      *e=NULL;
   }
   return(5);
}

/* this creates a new name based on arguments supplied, including the
   TYPE which adheres to flavor.h convention */

int CreateNewName(char *newname, int zone, int net, int node, int point, ULONG type)
{
   int tmp;
   char tmpstr[40];

   sprintf(newname,"%d.%d.%d.%d.",zone,net,node,point);

   if(type & flavor_BUNDLE)
   {
      if(type & flavor_SUNDAY) strcat(newname,"SU");
      if(type & flavor_MONDAY) strcat(newname,"MO");
      if(type & flavor_TUESDAY) strcat(newname,"TU");
      if(type & flavor_WEDNESDAY) strcat(newname,"WE");
      if(type & flavor_THURSDAY) strcat(newname,"TH");
      if(type & flavor_FRIDAY) strcat(newname,"FR");
      if(type & flavor_SATURDAY) strcat(newname,"SA");

      tmp=type&15;
      if(tmp>9)tmp-=9;

      ASPrintf(NULL,tmpstr,"%d",tmp);

      strcat(newname,tmpstr);

      return(1);
   }

   if(type & flavor_FLOWFILE)
   {
      if(type & flavor_CRASH) strcat(newname,"CLO");
      if(type & flavor_NORMAL) strcat(newname,"FLO");
      if(type & flavor_DIRECT) strcat(newname,"DLO");
      if(type & flavor_HOLD) strcat(newname,"HLO");
      if(type & flavor_NONE) strcat(newname,"NLO");

      return(1);
   }

   if(type & flavor_PKTFILE)
   {
      if(type & flavor_CRASH) strcat(newname,"CUT");
      if(type & flavor_NORMAL) strcat(newname,"OUT");
      if(type & flavor_DIRECT) strcat(newname,"DUT");
      if(type & flavor_HOLD) strcat(newname,"HUT");
      if(type & flavor_NONE) strcat(newname,"NUT");

      return(1);
   }

   return(0);
}

/* pretty straightforward, pass it old and new and it tacks outbound: to the
   front and calls DOS Rename() */

int RenameOutbound(char *old, char *new)
{
   char old1[100];
   char new1[100];

   ASPrintf(NULL,old1,"OUTBOUND:%s",old);
   ASPrintf(NULL,new1,"OUTBOUND:%s",new);

   return((int)Rename(old1,new1));
}

/* this creates a random packet name and checks to make sure it is not in
   use in outbound: at the time */


int CreatePKTName(char *name)
{
   unsigned char clock[10];
   ULONG t;
// BPTR fh;
   char str[50];

   ULONG N;
   ULONG n;

   N=_MyNet;
   N=N<<17;

   n=_MyNode;
   n=n&0xef;
   n=n<<2;

   while(1)
   {
      getclk(clock);
      t=((clock[2]<<28)+(clock[3]<<23)+(clock[4]<<18)+(clock[5]<<12)+(clock[6]<<6)+(clock[7]/2));

      // To get around ASPrintf's lack of hex handling
      stcl_h(str,t);
      Upper(str);
      // End hack

      ASPrintf(NULL,name,"%08.8s.PKT",str);

      ASPrintf(NULL,str,"OUTBOUND:%s",name);
      
      if(!Exists(str)) break;

//      fh=Lock(str,ACCESS_READ);

//    if(!fh) break;
//    UnLock(fh);
   }
   return(1);
}

/* this interfaces between the outside world and the inside flavor_defines */

ULONG UserType(char *spec, char *pktorflow)
{
   char s[100], p[100];

   strcpy(s,spec);
   strcpy(p,pktorflow);

   Upper(s);
   Upper(p);

   if(*p=='P')
   {
      if(*s=='C') return(flavor_PKTFILE | flavor_CRASH);
      if(*s=='N') return(flavor_PKTFILE | flavor_NORMAL);
      if(*s=='D') return(flavor_PKTFILE | flavor_DIRECT);
      if(*s=='H') return(flavor_PKTFILE | flavor_HOLD);
      if(*s=='!') return(flavor_PKTFILE | flavor_NONE);
      if(*s=='?') return(flavor_PKTFILE | flavor_ANY);
   }
   if(*p=='F')
   {
      if(*s=='C') return(flavor_FLOWFILE | flavor_CRASH);
      if(*s=='N') return(flavor_FLOWFILE | flavor_NORMAL);
      if(*s=='D') return(flavor_FLOWFILE | flavor_DIRECT);
      if(*s=='H') return(flavor_FLOWFILE | flavor_HOLD);
      if(*s=='!') return(flavor_FLOWFILE | flavor_NONE);
      if(*s=='?') return(flavor_FLOWFILE | flavor_ANY);
   }
   return(0);
}

int ShowFlags(ULONG flag)
{
   AFPrintf(NULL,sout,"Flags: [32m");

   if(flag & flavor_CRASH) AFPrintf(NULL,sout,"CRASH ");
   if(flag & flavor_NORMAL) AFPrintf(NULL,sout,"NORMAL ");
   if(flag & flavor_DIRECT) AFPrintf(NULL,sout,"DIRECT ");
   if(flag & flavor_HOLD) AFPrintf(NULL,sout,"HOLD ");
   if(flag & flavor_NONE) AFPrintf(NULL,sout,"NONE ");
   if(flag & flavor_ANY) AFPrintf(NULL,sout,"ANY ");
   if(flag & flavor_PKTFILE) AFPrintf(NULL,sout,"PKTFILE ");
   if(flag & flavor_FLOWFILE) AFPrintf(NULL,sout,"FLOWFILE ");
   if(flag & flavor_SUNDAY) AFPrintf(NULL,sout,"SUNDAY ");
   if(flag & flavor_MONDAY) AFPrintf(NULL,sout,"MONDAY ");
   if(flag & flavor_TUESDAY) AFPrintf(NULL,sout,"TUESDAY ");
   if(flag & flavor_WEDNESDAY) AFPrintf(NULL,sout,"WEDNESDAY ");
   if(flag & flavor_THURSDAY) AFPrintf(NULL,sout,"THURSDAY ");
   if(flag & flavor_FRIDAY) AFPrintf(NULL,sout,"FRIDAY ");
   if(flag & flavor_SATURDAY) AFPrintf(NULL,sout,"SATURDAY ");
   if(flag & flavor_BUNDLE) AFPrintf(NULL,sout,"BUNDLE ");

   AFPrintf(NULL,sout,"[0m\n");

   return(0);
}


/* this routine is not case sensitive. it's meant to take filename or
   fidoname and pattern match against pattern.

   it checks to see if the number of components (up to 5 are broken apart)
   match exactly. if not, returns 0

   it ignores the contents of a component when the pattern component is *

   it matches any character of the input string when the complementary
   character in the pattern is a ?

   all other characters must match exactly, and the length of the pattern
   and input string components must be identical for all components
*/

int FidoPatternMatch(char *s_in, char *s_pat)
{
   char sin[6][31];
   char spat[6][31];

   char in[500];
   char pat[500];

   int sinnum;
   int spatnum;

   int counter;

   int cc;

   strcpy(in,s_in);
   strcpy(pat,s_pat);

   Upper(in);
   Upper(pat);

   sinnum=NFComponents(in,sin[1],sin[2],sin[3],sin[4],sin[5]);
   spatnum=NFComponents(pat,spat[1],spat[2],spat[3],spat[4],spat[5]);

   if(sinnum!=spatnum) return(0); /* first level of error checking */

   for(counter=1;counter<(spatnum+1);counter++)
   {
      if(spat[counter][0]=='*') continue; /* it doesn't matter what's in the input file in this case */

      if(strlen(spat[counter])!=strlen(sin[counter])) return 0;   /* they can't match */

      for(cc=0;cc<(strlen(spat[counter])+1);cc++)
      {
         if(spat[counter][cc]=='?') continue;
         if(spat[counter][cc]!=sin[counter][cc]) return 0;  /* the character didn't match exactly */
      }
   }
   return(1);
}

int NFComponents(char *in, char *A, char *B, char *C, char *D, char *E)
{
   char *s,*p;


   s=in;
   p=in;

   p=stptok(s,A,31,".:");
   if(p!=in+strlen(in)) p++;
   s=p;
   p=stptok(s,B,31,"./");
   if(p!=in+strlen(in)) p++;
   s=p;
   p=stptok(s,C,31,".");
   if(p!=in+strlen(in)) p++;
   s=p;
   p=stptok(s,D,31,".");
   if(p!=in+strlen(in)) p++;
   s=p;
   strcpy(E,s);

   if(*E) return 5;
   if(*D) return 4;
   if(*C) return 3;
   if(*B) return 2;
   if(*A) return 1;
   return 0;
}
