/***************************************************************************
 *                                                                         *
 *   BBSINT.C                                                              *
 *                                                                         *
 *   Copyright (c) 1987-1997 Galacticomm, Inc.    All Rights Reserved.     *
 *                                                                         *
 *   This is the integration-checker that should be run in the WG batch    *
 *   file just before firing up the server each time.  If there has been   *
 *   any change in time, date, or size on any of the .MDF files in the     *
 *   current directory, or any re-arrangement of them, or any change in    *
 *   the time, date, or size of WGSMENU2.DAT since the last time it ran,   *
 *   it goes into the more elaborate integration checking logic, and       *
 *   re-creates WGSERV.CFG, WGSUTL.REF, WGSMDF.REF, WGSINT.REF, and        *
 *   WGSMDFS.LST.  It also runs any install utilities referenced on        *
 *   "Install:" lines in MDF files, and it rebuilds WGSUSER.DOC from the   *
 *   components given in "Online user manual:" lines in MDF files.         *
 *   Finally, it creates WGSBTR.BAT, which is called out in WG.BAT to set  *
 *   up Btrieve with the proper pagesize and file-count parameters.        *
 *                                                                         *
 *   The /w switch may be specified on the DOS command line to enable,     *
 *   at a minimum, just the basic checking logic, which warns the user     *
 *   if there are outstanding references to modules no longer present.     *
 *   This setting should be used upon entry to WG.BAT, to remind the       *
 *   guy to edit his Menu Tree if this condition is true.                  *
 *                                                                         *
 *                                            - T. Stryker 2/17/92         *
 *                                                                         *
 ***************************************************************************/

#ifdef GCWINNT
#include <windows.h>
#endif // GCWINNT
#include "gcomm.h"
#include "majorbbs.h"
#include "integrou.h"
#include "excphand.h"

#define FILREV "$Revision: 19 $"

#define ICOPATH "wgsicons"SLS"*.ico"    /* system's icon directory/filespec*/
#define DEFICO  "wgsdef"                /* default icon file name (no ext.)*/

struct iconew {                    /* in-memory linked list of icon files  */
     CHAR name[FNSIZE];            /*   file name, sans extension          */
     INT flags;                    /*   #defined bitflags                  */
     LONG size;                    /*   file size                          */
     INT date;                     /*   file date, DOS format              */
     INT time;                     /*   file time, DOS format              */
     struct iconew *next;          /*   next element in list, or NULL if no*/
} *infirst=NULL;

#define ICOCHNGD 0x0001       /* bitflag: icon has changed                 */
#define ICOINLST 0x0002       /* bitflag: icon is in WGSICONS.LST file     */

#define CFILBSZ  16384        /* copy file buffer size                     */

GBOOL redo=FALSE;             /* flag: need to redo list and possibly menus*/

CHAR *scnsav=NULL;            /* saved DOS image dynamic screen buffer     */

extern CHAR scntbl[][GVIDSCNSIZ];/* array of screens (c/o MAKESCNS)*/

GBOOL anychg(GBOOL firsttime);     /* (from ANYCHG.C)                      */

#ifndef UNIX
static VOID copyvirs(VOID);
#endif

VOID regntxt(VOID);
INT fndmod(CHAR *modnam);
static CHAR *choplast(CHAR *line);
VOID iconchek(VOID);
VOID iconrev(VOID);

INT
main(
INT argc,
CHAR *argv[])
{
TRY
     INT i;
     struct ffblk fb;
     CHAR *inp;
     INT savx,savy;
     FILE *fp;
#ifdef GCWINNT
     extern VOID checkreg(VOID);
#endif // GCWINNT

#ifdef GCWINNT
     if (!canRunWGSINT()) {
          MessageBox(NULL,NOPROCEED,
                    argv[0],MB_ICONSTOP|MB_OK|MB_TASKMODAL|MB_SETFOREGROUND);
          return(1);
     }
#endif // GCWINNT
     initvid();
     scnsav=alcmem(GVIDSCNSIZ);
     scn2mem(scnsav,0,GVIDSCNSIZ);
     savx=curcurx();
     savy=curcury();
     if (setjmp(disaster)) {
          setatr(0x4E);
          printf("\n    << Press any key to proceed >>");
          getchc();
          mem2scn(scnsav,0,GVIDSCNSIZ);
          locate(0,23);
#ifdef GCWINNT
          dfaStop();
#endif // GCWINNT
          return(1);
     }
     monorcol();
     cvtscn(scntbl[0]);
#ifdef GCWINNT
     cvtscn(scntbl[1]);
#endif //GCWINNT
     setcrit();
     iconchek();
#ifdef GCWINNT
     checkreg();
#endif // GCWINNT
     if (anychg(TRUE)) {
          if ((fp=fopen("WGSCMAPS.FLG",FOPWA)) != NULL) {
               fprintf(fp,"Flag file: check apps for compression\n");
               fclose(fp);
          }
          cursiz(GVIDNOCURS);
#ifndef UNIX
          copyvirs();
#endif
          iniint();
          wrtmjr();
          for (i=0 ; i < nmdfs ; i++) {
               inp=moddat[i].instal;
               if (*inp != '\0') {
                    if (isrunpgm(&fb,inp)) {
                         system(inp);
                         mem2scn(scnsav,0,GVIDSCNSIZ);
                         unlink(fb.ff_name);
                         if (!refsok()) {
                              clrefs();
                              ctrefs();
                         }
                    }
               }
          }
          regntxt();
          finint();
          if (anychg(FALSE)) {
               iniint();
               finint();
          }
          cursiz(GVIDLILCURS);
     }
     else if (argc > 1 && sameas(argv[1],"/w")) {
          iniint();
          reqchk();
     }
     if (redo) {
          iconrev();
     }
     mem2scn(scnsav,0,GVIDSCNSIZ);
     locate(savx,savy);
     clsvid();
#ifdef GCWINNT
     dfaStop();
#endif // GCWINNT
     return(0);
EXCEPT
#ifdef GCWINNT
     dfaStop();
     return(1);
#endif // GCWINNT
}

VOID
regntxt(VOID)                 /* regenerate WGSUSER.DOC from scratch       */
{
     CHAR *fname,*bp;
     INT mainum,i;

     explodeto(scntbl[0],0,0,27,4,25,10);
     cursiz(GVIDNOCURS);
     unlink("wgsuser.doc");
     if (*(fname=moddat[mainum=fndmod("Main Executive")].usrtxt) != '\0') {
          if (!cpyutl(fname,"wgsuser.doc",FOPRA,FOPWA)) {
               catastro("Unable to copy %s to wgsuser.doc",fname);
          }
     }
     for (i=0 ; i < nmdfs ; i++) {
          if (i != mainum && *(fname=moddat[i].usrtxt) != '\0') {
               if (!cpyutl(fname,"wgsuser.doc",FOPRA,FOPAA)) {
                    catastro("Unable to append %s to wgsuser.doc",fname);
               }
          }
          bp=bargph(19,(LONG)i+1,(LONG)nmdfs);
          locate(27,12);
          setatr(0x3E);
          printf("%3d%% ",bgperc);
          setatr(0x1F);
          printf("%s",bp);
     }
     rstcur();
}

INT
fndmod(                       /* find a module's index (in moddat) by name */
CHAR *modnam)                      /* name of module to get index for      */
{
     INT i;

     for (i=0 ; i < nmdfs ; i++) {
          if (sameas(modnam,moddat[i].modnam)) {
               return(i);
          }
     }
     catastro("CAN'T FIND \"%s\" MODULE!",modnam);
     return(-1);
}

#ifndef UNIX
static VOID
copyvirs(VOID)                /* copy .VIR files to .DATs where needed     */
{
     struct ffblk fb,fbd;
     CHAR datnam[GCMAXFNM];
     CHAR *pStr;

     if (fnd1st(&fb,GCVIRGIN"*.vir",0)) {
          do {
               setmem(datnam,sizeof(datnam),0);
               movmem(fb.ff_name,datnam,findstg(".",fb.ff_name));
               strcat(datnam,"dat");
               if (!fnd1st(&fbd,datnam,0)) {
                    if ((pStr=strchr(datnam,'.')) != 0) {
                         *pStr='\0';
                    }
                    dfaVirgin(datnam,datnam);
               }
          } while (fndnxt(&fb));
     }
}
#endif

/* icon checking begins here                                               */

static CHAR *
choplast(                          /* cut off last word in line,           */
CHAR *line)                        /*   return the new last word           */
{
     CHAR *s;

     if ((s=lastwd(line)) != line) {
          s--;
          *s='\0';
          s=lastwd(line);
     }
     return(s);
}

VOID
iconchek(VOID)                     /* check icon structure                 */
{
     FILE *fp;
     struct ffblk fb;
     CHAR fn[FNSIZE],*s;
     static CHAR line[100];
     INT tim,dat;
     LONG siz;
     struct iconew **inlcur,*inlprv;
     GBOOL listonly=TRUE;

     inlcur=&infirst;
     if (fnd1st(&fb,ICOPATH,0)) {
          do {
               stzcpy(fn,fb.ff_name,FNSIZE);
               if ((s=strchr(fn,'.')) != NULL) {
                    *s='\0';
               }
               *inlcur=(struct iconew *)alczer(sizeof(struct iconew));
               inlprv=*inlcur;
               inlprv->next=NULL;
               inlcur=&inlprv->next;
               stzcpy(inlprv->name,fn,FNSIZE);
               inlprv->size=fb.ff_fsize;
               inlprv->date=fb.ff_fdate;
               inlprv->time=fb.ff_ftime;
          } while (fndnxt(&fb));
     }
     if ((fp=fopen("wgsicons.lst",FOPRA)) != NULL) {
          while (fgets(line,sizeof(line),fp) != NULL) {
               if ((s=strchr(line,'\n')) != NULL) {
                    *s='\0';
               }
               s=lastwd(line);
               tim=atoi(s);
               s=choplast(line);
               dat=atoi(s);
               s=choplast(line);
               siz=atol(s);
               s=choplast(line);
               stzcpy(fn,s,FNSIZE);
               for (inlprv=infirst ; inlprv != NULL ; inlprv=inlprv->next) {
                    if (sameas(fn,inlprv->name)) {
                         inlprv->flags|=ICOINLST;
                         if (dat != inlprv->date
                          || tim != inlprv->time
                          || siz != inlprv->size) {
                              inlprv->flags|=ICOCHNGD;
                              listonly=FALSE;
                              redo=TRUE;
                         }
                         break;
                    }
               }
               if (inlprv == NULL) {
                    redo=TRUE;
               }
          }
          fclose(fp);
     }
     for (inlprv=infirst ; inlprv != NULL ; inlprv=inlprv->next) {
          if (!(inlprv->flags&ICOINLST)) {
               inlprv->flags|=ICOINLST;
               inlprv->flags|=ICOCHNGD;
               listonly=FALSE;
               redo=TRUE;
          }
     }
     if (redo) {
          if ((fp=fopen("wgsicons.lst",FOPWA)) != NULL) {
               for (inlprv=infirst ; inlprv != NULL ; inlprv=inlprv->next) {
                    fprintf(fp,"%s %ld %d %d\n",inlprv->name,
                                                inlprv->size,
                                                inlprv->date,
                                                inlprv->time);
               }
               fclose(fp);
          }
          if (listonly) {
               redo=FALSE;
          }
     }
}

VOID
iconrev(VOID)                      /* review WGSMENU2.DAT for icons        */
{
     DFAFILE *bb;
     struct ffblk fb;
     struct iconew *icoptr;
     CHAR key[PNMSIZ+1],*sptr;
     INT loop;
     GBOOL pagchg;
     static struct mnupag *mp;

     mem2scn(scnsav,0,GVIDSCNSIZ);
     explodeto(scntbl[0],0,5,32,7,21,9);
     cursiz(GVIDNOCURS);
     dfaMode(PRIMBV);
     mp=(struct mnupag *)alczer(sizeof(struct mnupag));
     bb=dfaOpen("wgsmenu2.dat",sizeof(struct mnupag),NULL);
     strcpy(key,"C");
     while (dfaAcqGT(mp,key,0) && mp->menutype[0] == key[0]) {
          stzcpy(&key[1],mp->pagnam,PNMSIZ);
          pagchg=FALSE;
          for (icoptr=infirst ; icoptr != NULL && !pagchg ; icoptr=icoptr->next) {
               if (!(mp->flags&(MDLPAG|FILPAG)) && (mp->flags&DFTDSP)
                && (icoptr->flags&ICOCHNGD)) {
                    for (loop=0 ; loop < mp->npages ; loop++) {
                         sptr=mp->page[loop].iconame;
                         if (sameas(sptr,icoptr->name)
                          || (sameas(DEFICO,icoptr->name)
                          && sptr[0] == '\0')) {
                              unpack(mp);
                              mp->ichange=time(NULL);
                              savepage(mp,FALSE);
                              pagchg=TRUE;
                              break;
                         }
                    }
               }
          }
     }
     dfaClose(bb);
     free(mp);
     fndfile(&fb,"wgsmenu2.dat",0);
     markfile("wgsmenus.idx",&fb,FALSE);
     markfile("wgsmenuc.idx",&fb,FALSE);
     markfile("wgsint.ref",&fb,TRUE);
     rstcur();
}
