home *** CD-ROM | disk | FTP | other *** search
/ Crawly Crypt Collection 1 / crawlyvol1.bin / telecomm / myterm / myterm.c next >
C/C++ Source or Header  |  1992-07-12  |  46KB  |  1,162 lines

  1.  
  2. /************************************************************************
  3.  *                                                                      *
  4.  *  My First Terminal, version 1.0             Written in Pure C v1.0   *
  5.  *                                                                      *
  6.  *  Source code created at Jul 1992 by Koos Kuil as a part of the way   *
  7.  *  to learn the C language.                                            *
  8.  *                                                                      *
  9.  *  This code is original developed using Sozobon C v1.33, but later    *
  10.  *  rewritten & redebugged using Pure C.                                *
  11.  *                                                                      *
  12.  *  Special Thanks to all the people with useful ideas and suggestions  *
  13.  *  and critique about my routines in C.                                *
  14.  *                                                                      *
  15.  *  if you have ideas or problems about this terminal, you can contact  *
  16.  *  me (Koos Kuil) on Fidonet  2:282/397 or NeST  90:4001/103           *
  17.  *                                                                      *
  18.  *  or call my BBS in Holland, (+31)-(0)5978-18087 for ATARI ST Soft.   *
  19.  *                                                                      *
  20.  ************************************************************************/
  21.  
  22. #include <tos.h>
  23. #include <stdio.h>
  24. #include <ctype.h>
  25. #include <string.h>
  26. #include <stdlib.h>
  27. #include <ext.h>
  28.  
  29. #define AUX         1                  /* Serial port device      */
  30. #define CONSOLE     2                  /* Console (screen) device */
  31. #define ENVIRONMENT ""
  32.  
  33. #define DIAL        "ATDT "            /* modem dial string       */
  34. #define RESET       "ATZ"              /* modem reset string      */
  35. #define ANSWER      "ATA"              /* modem answer string     */
  36. #define CR          "\r"               /* carrige return          */
  37. #define CRLF        "\n"               /* carrige return & line f */
  38.  
  39. #define gotoxy(x,y) printf ("\33Y%c%c",(y)+32,(x)+32);
  40.  
  41. #define DIALDIR     "myterm.dir"       /* Telephone directory     */
  42. #define LOGFILE     "myterm.log"       /* Logfile name            */
  43. #define CONFIGFILE  "myterm.cfg"       /* Configuration file      */
  44.  
  45. #define HELP        0x62               /* Scancodes for keys.     */
  46. #define CURS_DN     0x50
  47. #define CURS_UP     0x48
  48. #define ALT_A       0x1e
  49. #define ALT_B       0x30
  50. #define ALT_C       0x2e
  51. #define ALT_D       0x20
  52. #define ALT_E       0x12
  53. #define ALT_F       0x21
  54. #define ALT_H       0x23
  55. #define ALT_I       0x17
  56. #define ALT_L       0x26
  57. #define ALT_M       0x32
  58. #define ALT_P       0x19
  59. #define ALT_R       0x13
  60. #define ALT_X       0x2d
  61.  
  62. #define ESCAPE      0x01          /* Scancodes for keys, only the name  */
  63. #define S_KEY       0x1f          /* different to the ALT_. defines. I  */
  64. #define C_KEY       0x2e          /* use this to get normal keys & func */
  65. #define D_KEY       0x20          /* -tion keys in config_menu()        */
  66. #define A_KEY       0x1e
  67.  
  68. #define START_BD    2             /* Set default baudrate to 2400 baud. */
  69.  
  70. /**
  71.  **   Global Variables
  72.  **/
  73.  
  74. char woord[200],                   /* Buffers used by strings.           */
  75.      buf[200],                     /* Buffer for general use.            */
  76.      bd=0,                         /* Actual baudrate.                   */
  77.     *funckey[10];                  /* Function keys macros.              */
  78.  
  79. int  ext_p=0,                      /* number of external protocols.      */
  80.      flow_ctl=0,                   /* flow control.                      */
  81.      localecho=0,                  /* Local echo (Half Duplex)           */
  82.      begin=0;                      /* Begin of numbers dial directory    */
  83.  
  84. unsigned int baud[6][2] =
  85. {
  86.      300,9,
  87.     1200,7,
  88.     2400,4,
  89.     4800,2,
  90.     9600,1,
  91.    19200,0                         /* baudrates for use with Rsconf()    */
  92. };
  93.  
  94. char *flow[3] = { "None","Xon/Xoff","Rts/Cts" }; /* Flow control status */
  95. char *logstat[2] = { "Closed","Open" }; /* String for logfile status.   */
  96. char *echostat[2]= { "Off","On" };      /* String for Local Echo status */
  97.  
  98. /**
  99.  **   Record structure for Dial directory 'Myterm.dir'
  100.  **/
  101.  
  102. #define DIAL_LEN 58               /* record size for dial directory     */
  103.  
  104. struct
  105. {
  106.   char name[40];
  107.   char number[15];
  108.   int  baudrate;
  109. } dial_dir;
  110.  
  111. /**
  112.  **   External protocols array
  113.  **/
  114.  
  115. #define NPROTOCOLS  20
  116.  
  117. char *protocoltype[2]={"One file","Batch"};
  118.  
  119. struct extprot {
  120.  int   type;                      /* Type of protocol, batch or not     */
  121.  char  *f_name,                   /* Full name of external protocols.   */
  122.        *s_name,                   /* startup name                       */
  123.        *up_cli,                   /* upload array                       */
  124.        *down_cli;                 /* download array                     */
  125. } extprotocol[NPROTOCOLS];
  126.  
  127. /**
  128.  **   Function Prototypes.
  129.  **/
  130.  
  131. void getconfig ( void );
  132. void mdmreset ( void );
  133. void send ( void );
  134. void dialmenu (void );
  135. void configmenu ( void );
  136. void dropdtr ( void );
  137. int input ( int );
  138. void purge ( void );
  139. void displaybaudrates ( void );
  140. long GetHz200 ( void );
  141.  
  142. /**
  143.  **   Main function
  144.  **/
  145.  
  146. void main(void)
  147. {
  148.   int  end_term = 0,           /* flag end of terminal                  */
  149.        log=0,                  /* logfile open/closed                   */
  150.        scancode = 0,           /* Scancode variable, prepared from key  */
  151.        b=0;
  152.  
  153.   long key=0;                  /* return value of Bconin                */
  154.  
  155.   FILE *ifp;                   /* file descriptor pointer               */
  156.  
  157.   printf(" \33E\33v\33eMy first terminal in C, press \33p Help \33q for Help\n\n");
  158.  
  159.   getconfig();                 /* load external up/download protocols.  */
  160.   mdmreset ();                 /* Reset the modem.                      */
  161.  
  162.   while (!end_term){           /* End of terminal ?                     */
  163.  
  164.     if (Bconstat (CONSOLE)) {  /* Key pressed ?                         */
  165.       key=Bconin (CONSOLE);
  166.  
  167.       if ((int) key == 0) {    /* Is it a normal char or a Scancode ?   */
  168.  
  169.         scancode =(int) (key >> 16);  /* Get scancode                   */
  170.  
  171.         switch (scancode)      /* Look, if it's a terminal option.      */
  172.         {
  173.           case ALT_A :         /* Answer incoming call                  */
  174.  
  175.             printf ("\r\33KAnswering incoming call ...\n");
  176.             strcpy (buf,ANSWER);
  177.             strcat (buf,CR);
  178.             send();
  179.             break;
  180.  
  181.           case ALT_B :         /* Set a new baudrate.                   */
  182.  
  183.             if (++bd > 5) bd=0;
  184.             printf ("\r\33KSetting baudrate to %d baud.\n",baud[bd][0]);
  185.  
  186.             Rsconf (baud[bd][1], flow_ctl,-1,-1,-1,-1);
  187.             break;
  188.  
  189.           case ALT_C :         /* Clear screen & recover colors         */
  190.  
  191.             printf("\33q\33bc\33cd\33v\33E");
  192.             break;
  193.  
  194.           case ALT_D :         /* Jump to the dial directory.           */
  195.  
  196.             dialmenu ();
  197.             break;
  198.  
  199.           case ALT_E :         /* Toggle Local echo on or off           */
  200.  
  201.             localecho = !localecho;
  202.             printf("\r\33KLocal Echo now %s\n",echostat[localecho]);
  203.             break;
  204.  
  205.           case ALT_F :         /* Toggle flow control.                  */
  206.  
  207.             if (++flow_ctl > 2) flow_ctl = 0;
  208.             printf ("\r\33KSetting Flow Control to : %s\n", flow[flow_ctl]);
  209.             Rsconf (baud[bd][1], flow_ctl,-1,-1,-1,-1);
  210.             break;
  211.  
  212.           case ALT_H :         /* Drop DTR signal for end of connection.*/
  213.  
  214.             printf ("\r\33KDisconnecting ... \n");
  215.             dropdtr ();
  216.             break;
  217.  
  218.           case ALT_I :          /* Display information screen ...       */
  219.  
  220.             printf("\33E\n\33p My first terminal \33q is developed using Pure C v1.0 and\n"
  221.                      "written to learn a little bit of the C language.\n\n"
  222.                      "Special Thanks goes to all the people with useful ideas or suggestions\n"
  223.                      "on my source code written in C.\n\n"
  224.                      "If you have ideas or suggestions about my source code or this terminal,\n"
  225.                      "please contact me (Koos Kuil) on Fidonet 2:282/397 or NeST 90:4001/103\n\n"
  226.                      "or you can call my own BBS in Holland (+31)(0)5978-18087.\n\n"
  227.                      "You may copy this programm to al your (lady) friends only for nothing,\n"
  228.                      "not for money.\n\n         Have fun with it,  Koos Kuil\n\n"
  229.                      "Strike a key when ready ...");
  230.  
  231.             Bconin(CONSOLE);    /* Wait for a keypress ...              */
  232.             printf("\r\33K");   /* Cleanup last line Esc-K (Vt52)       */
  233.  
  234.             break;
  235.  
  236.           case ALT_L :          /* Open or close the logfile.           */
  237.  
  238.             if (log == 0) {
  239.               if ((ifp = fopen (LOGFILE, "a")) == 0)  /* Error opening logfile ? */
  240.                 printf ("Can't open logfile.\n");
  241.               else
  242.                 log = 1;        /* Everything allright ? Okay.          */
  243.             }
  244.          else {
  245.               log = 0;
  246.               fclose (ifp);
  247.             }
  248.  
  249.             printf ("\rLogfile now %s\n", logstat[log]);
  250.             break;
  251.  
  252.           case ALT_P :         /* Install external protocols & change   *
  253.                                 * function key macros.                  */
  254.             configmenu();
  255.             break;
  256.  
  257.           case ALT_R :         /* Set default baudrate & reset modem.   */
  258.  
  259.             printf ("\r\33KReintializing modem ... \n");
  260.             mdmreset ();
  261.             break;
  262.  
  263.           case ALT_X :          /* Quit terminal ?                      */
  264.  
  265.             printf("\r\33KQuit terminal y/n ? ");
  266.             key=(int) Bconin(CONSOLE);
  267.  
  268.             if (key != 89 && key != 121)
  269.               printf("\r\33K");
  270.             else {
  271.               printf ("\n\nThanks for using My first terminal, have a nice day.\n");
  272.  
  273.               end_term = 1;    /* End of terminal flag.                */
  274.             }
  275.             break;
  276.  
  277.           case HELP :          /* Panic!, Display help information      */
  278.  
  279.             printf("\33E\n\33p   My First Terminal, developed using Pure C, by Koos Kuil   \33q\n"
  280.                    "version 1.0, created at %s on %s\n\n"
  281.                    " ALT-A   Answer incoming call.\n"
  282.                    " ALT-B   Toggle baudrate, now %d baud.\n"
  283.                    " ALT-C   Clear screen & recover VT52 colors\n"
  284.                    " ALT-D   Telephone numbers dial directory.\n"
  285.                    " ALT-E   Toggle local echo %s\n"
  286.                    " ALT-F   Toggle flow control, current flow : %s.\n"
  287.                    " ALT-H   Hangup your connection.\n"
  288.                    " ALT-I   Information about this terminal.\n"
  289.                    " ALT-L   Logfile '%s' now %s.\n"
  290.                    " ALT-P   Protocol & Function key configuration menu.\n"
  291.                    " ALT-R   Reintialize modem.\n"
  292.                    " ALT-X   Quit My first Terminal.\n\n"
  293.                    " F1..F10 Send Function key macro to other side.\n"
  294.                    " Ctrl-Up Upload files with external protocols\n"
  295.                    " Ctrl-Dn Download files with external protocols\n\n"
  296.                    "Strike a key when ready ..."
  297.                   ,__DATE__,__TIME__,baud[bd][0],echostat[!localecho],flow[flow_ctl],LOGFILE,logstat[log]);
  298.  
  299.             Bconin(CONSOLE);    /* Wait on a keypress ...               */
  300.             printf ("\r\33K");  /* Cleanup last line Esc-K (Vt52)       */
  301.             break;
  302.  
  303.           case CURS_DN :        /* Cursor key down ?                    */
  304.  
  305.             if (Kbshift(-1) & 0x04) {    /* Check Control key.          */
  306.  
  307.               if (ext_p){
  308.                 printf ("\n\33p  Download protocol  \33q\n\n");
  309.                 for (b = 0;b < ext_p; ++b)
  310.                   printf ("%d. %s\n",b+1,extprotocol[b].s_name);
  311.  
  312.                 printf ("\nSelect : ");
  313.                 if (input (2)) {
  314.                   b=atoi (woord);
  315.                   if (b>=1 && b<=ext_p) { /* dec 1, array begins with 0 */
  316.  
  317.                     strcpy (buf+1,extprotocol[--b].down_cli);
  318.  
  319.                 /* One file transfer download like Xmodem ? */
  320.  
  321.                if (extprotocol[b].type == 0 ) {
  322.  
  323.                   printf("\n\nPlease enter filename for %s download : ",extprotocol[b].s_name);
  324.                  woord[0]=' ';          /* add extra space char */
  325.                     strcat (buf+1,woord);  /* after commandline    */
  326.  
  327.                       if (input (12))
  328.                     strcat (buf+1,woord);
  329.                  else
  330.                   strcat (buf+1,"noname.dwn\0");
  331.                }
  332.  
  333.                     buf[0]=strlen (buf+1);
  334.  
  335.                     printf ("\n\nStarting external %s ...\n",extprotocol[b].s_name);
  336.                     Pexec (0,extprotocol[b].f_name,buf,ENVIRONMENT);
  337.                     printf ("\rBack to My first terminal\n");
  338.                   }
  339.                   else
  340.                     printf("\r\33KWrong number entered.\n");
  341.                 }
  342.                 else
  343.                   printf("\r\33K");
  344.               }
  345.               else
  346.                 printf("\nNo external download protocols available.\n");
  347.             }
  348.             break;
  349.  
  350.           case CURS_UP :        /* Cursor up ?                          */
  351.  
  352.             if (Kbshift(-1) & 0x04) {    /* Check Control key.          */
  353.  
  354.               if (ext_p) {
  355.                 printf ("\n\33p  Upload protocol  \33q\n\n");
  356.                 for (b = 0;b < ext_p; ++b)
  357.                   printf ("%d. %s\n",b+1,extprotocol[b].s_name);
  358.                 printf ("\nSelect : ");
  359.  
  360.                 if (input(2)){
  361.                   b=atoi(woord);
  362.                   if (b >= 1 && b <= ext_p) {
  363.                     printf ("\n\nEnter filename(s) for upload :");
  364.                     input (100);
  365.                     if (!strlen (woord))
  366.                       printf ("\r\33KNo filenames entered for upload\n");
  367.                     else {
  368.                       strcpy (buf,woord);   /* add after the commanline */
  369.                       woord[0]=' ';         /* a extra space char and   */
  370.                       strcpy (woord+1,buf); /* the filenames to upload. */
  371.  
  372.                       buf[1]=0;             /* Clear commanline buffer. *
  373.                                              * copy the cli for your    *
  374.                                              * selected upload protocol */
  375.  
  376.                       strcpy (buf+1,extprotocol[--b].up_cli);
  377.  
  378.                       strcat (buf+1,woord); /* Add upload filenames.    */
  379.                       buf[0]=strlen(buf+1); /* Size commandline.        */
  380.  
  381.                       printf ("\n\nStarting external %s ...\n",extprotocol[b].s_name);
  382.                       Pexec (0,extprotocol[b].f_name,buf,ENVIRONMENT);
  383.                       printf ("\rBack to My first terminal\n");
  384.                     }
  385.                   }
  386.                   else
  387.                     printf ("\r\33KWrong number entered.\n");
  388.                 }
  389.                 else
  390.                   printf ("\r\33K");
  391.               }
  392.               else
  393.                 printf ("\nNo external upload protocols available.\n");
  394.             }
  395.             break;
  396.  
  397.         default:
  398.  
  399.           if (scancode >= 0x3b && scancode <= 0x44) {  /* Function key ?          */
  400.             strcpy (buf,funckey[scancode - 0x3b]);     /* Copy func. key to buf   */
  401.             strcat (buf,CR);                  /* Add return char         */
  402.             send ();                          /* Send it.                */
  403.           }
  404.         }
  405.       }
  406.       else {
  407.         Bconout(AUX,(int) key);
  408.         if (localecho) putchar ((int) key); /* Local echo on ?       */
  409.       }
  410.     }
  411.  
  412.     if (Bconstat(AUX)) {                   /* Something on serial port? */
  413.       b=(int) Bconin(AUX);                 /* Get it.                   */
  414.       putchar (b);
  415.       if (log) putc( (char) b,ifp);                /* Write it to logfile.      */
  416.     }
  417.   }
  418.   if (log) fclose(ifp);                    /* Logfile open ? Close it.  */
  419. }
  420.  
  421. /************************************************************************
  422.  *                                                                      *
  423.  *  Procedure : send();                                                 *
  424.  *  Return    : No return value.                                        *
  425.  *                                                                      *
  426.  *  Send string array buf[] to the serial port.                         *
  427.  *                                                                      *
  428.  ************************************************************************/
  429.  
  430. void send(void)
  431. {
  432.   int i=0;
  433.   while (buf[i]) Bconout (AUX,buf[i++]);
  434. }
  435.  
  436. /************************************************************************
  437.  *                                                                      *
  438.  *  Procedure : Purge();                                                *
  439.  *  Return    : No return value.                                        *
  440.  *                                                                      *
  441.  *  Cleanup the serial port for one second.                             *
  442.  *                                                                      *
  443.  ************************************************************************/
  444.  
  445. void purge(void)
  446. {
  447.  long timer = GetHz200();                 /* 200 Hz timer, Sozobon C     */
  448.  
  449.  do {
  450.    while (Bconstat(AUX)) {
  451.      timer = GetHz200();                  /* 200 Hz timer, for wait a    */
  452.      Bconin(AUX);                         /* second to purge serial port.*/
  453.    }
  454.  } while ( (timer + 200 >= GetHz200()) && (Bconstat (CONSOLE)) == 0 );
  455.                                 /* serial port 1 second clean? */
  456. }
  457.  
  458. /************************************************************************
  459.  *                                                                      *
  460.  *  Procedure : mdmreset();                                             *
  461.  *  Return    : No return value.                                        *
  462.  *                                                                      *
  463.  *  Set startup baudrate, purge serial port & Reset modem.              *
  464.  *                                                                      *
  465.  ************************************************************************/
  466.  
  467. void mdmreset(void)
  468. {
  469.   Rsconf (baud[START_BD][1], flow_ctl,-1,-1,-1,-1);
  470.   bd=START_BD;                             /* startup baudrate.         */
  471.   purge ();                                /* Clear input buffer.       */
  472.   strcpy (buf,RESET);                      /* prepare reset string.     */
  473.   strcat (buf,CR);
  474.   send ();                                 /* and reset modem ...       */
  475. }
  476.  
  477. /************************************************************************
  478.  *                                                                      *
  479.  *  Procedure : dropdtr();                                              *
  480.  *  Return    : No return value.                                        *
  481.  *                                                                      *
  482.  *  Drop the modem DTR signal for one second & cleanup the serial port. *
  483.  *                                                                      *
  484.  ************************************************************************/
  485.  
  486. void dropdtr(void)
  487. {
  488.   Ongibit (16);                            /* Drop DTR signal           */
  489.   sleep (1);                               /* Wait one second         */
  490.   Offgibit (239);                          /* DTR high again.           */
  491.   purge();
  492. }
  493.  
  494. /************************************************************************
  495.  *                                                                      *
  496.  *  Procedure : input(length);                                          *
  497.  *  Return    : NULL, For everything allright, user entered something.  *
  498.  *              ONE,  If the user has escaped from input by pressing    *
  499.  *                    the escape key.                                   *
  500.  *                                                                      *
  501.  *  Get a limited string from the keyboard, length is maximum size that *
  502.  *  can entered. The entered string comes into string array woord[]     *
  503.  *                                                                      *
  504.  ************************************************************************/
  505.  
  506. int input (length)
  507. {
  508.   int i=0,
  509.       a=0;
  510.  
  511.   while ((a =(char) Bconin(CONSOLE)) != 13 && (a != 27)){
  512.     if (a == 8) {
  513.       if (i) {
  514.         woord[--i]=0;               /* Get backspace from keyboard.     */
  515.         printf("\b \b");            /* Send destructive backspace char. */
  516.       }
  517.       else
  518.        putchar (7);                 /* Backspace not possible. Beep !   */
  519.     }
  520.     else {
  521.       if (i >= length)
  522.         putchar (7);                /* Maximum size, beep               */
  523.       else {
  524.         woord[i++]=a;               /* Append key to string.            */
  525.         putchar (a);                /* and display it on screen.        */
  526.       }
  527.     }
  528.   }
  529.   woord[i]=0;                       /* end of string char.              */
  530.   if (a == 27)                      /* Escape from input ? return zero  */
  531.     return(0);
  532.   else
  533.     return(1);                /* Everything okay ...           */
  534. }
  535.  
  536. /************************************************************************
  537.  *                                                                      *
  538.  *  Procedure : dial_menu();                                            *
  539.  *  Return    : No return value.                                        *
  540.  *                                                                      *
  541.  *  Telephone number directory, including options for change, append &  *
  542.  *  delete numbers, Autodial function etc..                             *
  543.  *                                                                      *
  544.  ************************************************************************/
  545.  
  546. void dialmenu(void)
  547. {
  548.  /*
  549.   * Protypes
  550.   */
  551.  
  552.   void displaybadrate ( void );
  553.  
  554.   long  offset=0;                        /* offset pointer for fseek()   */
  555.  
  556.   int   numbers = 0,                     /* Total numbers in dial list   */
  557.         i = 0,                           /* Used for calculation...      */
  558.         a = 0,
  559.         b = 0,
  560.         end = 0,                         /* End of number directory      */
  561.         dial_exit = 0;                   /* Exit flag                    */
  562.  
  563.   FILE *ifp, *ifp_b;                     /* file descriptor pointers     */
  564.  
  565.   DTA *DtaBuf = Fgetdta();               /* Get DTA address              */
  566.  
  567.   if (Fsfirst (DIALDIR,1) >= 0)          /* Does DIALDIR exist ?         */
  568.     numbers = (int) (DtaBuf -> d_length / DIAL_LEN); /* Get size DIALDIR */
  569.  
  570.   if (begin+15 <= numbers)               /* calculating begin/end for    */
  571.     end=begin+15;                        /* dial directory.              */
  572.   else
  573.     end=numbers;
  574.  
  575.   do {
  576.     printf("\33E\n\33p                     Telephone number directory ...                      \33q\n"
  577.                      "--------------- Bulletin Board Name -------------- Telephone ---- Baud --\n\n");
  578.     if (numbers) {
  579.  
  580.       ifp=fopen (DIALDIR,"r");               /* Open dial directory  */
  581.       offset=begin*DIAL_LEN;
  582.       fseek (ifp,offset,0);
  583.       for (i = begin ;i < end; ++i ){
  584.  
  585.         fread (&dial_dir,DIAL_LEN,1,ifp);
  586.         if (i < 9) printf (" ");
  587.         printf ("%d. %s",i+1,dial_dir.name); /* display name      */
  588.         gotoxy (49, (i-begin)+4);            /* jump to x,y       */
  589.         printf("| %s",dial_dir.number);      /* display number.   */
  590.         gotoxy (64, (i-begin)+4);            /* jump to x,y       */
  591.         printf ("| %d\n",baud[dial_dir.baudrate][0]);
  592.       }
  593.       fclose(ifp);
  594.     }
  595.     else {
  596.       printf("No telephone numbers in this dial listing.\n");
  597.     }
  598.     printf("\nOptions : \33p Esc \33q Exit   \33p A \33q Append    \33p C \33q Change   \33p D \33q Delete \n\n");
  599.     printf("Enter a option, dial list number or telephone number : ");
  600.  
  601.     if (input(20)) {                            /* Input telephone number */
  602.       if (strlen (woord)) {
  603.         switch (toupper (woord[0]))
  604.         {
  605.           case ('A') :
  606.             printf ("\r\33K\33p Append \33q\33j The name of the new BBS : ");
  607.             if (input(39)) {
  608.  
  609.               strcpy (dial_dir.name,woord);
  610.               printf ("\33k\33K\33j The telephone number of this new BBS : ");
  611.  
  612.               if (input(14)) {
  613.                 strcpy (dial_dir.number,woord);
  614.  
  615.                 displaybaudrates();                 /* display baudrates      */
  616.                 input(2);
  617.                 i=atoi (woord);                     /* get value from string. */
  618.                 if (i >= 1 && i <= 6)
  619.                   dial_dir.baudrate=i-1;
  620.                 else
  621.                   dial_dir.baudrate=START_BD;       /* wrong baudrate,default.*/
  622.  
  623.                 ifp=fopen (DIALDIR,"a");            /* open dial directory... */
  624.                 fwrite (&dial_dir,DIAL_LEN,1,ifp);  /* and append it.         */
  625.                 fclose (ifp);                       /* close it.              */
  626.                 ++numbers;                          /* increase numbers.      */
  627.                 if (begin+15 > end)
  628.                   ++end;                            /* increas dial directory */
  629.               }
  630.             }
  631.             break;
  632.  
  633.            case ('C') :
  634.  
  635.              if (numbers){
  636.               printf("\r\33K\33p Change \33q\33j Enter number of the BBS : ");
  637.               if (input(2)) {
  638.                 if (strlen(woord)){
  639.                   i=atoi(woord);
  640.                   if ((i >=1) & (i <= numbers)){
  641.                     ifp=fopen(DIALDIR,"r+");
  642.                     offset=(i-1)*DIAL_LEN;        /* Calculate offset       */
  643.                     fseek (ifp,offset,0);
  644.                     fread (&dial_dir,DIAL_LEN,1,ifp);
  645.  
  646.                     printf("\33k\33K\33j Enter the new BBS name : ");
  647.                     if (input(39)){
  648.                       if (strlen (woord))
  649.                         strcpy (dial_dir.name, woord);
  650.  
  651.                       printf("\33k\33K\33j Enter the new BBS telephone number : ");
  652.                       if (input(14)) {
  653.  
  654.                         if (strlen (woord))
  655.                           strcpy (dial_dir.number, woord);
  656.  
  657.                         displaybaudrates();
  658.  
  659.                         input(2);
  660.                         i=atoi (woord);               /* Get value from string. */
  661.                         if (i >= 1 && i <= 6)
  662.                           dial_dir.baudrate=i-1;
  663.  
  664.                         fseek (ifp,offset,0);              /* Seek to offset &  */
  665.                         fwrite (&dial_dir,DIAL_LEN,1,ifp); /* write new record  */
  666.                         fclose (ifp);                      /* close dial dir.   */
  667.                       }
  668.                     }
  669.                   }
  670.                 }
  671.               }
  672.             }
  673.             break;
  674.  
  675.           case ('D') :
  676.  
  677.             if (numbers){
  678.               printf("\r\33K\33p Delete \33q Enter number of the BBS : ");
  679.               if (input(2)) {
  680.                 if (strlen(woord)){
  681.                   i=atoi(woord);
  682.                   if ((i >=1) & (i <= numbers)){
  683.                     ifp=fopen(DIALDIR,"r");
  684.                     ifp_b=fopen("temp.$$$","w");
  685.                     for (b=0;b<numbers;++b){
  686.                       fread (&dial_dir,DIAL_LEN,1,ifp);
  687.                         if (b != i-1)
  688.                           fwrite (&dial_dir,DIAL_LEN,1,ifp_b);
  689.                     }
  690.                     fclose (ifp);
  691.                     fclose (ifp_b);
  692.                     remove(DIALDIR);
  693.                     rename("temp.$$$",DIALDIR);
  694.                     --numbers;
  695.                     if (end>numbers)
  696.                       end=numbers;
  697.                   }
  698.                 }
  699.               }
  700.             }
  701.             break;
  702.  
  703.           default :
  704.  
  705.             i=atoi(woord);      /* get value from string like Val(a$)   */
  706.             if ((i >= 1) & (i <= numbers)){
  707.               ifp=fopen(DIALDIR,"r");
  708.               offset=(i-1)*DIAL_LEN;              /* calculate offset   */
  709.               fseek (ifp,offset,1);               /* Seek  to offset... */
  710.               fread (&dial_dir,DIAL_LEN,1,ifp);   /* & read dial record */
  711.               fclose(ifp);
  712.             }
  713.             else {
  714.               strcpy (dial_dir.name,"The Unknown BBS at ");
  715.               strcat (dial_dir.name,woord);       /* add unknown number.*/
  716.               dial_dir.baudrate=bd;               /* actual baudrate.   */
  717.               strcpy(dial_dir.number,woord);      /* telephone number   */
  718.             }
  719.  
  720.             strcpy (buf,DIAL);                    /* prepare modem dial */
  721.             strcat (buf,dial_dir.number);         /* string.            */
  722.             strcat (buf,CR);
  723.  
  724.             printf("\r\33KDialing %s ...",dial_dir.name);
  725.  
  726.             Rsconf(baud[dial_dir.baudrate][1], flow_ctl,-1,-1,-1,-1);
  727.             purge();
  728.             send();                               /* and dial number... */
  729.  
  730.             a = 0;   /* pointer for result modem string after dial.     */
  731.          woord[0]='\0';
  732.  
  733.             do {
  734.               long timer = GetHz200();            /* Get 200 Hz timer   */
  735.               do {
  736.                 while (Bconstat (AUX)) {
  737.                   timer = GetHz200();             /* Wait a second to   */
  738.                   woord[a++]=Bconin (AUX);        /* purge serial port. */
  739.                   woord[a+1]='\0';
  740.                 }
  741.               } while (timer+100 > GetHz200());   /* serial port clean? */
  742.  
  743.               if (strstr(woord,"BUSY") || strstr(woord,"NO CARRIER") || strstr(woord,"NO DIALTONE")){
  744.                 printf("\r\33KNo carrier or Busy ...");
  745.                 a=0;
  746.                 woord[0]='\0';
  747.                 purge();
  748.  
  749.                 timer = GetHz200();               /* Get 200 Hz timer   *
  750.                                                    * Wait 10 Seconds... */
  751.                 while ( (!Bconstat(CONSOLE)) && (timer + 2000 > GetHz200()) );
  752.                 if (!Bconstat(CONSOLE)) {
  753.                   printf("\r\33KDialing %s ...",dial_dir.name);
  754.                   send();
  755.                 }
  756.               }
  757.             } while ((strstr(woord,"CONNECT") == 0) && (Bconstat(CONSOLE) == 0));
  758.  
  759.             if (Bconstat(CONSOLE)) {
  760.               printf("\nAuto Dial session aborted.\n");
  761.               dropdtr();
  762.             }
  763.             else
  764.               printf("\nConnect...\07\n");
  765.             dial_exit=1;
  766.           }
  767.       }
  768.       else {
  769.          if (begin+15 <= numbers)
  770.            begin+=15;
  771.          else
  772.            begin=0;
  773.          if (begin+15 <= numbers)
  774.            end=begin+15;
  775.          else
  776.          end=numbers;
  777.       }
  778.     }
  779.     else {
  780.       dial_exit=1;
  781.     }
  782.   } while (!dial_exit);         /* Dial list exit flag.                 */
  783.   printf("\r\33K");             /* Cleanup line.                        */
  784. }
  785.  
  786. /************************************************************************
  787.  *                                                                      *
  788.  *  Procedure : display_baudrates();                                    *
  789.  *  Return    : No return value.                                        *
  790.  *                                                                      *
  791.  *  Display the baudrates for use with the Change & Append option in    *
  792.  *  the telephone number directory.                                     *
  793.  *                                                                      *
  794.  ************************************************************************/
  795.  
  796. void displaybaudrates(void)
  797. {
  798.   int i;
  799.  
  800.   printf ("\33k\33K Baudrate :\33j    ");
  801.  
  802.   for (i = 0; i < 6; ++i)
  803.     printf ("\33p %d \33q %d ",i+1,baud[i][0]);
  804.   printf ("\33k");
  805. }
  806.  
  807. /************************************************************************
  808.  *                                                                      *
  809.  *  Procedure : config_menu();                                          *
  810.  *  Return    : No return value.                                        *
  811.  *                                                                      *
  812.  *  Install & Change external installed up & download protocols or      *
  813.  *  function keys or Save the changed option into file CONFIGFILE       *
  814.  *                                                                      *
  815.  ************************************************************************/
  816.  
  817. void configmenu(void)
  818. {
  819.   int configexit = 0, /* Configuration menu exit flag.         */
  820.       b = 0,          /* local variables                       */
  821.       select = 0,
  822.      scancode = 0,
  823.      a = 0;
  824.  
  825.   long key = 0;
  826.  
  827.   FILE *ifp;          /* File descriptor pointer.              */
  828.  
  829.   do {
  830.  
  831.     printf ("\33E\n\33p  Configuration  Menu for protocols & function keys   \33q\n\n");
  832.  
  833.     for (b = 0; b < 10; ++b){          /* Display function keys  */
  834.       printf ("F%d.",b+1);
  835.       if (b < 9) printf (" ");
  836.       printf ("%s\n",funckey[b]);
  837.     }
  838.  
  839.     printf ("\n\33p  External installed up & download protocols listing  \33q\n\n");
  840.  
  841.     for (b = 0; b < ext_p; ++b){  /* Display names of external protocols */
  842.       if (b < 6) {                /* into 2 columns.                     */
  843.         gotoxy (0,16+b);
  844.       }
  845.       else
  846.         gotoxy (40,16+(b-6));
  847.       if (b < 9)
  848.         printf (" ");
  849.       printf ("%d. %s\n",b+1,extprotocol[b].s_name);
  850.     }
  851.  
  852.     gotoxy (0,23);
  853.     printf ("\33p Esc \33q Exit  \33p F1...F10 \33q  \33p A \33q Append  \33p C \33q Change  \33p D \33q Delete  \33p S \33q Save  Select: ");
  854.  
  855.     do {                       /* End of configuration menu ?           */
  856.       key=Bconin (CONSOLE);    /* Get scancode                          */
  857.       scancode = (int) (key >> 16);
  858.     } while (!( (scancode == S_KEY) || (scancode == A_KEY) || (scancode == C_KEY) || (scancode == D_KEY) || (scancode == ESCAPE) || (scancode >=0x3a && scancode <=0x44) ));
  859.  
  860.     switch (scancode)
  861.     {
  862.        case A_KEY :
  863.  
  864.          if (ext_p < 12) {
  865.            for (b = 16; b < 22; ++b) {     /* Cleanup window */
  866.              gotoxy (0,b);
  867.              printf ("\33K");
  868.            }
  869.            gotoxy (0,16);
  870.            printf ("\33p Full name            : \33q \n"
  871.                    "\33p Protocol type        : \33q \n"
  872.                    "\33p Start up name        : \33q \n"
  873.                    "\33p Upload Commandline   : \33q \n"
  874.                    "\33p Download Commandline : \33q \n\n");
  875.  
  876.            select = ext_p;
  877.  
  878.            gotoxy (25,16);
  879.            if (input(40)) {
  880.              extprotocol[select].s_name = calloc (strlen(woord)+1, sizeof(char));
  881.              strcpy (extprotocol[select].s_name, woord);
  882.  
  883.           gotoxy (25,17);
  884.           printf ("\33p O \33q One file transfer or \33p B \33q Batch transfer ? : ");
  885.              if (( toupper ((char) Bconin(CONSOLE))) == 'B')
  886.                 extprotocol[select].type=1;
  887.           else
  888.             extprotocol[select].type=0;
  889.           gotoxy (25,17);
  890.           printf ("\33K%s",protocoltype[extprotocol[select].type]);
  891.  
  892.              gotoxy (25,18);
  893.              if (input(40)) {
  894.                extprotocol[select].f_name = calloc (strlen(woord)+1, sizeof(char));
  895.                strcpy (extprotocol[select].f_name, woord);
  896.  
  897.                gotoxy (25,19);
  898.                if (input(40)) {
  899.                  extprotocol[select].up_cli = calloc (strlen(woord)+1, sizeof(char));
  900.                  strcpy (extprotocol[select].up_cli, woord);
  901.  
  902.                  gotoxy (25,20);
  903.                  if (input(40)) {
  904.                    extprotocol[select].down_cli = calloc (strlen(woord)+1, sizeof(char));
  905.                    strcpy (extprotocol[select].down_cli, woord);
  906.                    ++ext_p;
  907.                  }
  908.                }
  909.              }
  910.            }
  911.          }
  912.          else {
  913.            printf("\r\33K You can not install more then 12 external protocols.");
  914.            Bconin(CONSOLE);
  915.          }
  916.          break;
  917.  
  918.        case C_KEY :
  919.  
  920.          if (ext_p) {
  921.            printf("\r\33K\33p Change \33q External protocol number : ");
  922.            if (input(2)){
  923.              select=atoi(woord);
  924.              if (select >= 1 && select <= ext_p) {
  925.                for (b = 16; b < 22; ++b) {       /* Cleanup window */
  926.                  gotoxy (0,b);
  927.                  printf ("\33K");
  928.                }
  929.                select--;
  930.                gotoxy (0,16);
  931.                printf ("\33p Full name            : \33q %s\n"
  932.                   "\33p Protocol type        : \33q %s\n"
  933.                        "\33p Start up name        : \33q %s\n"
  934.                        "\33p Upload Commandline   : \33q %s\n"
  935.                        "\33p Download Commandline : \33q %s\n\n"
  936.                        ,extprotocol [select].s_name,protocoltype [extprotocol [select].type],
  937.                         extprotocol [select].f_name,extprotocol [select].up_cli,
  938.                         extprotocol [select].down_cli);
  939.  
  940.                gotoxy (0,23);
  941.                printf ("\33K\33p Change \33q\33j Enter the new Full name : ");
  942.                if (input(40)) {
  943.                  if (strlen(woord)) {
  944.                    extprotocol[select].s_name = calloc (strlen(woord)+1, sizeof(char));
  945.                    strcpy (extprotocol[select].s_name, woord);
  946.                  }
  947.  
  948.                 printf ("\33k\33K\33j \33q \33p O \33q One file transfer or \33p B \33q Batch transfer ? : ");
  949.                  if (( toupper ((char) Bconin(CONSOLE))) == 'B')
  950.                    extprotocol[select].type=1;
  951.              else
  952.                   extprotocol[select].type=0;
  953.  
  954.                  printf ("\33k\33K\33j Enter the new Startup name : ");
  955.                  if (input(40)) {
  956.                    if (strlen(woord)) {
  957.                      extprotocol[select].f_name = calloc (strlen(woord)+1, sizeof(char));
  958.                      strcpy (extprotocol[select].f_name, woord);
  959.                    }
  960.  
  961.                    printf ("\33k\33K\33j Enter the new Upload CLI : ");
  962.                    if (input(40)) {
  963.                      if (strlen(woord)) {
  964.                        extprotocol[select].up_cli = calloc (strlen(woord)+1, sizeof(char));
  965.                        strcpy (extprotocol[select].up_cli, woord);
  966.                      }
  967.  
  968.                      printf ("\33k\33K\33j Enter the new Download CLI : ");
  969.                      if (input(40)) {
  970.                        if (strlen(woord)) {
  971.                          extprotocol[select].down_cli = calloc (strlen(woord)+1, sizeof(char));
  972.                          strcpy (extprotocol[select].down_cli, woord);
  973.                        }
  974.                      }
  975.                    }
  976.                  }
  977.                }
  978.              }
  979.            }
  980.          }
  981.          else {
  982.            printf("\r\33K You can't change a external protocol if there is none...");
  983.            Bconin(CONSOLE);
  984.          }
  985.          break;
  986.  
  987.        case D_KEY :
  988.  
  989.          printf("\r\33K\33p Delete \33q External protocol number : ");
  990.          if (input(2)){
  991.            select=atoi(woord);
  992.            if (select >= 1 && select <= ext_p) {
  993.              printf ("\r\33K\33p Delete \33q Delete this protocol ? y/n ");
  994.              if (input(2)) {
  995.                if (strlen (woord)) {
  996.                  if (toupper(woord[0]) == 'Y' ) {
  997.                    --select;
  998.                    for (b = ext_p; b > select; --b) {
  999.                      extprotocol[b-1].s_name = extprotocol[b].s_name;
  1000.                      extprotocol[b-1].f_name = extprotocol[b].f_name;
  1001.                      extprotocol[b-1].up_cli = extprotocol[b].up_cli;
  1002.                      extprotocol[b-1].down_cli = extprotocol[b].down_cli;
  1003.                    }
  1004.                    --ext_p;
  1005.                  }
  1006.                }
  1007.              }
  1008.            }
  1009.          }
  1010.          break;
  1011.  
  1012.        case S_KEY :
  1013.  
  1014.          printf("\r\33K\33p Saving \33q Function keys & Installed protocols into file %s ...",CONFIGFILE);
  1015.          if ((ifp = fopen (CONFIGFILE,"w")) != 0) {
  1016.             for (b = 0;b < 10; ++b) {
  1017.               fputs (funckey[b], ifp);
  1018.               fputs (CRLF, ifp);          /* add cr+lf */
  1019.             }
  1020.             for (b = 0;b < ext_p; ++b) {
  1021.               fprintf (ifp, "%d\n",extprotocol[b].type);
  1022.               fputs (extprotocol[b].s_name, ifp);
  1023.               fputs (CRLF, ifp);
  1024.               fputs (extprotocol[b].f_name, ifp);
  1025.               fputs (CRLF, ifp);
  1026.               fputs (extprotocol[b].up_cli, ifp);
  1027.               fputs (CRLF, ifp);
  1028.               fputs (extprotocol[b].down_cli, ifp);
  1029.               fputs (CRLF, ifp);
  1030.             }
  1031.             fclose (ifp);
  1032.           }
  1033.           break;
  1034.  
  1035.         case ESCAPE :            /* Escape ? */
  1036.  
  1037.           configexit=1;
  1038.           break;
  1039.     }
  1040.  
  1041.     /* Function key pressed ? */
  1042.  
  1043.     if (scancode >= 0x3b && scancode <= 0x44) {
  1044.  
  1045.       a = scancode - 0x3a;                /* Get function key number */
  1046.  
  1047.       printf ("\r\33K\33p Change \33q Function key %d to : ",a);
  1048.       if (input(40)) {
  1049.         funckey[--a]=calloc (strlen(woord)+1,sizeof(char));
  1050.         strcpy (funckey[a],woord);
  1051.       }
  1052.     }
  1053.  
  1054.   } while (!configexit);
  1055.   printf("\r\33K");
  1056. }
  1057.  
  1058. /************************************************************************
  1059.  *                                                                      *
  1060.  *  Procedure : get config();                                           *
  1061.  *  Return    : No return value.                                        *
  1062.  *                                                                      *
  1063.  *  Read funtion key macros & the external upload & download protocols, *
  1064.  *  into structure array *extprotocol[].                                *
  1065.  *                                                                      *
  1066.  *  The Clean ascii file CONFIGFILE is used for this.                   *
  1067.  *                                                                      *
  1068.  ************************************************************************/
  1069.  
  1070. void getconfig(void)
  1071. {
  1072.  
  1073.   char line[50],                 /* work room.                           */
  1074.        *pointer;                 /* pointer for calloc()                 */
  1075.  
  1076.   int  i;
  1077.  
  1078.   long length;
  1079.  
  1080.   FILE *ifp;                     /* local file descriptor pointer        */
  1081.  
  1082.   if (Fsfirst(CONFIGFILE,0) == 0) {  /* does CONFIGFILE exist ? */
  1083.  
  1084.     if ((ifp = fopen (CONFIGFILE,"r")) != 0 ) {
  1085.       for (i = 0;(i < 10 && (fgets (line,40,ifp) != 0)); ++i) {
  1086.  
  1087.         length=strlen (line);
  1088.         if (length) {
  1089.           line[length-1]='\0';    /* strip CR char               */
  1090.  
  1091.           funckey[i] = calloc (length, sizeof(char));
  1092.           strcpy (funckey[i],line);
  1093.         }
  1094.       }
  1095.       do {
  1096.       length = 0;
  1097.         for (i = 0;(i <= 4 && (fgets (line,50,ifp) != 0)); ++i) {
  1098.  
  1099.           length=strlen (line);
  1100.           if (length) {
  1101.             line[length-1]='\0';    /* strip CR char               */
  1102.  
  1103.          if (i) {
  1104.               pointer = calloc (length, sizeof(char));
  1105.               strcpy (pointer,line);
  1106.             }
  1107.             switch (i)
  1108.             {
  1109.            case 0 :
  1110.             extprotocol[ext_p].type = atoi (line);
  1111.  
  1112.               case 1 :
  1113.                 extprotocol[ext_p].s_name = pointer ;
  1114.                 break;
  1115.  
  1116.               case 2 :
  1117.                 extprotocol[ext_p].f_name = pointer ;
  1118.                 break;
  1119.  
  1120.               case 3 :
  1121.                 extprotocol[ext_p].up_cli = pointer ;
  1122.                 break;
  1123.  
  1124.               case 4 :
  1125.                 extprotocol[ext_p].down_cli = pointer ;
  1126.                 ++ext_p;
  1127.             }
  1128.           }
  1129.         }
  1130.       } while (length);
  1131.       fclose(ifp);
  1132.     }
  1133.     else
  1134.       printf ("Unable to open configuration file.\n");
  1135.  
  1136.   printf ("%d Up/Download protocols installed.\n",ext_p);
  1137.   }
  1138.   else
  1139.     printf("No Up/Download protocols installed.\n");
  1140. }
  1141.  
  1142. /************************************************************************
  1143.  *                                                                      *
  1144.  *  Procedure : GetHz200();                                             *
  1145.  *  Return    : long 200 Hz timer                                       *
  1146.  *                                                                      *
  1147.  *  Returns 200 Hz timer of Supervisor address 0x4ba, for waiting a few *
  1148.  *  seconds.                                                            *
  1149.  *                                                                      *
  1150.  ************************************************************************/
  1151.  
  1152. long GetHz200 (void)
  1153. {
  1154.   long old_super_stack = Super (0L),   /* Get into Supervisor mode  */
  1155.        timer = 0;
  1156.  
  1157.   timer = (* ( long *) 0x4ba );        /* Get 200 Hz timer        */
  1158.  
  1159.   Super ((void *) old_super_stack );   /* Get Back to user mode     */
  1160.  
  1161.   return (timer);
  1162. }