/***************************************************************************
 *                                                                         *
 *  GMETVBAH.CPP                                                           *
 *                                                                         *
 *  Active HTML Email Text Variable Classes                                *
 *                                                                         *
 *  Copyright 1998, Galacticomm, Inc., All Rights Reserved                 *
 *                                                                         *
 *                                                     6/8/98 N C Osterc   *
 *                                                            P Henning    *
 *                                                                         *
 ***************************************************************************/

#include "gcomm.h"
#include "majorbbs.h"
#include "ahutil.h"
#include "gme.h"
#include "msgah.h"
#include "gmetvbah.h"
#include "galmsgah.h"
#include "fcntl.h"
#include <cstring.h>
#include "dnfmgr.h"
#include "io.h"

#define FILREV "$Revision: 46 $"

#if defined(EXTRA_LOGGING)
#define LOGFILE "galme.log"        //HACK: change when want EML-only logging
static VOID logmsg(CHAR const * fmt,...);
static VOID vlogmsg(CHAR const * fmt,va_list ap);
#define LOG0(s)               logmsg(s)
#define LOG1(s,v1)            logmsg(s,v1)
#define LOG2(s,v1,v2)         logmsg(s,v1,v2)
#define LOG3(s,v1,v2,v3)      logmsg(s,v1,v2,v3)
#define LOG4(s,v1,v2,v3,v4)   logmsg(s,v1,v2,v3,v4)
#else
#define LOG0(s)               ((VOID)0)
#define LOG1(s,v1)            ((VOID)0)
#define LOG2(s,v1,v2)         ((VOID)0)
#define LOG3(s,v1,v2,v3)      ((VOID)0)
#define LOG4(s,v1,v2,v3,v4)   ((VOID)0)
#endif /* EXTRA_LOGGING */

#define SPRINTFSIZ 16384           // buffer size in set() method
#define DOFWEEK(X)  (dayFromDate(ddyear(X),ddmon(X),ddday(X)))


CHAR shortDays[7][6]={"Sun","Mon","Tue","Wed","Thu","Fri","Sat"};


gmeTvb mMsgId("MHDR_MSGID");
gmeTvb mThrdId("MHDR_THRID");
gmeTvb mForId("MHDR_FORID");
gmeTvb mGlbId("MHDR_GLBID");
gmeTvb mForName("MHDR_FORNAME");
gmeTvb mForNameUrl("MHDR_FORNAME_U");
gmeTvb mForDisp("MHDR_FORDISP");
gmeTvb mTo("MHDR_TO");
gmeTvb mToUrl("MHDR_TO_U");
gmeTvb mToNoPfx("MHDR_TO_NOPFX");
gmeTvb mToMailTo("MHDR_TO_MAILTO");
gmeTvb mFrom("MHDR_FR");
gmeTvb mFromUrl("MHDR_FR_U");
gmeTvb mFromNoPfx("MHDR_FR_NOPFX");
gmeTvb mFromMailTo("MHDR_FR_MAILTO");
gmeTvb mTopic("MHDR_TOPIC");
gmeTvb mHistory("MHDR_HISTORY");
gmeTvb mHistoryP("MHDR_HISTORY_P");
gmeTvb mAttName("MHDR_ATTNAME");
gmeTvb mAttPfx("MHDR_ATTPFX");
gmeTvb mAttApp("MHDR_ATTAPP");
gmeTvb mReplyTo("MHDR_REPLYTO");
gmeTvb mDateUsaLong("MHDR_DATE_USA_L");
gmeTvb mDateUsaShort("MHDR_DATE_USA_S");
gmeTvb mDateEurLong("MHDR_DATE_EUR_L");
gmeTvb mDateEurShort("MHDR_DATE_EUR_S");
gmeTvb mYearLong("MHDR_DATE_Y_L");
gmeTvb mYearShort("MHDR_DATE_Y_S");
gmeTvb mMonthLong("MHDR_DATE_M_L");
gmeTvb mMonthShort("MHDR_DATE_M_S");
gmeTvb mMonthNumeric("MHDR_DATE_M_N");
gmeTvb mMonthNumPad("MHDR_DATE_M_N0");
gmeTvb mDayNum("MHDR_DATE_D");
gmeTvb mDayNumPad("MHDR_DATE_D0");
gmeTvb mDayWeekLong("MHDR_DATE_W_L");
gmeTvb mDayWeekShort("MHDR_DATE_W_S");
gmeTvb mTime12Long("MHDR_TIME_12_L");
gmeTvb mtime12Short("MHDR_TIME_12_S");
gmeTvb mTime24Long("MHDR_TIME_24_L");
gmeTvb mTime24Short("MHDR_TIME_24_S");
gmeTvb mHour12("MHDR_TIME_H_12");
gmeTvb mHour120("MHDR_TIME_H_120");
gmeTvb mHour24("MHDR_TIME_H_24");
gmeTvb mHour240("MHDR_TIME_H_240");
gmeTvb mMinute("MHDR_TIME_M");
gmeTvb mMinutePad("MHDR_TIME_M0");
gmeTvb mSec("MHDR_TIME_S");
gmeTvb mSecPad("MHDR_TIME_S0");
gmeTvb mMeridiemLong("MHDR_TIME_A_L");
gmeTvb mMeridiemLongPeriods("MHDR_TIME_A_LP");
gmeTvb mMeridiemShort("MHDR_TIME_A_S");
gmeTvb mMeridiemLongCaps("MHDR_TIME_A_LC");
gmeTvb mMeridiemLongCapPer("MHDR_TIME_A_LPC");
gmeTvb mMeridiemShortCap("MHDR_TIME_A_SC");
gmeTvb mNumberOfReplies("MHDR_NREPLIES");
gmeTvb mDisplayNumReplies("MHDR_NRPL_DISP");
gmeTvb mPriority("MHDR_PRIORITY");
gmeTvb mExempt("MHDR_EXEMPT");
gmeTvb mReceipt("MHDR_RECEIPT");
gmeTvb mAttImage("MHDR_ATT_IMG");
gmeTvb mPriImage("MHDR_PRI_IMG");
gmeTvb mXmtImage("MHDR_XMT_IMG");
gmeTvb mRRRImage("MHDR_RRR_IMG");
gmeTvb mAttSize("MHDR_ATT_SIZ");
gmeTvb mMsgSize("MHDR_MSG_SIZ");

gmeTvb mNoMessage1("MLST_NOMSG_1");
gmeTvb mNoMessage2("MLST_NOMSG_2");
gmeTvb mNoMessage3("MLST_NOMSG_3");
gmeTvb mNoMessage4("MLST_NOMSG_4");
gmeTvb mNoMessage5("MLST_NOMSG_5");
gmeTvb mNoMessage6("MLST_NOMSG_6");
gmeTvb mNoMessage7("MLST_NOMSG_7");
gmeTvb mNoMessage8("MLST_NOMSG_8");
gmeTvb mNoMessage9("MLST_NOMSG_9");

gmeTvb mCount("MLST_COUNT");
gmeTvb mOrder("MLST_ORDER");
gmeTvb mMsgIdLow("MLST_MSGID_LOW");
gmeTvb mMsgIdHi("MLST_MSGID_HIGH");
gmeTvb mMoreLow("MSG_MORE_LOW");
gmeTvb mMoreHi("MSG_MORE_HIGH");

gmeTvb mWriteType("MWRT_TYPE");
gmeTvb mWriteOrgForId("MWRT_ORGFORID");
gmeTvb mWriteOrgMsgId("MWRT_ORGMSGID");
gmeTvb mWritePriChk("MWRT_PRI_CHK");
gmeTvb mWriteRRRChk("MWRT_RRR_CHK");
gmeTvb mWriteCCList("MWRT_CCLIST");
gmeTvb mWriteIncList("MWRT_INCLIST");
gmeTvb mWriteTmpid("MWRT_TMPID");
gmeTvb mWriteAttFlag("MWRT_ATT_FLG");

gmeTvb ePrefType("EPREF_TYPE");
gmeTvb ePrefTypeHtml("EPREF_TYPE_HTML");
gmeTvb ePrefTypeJava("EPREF_TYPE_JAVA");
gmeTvb ePrefUseFrames("EPREF_USEFRAMES");
gmeTvb mPrefReflow("MPREF_REFLOW");
gmeTvb mPrefQuote("MPREF_QUOTE");
gmeTvb mPrefIncList("MPREF_INCLIST");
gmeTvb mPrefUseTags("MPREF_USETAGS");
gmeTvb ePrefForwardee("EPREF_FORWARDEE");
gmeTvb ePrefClrReply("EPREF_CLRREPLY");
gmeTvb ePrefForumTo("EPREF_FORUMTO");

gmeTvb mErrorMsg("MERR_MESSAGE");
gmeTvb mErrorCode("MERR_CODE");

gmeTvb emlTarget1("EML_TARGET_1");
gmeTvb emlTarget2("EML_TARGET_2");
gmeTvb emlTarget3("EML_TARGET_3");
gmeTvb emlTarget4("EML_TARGET_4");
gmeTvb emlTarget5("EML_TARGET_5");
gmeTvb emlTarget6("EML_TARGET_6");
gmeTvb emlTarget7("EML_TARGET_7");
gmeTvb emlTarget8("EML_TARGET_8");
gmeTvb emlTarget9("EML_TARGET_9");


gmeTvb forID("FDEF_FORID");
gmeTvb forName("FDEF_FORNAME");
gmeTvb forNameU("FDEF_FORNAME_U");
gmeTvb forTopic("FDEF_TOPIC");
gmeTvb forOP("FDEF_FOROP");
gmeTvb forThreads("FDEF_THRS");
gmeTvb forMessages("FDEF_MSGS");
gmeTvb forFiles("FDEF_FILES");
gmeTvb forFilesWaiting("FDEF_FILES_WAIT");
gmeTvb forMsgLife("FDEF_MSGLIFE");
gmeTvb forChgPost("FDEF_CHG_POST");
gmeTvb forChgRead("FDEF_CHG_READ");
gmeTvb forChgUL("FDEF_CHG_UL");
gmeTvb forChgDL("FDEF_CHG_DL");
gmeTvb forChgULk("FDEF_CHG_ULK");
gmeTvb forChgDLk("FDEF_CHG_DLK");
gmeTvb forCrtDateUSALong("FDEF_CDAT_USL");
gmeTvb forCrtDateUSAShort("FDEF_CDAT_USS");
gmeTvb forCrtDateEurLong("FDEF_CDAT_EUL");
gmeTvb forCrtDateEurShort("FDEF_CDAT_EUS");
gmeTvb forCrtDateYearLong("FDEF_CDAT_YL");
gmeTvb forCrtDateYearShort("FDEF_CDAT_YS");
gmeTvb forCrtDateMonthLong("FDEF_CDATE_ML");
gmeTvb forCrtDateMonthShort("FDEF_CDAT_MS");
gmeTvb forCrtDateMonthNum("FDEF_CDAT_MN");
gmeTvb forCrtDateMonthNumPadded("FDEF_CDAT_MN0");
gmeTvb forCrtDateDayNum("FDEF_CDAT_D");
gmeTvb forCrtDateDayNumPadded("FDEF_CDAT_D0");
gmeTvb forCrtDateDayLong("FDEF_CDAT_WL");
gmeTvb forCrtDateDayShort("FDEF_CDAT_WS");
gmeTvb forInQScan("FDEF_INQSCAN");
gmeTvb forInQScanCH("FDEF_INQSCANCH");
gmeTvb forUsrAccess("FDEF_USRACCESS");

gmeTvb curforID("FCUR_FORID");
gmeTvb curforName("FCUR_FORNAME");
gmeTvb curforNameU("FCUR_FORNAME_U");
gmeTvb curforTopic("FCUR_TOPIC");
gmeTvb curforOP("FCUR_FOROP");
gmeTvb curforThreads("FCUR_THRS");
gmeTvb curforMessages("FCUR_MSGS");
gmeTvb curforFiles("FCUR_FILES");
gmeTvb curforFilesWaiting("FCUR_FILES_WAIT");
gmeTvb curforMsgLife("FCUR_MSGLIFE");
gmeTvb curforChgPost("FCUR_CHG_POST");
gmeTvb curforChgRead("FCUR_CHG_READ");
gmeTvb curforChgUL("FCUR_CHG_UL");
gmeTvb curforChgDL("FCUR_CHG_DL");
gmeTvb curforChgULk("FCUR_CHG_ULK");
gmeTvb curforChgDLk("FCUR_CHG_DLK");
gmeTvb curforCrtDateUSALong("FCUR_CDAT_USL");
gmeTvb curforCrtDateUSAShort("FCUR_CDAT_USS");
gmeTvb curforCrtDateEurLong("FCUR_CDAT_EUL");
gmeTvb curforCrtDateEurShort("FCUR_CDAT_EUS");
gmeTvb curforCrtDateYearLong("FCUR_CDAT_YL");
gmeTvb curforCrtDateYearShort("FCUR_CDAT_YS");
gmeTvb curforCrtDateMonthLong("FCUR_CDATE_ML");
gmeTvb curforCrtDateMonthShort("FCUR_CDAT_MS");
gmeTvb curforCrtDateMonthNum("FCUR_CDAT_MN");
gmeTvb curforCrtDateMonthNumPadded("FCUR_CDAT_MN0");
gmeTvb curforCrtDateDayNum("FCUR_CDAT_D");
gmeTvb curforCrtDateDayNumPadded("FCUR_CDAT_D0");
gmeTvb curforCrtDateDayLong("FCUR_CDAT_WL");
gmeTvb curforCrtDateDayShort("FCUR_CDAT_WS");
gmeTvb curforInQScan("FCUR_INQSCAN");
gmeTvb curforInQScanCH("FCUR_INQSCANCH");
gmeTvb curforUsrAccess("FCUR_USRACCESS");

gmeTvb mIsAuthor("MHDR_ISAUTHOR");
gmeTvb forQuotePref("FMPREF_QUOTE");
gmeTvb forReflowPref("FMPREF_REFLOW");
gmeTvb forType("FPREF_TYPE");
gmeTvb forTypeHTML("FPREF_TYPE_HTML");
gmeTvb forTypeJava("FPREF_TYPE_JAVA");

gmeTvb forTarget1("FOR_TARGET_1");
gmeTvb forTarget2("FOR_TARGET_2");
gmeTvb forTarget3("FOR_TARGET_3");
gmeTvb forTarget4("FOR_TARGET_4");
gmeTvb forTarget5("FOR_TARGET_5");
gmeTvb forTarget6("FOR_TARGET_6");
gmeTvb forTarget7("FOR_TARGET_7");
gmeTvb forTarget8("FOR_TARGET_8");
gmeTvb forTarget9("FOR_TARGET_9");

MARKSOURCE(gmetvbah);

template <class T>
string stringFormat(T val)         // format any value to a string
{
     string str;
     ostrstream ost;
     ost << val << ends;
     str=ost.str();
     ost.rdbuf()->freeze(0);
     return(str);
}

gmeTvb::gmeTvb(                    // constructor
const CHAR* name) : tvbDefinition(name)
                  , bHtmlEncode(TRUE)
                  , bCgiEncode(FALSE)
                  , m_pVal(NULL)
{
     registerDef();
     m_pVal=new string("");
}

gmeTvb::~gmeTvb()                  // destructor
{
     if (m_pVal != NULL) {
          delete m_pVal;
     }
}

VOID
gmeTvb::set(                       // set a tvb value
const CHAR *fmt,                   // format specifier(s)
...)                               // variable argument list
{
     CHAR buf[SPRINTFSIZ];

     setmem(buf,SPRINTFSIZ,0);
     va_list ap;
     va_start(ap,fmt);
     vsprintf(buf,fmt,ap);
     *m_pVal=buf;
     va_end(ap);
}

VOID
gmeTvb::set2(                       // set a tvb value
const CHAR *fmt)                    // variable argument list
{                                   // % in msg topic sometimes cause the system to crash due to invalid pointer.
     *m_pVal=fmt;
}

const CHAR*                        // tvb value
gmeTvb::get() const                // get it
{
     return(m_pVal->c_str());
}

VOID
gmeTvb::clr()                      // clear tvb value
{
     *m_pVal="";
}

GBOOL
gmeTvb::cgiEncodeIt()              // should we cgi encode?
{
     return(bCgiEncode);
}

VOID
gmeTvb::setCgiEncode(              // set cgi encode for tvb
GBOOL bVal)                        // boolean set value
{
     bCgiEncode=bVal;
     bHtmlEncode=!bVal;
}

GBOOL
gmeTvb::htmlEncodeIt()             // should we html encode?
{
     return(bHtmlEncode);
}

VOID
gmeTvb::setHtmlEncode(             // set html encode for tvb
GBOOL bVal)                        // boolean set value
{
     bHtmlEncode=bVal;
     bCgiEncode=!bVal;
}

const CHAR*                        // the resolved value of the tvb
gmeTvb::resolve(                   // resolve the value of a tvb
const CHAR* nam)                   // the name of the tvb
{
     if (m_pVal->length() > 0) {
          if (htmlEncodeIt()) {
               // Stp4Html does not do an in-place change, so casting
               // is ok.
               return((const CHAR*)Stp4Html((CHAR*)m_pVal->c_str()));
          }
          else if(cgiEncodeIt()) {
               return(cgiEncode(m_pVal->c_str()));
          }
          else {
               return(m_pVal->c_str());
          }
     }
     (VOID*)nam;
     return("");
}

VOID
setUpMessageHeaderDefs(            // work-horse method-sets up majority of tvbs
struct message *msghdr)            // ptr to message structure to use
{
     ASSERT(msghdr != NULL);
     struct fordef fdef;
     GBOOL isEmail=TRUE;

     if (msghdr == NULL) {
          return;
     }

     setmbk(gmeAHmbk);
     mMsgId.set("%d",msghdr->msgid);
     mThrdId.set("%d",msghdr->thrid);
     mForId.set("%d",msghdr->forum);
     clrprf();
     prfmsg(GLBIDFMT,ltoa(msghdr->rplto.sysid),ltoa(msghdr->rplto.msgid));
     mGlbId.set(stpans(prfbuf));
     if (msghdr->forum == EMLID) {
          mForDisp.set(dispEml);
     }
     else if (getdefb(msghdr->forum,&fdef) != NULL) {
          isEmail=FALSE;
          mForName.set(fdef.name);
          mForNameUrl.set(fdef.name);
          clrprf();
          prfmsg(DISPFOR,fdef.name);
          mForDisp.set(stpans(prfbuf));
     }
     if (strlen(msghdr->attname) > 0) {
          mAttApp.set(msghdr->flags&FILAPV ? "1" : "0");
     }
     else {
          mAttApp.set("0");
     }
     mTo.set(msghdr->to);
     mToUrl.set(msghdr->to);
     mToNoPfx.set(skppfx(msghdr->to));
     mToMailTo.set(mailToAddr(msghdr->to));
     mFrom.set(msghdr->from);
     mFromUrl.set(msghdr->from);
     mFromNoPfx.set(skppfx(msghdr->from));
     mFromMailTo.set(mailToAddr(msghdr->from));
     // mTopic.set(msghdr->topic);  this would cause system to crash if % in subject line. bad pointer
     mTopic.set2(msghdr->topic);
     mHistory.set(msghdr->history);
     mHistoryP.set(historyParens(msghdr->history));
     mAttName.set(msghdr->attname);
     if (strlen(msghdr->attname) > 0) {
          mAttImage.set(imgAtty);
          mAttPfx.set(attFmt);
          if (msghdr->msgid > 0 && (msghdr->forum == EMLID
           || fidxst(msghdr->forum))) {
               INT handle=open(dlname(msghdr),O_RDONLY);
               mAttSize.set("%ld",filelength(handle));
               close(handle);
          }
     }
     else {
          mAttImage.set(imgAttn);
          mAttPfx.set("");
     }
     clrprf();
     prfmsg(GLBIDFMT,ltoa(msghdr->rplto.sysid),ltoa(msghdr->rplto.msgid));
     mReplyTo.set(stpans(prfbuf));
     mDateUsaLong.set(prndat(PRND_MMMDYY,msghdr->crdate,'/'));
     mDateUsaShort.set(ncdate(msghdr->crdate));
     mDateEurLong.set("%d %s %d"
                              ,ddday(fdef.crdate)
                              ,strMonths[ddmon(fdef.crdate)-1]
                              ,ddyear(fdef.crdate));
     mDateEurShort.set(ncedat(fdef.crdate));
     mYearLong.set("%d",ddyear(msghdr->crdate));
     string shortyear("");
     shortyear=stringFormat(ddyear(msghdr->crdate));
     mYearShort.set(shortyear.c_str()+2);
     mMonthLong.set(strMonths[ddmon(msghdr->crdate)-1]);
     mMonthShort.set("%.3s",strMonths[ddmon(msghdr->crdate)-1]);
     mMonthNumeric.set("%d",ddmon(msghdr->crdate));
     mMonthNumPad.set("%.2d",ddmon(msghdr->crdate));
     mDayNum.set("%d",ddday(msghdr->crdate));
     mDayNumPad.set("%.2d",ddday(msghdr->crdate));
     mDayWeekLong.set(strDays[DOFWEEK(msghdr->crdate)]);
     mDayWeekShort.set(shortDays[DOFWEEK(msghdr->crdate)]);
     mTime12Long.set(prntim(PRNT_HMS_PM,msghdr->crtime));
     mtime12Short.set(prntim(PRNT_HM_PM,msghdr->crtime));
     mTime24Long.set(prntim(PRNT_HMS,msghdr->crtime));
     mTime24Short.set(prntim(PRNT_HM,msghdr->crtime));

     INT hour=dthour(msghdr->crtime);
     mHour12.set("%d",hour%12);
     mHour120.set("%.2d",hour%12);
     mHour24.set("%d",hour);
     mHour240.set("%.2d",hour);

     INT min=dtmin(msghdr->crtime);
     mMinute.set("%d",min);
     mMinutePad.set("%.2d",min);

     INT sec=dtsec(msghdr->crtime);
     mSec.set("%d",sec);
     mSecPad.set("%.2d",sec);

     mMeridiemLong.set(formatMeridiem(msghdr->crtime,FMT_L));
     mMeridiemLongPeriods.set(formatMeridiem(msghdr->crtime,FMT_LP));
     mMeridiemShort.set(formatMeridiem(msghdr->crtime,FMT_S));
     mMeridiemLongCaps.set(formatMeridiem(msghdr->crtime,FMT_LC));
     mMeridiemLongCapPer.set(formatMeridiem(msghdr->crtime,FMT_LPC));
     mMeridiemShortCap.set(formatMeridiem(msghdr->crtime,FMT_SC));
     mNumberOfReplies.set("%d",msghdr->nrpl);
     clrprf();
     switch(msghdr->nrpl) {
     case 0:
          prfmsg(NRPLZER);
          break;
     case 1:
          prfmsg(NRPLONE);
          break;
     default:
          prfmsg(NRPLMULT,msghdr->nrpl);
          break;
     }
     mDisplayNumReplies.set(stpans(prfbuf));
     if (!isEmail || !(msghdr->flags&PRIMSG)) {
          mPriImage.set(imgPrin);
     }
     else if (msghdr->flags&PRIMSG) {
          mPriority.set(priDsp);
          mPriImage.set(imgPriy);
     }
     if (isEmail || !(msghdr->flags&EXEMPT)) {
          mXmtImage.set(imgXmtn);
     }
     else if (msghdr->flags&EXEMPT) {
          mExempt.set(xmtDsp);
          mXmtImage.set(imgXmty);
     }
     if (!isEmail || !(msghdr->flags&RECREQ)) {
          mRRRImage.set(imgrrrn);
     }
     else if (msghdr->flags&RECREQ) {
          mReceipt.set(rrrDsp);
          mRRRImage.set(imgrrry);
     }
     rstmbk();
}

VOID
setCountTvb(                       // establish value of count tvb
INT count)                         // value to establish
{
     mCount.set("%d",count);
}

VOID
setOrderTvb(                       // establish value of order tvb
const CHAR *order)                 // order ("ascending"/"descending")
{
     ASSERT(order != NULL);
     ASSERT(sameas(order,"ascending") || sameas(order,"descending"));
     mOrder.set(order);
}

VOID
setMsgIdLowTvb(                    // establish value of low msg
ULONG msgid)                       // value to establish
{
     mMsgIdLow.set("%d",msgid);
}

VOID
setMsgIdHiTvb(                     // establish value of hi msg
ULONG msgid)                       // value to establish
{
     mMsgIdHi.set("%d",msgid);
}

VOID
setMoreLowTvb(                     // establish if there are more low msgs
GBOOL more)                        // yes or no
{
     mMoreLow.set(more ? "1" : "0");
}

VOID
setMoreHiTvb(                      // establish if there are more hi msgs
GBOOL more)                        // yes or no
{
     mMoreHi.set(more ? "1" : "0");
}

VOID
setUpNoMessages()                  // handle no msg tvbs
{
     mNoMessage1.set(noMsg1);
     mNoMessage2.set(noMsg2);
     mNoMessage3.set(noMsg3);
     mNoMessage4.set(noMsg4);
     mNoMessage5.set(noMsg5);
     mNoMessage6.set(noMsg6);
     mNoMessage7.set(noMsg7);
     mNoMessage8.set(noMsg8);
     mNoMessage9.set(noMsg9);
}

VOID
setErrorMessage(                   // set an error message tvb
const CHAR *errmsg)                // the error message
{
     ASSERT(errmsg != NULL);

     mErrorMsg.set(errmsg);
}

VOID
setErrorCode(                      // set an error code tvb
INT code)                          // the error code
{
     mErrorCode.set("%d",code);
}

VOID
setEmailTargetTvbs(                // set up email target tvb values
GBOOL set)
{
     if (set) {
          emlTarget1.set(eTarget1);
          emlTarget2.set(eTarget2);
          emlTarget3.set(eTarget3);
          emlTarget4.set(eTarget4);
          emlTarget5.set(eTarget5);
          emlTarget6.set(eTarget6);
          emlTarget7.set(eTarget7);
          emlTarget8.set(eTarget8);
          emlTarget9.set(eTarget9);
     }
     else {
          emlTarget1.clr();
          emlTarget2.clr();
          emlTarget3.clr();
          emlTarget4.clr();
          emlTarget5.clr();
          emlTarget6.clr();
          emlTarget7.clr();
          emlTarget8.clr();
          emlTarget9.clr();
     }
}

GBOOL
setForumDefByID(                   // set up forum definition tvb by fid
USHORT fmid)                       // fid to setup
{
     struct fordef fdef;

     if (getdefb(fmid,&fdef) != NULL) {
          forID.set("%hd",fdef.forum);
          forName.set(fdef.name);
          forNameU.set(fdef.name);
          forTopic.set(fdef.topic);
          forOP.set(fdef.forop);
          forThreads.set("%hd",fdef.nthrs);
          forMessages.set("%hd",fdef.nmsgs);
          forFiles.set("%hd",fdef.nfiles);
          forFilesWaiting.set("%hd",fdef.nw4app);
          forMsgLife.set("%hd",fdef.msglif);
          forChgPost.set("%hd",fdef.chgmsg);
          forChgRead.set("%hd",fdef.chgrdm);
          forChgUL.set("%hd",fdef.chgatt);
          forChgDL.set("%hd",fdef.chgadl);
          forChgULk.set("%hd",fdef.chgupk);
          forChgDLk.set("%hd",fdef.chgdpk);
          forCrtDateUSALong.set(prndat(PRND_MMMDYY,fdef.crdate,' '));
          forCrtDateUSAShort.set(ncdate(fdef.crdate));
          forCrtDateEurShort.set(ncedat(fdef.crdate));
          forCrtDateYearLong.set("%d",ddyear(fdef.crdate));
          forCrtDateYearShort.set("%d",ddyear(fdef.crdate)+2);
          forCrtDateMonthLong.set(strMonths[ddmon(fdef.crdate)-1]);
          forCrtDateMonthShort.set("%.3s",strMonths[ddmon(fdef.crdate)-1]);
          forCrtDateMonthNum.set("%d",ddmon(fdef.crdate));
          forCrtDateMonthNumPadded.set("%.2d",ddmon(fdef.crdate));
          forCrtDateDayNum.set("%d",ddday(fdef.crdate));
          forCrtDateDayNumPadded.set("%.2d",ddday(fdef.crdate));
          forCrtDateDayLong.set(strDays[DOFWEEK(fdef.crdate)]);
          forCrtDateDayShort.set(shortDays[DOFWEEK(fdef.crdate)]);
          forCrtDateEurLong.set("%d %s %d"
                                   ,ddday(fdef.crdate)
                                   ,strMonths[ddmon(fdef.crdate)-1]
                                   ,ddyear(fdef.crdate));
          return(TRUE);
     }
     return(FALSE);
}

GBOOL
setForumDefByName(                 // set up forum definition tvb by forum name
const CHAR* name)                  // forum name
{
     USHORT fmid=getfid(name);
     if (fmid != EMLID) {
          return(setForumDefByID(fmid));
     }
     return(FALSE);
}

GBOOL
setCurForumDefByID(                // set up forum definition tvb by fid
USHORT fmid)                       // fid to setup
{
     struct fordef fdef;

     if (getdefb(fmid,&fdef) != NULL) {
          curforID.set("%hd",fdef.forum);
          curforName.set(fdef.name);
          curforNameU.set(fdef.name);
          curforTopic.set(fdef.topic);
          curforOP.set(fdef.forop);
          curforThreads.set("%hd",fdef.nthrs);
          curforMessages.set("%hd",fdef.nmsgs);
          curforFiles.set("%hd",fdef.nfiles);
          curforFilesWaiting.set("%hd",fdef.nw4app);
          curforMsgLife.set("%hd",fdef.msglif);
          curforChgPost.set("%hd",fdef.chgmsg);
          curforChgRead.set("%hd",fdef.chgrdm);
          curforChgUL.set("%hd",fdef.chgatt);
          curforChgDL.set("%hd",fdef.chgadl);
          curforChgULk.set("%hd",fdef.chgupk);
          curforChgDLk.set("%hd",fdef.chgdpk);
          curforCrtDateUSALong.set(prndat(PRND_MMMDYY,fdef.crdate,' '));
          curforCrtDateUSAShort.set(ncdate(fdef.crdate));
          curforCrtDateEurShort.set(ncedat(fdef.crdate));
          curforCrtDateYearLong.set("%d",ddyear(fdef.crdate));
          curforCrtDateYearShort.set("%d",ddyear(fdef.crdate)+2);
          curforCrtDateMonthLong.set(strMonths[ddmon(fdef.crdate)-1]);
          curforCrtDateMonthShort.set("%.3s",strMonths[ddmon(fdef.crdate)-1]);
          curforCrtDateMonthNum.set("%d",ddmon(fdef.crdate));
          curforCrtDateMonthNumPadded.set("%.2d",ddmon(fdef.crdate));
          curforCrtDateDayNum.set("%d",ddday(fdef.crdate));
          curforCrtDateDayNumPadded.set("%.2d",ddday(fdef.crdate));
          curforCrtDateDayLong.set(strDays[DOFWEEK(fdef.crdate)]);
          curforCrtDateDayShort.set(shortDays[DOFWEEK(fdef.crdate)]);
          curforCrtDateEurLong.set("%d %s %d"
                                   ,ddday(fdef.crdate)
                                   ,strMonths[ddmon(fdef.crdate)-1]
                                   ,ddyear(fdef.crdate));
          return(TRUE);
     }
     return(FALSE);
}

GBOOL
setCurForumDefByName(                 // set up forum definition tvb by forum name
const CHAR* name)                  // forum name
{
     USHORT fmid=getfid(name);
     if (fmid != EMLID) {
          return(setForumDefByID(fmid));
     }
     return(FALSE);
}

VOID
setCurForInQScanVar(               // set inqscan text variable
const CHAR* forum,                 // forum to check
const CHAR* userid)                // user to check
{
     ASSERT(forum != NULL);
     ASSERT(userid != NULL);

     GMEUSERHANDLE hndl;

     if (gmeUserReference(userid,&hndl) != GMEOK) {
          ASSERTM(FALSE,"Gme User records not loaded!");
          return;
     }
     LOG1("MSG.setCurForInQScanVar Reference: h=%lu",hndl);
     struct qscfg* pqs=gmeUserGetQS(hndl);
     INT forumid=getfid(forum);
     if (forumid == EMLID) {
          curforInQScan.set("0");
          curforUsrAccess.set("0");
          curforInQScanCH.clr();
     }
     else {
          curforInQScan.set(gethi(pqs,forumid) > 0 ? "1" : "0");
          curforUsrAccess.set("%d",gforac(userid,forumid));
          curforInQScanCH.set(gethi(pqs,forumid) > 0 ? "CHECKED" : "");
     }
     LOG1("MSG.setCurForInQScanVar closing: h=%lu",hndl);
     gmeUserClose(hndl);
}


VOID
setInQScanVar(                     // set inqscan text variable
const CHAR* forum,                 // forum to check
const CHAR* userid)                // user to check
{
     ASSERT(forum != NULL);
     ASSERT(userid != NULL);

     GMEUSERHANDLE hndl;

     if (gmeUserReference(userid,&hndl) != GMEOK) {
          ASSERTM(FALSE,"Gme User records not loaded!");
          return;
     }
     LOG1("MSG.setInQScanVar Reference: h=%lu",hndl);
     struct qscfg* pqs=gmeUserGetQS(hndl);
     INT forumid=getfid(forum);
     if (forumid == EMLID) {
          forInQScan.set("0");
          forUsrAccess.set("0");
          forInQScanCH.clr();
     }
     else {
          forInQScan.set(gethi(pqs,forumid) > 0 ? "1" : "0");
          forUsrAccess.set("%d",gforac(userid,forumid));
          forInQScanCH.set(gethi(pqs,forumid) > 0 ? "CHECKED" : "");
     }
     LOG1("MSG.setInQScanVar closing: h=%lu",hndl);
     gmeUserClose(hndl);
}

VOID
setAuthorVar(                      // set the Author TVB value
const CHAR* userid,                // to this user
const CHAR* msgfrom)               // from this user
{
     ASSERT(userid != NULL && msgfrom != NULL);

     mIsAuthor.set(sameas(userid,msgfrom) ? "1" : "0");
}

VOID
clearAllDefs()                     // clear all tvb values
{
     mMsgId.clr();
     mThrdId.clr();
     mForId.clr();
     mGlbId.clr();
     mForName.clr();
     mForNameUrl.clr();
     mForDisp.clr();
     mTo.clr();
     mToUrl.clr();
     mToNoPfx.clr();
     mToMailTo.clr();
     mFrom.clr();
     mFromUrl.clr();
     mFromNoPfx.clr();
     mFromMailTo.clr();
     mTopic.clr();
     mHistory.clr();
     mHistoryP.clr();
     mAttName.clr();
     mAttPfx.clr();
     mReplyTo.clr();
     mDateUsaLong.clr();
     mDateUsaShort.clr();
     mDateEurLong.clr();
     mDateEurShort.clr();
     mYearLong.clr();
     mYearShort.clr();
     mMonthLong.clr();
     mMonthShort.clr();
     mMonthNumeric.clr();
     mMonthNumPad.clr();
     mDayNum.clr();
     mDayNumPad.clr();
     mDayWeekLong.clr();
     mDayWeekShort.clr();
     mTime12Long.clr();
     mtime12Short.clr();
     mTime24Long.clr();
     mTime24Short.clr();
     mHour12.clr();
     mHour120.clr();
     mHour24.clr();
     mHour240.clr();
     mMinute.clr();
     mMinutePad.clr();
     mSec.clr();
     mSecPad.clr();
     mMeridiemLong.clr();
     mMeridiemLongPeriods.clr();
     mMeridiemShort.clr();
     mMeridiemLongCaps.clr();
     mMeridiemLongCapPer.clr();
     mMeridiemShortCap.clr();
     mNumberOfReplies.clr();
     mDisplayNumReplies.clr();
     mPriority.clr();
     mExempt.clr();
     mReceipt.clr();
     mAttImage.clr();
     mPriImage.clr();
     mXmtImage.clr();
     mRRRImage.clr();
     mAttSize.clr();
     mMsgSize.clr();

     mNoMessage1.clr();
     mNoMessage2.clr();
     mNoMessage3.clr();
     mNoMessage4.clr();
     mNoMessage5.clr();
     mNoMessage6.clr();
     mNoMessage7.clr();
     mNoMessage8.clr();
     mNoMessage9.clr();

     mCount.clr();
     mOrder.clr();
     mMsgIdLow.clr();
     mMsgIdHi.clr();
     mMoreLow.clr();
     mMoreHi.clr();

     mWriteType.clr();
     mWriteOrgForId.clr();
     mWriteOrgMsgId.clr();
     mWritePriChk.clr();
     mWriteRRRChk.clr();
     mWriteCCList.clr();
     mWriteIncList.clr();
     mWriteTmpid.clr();

     ePrefType.clr();
     ePrefTypeHtml.clr();
     ePrefTypeJava.clr();
     ePrefUseFrames.clr();
     mPrefReflow.clr();
     mPrefQuote.clr();
     mPrefIncList.clr();
     mPrefUseTags.clr();
     ePrefForwardee.clr();
     ePrefClrReply.clr();
     ePrefForumTo.clr();

     mErrorMsg.clr();
     mErrorCode.clr();

     dnfClearTemplateTvb();


     forID.clr();
     forName.clr();
     forTopic.clr();
     forOP.clr();
     forThreads.set("0");
     forMessages.set("0");
     forFiles.set("0");
     forFilesWaiting.set("0");
     forMsgLife.clr();
     forChgPost.clr();
     forChgPost.clr();
     forChgUL.clr();
     forChgDL.clr();
     forChgULk.clr();
     forChgDLk.clr();
     forCrtDateUSALong.clr();
     forCrtDateUSAShort.clr();
     forCrtDateEurShort.clr();
     forCrtDateYearLong.clr();
     forCrtDateYearShort.clr();
     forCrtDateMonthLong.clr();
     forCrtDateMonthShort.clr();
     forCrtDateMonthNum.clr();
     forCrtDateMonthNumPadded.clr();
     forCrtDateDayNum.clr();
     forCrtDateDayNumPadded.clr();
     forCrtDateDayLong.clr();
     forCrtDateDayShort.clr();
     forCrtDateEurLong.clr();
     forUsrAccess.set("0");

     curforID.clr();
     curforName.clr();
     curforTopic.clr();
     curforOP.clr();
     curforThreads.set("0");
     curforMessages.set("0");
     curforFiles.set("0");
     curforFilesWaiting.set("0");
     curforMsgLife.clr();
     curforChgPost.clr();
     curforChgPost.clr();
     curforChgUL.clr();
     curforChgDL.clr();
     curforChgULk.clr();
     curforChgDLk.clr();
     curforCrtDateUSALong.clr();
     curforCrtDateUSAShort.clr();
     curforCrtDateEurShort.clr();
     curforCrtDateYearLong.clr();
     curforCrtDateYearShort.clr();
     curforCrtDateMonthLong.clr();
     curforCrtDateMonthShort.clr();
     curforCrtDateMonthNum.clr();
     curforCrtDateMonthNumPadded.clr();
     curforCrtDateDayNum.clr();
     curforCrtDateDayNumPadded.clr();
     curforCrtDateDayLong.clr();
     curforCrtDateDayShort.clr();
     curforCrtDateEurLong.clr();
     curforUsrAccess.set("0");


     mIsAuthor.set("0");
}

VOID
setForTargetTvb(                   // set forum target tvb values
GBOOL useframes)
{
     if (useframes) {
          forTarget1.set(fTarget1);
          forTarget2.set(fTarget2);
          forTarget3.set(fTarget3);
          forTarget4.set(fTarget4);
          forTarget5.set(fTarget5);
          forTarget6.set(fTarget6);
          forTarget7.set(fTarget7);
          forTarget8.set(fTarget8);
          forTarget9.set(fTarget9);
     }
     else {
          forTarget1.clr();
          forTarget2.clr();
          forTarget3.clr();
          forTarget4.clr();
          forTarget5.clr();
          forTarget6.clr();
          forTarget7.clr();
          forTarget8.clr();
          forTarget9.clr();
     }
}

VOID
setDnfTemplateTvb(                 // set the template text variable value
const dnfHandler* dnf)             // given pointer to dnfHandler
{
     dnfSetTemplateTvb(dnf);
}

#ifdef EXTRA_LOGGING

static VOID
vlogmsg(                           /* output to log file                   */
CHAR const * fmt,
va_list ap)
{
     FILE * fp;

     if ((fp=fopen(LOGFILE,FOPAA)) != NULL) {
          fprintf(fp,"%s %s: ",ncdate(today()),nctime(now()));
          vfprintf(fp,fmt,ap);
          fprintf(fp,"\n");
          fclose(fp);
     }
}

static VOID
logmsg(                            /* output to log file                   */
CHAR const * fmt,
...)
{
     va_list ap;

     va_start(ap,fmt);
     vlogmsg(fmt,ap);
     va_end(ap);
}

#endif /* EXTRA_LOGGING */
