/***************************************************************************
 *                                                                         *
 *   INPOST.C                                                              *
 *                                                                         *
 *   Copyright (c) 1994-1997 Galacticomm, Inc.    All Rights Reserved.     *
 *                                                                         *
 *   Deliver mail to gateway IN directory for MHS processing, along        *
 *   with file attachments.                                                *
 *                                                                         *
 *                                        - J. Alvrus  6/20/94             *
 *                                                                         *
 ***************************************************************************/

#include <fcntl.h>
#include "gcomm.h"

#define FILREV "$Revision: 5 $"

#define MAXSTR 256                 /* temporary string length              */
#define CPYBSZ 65520U              /* copy buffer size                     */
#if defined(GCDOS) || defined(GCWINNT)
#define STARDOT "*."
#endif

                                   /* errorlevel codes                     */
#define NONE        0              /*   everything is ok                   */
#define NOMEM       1              /*   insufficient memory                */
#define BADARG      2              /*   invalid command line arguments     */
#define OPENCFG     3              /*   unable to open OUTPOST.CFG         */
#define BADCFG      4              /*   invalid OUTPOST.CFG                */
#define UNKNOWN     255            /*   unknown error                      */

CHAR atthdr[]="Attachment-name:";
CHAR tmpstr[MAXSTR],               /* scratch string area                  */
     *srcdir,                      /* dir where svr puts outgoing messages */
     *newmsg,                      /* message file search mask             */
     *dstmsg,                      /* gateway message submission directory */
     *dstatt;                      /* gateway attachment submission dir    */
FILE *infp,                        /* input file pointer                   */
     *outfp;                       /* output file pointer                  */
VOID *cpybuf;                      /* buffer for copying file attachments  */

VOID init(INT argc,CHAR *argv[]);
VOID readcfg(CHAR *gtwdir);
VOID scandir(VOID);
VOID domsg(CHAR *msgfil);
INT doatt(FILE *moutf,CHAR *attlin);
INT cpyfil(FILE *inf,FILE *outf);
VOID makebad(CHAR *badfil);
#ifdef GCDOS
INT netseterror(INT mode);
#else
#define netseterror(m) ((VOID)0)
#endif

VOID
main(
INT argc,
CHAR *argv[])
{
     init(argc,argv);
     if ((cpybuf=malloc(CPYBSZ)) == NULL) {
          exit(NOMEM);
     }
     scandir();
     exit(NONE);
}

VOID
init(                              /* initialize program                   */
INT argc,                          /*   # command line arguments           */
CHAR *argv[])                      /*   command line argument array        */
{
     if (argc != 4) {
          exit(BADARG);
     }
     readcfg(argv[2]);
     strcpy(tmpstr,srcdir);
     strcat(tmpstr,STARDOT);
     if ((newmsg=strdup(tmpstr)) == NULL) {
          exit(NOMEM);
     }
     strcpy(tmpstr,argv[2]);
     strcat(tmpstr,"IN" SLS);
     if ((dstmsg=strdup(tmpstr)) == NULL) {
          exit(NOMEM);
     }
     strcpy(tmpstr,argv[2]);
     strcat(tmpstr,"IPARCEL" SLS);
     if ((dstatt=strdup(tmpstr)) == NULL) {
          exit(NOMEM);
     }
}

VOID
readcfg(                           /* read OUTPOST.CFG file                */
CHAR *gtwdir)                      /*   gateway root directory             */
{
     CHAR cfgfile[128],*ptr;
     INT handle;
     FILE *fp;
     struct ffblk fb;

     strcpy(cfgfile,gtwdir);
     strcat(cfgfile,"PUBLIC" SLS "OUTPOST.CFG");
     _fmode=O_TEXT;
     netseterror(1);
     if ((handle=sopen(cfgfile,O_RDONLY,SH_COMPAT,0)) > -1) {
          netseterror(0);
          if ((fp=fdopen(handle,"r")) == NULL) {
               close(handle);
               exit(OPENCFG);
          }
          else {
               fgets(tmpstr,MAXSTR,fp);
               if (strchr(tmpstr,'\n') == NULL) {
                    fclose(fp);
                    exit(BADCFG);
               }
               fgets(tmpstr,MAXSTR,fp);
               fclose(fp);
               if ((ptr=strchr(tmpstr,'\n')) == NULL) {
                    exit(BADCFG);
               }
               *ptr='\0';
               if (findfirst(tmpstr,&fb,FA_DIREC) != 0) {
                    exit(BADCFG);
               }
               strcat(tmpstr,SLS);
               if ((srcdir=strdup(tmpstr)) == NULL) {
                    exit(NOMEM);
               }
          }
     }
     else {
          exit(OPENCFG);
     }
}

VOID
scandir(VOID)                      /* process messages in outgoing dir     */
{
     struct ffblk fb;

     if (findfirst(newmsg,&fb,0) == 0) {
          do {
               if (fb.ff_fsize > 0) {
                    domsg(fb.ff_name);
               }
          } while (findnext(&fb) == 0);
     }
}

VOID
domsg(                             /* process a message                    */
CHAR *msgfil)                      /*   message file name                  */
{
     INT handle;
     CHAR srcfil[GCMAXPTH],dstfil[GCMAXPTH];
     FILE *infp,*outfp;

     strcpy(srcfil,srcdir);
     strcat(srcfil,msgfil);
     _fmode=O_TEXT;
     netseterror(1);
     if ((handle=sopen(srcfil,O_RDONLY,SH_COMPAT,0)) > -1) {
          netseterror(0);
          if ((infp=fdopen(handle,"r")) == NULL) {
               close(handle);
          }
          else {
               strcpy(dstfil,dstmsg);
               netseterror(1);
               if ((handle=creattemp(dstfil,0)) > -1) {
                    netseterror(0);
                    if ((outfp=fdopen(handle,"w")) == NULL) {
                         close(handle);
                         fclose(infp);
                    }
                    else {
                         while (!feof(infp)) {
                              if (fgets(tmpstr,MAXSTR,infp) > 0) {
                                   if (sameto(atthdr,tmpstr)) {
                                        if (!doatt(outfp,tmpstr)) {
                                             makebad(dstfil);
                                             fclose(infp);
                                             fclose(outfp);
                                             remove(dstfil);
                                             return;
                                        }
                                   }
                                   else {
                                        fputs(tmpstr,outfp);
                                   }
                              }
                         }
                         fclose(infp);
                         fclose(outfp);
                         remove(srcfil);
                    }
               }
               else {
                    netseterror(0);
                    fclose(infp);
               }
          }
     }
     else {
          netseterror(0);
     }
}

INT                                /*   returns TRUE if successful         */
doatt(                             /* handle attachment portion of message */
FILE *moutf,                       /*   message output file                */
CHAR *attlin)                      /*   "Attachment-name" line from org msg*/
{
     INT handle;
     CHAR *attnam,oldatt[GCMAXPTH],newatt[GCMAXPTH];
     FILE *ainf,*aoutf;

     attnam=attlin;
     attnam=attnam+strlen(atthdr);
     while (isspace(*attnam)) {
          ++attnam;
     }
     strcpy(oldatt,attnam);
     attnam=oldatt;
     while (!isspace(*attnam)) {
          ++attnam;
     }
     *attnam='\0';
     _fmode=O_BINARY;
     netseterror(1);
     if ((handle=sopen(oldatt,O_RDONLY,SH_COMPAT,0)) > -1) {
          netseterror(0);
          if ((ainf=fdopen(handle,"r")) == NULL) {
               close(handle);
               return(0);
          }
          else {
               strcpy(newatt,dstatt);
               attnam=newatt+strlen(newatt);
               netseterror(1);
               if ((handle=creattemp(newatt,0)) > -1) {
                    netseterror(0);
                    if ((aoutf=fdopen(handle,"w")) == NULL) {
                         fclose(ainf);
                         makebad(newatt);
                         close(handle);
                         remove(newatt);
                         return(0);
                    }
                    else {
                         if (cpyfil(ainf,aoutf)) {
                              fclose(ainf);
                              fclose(aoutf);
                              fprintf(moutf,"Attachment: %s\n",attnam);
                              remove(oldatt);
                         }
                         else {
                              makebad(newatt);
                              fclose(ainf);
                              fclose(aoutf);
                              remove(newatt);
                              return(0);
                         }
                    }
               }
               else {
                    fclose(ainf);
                    netseterror(0);
                    return(0);
               }
          }
     }
     else {
          netseterror(0);
          return(0);
     }
     return(1);
}

INT                                /*   returns TRUE if successful         */
cpyfil(                            /* copy file attachment to MHS dir      */
FILE *inf,                         /*   source file                        */
FILE *outf)                        /*   destination file                   */
{
     UINT frdsiz;

     while (!feof(inf)) {
          if ((frdsiz=fread(cpybuf,1,CPYBSZ,inf)) <= CPYBSZ) {
               if (frdsiz > 0) {
                    fwrite(cpybuf,1,frdsiz,outf);
               }
          }
          else {
               return(0);
          }
          if (ferror(inf) || ferror(outf)) {
               return(0);
          }
     }
     return(1);
}

VOID
makebad(                           /* add ".BAD" extension to file name    */
CHAR *badfil)                      /*   path+file name to make bad         */
{
     CHAR newnam[GCMAXPTH];

     strcpy(newnam,badfil);
     strcat(newnam,".BAD");
     rename(badfil,newnam);
}

#ifdef GCDOS
INT                                /*   returns network response code      */
netseterror(                       /* set network error mode               */
INT mode)                          /*   error mode to set                  */
{
     CHAR rv;

     asm mov ah,0x0DD;
     asm mov dx,mode;
     asm INT 21h;
     asm xor ah,ah;
     asm mov rv,al;
     return(rv);
}
#endif

