/****************************************************************************/
/*                                                                          */
/*    MSGHELP.C   : Maximus message handler routines                        */
/*                    Currently Maximus only handles old fido style         */
/*                    1.MSG message format, so only will here as well.      */
/*                    But that is expected to change soon!                  */
/*                    And I will add routines to support it.                */
/*                                                                          */
/*                   Alll message calls handling FIDO style messages        */
/*                   will have "fido" embedded in the function name         */
/*                   so its easy to distinguish. The new Maximus            */
/*                   format will have "max" in replace of "fido"            */
/*                   when it is stable. Actually Maximus will still         */
/*                   support the old style on an area by area basis.        */
/*                                                                          */
/*                   All these functions are as self-contained as           */
/*                   possible.                                              */
/****************************************************************************/

#include "MaxMail.h"

int     fido_init = FALSE;
char  _far *msgbuffer;
struct  _msg amsg;

char     msg_line[130];


/* You MUST call this first to initialize things */
int _pascal fidomsg_init()
{
   msgbuffer = (char _far *) _fmalloc(((unsigned) MAXFMSGSIZ));
   if (msgbuffer == NULL)  
      return(MEMORY_ALLOC_ERR);
   fido_init = TRUE;
   return(0);
}

/* Return the highest message in an area. -1 if error
   msgpath:  DOS path for messages (has a trailing \)  */

int _pascal find_fidohigh(char *msgpath)
{
   register	int  done,highest=0;
   int	  h;
   struct  find_t  c_file;
   char    apath[66];

   if (!fido_init)
      return(0);
   sprintf(apath,"%s*.MSG",msgpath);
   done = _dos_findfirst(apath,0,&c_file);
   if (done)  {
      /* Invalid Path and/or empty directory!! */
      return(0);
   }
   while (!done && highest < MAXFMSGS){
      h = atoi(c_file.name);
      if (h>highest && (c_file.size > 0L)) {
         highest=h;
      }
	   done=_dos_findnext(&c_file);
   }
   return(highest);
}

/* Read a Fido style message to a file
   i:      Message #
   flags:  Types of Messages and whether to output to screen also
   path:   Message path (with trailing \)
   output: Output file to write to
*/

int _pascal file_fidomsg(int i,int flags,FILE *output,struct msgupd_st *msgupd,struct msghead *MSGHD)
{
   int         infp,j,m,n,start;
   struct      find_t      c_file;
   long	      size;
   char        temp[9];


   if (!fido_init)
      return(NOT_INITIALIZED);
   j = n = 0;
   sprintf(temp1,"%s%u%s",msgupd->msgpath,i,".MSG");
   if (_dos_findfirst(temp1,0,&c_file) !=0) 
      return(FILE_SRCH_ERR);

   if (c_file.size >= (long) MAXFMSGSIZ) 	/* Message is too big! */
      return(FILE_SIZE_ERR);

   size=c_file.size - ((long) sizeof(struct _msg));
   infp=sopen(temp1,O_RDONLY|O_BINARY,SH_DENYNO,S_IREAD);
   if (infp < 0) 
      return(FILE_OPEN_ERR);

   j = read(infp,(char *) &amsg,sizeof(struct _msg));
   if (j != sizeof(struct _msg)) 
      return(FILE_READ_ERR);

   _dos_read(infp,msgbuffer,(unsigned)size,&j);
   if (j != (int)size) 
      return(FILE_READ_ERR);

   close(infp);
   if ( (flags & PRIVATE) && (amsg.attr & MSGPRIVATE)) {
      if (strcmpi(amsg.to,MSGHD->ourname) != 0)
         return(PVTMSG_ERR);		/* No messages to read */
   }

   if (infp) {		/* We had a valid MSG file */
      fprintf(output,"\n\nMESSAGE #:   %u  of %u",i,msgupd->himsg);
      if (amsg.up)
         fprintf(output,"  (replies: #%d)",amsg.up);
      fprintf(output,"\n");
      fprintf(output,"FROM:        %s",amsg.from);
      strcpy(MSGHD->from,amsg.from);
      strcpy(MSGHD->subject,amsg.subj);
      if (amsg.attr & MSGPRIVATE) fprintf(output,"     (PRIVATE)");
      if (amsg.reply)
         fprintf(output," (reply to #%d)",amsg.reply);
      if (strcmpi(amsg.to,MSGHD->ourname) == 0) {
         if (!(AREA.attrib[UserClass] & ECHOMAIL)) {		/* Its a local area */
            infp = sopen(temp1,O_RDWR|O_BINARY,SH_DENYWR,S_IWRITE);
            if (infp >= 0) {
               j = read(infp,(char *) &amsg,sizeof(struct _msg));
               if (j == sizeof(struct _msg)) { 	/* Mark message as rcvd */
                  amsg.attr |= MSGREAD;
                  lseek(infp,0L,SEEK_SET);		/* Rewind */
                  write(infp,(char *) &amsg,sizeof(struct _msg));
               }
               close(infp);
            }
         }
         fprintf(output,"\nTO:          %s       <<PERSONAL MESSAGE>>\n",amsg.to);
         j = MSGHD->ourmail;
         MSGHD->ourmail++;
         if (MSGHD->answers == NULL) {		/* Start of list */
            MSGHD->answers = (int *) calloc(1,sizeof(int));
            if (MSGHD->answers == NULL)
               aborterror(BADALLOC,NULL);
         }
         else {
            MSGHD->answers = (int *) realloc(MSGHD->answers,(j + 1) * sizeof(int));
            if (MSGHD->answers == NULL)
               aborterror(BADALLOC,NULL);
         }
         MSGHD->answers[j] = i;
      }
      else fprintf(output,"\nTO:          %s\n",amsg.to);
      fprintf(output,"Subject:     %s\n",amsg.subj);
      fprintf(output,"Date:        %s\n\n",amsg.date);

	   j=0;
	   start=0;
      while (msgbuffer[j] == '\0') {
         j++;
         start++;
      }

      for (j = start; j <= (int) size; j++) {		/* Search for SEEN-BY, returns */
         if (msgbuffer[j] == SOFT) {
            if (msgbuffer[j-1] == '\n') {
               msgbuffer[j-2]=' ';
               msgbuffer[j-1]=' ';
            }
         }
         if ((msgbuffer[j] == SOFT) || (msgbuffer[j]=='\r')) {
            if (msgbuffer[j+1] == '\r')
               msgbuffer[j]='\n';
            if (msgbuffer[j+1] != '\n')
               msgbuffer[j]='\n';
            else msgbuffer[j]=' ';
         }
         if (msgbuffer[j+1] == 'S'){
            if ((msgbuffer[j]=='\012') || (msgbuffer[j] == '\001')) {
               for (m=0;m<=7;m++)
                  temp[m]=msgbuffer[j+m+1];
               temp[8]='\0';
               if (strcmp(temp,SEEN) ==0) size = (long)j-1;
            }
         }
      }		/* End of search for SEEN-BY, returns */
      for (j = start;j <= (int)size; j++) {
         if (msgbuffer[j] == '\001' ) {
            while (msgbuffer[j] == '\001') {
               while ((msgbuffer[j] != 0x0A) && (msgbuffer[j] !=0x0D))
                  j++;
               while ((msgbuffer[j] < ' ') && (msgbuffer[j] > '\001'))
                  j++;
            }
         }
         msg_line[n] = msgbuffer[j];
         if (n>79) {		/* Do word-wrap */
            do {
               n--;
               j--;
            } while ((msg_line[n] != ' ') && (n>10));
            msg_line[n] = '\n';
         }		/* End of word-wrap */
         else if (msg_line[n] != '\n') {
            n++;
            msg_line[n] = 0x00;
         }
         if ((msgbuffer[j] == '\n') || (msg_line[n] == '\n')) {
            msg_line[n+1] = 0x00;
            n = 0;
            fputs(msg_line,output);
            msg_line[0] = 0x00;
            msg_line[1] = 0x00;
         }
      }
      if (msg_line[n] != '\n') {
         msg_line[n+1] = '\n';
         n++;
      }
      msg_line[n+1] = 0x00;
      fputs(msg_line,output);
   }

   if (fflush(output) == EOF) 
      return(FILE_WRITE_ERR);
   return(i);		/* No errors!, return message number */
}

