/***************************************************************************
 *                                                                         *
 *  WGSETUP.C                                                              *
 *                                                                         *
 *  Copyright (c) 1993-1997 Galacticomm, Inc.        All Rights Reserved.  *
 *                                                                         *
 *  Modem auto-sense and setup utility.                                    *
 *                                                                         *
 *                                                - B. Stephens   7/30/93  *
 *                                                                         *
 *  Porting note: Although this was ported to use the new types and video  *
 *  API, it still uses the *old* GSBL functions.  This is because this     *
 *  uses an old 64-user GSBL contained in the file BBRKTHU.LIB             *
 *  (see WGSETUP.MAK) which was built with the old GSBL stuff.             *
 *                                                                         *
 *                                                - Bill Hyatt    6/25/96  *
 *                                                                         *
 ***************************************************************************/

#include "gcomm.h"
#include "brkthu.h"

#define FILREV "$Revision: 6 $"

#define TIMOUT      4              /* max secs to wait for modem response  */
#define MXBAUD      2400           /* maximum baud rate                    */
#define MAXBUF      256            /* maximum input/output buffer size     */
#define RECLEN      80             /* Max record length in WGSSETUP.LST    */
#define MODLEN      41             /* Modem description length +1 for NUL  */
#define INILEN      45             /* Ini string length +1 for NUL         */
#define BAULEN      6              /* Baud rate length +1 for NUL          */
#define LOKLEN      4              /* Lock port length +1 for NUL          */

#define WHTGRN      0x2F           /* Bright white on green                */
#define YELGRN      0x2E           /* Bright yellow on green               */
#define BWHTGRN     0xAF           /* Blinking bright white on green       */
#define BLKGRY      0x70           /* Black on grey                        */
#define WHTGRY      0x7F           /* White on grey                        */

#define DONE        1              /* Done configuring current COM port    */
#define ASKYN       2              /* Use modem on current COM port?       */
#define PICKIT      3              /* Pick modem from modem list           */

extern
volatile unsigned long btuhrt;     /* increments 65536 times a second      */
                                   /* NOTE: old-style - see comment above  */
VOID genini(VOID);
VOID getmod(INT idx);
VOID getini(INT idx);
VOID getbau(INT idx);
VOID getlok(INT idx);
VOID getblk(VOID);
INT chkcom(INT i);
INT rstchn(VOID);
VOID modset(INT curcom);

CHAR *scn1,*scn2,*scn3,*scn4;      /* pointers to saved screens            */
extern CHAR scntbl[1][GVIDSCNSIZ]; /* table of screens                     */
FILE *fp;                          /* file pointer for WGSSETUP.LST        */
INT maxnum;                        /* total # of entries in WGSSETUP.LST   */
CHAR *mlist,*ilist,*blist,         /* pointers to modem info               */
     *llist,**mptrs;

INT search[]={1,1,1,1};            /* "to search" or "not 2 search" list   */

UINT comprt[]={0x3F8,0x2F8,        /* list of COM addresses                */
               0x3E8,0x2E8};
CHAR comlst[4][4]={"3F8\0",        /* list of "displayed" COM addresses    */
                   "2F8\0",
                   "3E8\0",
                   "2E8\0"};
INT aborted=0;                     /* user "aborted" flag                  */
INT curnum=0;                      /* currently selected modem list entry  */
INT chngrp=1;                      /* current channel group being used     */

GBOOL intrun;                      /* is this being run from Internet cfg? */

VOID
main(                              /* WGSETUP mainline code                */
INT argc,                          /*   number of command line arguments   */
CHAR *argv[])                      /*   array of command line arguments    */
{
     INT i,state,c;
     CHAR reply[10];
     INT modfnd=0;
     INT modcho=0;
     CHAR mod1[15],mod2[15],tmpmod[60];

     genini();
     if (argc == 2 && sameas(argv[1],"/ICO")) {
          chngrp=16;
          intrun=TRUE;
     }
     else {
          intrun=FALSE;
     }
     for (i=1 ; i <= 4 && chngrp <= 16 ; i++) {
          state=0;
          if (search[i-1] == 0) {
               setatr(YELGRN);
               prat(2,i*2,"COM%1d: Skipped.                    ",i);
          }
          while (state != DONE && search[i-1] == 1) {
               if (aborted) {
                    break;
               }
               switch (state) {
               case 0:
                    setatr(WHTGRN);
                    prat(2,i*2,"COM%1d: Searching for modem...    ",i);
                    setatr(BWHTGRN);
                    prat(2,11,"Searching, please wait...");
                    if (chkcom(i) == TRUE) {
                         setatr(WHTGRN);
                         prat(2,i*2,"COM%1d: Modem found!                ",i);
                         modfnd++;
                         state=ASKYN;
                    }
                    else {
                         setatr(YELGRN);
                         prat(2,i*2,"COM%1d: No modem found.             ",i);
                         state=DONE;
                    }
                    break;
               case ASKYN:
                    setatr(WHTGRN);
                    prat(2,11,"There was a modem found at COM%1d.",i);
                    setatr(WHTGRN);
                    prat(2,12,"Do you wish to use this modem (Y/N)?");
                    strcpy(reply,"Yes");
                    if (edtval(57,19,4,reply,validyn,0) == 0) {
                         aborted=1;
                         break;
                    }
                    if (reply[0] == 'Y' || reply[0] == 'y') {
                         modcho++;
                         state=PICKIT;
                    }
                    else {
                         prat(2,12,"                                        ");
                         prat(2,11,"                                  ",i);
                         setatr(YELGRN);
                         prat(2,i*2,"COM%1d: Modem not configured.       ",i);
                         state=DONE;
                    }
                    break;
               case PICKIT:
                    scn2mem(scn3,0,GVIDSCNSIZ);
                    explodeto(scntbl[0],0,11,43,24,22,9);
                    setatr(BLKGRY);
                    prat(6,0,"%1d",i);
                    supchc(maxnum,mptrs,2,1,41,9,1);
                    dspchc();
                    cursiz(GVIDNOCURS);
                    do {
                         c=getchc();
                         if (c == F1) {
                              scn2mem(scn4,0,GVIDSCNSIZ);
                              explodeto(scntbl[1],0,14,66,24,7,9);
                              getchc();
                              mem2scn(scn4,0,GVIDSCNSIZ);
                         }
                         curnum=hdlchc(c);
                    } while (curnum == maxnum);
                    rstcur();
                    if (curnum != -ESC) {
                         modset(i);
                         state=DONE;
                    }
                    else {
                         aborted=1;
                    }
                    mem2scn(scn3,0,GVIDSCNSIZ);
                    proff(18,7);
                    setatr(YELGRN);
                    prat(2,12,"                                        ");
                    prat(2,11,"                                  ",i);
                    if (!aborted) {
                         setatr(WHTGRN);
                         strcpy(tmpmod,&mlist[curnum*MODLEN]);
                         tmpmod[34]='\0';
                         prat(2,i*2,"COM%1d: %s",i,tmpmod);
                    }
               }
          }
     }
     btuend();
     if (!aborted) {
          proff(18,7);
          setatr(WHTGRN);
          strcpy(mod1,"modems were");
          strcpy(mod2,"were");
          if (modfnd == 1) {
               strcpy(mod1,"modem was");
          }
          if (modcho == 1) {
               strcpy(mod2,"was");
          }
          prat(2,11,"%1d %s found; %1d %s configured.",modfnd,mod1,modcho,mod2);
          strcpy(mod1,"save");
          if (modcho == 0) {
               strcpy(mod1,"exit");
          }
          prat(2,12,"         Hit any key to %s...          ",mod1);
          if (getchc() == ESC) {
               aborted=1;
          }
     }
     if (chngrp > 1 && !aborted) {
          proff(18,7);
          setatr(WHTGRN);
          prat(2,11,"  Saving configuration data to disk.    ");
          setatr(BWHTGRN);
          prat(2,12,"             Please wait...             ");
          applyem("WGSMAJOR.MSG");
     }
     setatr(0x07);
     printf(" ");
     locate(0,24);
     mem2scn(scn1,0,GVIDSCNSIZ);
     cursiz(GVIDLILCURS);
     clsvid();
     exit(0);
}

VOID                               /* General WGSETUP initialization       */
genini(VOID)
{
     INT i,c;
     CHAR tmp[RECLEN];
     INT done=0;

     initvid();
     if (undwin()) {
          btuitm(alcmem(btusiz(1,MAXBUF,MAXBUF)));
          if (btuirp(-1) != 0) {
               btuend();
               catastro("WINDOWS: GALVIT.386 MUST BE IN SYSTEM.INI!");
          }
          btuhit(3);
          btuhit(4);
     }
     else {
          btuitz(alcmem(btusiz(1,MAXBUF,MAXBUF)));
     }
     btumxs(MXBAUD);

     cursiz(GVIDNOCURS);
     monorcol();
     scn1=alcmem(GVIDSCNSIZ);
     scn2=alcmem(GVIDSCNSIZ);
     scn3=alcmem(GVIDSCNSIZ);
     scn4=alcmem(GVIDSCNSIZ);
     scn2mem(scn1,0,GVIDSCNSIZ);
     explodeto(scntbl[0],44,11,79,24,22,7);
     if ((c=getchc()) == ESC || c == ALT_X || c == F10) {
          aborted=1;
          return;
     }
     mem2scn(scn1,0,GVIDSCNSIZ);
     scn2mem(scn1,0,GVIDSCNSIZ);
     explodeto(scntbl[0],0,0,35,10,22,7);
     while (!done) {
          switch(c=getchc()) {
          case '1':
          case '2':
          case '3':
          case '4':
               if (search[0+c-'1'] == 0) {
                    search[0+c-'1']=1;
                    setatr(0x1B);
                    prat(27,5+c-'1',"YES");
               }
               else {
                    search[0+c-'1']=0;
                    setatr(0x13);
                    prat(27,5+c-'1',"NO ");
               }
               break;
          case ESC:
               aborted=1;
               return;
          case '\r':
               done=1;
               break;
          case F1:
               scn2mem(scn2,0,GVIDSCNSIZ);
               explodeto(scntbl[0],36,0,79,10,18,7);
               getchc();
               mem2scn(scn2,0,GVIDSCNSIZ);
               proff(22,7);
               break;
          default:
               break;
          }
     }
     if ((fp=fopen("wgssetup.lst",FOPRA)) == NULL) {
          btuend();
          catastro("WGSETUP: COULDN'T OPEN WGSSETUP.LST!");
     }
     maxnum=0;
     while (fgets(tmp,RECLEN,fp) != NULL) {
          maxnum++;
     }
     maxnum=maxnum/8;
     mlist=alczer(maxnum*MODLEN);
     ilist=alczer(maxnum*INILEN);
     blist=alczer(maxnum*BAULEN);
     llist=alczer(maxnum*LOKLEN);
     mptrs=(CHAR **)alczer((maxnum+1)*sizeof(CHAR *));
     for (i=0 ; i < maxnum ; i++) {
          mptrs[i]=&mlist[i*MODLEN];
     }
     mptrs[maxnum]=NULL;
     rewind(fp);
     for (i=0 ; i < maxnum ; i++) {
          getmod(i);
          getbau(i);
          getlok(i);
          getini(i);
          getblk();
          getblk();
          getblk();
          getblk();
     }
     fclose(fp);
     scn2mem(scn2,0,GVIDSCNSIZ);
     explodeto(scntbl[1],0,0,43,13,18,7);
}

VOID                               /* get modem name from WGSSETUP.LST      */
getmod(INT idx)
{
     INT i,len;
     CHAR tmp[RECLEN];

     fgets(tmp,RECLEN,fp);
     len=strlen(tmp)-1;                           /* remove <CR>           */
     for (i=0 ; i < len ; i++) {                  /* change '_' to spaces  */
          tmp[i]=(tmp[i] == '_') ? ' ' : tmp[i];
     }
     for (i=len ; i < MODLEN ; i++) {             /* pad with spaces       */
          tmp[i]=' ';
     }
     tmp[MODLEN-1]='\0';
     strcpy(&mlist[idx*MODLEN],tmp);
}

VOID                               /* get init string from WGSSETUP.LST     */
getini(INT idx)
{
     INT i,len;
     CHAR tmp[RECLEN];

     fgets(tmp,RECLEN,fp);
     len=strlen(tmp)-1;
     for (i=len ; i < INILEN ; i++) {             /* pad with spaces       */
          tmp[i]=' ';
     }
     tmp[INILEN-1]='\0';
     strcpy(&ilist[idx*INILEN],tmp);
}

VOID                               /* get baud rate from WGSSETUP.LST       */
getbau(INT idx)
{
     INT i,len;
     CHAR tmp[RECLEN];

     fgets(tmp,RECLEN,fp);
     len=strlen(tmp)-1;
     for (i=len ; i < BAULEN ; i++) {             /* pad with spaces       */
          tmp[i]=' ';
     }
     tmp[BAULEN-1]='\0';
     strcpy(&blist[idx*BAULEN],tmp);
}

VOID                               /* get lock info from WGSSETUP.LST       */
getlok(INT idx)
{
     INT i,len;
     CHAR tmp[RECLEN];

     fgets(tmp,RECLEN,fp);
     len=strlen(tmp)-1;
     for (i=len ; i < LOKLEN ; i++) {             /* pad with spaces       */
          tmp[i]=' ';
     }
     tmp[LOKLEN-1]='\0';
     strcpy(&llist[idx*LOKLEN],tmp);
}

VOID                               /* get blank line from WGSSETUP.LST      */
getblk(VOID)
{
     CHAR tmp[RECLEN];

     fgets(tmp,RECLEN,fp);
}

INT                                /* check ports for responses            */
chkcom(INT i)
{
     long oldtck;
     INT portok,status,c;
     CHAR buf[MAXBUF];
     INT count=0,okcnt=0;

     btudef(0,comprt[i-1],1);
     if ((portok=rstchn()) == 1) {
          btubrt(0,MXBAUD);
          btuxmt(0,"AT\r");
     }
     oldtck=btuhrt;
     while (count <= TIMOUT*16) {
          if (btuhrt-oldtck >= 4096L) {
               count++;
               oldtck=btuhrt;
          }
          setatr(WHTGRY);
          prat(2,i*2+1,"%s",bargph(25,(long)count,(long)TIMOUT*16));
          setatr(YELGRN);
          prat(28,i*2+1,"%d\%",count+count/2+count/16);
          if (kbhit()) {
               if ((c=getchc()) == ESC || c == ALT_X || c == F10) {
                    aborted=1;
                    return(FALSE);
               }
          }
          if (portok && btuscn() >= 0) {
               status=btusts(0);
               switch (status) {
               case 3:
                    btuinp(0,buf);
                    if (strcmp(buf,"OK") == 0) {
                         okcnt++;
                         rstchn();
                    }
                    btucmd(0,"p");
                    break;
               case 5:
                    btulok(0,0);
                    btuoes(0,0);
               }
          }
     }
     setatr(YELGRN);
     prat(2,i*2+1,"                              ");
     btuudf(0,1);
     if (okcnt) {
          return(TRUE);
     }
     return(FALSE);
}

INT                                /* reset channel                        */
rstchn(VOID)
{
     if (bturst(0) != 1) {
          return(0);
     }
     btulok(0,1);
     btuoes(0,1);
     btuech(0,0);
     btucli(0);
     return(1);
}

VOID                               /* write info to WGSMAJOR.MSG           */
modset(INT curcom)
{
     CHAR tmp[10],tmp2[10];

     strcpy(tmp,"GROUP");
     itoa(chngrp,tmp2,10);
     strcat(tmp,tmp2);
     setcnf(tmp,"MODEM");

     strcpy(tmp,"START");
     itoa(chngrp,tmp2,10);
     strcat(tmp,tmp2);
     setcnf(tmp,intrun ? "FF" : tmp2);

     strcpy(tmp,"NUMBR");
     itoa(chngrp,tmp2,10);
     strcat(tmp,tmp2);
     setcnf(tmp,"1");

     strcpy(tmp,"ADDR");
     itoa(chngrp,tmp2,10);
     strcat(tmp,tmp2);
     setcnf(tmp,comlst[curcom-1]);

     strcpy(tmp,"BAUD");
     itoa(chngrp,tmp2,10);
     strcat(tmp,tmp2);
     setcnf(tmp,unpad(&blist[curnum*BAULEN]));

     strcpy(tmp,"LOCK");
     itoa(chngrp,tmp2,10);
     strcat(tmp,tmp2);
     setcnf(tmp,unpad(&llist[curnum*LOKLEN]));

     strcpy(tmp,"DUPLX");
     itoa(chngrp,tmp2,10);
     strcat(tmp,tmp2);
     setcnf(tmp,"YES");

     strcpy(tmp,"HTYPE");
     itoa(chngrp,tmp2,10);
     strcat(tmp,tmp2);
     setcnf(tmp,"SINGLE");

     strcpy(tmp,"INIT");
     itoa(chngrp,tmp2,10);
     strcat(tmp,tmp2);
     setcnf(tmp,unpad(&ilist[curnum*INILEN]));
     chngrp++;
}

