/***************************************************************************
 *                                                                         *
 *   FRMEMAIL.C                                                            *
 *                                                                         *
 *   Copyright (c) 1995-1997 Galacticomm, Inc.  All rights reserved.       *
 *                                                                         *
 *   This is the forms->e-mail World-Wide Web add-on for Worldgroup.       *
 *                                                                         *
 *                                                -C. Dunn 11/28/95        *
 *                                                                         *
 ***************************************************************************/

#include "gcomm.h"
#include "majorbbs.h"
#include "gme.h"
#include "tcpip.h"
#include "mimectyp.h"
#include "webd.h"
#include "smtpexp.h"
#include "qrystg.h"
#include "galfmeml.h"

#define FILREV "$Revision: 13 $"

#define MSGXTR 256                 /* extra room for formatting EMLBDY     */
#define MSGSIZ (txtlen()-MSGXTR)   /* maximum size of text body for msg    */
#define FMADDR "From Address"      /* field to indicate From: address      */
#define MSGTPC "Topic"             /* field to indicate topic of message   */

static VOID femwebreq(CHAR *uri);
static VOID (*oldwebreq)(CHAR *uri);
static CHAR *getfval(CHAR *qrystg,CHAR *fldnam,CHAR *fvalue,UINT flen);
static GBOOL isAddrOk(CHAR *toAddr);

static HMCVFILE femmb;             /* file pointer to GALFMEML.MCV         */

static CHAR *fempfx;               /* forms->e-mail prefix string          */
static CHAR *fbkto;                /* forms->e-mail fallback To: address   */
static CHAR *fbkfrm;               /* forms->e-mail fallback From: address */
static CHAR *fbktpc;               /* forms->e-mail fallback message topic */
static GBOOL exportAddrOk;         /* accept form-to-exporter (e.g IN:)    */
static GBOOL forumAddrOk;          /* accept form-to-forum                 */

VOID EXPORT
init__galfmeml(VOID)               /* forms->e-mail module init routine    */
{
     init__webd();
     femmb=opnmsg("galfmeml.mcv");
     exportAddrOk=ynopt(F2EXP);
     forumAddrOk=ynopt(F2FOR);
     fempfx=getmsg(FEMPFX);
     if (*fempfx != '/') {
          movmem(fempfx,fempfx+1,strlen(fempfx)+1);
          *fempfx='/';
     }
     if (!samend(fempfx,"/")) {
          strcat(fempfx,"/");
     }
     fempfx=strdup(fempfx);
     stpans(fbkto=stgopt(FBKTO));
     stpans(fbkfrm=stgopt(FBKFRM));
     stpans(fbktpc=stgopt(FBKTPC));
     oldwebreq=hdlwebreq;
     hdlwebreq=femwebreq;
     dclvda(txtlen());
}

VOID EXPORT
initwc__galfmeml(VOID)
{
     init__galfmeml();
}

static VOID
femwebreq(                         /* forms->e-mail request handler        */
CHAR *uri)
{
     GBOOL more;
     struct qrsinf qsinf;
     CHAR *femuri,*qpos;
     INT rc;
     struct addrinf addrinf;
     static struct message msg;

     if (!sameto(fempfx,uri)) {
          (*oldwebreq)(uri);
          return;
     }
     setmbk(femmb);
     if (!sameas(webdptr->method,"GET")) {
          byeweb(NOMETH,webdptr->method);
          return;
     }
     femuri=uri+strlen(fempfx);
     if ((qpos=strchr(femuri,'?')) == NULL) {
          byeweb(BADFMT,fempfx);
          return;
     }
     *qpos++='\0';
     strrpl(femuri,'+',' ');
     setmem(&msg,sizeof(struct message),0);
     stlcpy(msg.to,femuri,MAXADR);
     decurl(msg.to);
     if (!isAddrOk(msg.to)) {
          stlcpy(msg.to,fbkto,MAXADR);
          if (!isAddrOk(msg.to)) {
               byeweb(SNDADR,msg.to);
               return;
          }
     }
     strrpl(qpos,'+',' ');
     if (sameas(getfval(qpos,FMADDR,msg.from,MAXADR),"")) {
          stlcpy(msg.from,fbkfrm,MAXADR);
     }
     else if ((fixadr(NULL,msg.from) && sameto(smtfpx,msg.from))
           || smtval(msg.from)) {
          /* remove any existing IN prefix, smtpCvtFrom will add */
          if (sameto(smtfpx,msg.from)) {
               strmove(msg.from,msg.from+strlen(smtfpx));
          }
          parseIntAddr(msg.from,&addrinf);
          smtpCvtFrom(msg.from,&addrinf);
     }
     if (sameas(getfval(qpos,MSGTPC,msg.topic,TPCSIZ),"")) {
          stlcpy(msg.topic,fbktpc,TPCSIZ);
     }
     prfmsg(EMLHDR1,webdptr->refer == NULL ? "<none>" : webdptr->refer);
     stpans(prfbuf);
     strcpy(vdatmp,"\r");
     stlcat(vdatmp,prfbuf,MSGSIZ);
     for (more=qrs1st(&qsinf,qpos) ; more ; more=qrsnxt(&qsinf)) {
          if (!sameto(FMADDR,qsinf.name)
           && !sameto(MSGTPC,qsinf.name)) {
               clrprf();
               strstp(qsinf.value,'\r');           /* GME needs only '\n's */
               prfmsg(EMLBDY,qsinf.name,qsinf.value);
               stpans(prfbuf);
               if (strlen(vdatmp)+strlen(prfbuf) >= MSGSIZ) {
                    prfmsg(FRMLONG);
                    stlcat(vdatmp,stpans(prfbuf),MSGSIZ);
                    break;
               }
               stlcat(vdatmp,stpans(prfbuf),MSGSIZ);
          }
     }
     clrprf();
     prfmsg(EMLFTR);
     stlcat(vdatmp,stpans(prfbuf),MSGSIZ);
     clrprf();
     if ((rc=simpsnd(&msg,vdatmp,NULL)) >= GMEAGAIN) {
          byeweb(SENTOK);
     }
     else {
          byeweb(SNDERR,rc);
     }
}

static CHAR *                      /*   return "" if field value not found */
getfval(                           /* get field value from query string    */
CHAR *qrystg,                      /*   query string to search             */
CHAR *fldnam,                      /*   field name to search for           */
CHAR *fvalue,                      /*   field value buffer space           */
UINT flen)                         /*   maximum field value length (incl 0)*/
                                   /*   Note: It is up to the programmer   */
                                   /*   to ensure that fvalue's buffer     */
                                   /*   space is large enough for fvalue!  */
{
     UINT siz;
     CHAR *namptr;
     CHAR *eqptr;
     CHAR *ampptr;

     namptr=qrystg;
     while (1) {
          if (sameto(fldnam,namptr) && *(eqptr=namptr+strlen(fldnam)) == '=') {
               if ((ampptr=strchr(eqptr,'&')) == NULL) {
                    siz=flen;
               }
               else {
                    siz=min(flen,(UINT)(ampptr-eqptr));
               }
               return(decurl(stlcpy(fvalue,eqptr+1,siz)));
          }
          if ((ampptr=strchr(namptr,'&')) == NULL) {
               break;
          }
          namptr=ampptr+1;
     }
     return(strcpy(fvalue,""));
}

static GBOOL                       //   TRUE - Ok
isAddrOk(                          // accept form-to that address
CHAR *toAddr)                      //   address to check
{
     return(adrxst(toAddr) && !isdlst(toAddr)
            && (exportAddrOk || !isexpa(toAddr))
            && (forumAddrOk || !isforum(toAddr)));
}
