#define MAIN
#include "hydracom.h"


void main (int argc, char *argv[])
{
        FILE    *ctl;
        char     ctlname[PATHLEN];
        int      err = 0;              /* assume all went well: errorlevel 0 */
        int      ac;
        char    *p;
        register int i, res;

        av = (char **) malloc(MAXARGS * ((int) sizeof (char *)));
        port = 0;                                   /* default configuration */
        strcpy(device,"serial.device");	/* OLSEN */
        cur_speed = com_speed = 0U;
        parity = false;
        noinit = nocarrier = dropdtr = false;
        nobell = false;
        mailer = false;
        hdxsession = nooriginator = false;
        hydra_txwindow = hydra_rxwindow = 0L;
        flowflags = 0;
        dcdmask = 0x80;
        noresume = nostamp = false;
        hydra_options = 0x0L;
        result = opuslog = NULL;
        download = "";
        single_file[0] = '\0';
        single_done = false;
        logfp = NULL;
        loglevel = 2;
        opustask = -1;
        didsome = false;
#if !WIN_AGL
        file_x = 0;
#endif

#ifndef AMIGA
        signal(SIGINT,SIG_IGN);                            /* disable Ctrl-C */
#endif	/* AMIGA */

        if (!getenv("TZ"))
           putenv("TZ=GMT0");
        tzset();
        dos_sharecheck();

#if !WIN_AGL && !defined(AMIGA)
/* HJW The Topspeed gettext and puttext window procedures do have a
   bug in non video mode, at least in version 3.02. The only thing we
   can do is to enable direct viodeo. Also: The clipping window
   module reports always 25 x 80 as the screen dimensions. The bugs
   are reported to JPI
*/

#ifdef _JPI_
        directvideo = 1;
#else
        directvideo = 0;
#endif
#endif

        strcpy(ourname,argv[0]);
        strcat(ourname,".");
        if (getenv("DSZLOG"))
           result = strdup(getenv("DSZLOG"));

        strcpy(work,ourname); strcat(work,"CFG");    /* extra configuration? */
        if ((ctl=sfopen(work,"rt",DENY_WRITE)) != NULL) {
           while (fgets(buffer,200,ctl)) {
                 ac = parse(buffer);
                 if (ac && !config(ac,av))
                    message(1,"-Unknown configurationfile option '%s'",av[0]);
           }
           fclose(ctl);
        }

        strcpy(ctlname,ourname); strcat(ctlname,"CTL");    /* Opus ext <1.10 */
        if ((ctl=sfopen(ctlname,"rt",DENY_WRITE)) != NULL) {
           strcpy(buffer,ourname); strcat(buffer,"LOG");
           opuslog = strdup(buffer);
           goto opusctl;
        }

#ifndef AMIGA
        for (i = 1; i < argc; i++)
            strupr(argv[i]);
#endif	/* AMIGA */

        i = 1;
        while (i < argc) {
              res = config(argc - i,&argv[i]);
              if (res) {
                 i += res;

                 if (opustask >= 0) {/* Opus External Interface Version 1.10 */
                    strcpy(ctlname,ourname);
                    sprintf(&ctlname[((int) strlen(ctlname)) - 3],"%02x.CTL",opustask);
                    if ((ctl=sfopen(ctlname,"rt",DENY_WRITE)) == NULL) {
                       message(1,"-Can't open Opus ext file '%s'",ctlname);
                       break;
                    }

                    strcpy(buffer,ourname);
                    sprintf(&buffer[((int) strlen(buffer)) - 3],"%02x.LOG",opustask);
                    opuslog = strdup(buffer);

opusctl:            if (ffirst(opuslog))           /* delete any old logfile */
                       unlink(opuslog);
                    while (fgets(buffer,200,ctl)) {
                          ac = parse(buffer);
                          if (!ac) continue;
                          if (!stricmp(av[0],"SEND")) {	/* OLSEN */
                             if (!didsome) {
                                init();
                                hydra_init(hydra_options);
                             }
                             didsome = true;
                             err = batch_hydra(av[1],ac > 2 ? av[2] : NULL);
                          }
                          else
                             config(ac,av);

                          /* quit on errors during zsend or zrecv */
                          if (err) break;
                    }/*while(fgets(ctl))*/

                    fclose(ctl);
                    unlink(ctlname);

                    if (!err) {
                       if (!didsome) {
                          init();
                          hydra_init(hydra_options);
                       }
                       didsome = true;
                       hydra(NULL,NULL);
                    }
                    hydra_deinit();
                    break;
                 }/*if(opustask>=0)*/

              }/*if(res)*/

              else {
                 if (!strnicmp(argv[i],"TER",3)) {	/* OLSEN */
                    init();
                    didsome = true;
                    hydracom();
                    break;
                 }

                 if (!strnicmp(argv[i],"SEN",3)) {	/* OLSEN */
                    init();
                    didsome = true;
                    hydra_init(hydra_options);
                    while (!err && ++i < argc) {
                          if (*argv[i]=='@') {
                             argv[i]++;
                             if ((ctl=sfopen(argv[i],"rt",DENY_WRITE))==NULL) {
                                message(3,"!Couldn't open batch-ctlfile %s",argv[i]);
                                continue;
                             }
                             while (!err && fgets(buffer,200,ctl)) {
                                   if (parse(buffer))
                                      err = batch_hydra(av[0],ac > 1 ? av[1] : NULL);
                             }
                             fclose(ctl);
                          }
                          else
                             err = batch_hydra(argv[i],NULL);
                    }

                    if (!err)
                       hydra(NULL,NULL);               /* end of batch stuff */
                    hydra_deinit();
                    break;
                 }

                 if (!strnicmp(argv[i],"GET",3)) {	/* OLSEN */
                    init();
                    didsome = true;
                    hydra_init(hydra_options);
                    if (++i < argc) {
                       splitpath(argv[i],work,single_file);
                       if (work[0]) {
                          p = &work[((int) strlen(work)) - 1];

                          download = strdup(work);
                       }
                    }
                    hydra(NULL,NULL);
                    hydra_deinit();
                    break;
                 }

                 message(1,"-Unknown commandline parameter '%s'",argv[i]);
                 i++;
              }
        }

        if (didsome) {
           if (!carrier() && dropdtr)
              dtr_out(0);
           sys_reset();
           endprog(err);
        }
        else
           cprint("Run %s without any options for usage screen\n",PRGNAME);

        if (logfp) fclose(logfp);

        exit (err);
}


void endprog (int errcode)
{
#if WIN_AGL
        if (didsome) win_deinit();
#endif
        message(1,"+%s v%s %s : end (exitcode=%d)",
                  PRGNAME,VERSION,HC_OS,errcode);
        resultlog(false,NULL,0L,0L);
        if (logfp) fclose(logfp);
        exit (errcode);
}


int config (int argc, char *argv[])
{
        register int opt = 0;
        register word temp;

        if (!strnicmp(argv[0],"-P",2)) {  /* -p<port>  */	/* OLSEN */
           port = atoi(&argv[0][2]);
           opt++;
        }
        else if (!strnicmp(argv[0],"-B",2)) {  /* -b<speed> */
           com_speed = (word) atol(&argv[0][2]);
           opt++;
        }
        else if (!strnicmp(argv[0],"-T",2)) {  /* -t<task> */
           opustask = atoi(&argv[0][2]);
           opt++;
        }
        else if (!strnicmp(argv[0],"POR",3) && argc>=2) {  /* port */	/* OLSEN */
           port = atoi(argv[1]);

           opt += 2;
        }
        else if (!strnicmp(argv[0],"DEV",3) && argc>=2) {  /* device */	/* OLSEN */
           strcpy (device,argv[1]);
           opt += 2;
        }
        else if ((!strnicmp(argv[0],"SPE",3) || !strnicmp(argv[0],"BAU",3)) && argc>=2) {	/* OLSEN */
           com_speed = (word) atol(argv[1]);
           opt += 2;
        }
        else if (!strnicmp(argv[0],"LIN",3)) {  /* line */
           cur_speed = (word) atol(argv[1]);
           opt += 2;
        }
        else if (!strnicmp(argv[0],"MOD",3) && argc >= 6) {  /* modem */
           sscanf(argv[1],"%x",&port);
           port--;
           sscanf(argv[2],"%x",&com_speed);
           sscanf(argv[3],"%x",&flowflags);
           sscanf(argv[4],"%x",&dcdmask);
           sscanf(argv[5],"%x",&cur_speed);
           if (flowflags & 0x09)
              hydra_options |= HOPT_XONXOFF;
           opt += 6;
        }
        else if (!strnicmp(argv[0],"PAR",3)) {   /* parity */	/* OLSEN */
           parity = true;
           hydra_options |= HOPT_HIGHBIT;
           opt++;
        }
        else if (!strnicmp(argv[0],"HAN",3) && argc >= 2) {   /* handshake */	/* OLSEN */
           if      (!strnicmp(argv[1],"SOF",3)) flowflags |= 0x09;	/* OLSEN */
           else if (!strnicmp(argv[1],"HAR",3)) flowflags |= 0x02;	/* OLSEN */
           else if (!strnicmp(argv[1],"BOT",3)) flowflags |= 0x0b;	/* OLSEN */
           else if (!strnicmp(argv[1],"NON",3)) flowflags = 0;	/* OLSEN */
           if (flowflags & 0x09)
              hydra_options |= HOPT_XONXOFF;
           opt += 2;
        }
        else if (!strnicmp(argv[0],"NOI",3)) {   /* noinit */	/* OLSEN */
           noinit = true;
           opt++;
        }
        else if (!strnicmp(argv[0],"DRO",3)) {   /* dropdtr */	/* OLSEN */
           dropdtr = true;
           opt++;
        }
        else if (!strnicmp(argv[0],"NOB",3)) {   /* nobell */	/* OLSEN */
           nobell = true;
           opt++;
        }
        else if (!strnicmp(argv[0],"MAI",3)) {   /* mailer */	/* OLSEN */
           mailer = true;
           opt++;
        }
        else if (!strnicmp(argv[0],"NOO",3)) {   /* nooriginator */	/* OLSEN */
           nooriginator = true;
           opt++;
        }
        else if (!strnicmp(argv[0],"HDX",3)) {   /* hdxlink */	/* OLSEN */
           hdxsession = true;
           opt++;
        }
        else if (!strnicmp(argv[0],"TXW",3) && argc >= 2) {  /* txwindow */
           hydra_txwindow = atol(argv[1]);
           if (hydra_txwindow < 0L)
              hydra_txwindow = 0L;
           opt += 2;
        }
        else if (!strnicmp(argv[0],"RXW",3) && argc >= 2) {  /* rxwindow */
           hydra_rxwindow = atol(argv[1]);
           if (hydra_rxwindow < 0L)
              hydra_rxwindow = 0L;
           opt += 2;
        }
        else if (!strnicmp(argv[0],"NOC",3)) {   /* nocarrier */	/* OLSEN */
           nocarrier = true;
           opt++;
        }
        else if (!stricmp(argv[0],"LOG") && argc >= 2) {   /* log */	/* OLSEN */
           if (logfp) fclose(logfp);
           logfp = sfopen(argv[1],"at",DENY_WRITE);
           if (logfp == NULL)
              message(3,"-Couldn't open log-file %s",argv[1]);
           opt += 2;
        }
        else if (!strnicmp(argv[0],"LEV",3) && argc>=2) {  /* level */	/* OLSEN */
           temp = atoi(argv[1]);
           if (temp >=0 && temp <= 6)
              loglevel = temp;
           else
              message(6,"-Invalid log-level %d",temp);
           opt +=2;
        }
        else if (!strnicmp(argv[0],"RES",3) && argc>=2) {  /* DSZ-format log */	/* OLSEN */
           if (result) free(result);
           result = strdup(argv[1]);
           opt += 2;
        }
        else if ((!strnicmp(argv[0],"REC",3) || !strnicmp(argv[0],"UPL",3)) && argc>=2) {	/* OLSEN */
           char *p;

           strcpy(work,argv[1]);

           download = strdup(work);
           opt += 2;
        }
        else if (!strnicmp(argv[0],"NOR",3)) {             /* noresume */	/* OLSEN */
           noresume = true;
           opt++;
        }
        else if (!strnicmp(argv[0],"NOS",3)) {             /* nostamp */	/* OLSEN */
           nostamp = true;
           opt++;
        }
        else if (!strnicmp(argv[0],"OPT",3) && argc>=2) {  /* option  */	/* OLSEN */
           if      (!stricmp(argv[1],"XONXOFF")) hydra_options |= HOPT_XONXOFF;	/* OLSEN */
           else if (!stricmp(argv[1],"TELENET")) hydra_options |= HOPT_TELENET;
           else if (!stricmp(argv[1],"CTLCHRS")) hydra_options |= HOPT_CTLCHRS;
           else if (!stricmp(argv[1],"HIGHCTL")) hydra_options |= HOPT_HIGHCTL;
           else if (!stricmp(argv[1],"HIGHBIT")) hydra_options |= HOPT_HIGHBIT;
           else message(6,"-Invalid link option '%s'\n",argv[1]);
           opt += 2;
        }

        return (opt);
}


void init(void)
{
        /*if (logfp) fputs("\n",logfp);*/
        message(1,"+%s v%s %s : begin",PRGNAME,VERSION,HC_OS);

        sys_init();

#if WIN_AGL
        if (!win_init(10,CUR_NORMAL,CON_ANSI|CON_WRAP|CON_SCROLL|CON_UNBLANK,
                      CHR_NORMAL,KEY_ANSI)) {
           cprint("Can't initialize window system!\n");
           exit (1);
        }
#endif

        dtr_out(1);

        if (com_speed)
           com_setspeed(com_speed);
        if (!com_speed)
           com_speed = 2400U;
        if (!cur_speed)
           cur_speed = com_speed;
}/*init()*/


int batch_hydra (char *filespec, char *alias)
{
        char  path[PATHLEN];
        char *p;
        char  doafter;
        int   fd;

        switch (*filespec) {
               case '^':
               case '#': doafter = *filespec++;
                         break;
               default:  doafter = 0;
                         break;
        }

        splitpath(filespec,path,work);
        for (p = ffirst(filespec); p; p = fnext()) {
            mergepath(work,path,p);
            switch (hydra(work,alias)) {
                   case XFER_ABORT:
                        return (1);

                   case XFER_SKIP:
                        break;

                   case XFER_OK:
                        switch (doafter) {
                               case '^':  /* Delete */
                                    if (unlink(work))
                                       message(6,"!HSEND: Could not delete %s",work);
                                    else
                                       message(1,"+Sent-H deleted %s",work);
                                    break;

                               case '#':  /* Truncate */
                                    if ((fd = dos_sopen(work,2)) < 0) {
                                       message(6,"!HSEND: Error truncating %s",work);
                                       break;
                                    }
                                    dos_close(fd);
                                    message(1,"+Sent-H truncated %s",work);
                                    break;

                               default:
                                    message(1,"+Sent-H %s",work);
                                    break;
                        }
                        break;
            }
        }

        return (0);
}/*batch_hydra()*/


void hydracom (void)
{
        static   char *hauto = "\030cA\\f5\\a3\030a";
        register char *hseek = hauto;
        register int   c, i;
        boolean  echo;
        int      mask;
        char     queue[80];
        long t;

        message(0,"+Entering terminal mode");
        queue[0] =  '\0';
        echo = false;
        mask = parity ? 0x7f : 0xff;

        do {
#if WIN_AGL
           while (!win_keyscan()) {
#elif defined(AMIGA)
           while (!ConScanKey()) {
#else
           while (!kbhit()) {
#endif
                 if (!carrier()) {
                    cprint("\007\n");
                    message(1,"-Carrier lost, exiting (should use 'NOCarrier'?)");
                    return;
                 }

                 if ((c = com_getbyte()) != EOF) {
                    c &= mask;
                    if (c == 12)
                       cprint("\033[2J");
                    else
                       cprint("%c",c);

                    if ((c & 0x7f) == *hseek) {
                       if (!*++hseek) {
                          hseek = hauto;
                          goto autostart;
                       }
                    }
                    else hseek = hauto;
                 }
                 else
                    sys_idle();
           }/*while*/

           switch (c = ConGetKey()) {

                  case EOF: break;
                  case Alt_X: break;
                  case Alt_C: cprint("\033[2J");
                              break;
                  case Alt_B: if (parity)
                                 cprint("\r**Can't toggle 8th bit strip with parity 7E1\n");
                              else {
                                 mask ^= 0x80;
                                 cprint("\r**Strip 8th bit %s\n",
                                        (mask & 0x80) ? "Off" : "On");
                              }
                              break;
                  case Alt_E: echo = !echo;
                              cprint("\r**Local echo %s\n",
                                     echo ? "On" : "Off");
                              break;
                  case Alt_H: dtr_out(0);
                              for (t = time(NULL) + 1; time(NULL) < t; );
                              dtr_out(1);
                              cprint("\r**Dropped dtr\n");
                              break;
                  case PgUp:  switch (get_str("**Send",queue,70)) {
                                     case -1: cprint("\r**Send queue cleared\n");
                                              break;
                                     case  0: cprint("\r**Send queue empty\n");
                                              break;
                                     default: cprint("\r**Queue will be sent during next session\n");
                                              break;
                              }
                              break;
                  case PgDn:
autostart:                    hydra_init(hydra_options);
                              c = 0;
                              if (parse(queue))
                                 for (i = 0; av[i] && ((c = batch_hydra(av[i],NULL)) == 0); i++);
                              if (!c) hydra(NULL,NULL);
                              hydra_deinit();
                              queue[0] = '\0';
                              cprint("\r**Finished\n");
                              break;
                  default:    if (c < 0x100) {
                                 com_putbyte((byte) c);
                                 if (echo) {
                                    cprint("%c",c);
                                    if (c == '\r') cprint("\n");
                                 }
                              }
                              break;
           }
        } while (c != Alt_X && c != EOF);

        cprint("\n");
        message(0,"+Exiting terminal mode");
}/*hydracom()*/

/* end of hydracom.c */
