/***************************************************************************
 *                                                                         *
 *   SETCNF.C                                                              *
 *                                                                         *
 *   Copyright (c) 1987-1997 Galacticomm, Inc.    All Rights Reserved.     *
 *                                                                         *
 *   This is the GCOMM.LIB routine pair for setting up new values for      *
 *   specified options in an MSG file.  Usage is:                          *
 *                                                                         *
 *      setcnf(optnam,optval)      set CNF option named optnam to value    *
 *      CHAR *optnam,*optval;         option name and value are strings    *
 *                                                                         *
 *      applyem(filnam)            apply up to 100 setcnf's to MSG file    *
 *      CHAR *filnam;                 file name (and path if any)          *
 *                                                                         *
 *   You can call setcnf() up to 100 times between calls to applyem().     *
 *   You can call applyem() as many times as you like, with different      *
 *   file names, for a given group of setcnf() calls.  If a file name      *
 *   does not exist, applyem() will do nothing and simply return.  If      *
 *   option names specified in setcnf() do not exist in the file(s) to     *
 *   which the changes are applied, it will not bother anything.           *
 *                                                                         *
 *   Note that you do not have to worry about whether an option is a       *
 *   'S' or 'T' type, in which the option value is the whole of the        *
 *   text inside the curly braces, or a 'C', 'B', 'E', 'N', 'L', or        *
 *   'H' type, in which the option value is just the last word of the      *
 *   text inside the curly braces.  This utility automatically detects     *
 *   the option type, and takes the appropriate action (although it        *
 *   does not do any error checking for valid option values -- the         *
 *   programmer must be sure not to set options to invalid values).        *
 *                                                                         *
 *   MJRBBS.CFG file must be present (to dermine language info).           *
 *   For 'T' options, only the language 0 value will be changed.           *
 *                                                                         *
 *                                            - T. Stryker 2/17/92         *
 *                                            - R. Stein 1/28/93           *
 *                                                                         *
 ***************************************************************************/

#include "gcomm.h"

#define FILREV "$Revision: 6 $"

#define MAXCHG 100                 /* max number of changes per go-round   */

static INT nchgs=0;                /* number of changes at the moment      */
static CHAR *onams[MAXCHG];        /* option names to be changed           */
static CHAR *ovals[MAXCHG];        /* option values to change to           */
static FILE *wtfp;                 /* output file pointer                  */

static INT applied;                /* flag on if applyem() called since    */
                                   /*    the last time setcnf() was called */

static INT ck4mat(VOID);

VOID
setcnf(                            /* set a CNF option equal to a value    */
CHAR *optnam,                      /*   option name                        */
CHAR *optval)                      /*   option value to set it to          */
{
     INT i;

     if (applied) {
          applied=0;
          for (i=0 ; i < nchgs ; i++) {
               free(onams[i]);
               free(ovals[i]);
          }
          nchgs=0;
     }
     onams[nchgs]=alcdup(optnam);
     ovals[nchgs]=alcdup(optval);
     if (++nchgs > MAXCHG) {
          catastro("SETCNF: TOO MANY CHANGES");
     }
}

VOID
applyem(                           /* apply prior setcnf()'s to a MSG file */
CHAR *filnam)                      /*   filename (including .MSG) to write */
{
     CHAR tmpspec[GCMAXPTH],jnkspec[GCMAXPTH];
     SHORT i,idex,lingo;
     LONG fpos;
     CHAR otyp;

     inilingo();
     inimsgrdr(OPTSIZE);
     if ((rdfp=fopen(filnam,FOPRB)) != NULL) {
          for (i=0 ; i < 100 ; i++) {
            sprintf(tmpspec,"{TMP%04d",i);
               if (!isfile(tmpspec)) {
                    break;
               }
       }
       if (i == 100) {
               catastro("APPLYEM: CAN'T OPEN TEMP FILE");
          }
          if ((wtfp=fopen(tmpspec,FOPWB)) == NULL) {
               catastro("APPLYEM: CAN'T WRITE \"%s\"",tmpspec);
          }
          while (rdmsg()) {
               scanalt();
               litopts();
               fpos=ftell(rdfp);
               fprintf(wtfp,"%s"STR_EOL"%s {",hlpbuf,msgnam);
               if ((idex=ck4mat()) != -1) {
                    if ((otyp=lotype()) == 'T' || otyp == 'S') {
                         strcpy(txtbuf,ovals[idex]);
                    }
                    else {
                         strcpy(lastwd(txtbuf),ovals[idex]);
                    }
               }
               putval(wtfp);
               putc('}',wtfp);
               for (lingo=1 ; lingo < salingo ; lingo++) {
                    putc(',',wtfp);
                    if (altlnm[lingo].value.fsk != 0L) {
                         loadtv(rdfp,&altlnm[lingo]);
                         putc('{',wtfp);
                         putval(wtfp);
                         putc('}',wtfp);
                    }
               }
               fseek(rdfp,fpos,0);
               fprintf(wtfp,"%s"STR_EOL STR_EOL,lobuf);
          }
          fclose(wtfp);
          fclose(rdfp);
       sprintf(jnkspec,"{JNK");
          unlink(jnkspec);
          rename(filnam,jnkspec);
          rename(tmpspec,filnam);
          unlink(jnkspec);
     }
     applied=1;
}

static INT
ck4mat(VOID)                       /* check for match on curr option name  */
{
     INT i;

     for (i=0 ; i < nchgs ; i++) {
          if (sameas(onams[i],msgnam)) {
               return(i);
          }
     }
     return(-1);
}
