/****************************************************************************
 *                                                                          *
 *  GALNOTE.C                                                               *
 *                                                                          *
 *  Copyright (c) 1993-1997 Galacticomm, Inc.  All rights reserved.         *
 *                                                                          *
 *  Display text files automatically to each user at logon.                 *
 *                                                                          *
 *                                 - Bill Hyatt, March 1993                 *
 *                                                                          *
 ****************************************************************************/

#include "gcomm.h"
#include "majorbbs.h"
#include "wgsmajor.h"
#undef    LEVEL4                   /* don't need Level 4 from bbsmajor.msg */
#include "galnote.h"

#define FILREV "$Revision: 9 $"

#define ANCING -1                  /* announcing to user substate          */
#define noteptr ((struct noteusr *)vdaptr)
#define BYT2RD 512                 /* no. of bytes to read from disk       */
#define NTENAM "GCOMM NOTES"

GBOOL note(VOID);
GBOOL stubinp(VOID);
VOID notests(VOID);
INT  prcafl(VOID);
VOID endafl(VOID);
VOID clsafl(VOID);
VOID notefin(VOID);
static INT ntgge(VOID);
static VOID ntuge(VOID);

struct module noteblk={            /* module interface block               */
     "",                           /*    description for main menu         */
     note,                         /*    user logon supplemental routine   */
     stubinp,                      /*    input routine if selected         */
     notests,                      /*    status-input rtn if selected      */
     NULL,                         /*    "injoth" routine for this mod     */
     NULL,                         /*    user logoff supplemental rtn      */
     clsafl,                       /*    hangup (lost carrier) routine     */
     NULL,                         /*    midnight cleanup routine          */
     NULL,                         /*    delete-account routine            */
     notefin                       /*    finish-up (sys shutdown) rtn      */
};

struct noteusr {                   /* announcer vda data block             */
     FILE *notefil;                /*     handle for announcement file     */
};

static
INT notestt;                       /* Logon Notes state                    */

HMCVFILE notemb;                   /* GALNOTE.MCV                          */
FILE *notefil;                     /* file containing announcement text    */

CHAR *notefnm,                     /* name of file containing annc. text   */
      *txtatr;                     /* ANSI attr for announcement text      */

INT ufphdr,                        /* use text block FPGHDR as annc. txt hd*/
    shwalw;                        /* show announcements every logon 1=YES */

static
struct ffblk notefb;              /* ffblk structure for announcement fil*/

struct ntgen {                     /* bbsgen.dat load/save structure       */
     CHAR userid[UIDSIZ];          /*     User-ID for load/save            */
     CHAR modnam[MNMSIZ];          /*     Module name (GCOMM NOTES)        */
     struct ffblk ntblk;          /*     ffblk for last read file        */
} *ntgbuf;                         /* ptr to single load/save area         */


VOID EXPORT
init__galnote(VOID)                /* Initialize Logon Notes               */
{
     stzcpy(noteblk.descrp,gmdnam("galnote.mdf"),MNMSIZ);
     notestt=register_module(&noteblk);
     dclvda(sizeof(struct noteusr));
     notemb=opnmsg("galnote.mcv");
     notefnm=stgopt(ANCFNM);
     ufphdr=ynopt(UFPHDR);
     txtatr=stgopt(TXTATR);
     shwalw=ynopt(SHWALW);
     ntgbuf=(struct ntgen *)alcmem(sizeof(struct ntgen));
}

VOID EXPORT
initwc__galnote(VOID)
{
     init__galnote();
}

GBOOL
note(VOID)                         /* Logon Notes supp. logon routine      */
{
     if (usrptr->flags&WSGCSU) {
          return(FALSE);
     }
     setmbk(notemb);
     switch (usrptr->substt) {
     case 0:
          if ((noteptr->notefil=fopen(notefnm,FOPRB)) == NULL) {
               return(FALSE);
          }
          if (!shwalw) {
               fndfile(&notefb,notefnm,0);
               if (ntgge()) {
                    if (sameas(notefb.ff_name,ntgbuf->ntblk.ff_name)
               && notefb.ff_ftime == ntgbuf->ntblk.ff_ftime
               && notefb.ff_fdate == ntgbuf->ntblk.ff_fdate
               && notefb.ff_fsize == ntgbuf->ntblk.ff_fsize) {
                         fclose(noteptr->notefil);
                         noteptr->notefil=NULL;
                         return(FALSE);
                    }
               }
          }
          if ((usaptr->ansifl&ANSON) && (samend(notefnm,".ans")
                          || samend(notefnm,".ibm"))) {
               btutsw(usrnum,0);
               btuxnf(usrnum,0,19);
          }
          if (ufphdr) {
               setmbk(mjrmb);
               prfmsg(FPGHDR);
               rstmbk();
          }
          else {
               prfmsg(ANCHDR);
          }
          prf("\33[0m%s",txtatr);
          outprf(usrnum);
          usrptr->substt=ANCING;
          btuinj(usrnum,CYCLE);
          break;
     case ANCING:
          if (usrptr->flags&ABOIP) {
               endafl();
               return(FALSE);
          }
          break;
     case ANCTRL:
          prfmsg(ANCTRL);
          outprf(usrnum);
          return(FALSE);
     }
     return(TRUE);
}

GBOOL
stubinp(VOID)                      /* stub input routine                   */
{
     return(FALSE);
}

VOID
notests(VOID)                     /* Logon Notes status handler             */
{
     switch (status) {
     case CYCLE:
          if (noteptr->notefil != NULL) {
               if (prcafl()) {
                    btuinj(usrnum,CYCLE);
               }
               else {
                    usrptr->substt=ANCTRL;
                    injacr();
               }
          }
          break;
     default:
          dfsthn();
     }
}

INT
prcafl(VOID)                     /* ongoing announce-file read/processing   */
{
     INT oba;
     static CHAR txtbuf[BYT2RD];

     clrprf();
     oba=min(btuoba(usrnum),4096);
     while (oba > (BYT2RD*2)) {
          if (mdfgets(txtbuf,BYT2RD,noteptr->notefil) == NULL) {
               if (btuoba(usrnum) == outbsz-1 && prfbuf[0] == '\0') {
                    endafl();
                    return(0);
               }
               break;
          }
          prf("%s",txtbuf);
          oba-=strlen(txtbuf);
     }
     if (prfbuf[0] != '\0') {
          xltctls(prfbuf);       /* translate ^'s into control characters   */
          outprf(usrnum);
     }
     return(1);
}

VOID
endafl(VOID)                     /* file-read operation complete, finish up */
{
     clsafl();
     btutsw(usrnum,usaptr->scnwid);
     rstrxf();
     if (btuoba(usrnum) != outbsz-1) {
          btuclo(usrnum);
          prf("\r");
     }
     if (!shwalw) {
          ntuge();
     }
}

VOID
clsafl(VOID)                     /* close user's handle for anncmnt file    */
{
     if (usrptr->state == notestt && noteptr->notefil != NULL) {
          fclose(noteptr->notefil);
          noteptr->notefil=NULL;
     }
}

VOID
notefin(VOID)                    /* Logon Notes system shutdown rtn         */
{
     clsmsg(notemb);
}

static INT
ntgge(VOID)                        /* read bbsgen.dat's galnote info       */
{
     INT retval;

     setmem(ntgbuf,sizeof(struct ntgen),0);
     strcpy(ntgbuf->userid,usaptr->userid);
     strcpy(ntgbuf->modnam,NTENAM);
     dfaSetBlk(genbb);
     retval=dfaAcqEQ(ntgbuf,ntgbuf,0);
     dfaRstBlk();
     return(retval);
}

static VOID
ntuge(VOID)                        /* update bbsgen.dat's galnote info     */
{
     setmem(ntgbuf,sizeof(struct ntgen),0);
     strcpy(ntgbuf->userid,usaptr->userid);
     strcpy(ntgbuf->modnam,NTENAM);
     movmem(&notefb,&ntgbuf->ntblk,sizeof(struct ffblk));
     dfaSetBlk(genbb);
     if (dfaAcqEQ(NULL,ntgbuf,0)) {
          dfaUpdateV(ntgbuf,sizeof(struct ntgen));
     }
     else {
          dfaInsertV(ntgbuf,sizeof(struct ntgen));
     }
     dfaRstBlk();
}
