/***************************************************************************
 *                                                                         *
 *   WGSRVCLN.C                                                            *
 *                                                                         *
 *   Copyright (c) 1995-1997 Galacticomm, Inc.  All rights reserved.       *
 *                                                                         *
 *   This utility will run during WGSSTART.BAT, and delete all files in    *
 *   app directories (as well as GCSVCMAN) that are not listed in the      *
 *   .MDF/.DMD file.                                                       *
 *                                                                         *
 *                                                - C. Dunn 3/21/95        *
 *                                                                         *
 ***************************************************************************/

#include "gcomm.h"
#include "majorbbs.h"
#include "excphand.h"

#define FILREV "$Revision: 4 $"

#define MAXFIL 200                 /* max no. of files to store (per MDF)  */
#define MNOSET 12                  /* module name offset in MDF file       */
#define CLIEXE "Client app EXE:"   /* MDF file prefix for app file name    */
#define CLISUP "Client app support files:" /* MDF prefix for support files */
#define SHRSUP "Shared support files:" /* MDF prefix for shared spt files  */
#define MODNAM "Module Name:"      /* MDF file prefix for module's name    */
#define MDFSPC "*.mdf"             /* MDF file spec to process             */
#define DMDSPC "*.dmd"             /* DMD file spec to process             */
#define ALLFIL STAR                /* all files spec                       */
#define DELIMS ", \t;"             /* valid delimiters for support lists   */
#define GCSDIR "gcsvcman"          /* name of GCSVCMAN subdirectory        */
#define GCSLST "gcsvcman.lst"      /* name of list file used by WGM        */
#define GCSFLS "Worldgroup Manager Files" /* desc. for files in GCSLST     */

INT numfls;                        /* number of files in current MDF/LST   */

CHAR savdir[GCMAXPTH];             /* saved directory name to return to    */
CHAR lstbuf[BUFSIZ];               /* list file input buffer               */
CHAR savscn[GVIDSCNSIZ];           /* screen image save area               */

CHAR **newfls;                     /* dynamic array of 'new' files         */

extern CHAR scntbl[][GVIDSCNSIZ]; /* array of screen images via makescns  */

FILE *lstfp;                       /* file pointer to GCSLST               */

struct ffblk fb;                  /* for fnd1st()/fndnxt()                */

VOID clrlst(VOID);
GBOOL inlist(CHAR *filnam);
VOID prcgcs(VOID);
VOID prcmdf(CHAR *spec);
CHAR *gmdname(CHAR *mdfnam);

INT
main(                              /* main program loop                    */
INT argc,
CHAR *argv[])
{
TRY
     INT i;

#ifdef GCWINNT
     if (!canRunUtil()) {
          MessageBox(NULL,NOPROCEED,
                    argv[0],MB_ICONSTOP|MB_OK|MB_TASKMODAL|MB_SETFOREGROUND);
          return(1);
     }
#else
     (VOID)argv;
#endif // GCWINNT
     (VOID)argc;
     initvid();
     scn2mem(savscn,0,GVIDSCNSIZ);
     newfls=(CHAR **)alcmem(MAXFIL*sizeof(CHAR *));
     for (i=0 ; i < MAXFIL ; i++) {
          newfls[i]=alczer(FNEXSZ);
     }
     cursiz(GVIDNOCURS);
     getcwd(savdir,GCMAXPTH);
     explodeto(cvtscn(scntbl[0]),0,0,65,4,7,6);
     prcgcs();
     prcmdf(MDFSPC);
     prcmdf(DMDSPC);
     mem2scn(savscn,0,GVIDSCNSIZ);
     locate(0,24),
     setatr(0x07);
     printf("\n");
     cursiz(GVIDLILCURS);
     clsvid();
     return(0);
EXCEPT
#ifdef GCWINNT
     return(1);
#endif // GCWINNT
}

VOID
clrlst(VOID)                       /* clears new file list                 */
{
     INT i;

     numfls=0;
     for (i=0 ; i < MAXFIL ; i++) {
          setmem(newfls[i],FNEXSZ,0);
     }
}

GBOOL                              /*   return TRUE if file is in list     */
inlist(                            /* is file name in new files list?      */
CHAR *filnam)                      /*   file name to look for              */
{
     INT i;

     for (i=0 ; i < numfls ; i++) {
          if (sameas(newfls[i],filnam)) {
               return(TRUE);
          }
     }
     return(FALSE);
}

VOID
prcgcs(VOID)                       /* process files in gcsvcman.lst        */
{
     CHAR fptmp[GCMAXFNM];

     setatr(0x1E);
     prat(26,2,"%-26.26s",GCSFLS);
     if (chdir(GCSDIR) == -1) {
          catastro("PRCGCS: Error changing to %s!",fnmcse("gcsvcman"));
     }
     if ((lstfp=fopen(GCSLST,FOPRA)) == NULL) {
          catastro("PRCGCS: Error opening %s for input!",
                   fnmcse("gcsvcman.lst"));
     }
     clrlst();
     while (fgets(lstbuf,BUFSIZ,lstfp) != NULL && numfls < MAXFIL) {
          stlcpy(newfls[numfls++],
                 unpad(fileparts(GCPART_FNAM,lstbuf,fptmp,GCMAXFNM)),FNEXSZ);
     }
     if (fnd1st(&fb,ALLFIL,0)) {
          do {
               if (!sameas(fb.ff_name,GCSLST) && !inlist(fb.ff_name)) {
                    unlink(fb.ff_name);
               }
          } while (fndnxt(&fb));
     }
     if (chdir(savdir) == -1) {
          catastro("PRCGCS: Error restoring current directory!");
     }
     fclose(lstfp);
}

VOID
prcmdf(                            /* process files in all .MDF/.DMD files */
CHAR *spec)                        /*   file spec to search (*.MDF, *.DMD) */
{
     CHAR *filnam,*mdfnam,fptmp[GCMAXFNM];
     GBOOL revcln;
     struct ffblk appfb;

     setatr(0x1E);
     if (fnd1st(&fb,spec,0)) {
          do {
               mdfnam=gmdname(fb.ff_name);
               prat(26,2,"%-26.26s",mdfnam == "" ? fb.ff_name : mdfnam);
               clrlst();
               revcln=FALSE;
               if (tfsopn(fb.ff_name)) {
                    while (tfsrdl() != TFSDUN) {
                         if (tfstate == TFSLIN) {
                              if (tfspfx(CLIEXE)) {
                                   stlcpy(newfls[numfls++],tfspst,FNEXSZ);
                                   revcln=TRUE;
                              }
                              else if (tfspfx(CLISUP) || tfspfx(SHRSUP)) {
                                   if ((filnam=strtok(tfspst,DELIMS)) != NULL) {
                                        do {
                                             stlcpy(newfls[numfls++],filnam,
                                                    FNEXSZ);
                                        } while ((filnam=strtok(NULL,DELIMS))
                                              != NULL && numfls < MAXFIL);
                                   }
                              }
                         }
                    }
                    if (revcln) {
                         fileparts(GCPART_FILE,fb.ff_name,fptmp,GCMAXFNM);
                         if (chdir(fptmp) == 0) {
                              if (fnd1st(&appfb,ALLFIL,0)) {
                                   do {
                                        if (!inlist(appfb.ff_name)) {
                                             unlink(appfb.ff_name);
                                        }
                                   } while (fndnxt(&appfb));
                              }
                              if (chdir(savdir) == -1) {
                                   catastro("PRCMDF: Error restoring current "
                                            "directory!");
                              }
                         }
                    }
               }
          } while (fndnxt(&fb));
     }
}

CHAR *
gmdname(                           /* get module name from .MDF/.DMD file  */
CHAR *mdfnam)                      /*   name of module's .MDF file         */
{
     FILE *fp;
     static CHAR tmpbuf[40];

     if ((fp=fopen(mdfnam,FOPRA)) != NULL) {
          while (fgets(tmpbuf,sizeof(tmpbuf),fp) != NULL) {
               if (sameto(MODNAM,tmpbuf)) {
                    unpad(tmpbuf);
                    fclose(fp);
                    return(skpwht(tmpbuf+MNOSET));
               }
          }
          fclose(fp);
     }
     return("");
}
