#include "pdqnet.h"
#include "ivn.h"  /* to get product version and revision #'s */

BPTR PKTfile;

BOOL MsgToPKT(char *beginning,int length,
   int destinationzone,int destinationnet,int destinationnode,int destinationpoint,
   int fromnet, int fromnode, BOOL crashpkt,int pk,char *newintlkludge,int skipthese,
   int pkt_f_zone,int pkt_f_net,int pkt_f_node,int pkt_f_point)
{
   int j,textlength;

   struct PackedMsg *pktmsg=NULL;

   int tozone,tonet,tonode,topoint;

   struct Fido_Msg_Header *bbsmsg;

   USHORT TMP;

   int waslocal=0;

   UBYTE *textstart;
   UBYTE string[200];

   Log("|||*-","In MsgToPkt()");

   pktmsg=(struct PackedMsg *)AllocMem(sizeof(struct PackedMsg),MEMF_PUBLIC | MEMF_CLEAR);
   if(pktmsg)
   {
      bbsmsg=      (void *)beginning;
      textstart=  (void *)(beginning+sizeof(struct Msg_Header));
      textlength= length-sizeof(struct Msg_Header);
   
      tozone=destinationzone;
      tonet=destinationnet;
      tonode=destinationnode;
      topoint=destinationpoint;
   
      if(NoRouteNetMail(tozone,tonet,tonode,topoint,bbsmsg->Attribute))
      {
         if(MyDEBUG) printf("destination in bundler routing file");
         Log("|||| ","Destination address in bundler routing file");
      }
      else
      {
         if(RouteNetMail(&tozone,&tonet,&tonode,&topoint,bbsmsg->Attribute))
            if(MyDEBUG) printf("\tRouting though [%d:%d/%d.%d]\n",tozone,tonet,tonode,topoint);
      }
      sprintf(logstring,"Building packet for %d:%d/%d.%d",tozone,tonet,tonode,topoint);
      Log("|||| ",logstring);
   
      /* ahem... time to load up the packet structure */


/* zone gate stuff */

      if(tozone==tonet)
      {
         if(tozone>0 && tozone<8)
         {
            if(tonode==destinationzone && (tonode<8 && tonode>0) && (tonode!=_MyZone))
            {
               printf("Zone Gate Readdressing");
               Log("|||| ","Zone Gate Readdressing");
               destinationnode=tonode;
               destinationnet=tonet;
            }
         }
      }
   
      pktmsg->MsgType=  FixNumbers((USHORT)FIDOMSGTYPE);
      pktmsg->OrigNode=FixNumbers((USHORT)fromnode);
      pktmsg->DestNode=FixNumbers(destinationnode);
      pktmsg->OrigNet=  FixNumbers((USHORT)fromnet);
      pktmsg->DestNet=  FixNumbers(destinationnet);

      TMP=bbsmsg->Attribute;

      if(TMP & LOCAL)
      {
         waslocal++;
         TMP ^= LOCAL;
      }
      if(TMP & RECD) TMP ^= RECD;

      pktmsg->Attribute=FixNumbers((USHORT)TMP);

      pktmsg->Cost=FixNumbers((USHORT)NULL);
      strcpy(string,bbsmsg->Date);
      strcat(string,"                      ");
      string[19]=NULL;
      strcpy(pktmsg->Date,string);
   
      /*structure is now filled, time to append it*/
   
      j=OpenPKT(tozone,tonet,tonode,topoint,crashpkt,pkt_f_zone,pkt_f_net,pkt_f_node,pkt_f_point);
      if(j)
      {
         if(*newintlkludge) printf("NEW INTL KLUDGE: [%s]\n",newintlkludge);

         Log("||||*","Packet open");
         AppendToPKT((void *)pktmsg,sizeof(struct PackedMsg),crashpkt);
      
         /* this area needs a little assistance */
      
         strcpy(string,bbsmsg->To);
         AppendToPKT((void *)string,strlen(string)+1,NULL);
      
         strcpy(string,bbsmsg->From);
         AppendToPKT((void *)string,strlen(string)+1,NULL);
      
         strcpy(string,bbsmsg->Title);
         AppendToPKT((void *)string,strlen(string)+1,NULL);
      
         if(*newintlkludge)
         {
            sprintf(string,"INTL %s\r",newintlkludge);
            AppendToPKT((void *)string,strlen(string),NULL);
         }
         if(pk)
         {
            sprintf(string,"TOPT %d\r",pk);
            AppendToPKT((void *)string,strlen(string),NULL);
         }

// new march 1995
         if(waslocal)
         {
            sprintf(string,"PID: DLGMail %s %s\r",_VERSION,_DLGSERIAL);
            AppendToPKT((void *)string,strlen(string),NULL);
         }
// end new

         AppendToPKT((void *)(textstart+skipthese),textlength-skipthese,NULL);   /* message body */


/* via bullshit */


         if(pkt_f_zone)
            sprintf(string,"Via DLGMail @ %d:%d/%d.%d\r\n",pkt_f_zone,pkt_f_net,pkt_f_node,pkt_f_point);
         else
            sprintf(string,"Via DLGMail @ %d:%d/%d.%d (primary default address)\r\n",_MyZone,_MyNet,_MyNode,_MyPoint);
         

         AppendToPKT((void *)string,strlen(string),NULL);










      
         strcpy(string,"");      /* ahem, null byte between messages */
         AppendToPKT((void *)string,1,NULL);
   
         if(crashpkt)
         {
            Log("|||||","CRASH PACKET!");
            /* write extra 0 bytes */
            strcpy(string,"");      /* ahem, null byte between messages */
            AppendToPKT((void *)string,1,NULL);
            AppendToPKT((void *)string,1,NULL);
         }  
         ClosePKT();
         Log("||||*","Packet closed");
      }
   
      if(MyDEBUG) printf("\tMessage added to packet...\n");
   
      FreeMem(pktmsg,sizeof(struct PackedMsg));
   }
   else
   {
      printf("ERROR: Couldn't allocate memory for packet header\n");
      Log("|||*-","ERROR: Couldn't allocte mem for pkt header");
      return(0);
   }
   Log("|||*-","Done MsgToPkt()");

   return(1);
}

int AppendToPKT(UBYTE *what, int howmuch, BOOL crashpkt)
{
   int i;
   int j;

   if(crashpkt) j=-2;
   else j=0;

   i=Seek(PKTfile,j,OFFSET_END); /* move to end */
   if(MyDEBUG>2) printf("AT LOCATION ** %d **  WRITING %d BYTES ...\n",i,howmuch);

   i=Write(PKTfile,(void *)what,howmuch);
   if(i!=howmuch)
   {
      printf("ERROR: Wrote wrong number of bytes - %d",i);
   }
   return(i);
}

OpenPKT(int zone, int net, int node, int point, BOOL crashpkt,int fromzone,int fromnet,int fromnode,int frompoint)
{

/* this routine has been kludged back until we figger out
what to do with the packed origin net and node */


/* rekludged again */

   int i,j;

   char addr[40];
   char pw[10];
   char use[10];

   char string[100];

   char pktname[100];

   UBYTE clock[8];

   struct Packet_Header *pkthead;

   pkthead=(void *)AllocMem(sizeof(struct Packet_Header),MEMF_PUBLIC | MEMF_CLEAR);
   if(!pkthead)
   {
      printf("ERROR: Couldn't allocate memory for packet header\n");
      return(-9);
   }     


   sprintf(pktname,"OUTBOUND:%d.%d.%d.%d.",zone,net,node,point);

   if(crashpkt)
   {
      strcat(pktname,"CUT");
      MADECRASH=TRUE;
   }
   else
   {
      strcat(pktname,"RAWPKT");
      MADENORMAL=TRUE;
   }

   for(i=0;i<10;i++)
   {
      PKTfile=NULL;
      PKTfile=Open(pktname,MODE_OLDFILE);
      if(PKTfile)
      {
         sprintf(logstring,"OLD %s packet opened successfully",pktname);
         Log("||||*",logstring);
         if(MyDEBUG)printf("[32mold %s opened successfully[0m\n",pktname);
         FreeMem(pkthead,sizeof(struct Packet_Header));
         return(1);
      }
      else
      {
         PKTfile=NULL;
         PKTfile=Open(pktname,MODE_NEWFILE);
         if(PKTfile)
         {
            sprintf(logstring,"NEW %s packet opened successfully",pktname);
            Log("||||*",logstring);
            sprintf(string,"%d:%d/%d.%d",zone,net,node,point);
            SetComment(pktname,string);            

            if(MyDEBUG)printf("NEW %s opened successfully\n",pktname);

            /*strcat(logstring," (<=NEWPKT)");*/
   
            /* build packet header here */
            
            /* figure out time here */

            getclk(clock);




      /*v39*/     pkthead->CapabilityWord=FixNumbers((USHORT) CAPABILITYWORD);
            pkthead->ProductCode=   (UBYTE) PRODUCTCODE;
            pkthead->ProductCode_HIBYTE=0;
            pkthead->PV_Version=PROGVER;
            pkthead->PV_Revision=PROGREV;
            pkthead->MySerialNumber=_XORCRC;
      /*v48*/     pkthead->CWValidate=(USHORT)CAPABILITYWORD;






      /*v39*/     pkthead->DestZone1=  FixNumbers((USHORT)zone);
      /*v39*/     pkthead->DestZone2=  FixNumbers((USHORT)zone);
            pkthead->DestNet= FixNumbers((USHORT) net);
            pkthead->DestNode=   FixNumbers((USHORT)node);
      /*v39*/     pkthead->DestPoint=  FixNumbers((USHORT)point);

            pkthead->Year=    FixNumbers((USHORT) (clock[1]+1980));
            pkthead->Month=      FixNumbers((USHORT) clock[2]-1);
            pkthead->Day=     FixNumbers((USHORT) clock[3]);
            pkthead->Hour=    FixNumbers((USHORT) clock[4]);
            pkthead->Minute=  FixNumbers((USHORT) clock[5]);
            pkthead->Second=  FixNumbers((USHORT) clock[6]);
            pkthead->Baud=0;
            pkthead->PacketType= FixNumbers((USHORT) FIDOPKTTYPE);


            if(fromnet)       pkthead->OrigNet=FixNumbers((USHORT)fromnet);
            else        pkthead->OrigNet=FixNumbers((USHORT)_MyNet);

            if(fromnode)      pkthead->OrigNode=FixNumbers((USHORT)fromnode);
            else        pkthead->OrigNode=FixNumbers((USHORT)_MyNode);

      /*v39*/     if(frompoint)     pkthead->OrigPoint=FixNumbers((USHORT)frompoint);
            else        pkthead->OrigPoint=FixNumbers((USHORT)_MyPoint);

      /*v39*/     if(fromzone)
            {
               pkthead->OrigZone1=FixNumbers((USHORT)fromzone);
               pkthead->OrigZone2=FixNumbers((USHORT)fromzone);
            }
            else
            {
               pkthead->OrigZone1=FixNumbers((USHORT)_MyZone);
               pkthead->OrigZone2=FixNumbers((USHORT)_MyZone);
            }              








            pkthead->Password[0]=0;
            pkthead->Password[1]=0;
            pkthead->Password[2]=0;
            pkthead->Password[3]=0;
            pkthead->Password[4]=0;
            pkthead->Password[5]=0;
            pkthead->Password[6]=0;
            pkthead->Password[7]=0;


            sprintf(addr,"%d:%d/%d.%d",zone,net,node,point);
            if(GetPKTPw(addr,pw,use)==1)
            {
               if(0==strnicmp(use,"OUT",3) || 0==strnicmp(use,"BOTH",4))
               {
                  strncpy(pkthead->Password,pw,8);
                  sprintf(logstring,"Packet password for [%s] is [%s]",addr,pw);
               }
            }









            
            j=Write(PKTfile,(void *)pkthead,sizeof(struct Packet_Header));
   
            if(crashpkt)
            {
               /* write an extra 2 0 bytes out here... */
               strcpy(string,"");      /* ahem, null byte between messages */
               Write(PKTfile,string,1);
               Write(PKTfile,string,1);
            }

            if(j==sizeof(struct Packet_Header))
            {
               if(MyDEBUG)printf("packet header written successfully\n");
            }
            else
            {
               printf("ERROR: Problem writing packet header\n");
               Close(PKTfile);
               PKTfile=NULL;
               Delay(10);
               DeleteFile(pktname);
               Delay(10);
            }
            if(PKTfile) Close(PKTfile);
            PKTfile=NULL;
            Delay(10);
         }
      }
   }
   PKTfile=NULL;
   FreeMem(pkthead,sizeof(struct Packet_Header));
   return(0);
}

int ClosePKT()
{
   if(PKTfile) Close(PKTfile);
   PKTfile=NULL;
   if(MyDEBUG) printf("PKTfile closed\n");
   return(0);
}

RouteNetMail(int *zone, int *net, int *node, int *point,int attrib)
{
   FILE *fp;
   char buffer[250],buf[250];

   char wastezone[100],wastenet[100],wastenode[100],wastepoint[100],wasteext[100];

   char majic[250];

   int wz,wN,wn,wp;

   char *s,*p;

   /* just in case we get lost later */

   wz=*zone;
   wN=*net;
   wn=*node;
   wp=*point;

   sprintf(majic,"%d:%d/%d.%d",wz,wN,wn,wp);

   /* these things don't get routed */

   if(attrib&CRASH) return(0);
   if(attrib&FILEREQUEST) return(0);




   if((*point==0) && attrib&FILEATTACHED) return(0);




   /* the rest we must check for */

   /* ok, here's the poop. we make one pass through the routing file looking
   for the first match. when found, we return the routing address and the
   value 1.

   routing file format is:

   fulladdress THRU address
   ZONEzone THRU address
   NETzonenet THRU address
   
   */

   fp=fopen("FIDO:DLGMail.MRT","r");
   if(!fp)
   {
      if(MyDEBUG) printf("no FIDO:DLGMail.MRT routing file available\n");
      return(0);
   }

   while(1)
   {
      if(NULL==fgets(buffer,248,fp))
         break;

      buffer[strlen(buffer)-1]=NULL;

      if(buffer[0]==';') continue;
      if(strlen(buffer)==0) continue;

      p=buffer;
      s=p;
      p=stptok(s,buf,sizeof(buf)," \t");

      if(_LOG && MyDEBUG) printf("\nComparing [%s] to [%s]... ",majic,buf);

      if(FidoPatternMatch(majic,buf))
      {
         /* got our match */

         if(_LOG && MyDEBUG) printf("MATCH! ");

         s=stpblk(p);   /* pass blanks */
         if(p==s) break;   /* hmmm... fuckup... break! */

         if(*p==';') break;   /* hmmmmm. comment... break! */

         p=stptok(s,buf,sizeof(buf)," \t");
         if(0==stricmp(buf,"THRU") || 0==stricmp(buf,"THROUGH"))
         {
            /* found our routing keyword, now skip blanks and get the address */       
            s=stpblk(p);
            if(p==s) break;
            if(*p==';') break;
            p=stptok(s,buf,sizeof(buf), " \t");
            /* buf should now hold a legit address */
            
            NFComponents(buf,wastezone,wastenet,wastenode,wastepoint,wasteext);
            *zone=atoi(wastezone);
            *net=atoi(wastenet);
            *node=atoi(wastenode);
            *point=atoi(wastepoint);
         }
         else
         {
            break;
         }

         fclose(fp);
         return(1);
      }  
      else
      {
         continue;
      }
   }
   fclose(fp);
   return(0);
}

int NoRouteNetMail(int zone, int net, int node, int point,int attrib)
{
   FILE *fp;
   char buffer[250],buf[250];

   char majic[250];

   char *s,*p;

   sprintf(majic,"%d:%d/%d.%d",zone,net,node,point);

   /* these things don't get routed */

   if(attrib&CRASH) return(0);
   if(attrib&FILEREQUEST) return(0);
   if((point==0) && (attrib&FILEATTACHED)) return(0);

   /* the rest we must check for */

   /* ok, here's the poop. we make one pass through the routing file looking
   for the first match. when found, we return the routing address and the
   value 1.

   */

   fp=fopen("FIDO:DLGMail.BUN","r");
   if(!fp)
   {
      if(MyDEBUG) printf("no FIDO:DLGMail.BUN routing file available\n");
      return(0);
   }

   while(1)
   {
      if(NULL==fgets(buffer,248,fp))
         break;

      buffer[strlen(buffer)-1]=NULL;

      if(buffer[0]==';') continue;
      if(strlen(buffer)==0) continue;

      p=buffer;
      s=p;
      p=stptok(s,buf,sizeof(buf)," \t");

      if(_LOG && MyDEBUG) printf("\nComparing [%s] to [%s]... ",majic,buf);

      if(FidoPatternMatch(majic,buf))
      {
         /* got our match */

         if(_LOG && MyDEBUG) printf("MATCH! ");

         fclose(fp);
         return(1);
      }  
      else
      {
         continue;
      }
   }
   fclose(fp);
   return(0);
}



int FileToPKT()
{
   /* we add a 0 byte for each .RAWPKT found and
      change the name to something that oMMM
      now understands */

   struct FileInfoBlock *ThisFIB;

   char junque[150];

   int i;
   int j;
   char packets[100][35];
   char *pkts[100];
   int type;
   char *filename;
   char comment[50];

   char string[100];
   char newfilename[100];

   char *notused;
   char *loc;
   char buffer[100];
   int zone,k,l,point;

   BPTR LockFile;

   if(MyDEBUG) printf("I'm in FileToPKT()\n");

   ThisFIB=(struct FileInfoBlock *)AllocMem(sizeof(struct FileInfoBlock),MEMF_PUBLIC | MEMF_CLEAR);
   if(!ThisFIB) return(-10);

   sprintf(logstring,".RAWPKT -> .PKT");
   Log("|*---",logstring);

   LockFile=Lock("OUTBOUND:",ACCESS_READ);
   if(LockFile)
   {

      i=Examine(LockFile,ThisFIB);
      if(i)
      {
         j=0;
         while(1)
         {
            type=ThisFIB->fib_DirEntryType;
            filename=ThisFIB->fib_FileName;
            strupr(filename);
            if(type<0 && (0!=stcpm(filename,"RAWPKT",&notused)))
            {
               if(MyDEBUG) printf("Raw packet found: %s\n",filename);
               strcpy(packets[j],filename);
               pkts[j]=packets[j];
               j++;
            }
            i=ExNext(LockFile,ThisFIB);
            if( !i || j==99 ) break;
         }
         tqsort(pkts,j);
         for(i=0;i<j;i++)
         {
            if(MyDEBUG) printf("Packets in ascending order: %s\n",pkts[i]);
         }
      }
      UnLock(LockFile);

   /************************ new routine to rename and add pkt 0 terminator ***************/

      if(j) /* j=number of packets to clean up */
      {
         for(i=0;i<j;i++)
         {
            filename=pkts[i];


            if(MyDEBUG) printf("parsing %s\n",filename);

            loc=memreaduntilterm(filename,buffer,".P");
            zone=atoi(buffer);

            loc=memskipchars(loc,".");
            loc=memreaduntilterm(loc,buffer,".P");
            k=atoi(buffer);

            loc=memskipchars(loc,".");
            loc=memreaduntilterm(loc,buffer,".P");
            l=atoi(buffer);

            loc=memskipchars(loc,".");
            loc=memreaduntilterm(loc,buffer,".P");
            point=atoi(buffer);

            sprintf(comment,"%d:%d/%d.%d",zone,k,l,point);
            sprintf(buffer,"OUTBOUND:%s",filename);
            SetComment(buffer,comment);





            if(ZMAIL_NAME_FORMAT)
            {
               CreatePKTName(newfilename);
               sprintf(junque,"OUTBOUND:%s",newfilename);
               strcpy(newfilename,junque);
            }
            else
            {
               sprintf(newfilename,"OUTBOUND:%04X%04X.OUT",k,l);
            }





            if(MyDEBUG) printf("trying to rename packet %s to %s\n",buffer,newfilename);

            if(Rename(buffer,newfilename))
            {
               if(MyDEBUG) printf("%s-->%s\n",buffer,newfilename);
               sprintf(logstring,"%s -> %s",buffer,newfilename);
               Log("||   ",logstring);
               PKTfile=Open(newfilename,MODE_OLDFILE);
               if(PKTfile)
               {
                  strcpy(string,"");      /* ahem, null byte between messages */
                  Seek(PKTfile,0,OFFSET_END);
                  Write(PKTfile,(void *)string,1);
   /* write two zero bytes */    Seek(PKTfile,0,OFFSET_END);
                  Write(PKTfile,(void *)string,1);
                  Close(PKTfile);
                  sprintf(logstring,"Appended 0 bytes");
                  Log("||   ",logstring);
               }
               else
               {
                  printf("WARNING: Problem appending 0 bytes\n");
                  sprintf(logstring,"ERROR: Couldn't append 0 byte");
                  Log("||   ",logstring);
               }
            }
            else
            {
               printf("ERROR: COULDN'T RENAME FILE\n");

               sprintf(logstring,"ERROR: Couldn't rename %s -> %s",buffer,newfilename);
               Log("||   ",logstring);
            }
         }
      }
   }
   else
   {
      printf("ERROR: No lock on outbound:\n");
      sprintf(logstring,"Couldn't get a lock on outbound:");
      Log("||   ",logstring);
   }
   sprintf(logstring,"Done .RAWPKT -> .PKT");
   Log("|*---",logstring);
   FreeMem((char *)ThisFIB,sizeof(struct FileInfoBlock));
   return(0);
}



