home *** CD-ROM | disk | FTP | other *** search
/ Crawly Crypt Collection 2 / crawlyvol2.bin / program / c / bts310b5 / mdm_proc.c < prev    next >
C/C++ Source or Header  |  1993-11-20  |  19KB  |  709 lines

  1. /*--------------------------------------------------------------------------*/
  2. /*                                                                            */
  3. /*                                                                            */
  4. /*        ------------         Bit-Bucket Software, Co.                        */
  5. /*        \ 10001101 /         Writers and Distributors of                    */
  6. /*         \ 011110 /          Freely Available<tm> Software.                 */
  7. /*          \ 1011 /                                                            */
  8. /*           ------                                                            */
  9. /*                                                                            */
  10. /*    (C) Copyright 1987-90, Bit Bucket Software Co., a Delaware Corporation. */
  11. /*                                                                            */
  12. /*                                                                            */
  13. /*                 This module was written by Vince Perriello                 */
  14. /*                                                                            */
  15. /*                                                                            */
  16. /*                      BinkleyTerm Modem Handler Module                        */
  17. /*                                                                            */
  18. /*                                                                            */
  19. /*      For complete    details  of the licensing restrictions, please refer    */
  20. /*      to the License  agreement,  which  is published in its entirety in    */
  21. /*      the MAKEFILE and BT.C, and also contained in the file LICENSE.240.    */
  22. /*                                                                            */
  23. /*      USE  OF THIS FILE IS SUBJECT TO THE  RESTRICTIONS CONTAINED IN THE    */
  24. /*      BINKLEYTERM  LICENSING  AGREEMENT.  IF YOU DO NOT FIND THE TEXT OF    */
  25. /*      THIS    AGREEMENT IN ANY OF THE  AFOREMENTIONED FILES,    OR IF YOU DO    */
  26. /*      NOT HAVE THESE FILES,  YOU  SHOULD  IMMEDIATELY CONTACT BIT BUCKET    */
  27. /*      SOFTWARE CO.    AT ONE OF THE  ADDRESSES  LISTED BELOW.  IN NO EVENT    */
  28. /*      SHOULD YOU  PROCEED TO USE THIS FILE    WITHOUT HAVING    ACCEPTED THE    */
  29. /*      TERMS  OF  THE  BINKLEYTERM  LICENSING  AGREEMENT,  OR  SUCH OTHER    */
  30. /*      AGREEMENT AS YOU ARE ABLE TO REACH WITH BIT BUCKET SOFTWARE, CO.        */
  31. /*                                                                            */
  32. /*                                                                            */
  33. /* You can contact Bit Bucket Software Co. at any one of the following        */
  34. /* addresses:                                                                */
  35. /*                                                                            */
  36. /* Bit Bucket Software Co.          FidoNet  1:104/501, 1:132/491, 1:141/491    */
  37. /* P.O. Box 460398                  AlterNet 7:491/0                            */
  38. /* Aurora, CO 80046               BBS-Net  86:2030/1                        */
  39. /*                                  Internet f491.n132.z1.fidonet.org         */
  40. /*                                                                            */
  41. /* Please feel free to contact us at any time to share your comments about    */
  42. /* our software and/or licensing policies.                                    */
  43. /*                                                                            */
  44. /*--------------------------------------------------------------------------*/
  45.  
  46. #include <stdio.h>
  47. #include <stdlib.h>
  48. #include <ctype.h>
  49. #include <string.h>
  50. /* #include <signal.h> */
  51. /* #include <conio.h> */
  52.  
  53. #include "bink.h"
  54. /* #include "prototyp.h" */
  55. #include "msgs.h"
  56. #include "com.h"
  57. #include "zmodem.h"
  58. #include "sbuf.h"
  59. #include "sched.h"
  60. #include "nodeproc.h"
  61.  
  62. static int dial_modem (char *);
  63. static void phone_translate (char *, char *);
  64. static char *get_response (long);
  65. static int parse_response (char *);
  66. static void empty_delay (void);
  67.  
  68. #undef FAILURE
  69. #define FAILURE   0
  70. #define IGNORE      1
  71. #define CONNECTED 2
  72. #define RINGING   3
  73. #define INCOMING  4
  74. #define FAX           5
  75.  
  76. struct resp_str
  77. {
  78.     char *resp;
  79.     unsigned disp;
  80. };
  81.  
  82. static struct resp_str mdm_resps[] = 
  83. {
  84.     { "RINGING",         1 },
  85.     { "RING RESPONSE",     1 },
  86.     { "RING",             3 },
  87.     { "+FCON",          5 },
  88.     { "FCON",           5 },
  89.     { "CONNECT FAX",    5 },
  90.     { "CONNECT",         2 },
  91.     { "V.23 CONNECT",    2 },
  92.     { "RRING",             1 },
  93.     { "BUSY",             0 },
  94.     { "VOICE",             0 },
  95.     { "ERROR",             0 },
  96.     { "OK",             0 },
  97.     { "NO CARRIER",     0 },
  98.     { "NO DIAL",         0 },    /* "NO DIAL TONE" or "NO DIALTONE" */ 
  99.     { "DIALING",         1 },
  100.     { "NO ANSWER",         0 },
  101.     { "DIAL TONE",         1 },
  102.     { NULL,             0 }
  103. };
  104.  
  105. void do_dial_strings ()
  106. {
  107.     MDM_TRNS *m;
  108.  
  109.     predial = normprefix;
  110.     postdial = normsuffix;
  111.  
  112.  
  113.     if(node_prefix)                 /* This is set by nodefind */
  114.     {
  115.         predial = node_prefix;
  116.         return;
  117.     }
  118.  
  119.     m = mm_head;
  120.     while (m != NULL)
  121.     {
  122.         if (m->mdm & newnodedes.ModemType)
  123.         {
  124.             predial = m->pre;
  125.             postdial = m->suf;
  126.             return;
  127.         }
  128.         m = m->next;
  129.     }
  130. }
  131.  
  132. void try_2_connect (char *phnum)
  133. {
  134.     long t1;
  135.     int j, k;
  136.  
  137.     for (j = 0; (j < poll_tries && !KEYPRESS ()); j++)         /* do polltries or till keypress */
  138.     {
  139.         CLEAR_INBOUND ();
  140.         k = dial_modem (phnum);
  141.  
  142.         if ((un_attended || doing_poll) && fullscreen)
  143.         {
  144.             ++hist.calls_made;
  145.             sb_move (historywin, HIST_ATT_ROW, HIST_COL);
  146.             (void) sprintf (junk, "%-4d", hist.calls_made);
  147.             sb_puts (historywin, (unsigned char *) junk);
  148.         }
  149.  
  150.         if ((k > 0) || KEYPRESS ())
  151.             break;
  152. #ifndef NEW
  153.         hang_up();        /* Futile attempt to save having to set the baud rate again */
  154. #else
  155.         mdm_hangup();    /* Added from 2.50 */
  156. #endif
  157. #ifdef NEW    /* SWG 29jun91 : What is this delay for???? */
  158.         t1 = timerset (poll_delay * 10L);                /* time is give in 10th seconds */
  159.         while (!timeup (t1) && !KEYPRESS () && (PEEKBYTE() == -1))
  160.             time_release ();                                /* pause for 2 seconds */
  161. #endif
  162.     }
  163.     if (KEYPRESS ())                                      /* If user's been busy */
  164.     {
  165. #ifndef NEW /* Don't lose key! */
  166.         if (!caller)
  167.             (void) FOSSIL_CHAR ();                                 /* Eat the character    */
  168. #endif
  169.         if (!CARRIER)                                          /* Abort if no carrier */
  170.         {
  171.             status_line (msgtxt[M_CONNECT_ABORTED]);
  172.             mdm_hangup ();
  173.         }
  174.     }
  175.  
  176.     predial = normprefix;
  177.     postdial = normsuffix;
  178. }
  179.  
  180. int try_1_connect (phnum)
  181. char *phnum;
  182. {
  183.     int k;
  184.  
  185.     if ((k = dial_modem (phnum)) <= 0)
  186.     {
  187.         mdm_hangup ();
  188.     }
  189.  
  190.     if ((un_attended || doing_poll) && fullscreen)
  191.     {
  192.         ++hist.calls_made;
  193.         sb_move (historywin, HIST_ATT_ROW, HIST_COL);
  194.         (void) sprintf (junk, "%-4d", hist.calls_made);
  195.         sb_puts (historywin, (unsigned char *) junk);
  196.     }
  197.  
  198.     predial = normprefix;
  199.     postdial = normsuffix;
  200.  
  201.     return (k);
  202. }
  203.  
  204. static void phone_translate (number, translated)
  205. char *number;
  206. char *translated;
  207. {
  208.     PN_TRNS *p;
  209.     int suffix_position;    /* Position in number to test for Suffix */
  210.  
  211.     (void) strcpy (translated, number);
  212.     for (p = pn_head; p != NULL; p = p->next)
  213.     {
  214.         suffix_position = (int) (strlen (number) - p->suflen);
  215.         if (suffix_position < 0) suffix_position = 0;
  216.         
  217.         if (strncmp (p->prenum, number, p->prelen) == 0 &&
  218.             strncmp (p->sufnum, number + suffix_position, p->suflen) == 0
  219.            )
  220.         {
  221.             *(number + suffix_position) = '\0';
  222.             (void) sprintf (translated, "%s%s%s", p->prematch, &(number[p->prelen]), p->sufmatch);
  223.             break;
  224.         }
  225.     }
  226. }
  227.  
  228. static int dial_modem (char *number)
  229. {
  230.     int resp;
  231.     long t;
  232.     char translated[50];
  233.  
  234.     if (!*number)
  235.     {
  236.         status_line (msgtxt[M_BAD_NUMBER], Pretty_Addr_Str (&called_addr));
  237.         return (1);
  238.     }
  239.     
  240.     janus_OK = 0;
  241.     phone_translate (number, translated);
  242.     if (translated[0] == '\"')                            /* If it's a script          */
  243.         return (do_script (translated));               /* then do it that way        */
  244.  
  245.     status_line (msgtxt[M_DIALING_NUMBER], translated);
  246.     if (un_attended && fullscreen)
  247.     {
  248.         do_ready (msgtxt[M_READY_DIALING]);
  249.     }
  250.  
  251.     /* First of all, if we have something, don't hang up on the guy! */
  252.     if (!no_collide && CHAR_AVAIL ())
  253.         return (-1);
  254.  
  255.     if (dial_setup != NULL)
  256.     {
  257.         mdm_cmd_string (dial_setup, 1);
  258.     }
  259.     else
  260.     {
  261. #ifdef NEW /* FASTMODEM  10.09.1989 */
  262.       hang_up ();
  263. #else
  264.         DTR_OFF ();                                        /* drop DTR to reset modem    */
  265.         timer (20);                                        /* leave it down 2 seconds    */
  266. #endif
  267.         DTR_ON ();                                            /* then raise DTR again      */
  268.         timer (5);                                            /* and wait .5 sec for modem */
  269.     }
  270.  
  271.     if (!no_collide && CHAR_AVAIL ())            /* If we have something here, return */
  272.         return (-1);
  273.  
  274.     mdm_cmd_string (predial, 0);                /* transmit the dial prefix  */
  275.     mdm_cmd_string (translated, 0);             /* then the phone number     */
  276.     mdm_cmd_string (postdial, 0);                /* finally the dial suffix     */
  277.     if (no_collide)
  278.         CLEAR_INBOUND ();                        /* Throw out all echo to this point  */
  279.     mdm_cmd_char (CR);                            /* terminate the string      */
  280.  
  281.     resp = modem_response (7500);
  282.     if (resp)                                    /* we got a good response,     */
  283.     {
  284.         if (resp == 3)                            /* Incoming ring to be processed higher up */
  285.             return (-1);
  286.  
  287. #ifdef NEW    /* Why waste 2 seconds waiting for character? */
  288.         t = timerset(200);
  289.         while(!timeup(t) && !CARRIER && !KEYPRESS())
  290.             time_release ();
  291. #else
  292.         t = timerset (200);                             /* Wait up to 20 seconds      */
  293.         while (!timeup (t))
  294.         {                                               /* If carrier detect, AND    */
  295. #ifdef NEW    /* AbortCall SWG 24 June 91 */
  296.             if (KEYPRESS() || ((CHAR_AVAIL ()) && CARRIER))                      /* some sign of life, */
  297. #else
  298.             if ((CHAR_AVAIL ()) && CARRIER)                      /* some sign of life, */
  299. #endif
  300.                 break;                                           /* leave early...            */
  301.         }
  302. #endif
  303.         return ((int) CARRIER);                               /* Carrier should be on now  */
  304.     }
  305.     return (0);                                    /* no good */
  306. }
  307.  
  308. static char *get_response (long end_time)
  309. {
  310.     static char response_string[30];
  311.     char *p = response_string;                        /* points to character cell  */
  312.     char c;                                        /* current modem character    */
  313.     int count = 0;                                    /* count of characters         */
  314.  
  315.     while ((count < 50)                                /* until we have 50 chars,    */
  316.         && (!timeup (end_time))                     /* or out of time,             */
  317.         && (!KEYPRESS ()))                             /* or user gets impatient      */
  318.     {
  319.         if (!CHAR_AVAIL ())                                 /* if nothing ready yet,     */
  320.         {
  321.             time_release ();
  322.             continue;                                           /* just process timeouts     */
  323.         }
  324.         c = (char) (MODEM_IN () & 0xff);                   /* get a character            */
  325.         if (c == '\r' || c == '\n')                         /* if a line ending          */
  326.         {
  327.             if (count != 0)                                      /* and we have something,      */
  328.                 break;                                           /* get out                    */
  329.             else continue;                                      /* otherwise just keep going */
  330.         }
  331.         *p++ = c;                                          /* store the character       */
  332.         ++count;                                           /* increment the counter     */
  333.     }
  334.     *p = '\0';                                        /* terminate the new string  */
  335.  
  336.     if (count != 0 && strnicmp (response_string, "AT", 2))
  337.     {
  338.         fancy_str (response_string);                    /* make it pretty            */
  339.         status_line ("#%s", response_string);             /* pop it out on the screen  */
  340.     }
  341.  
  342.     return (response_string);                         /* return the pointer          */
  343. }
  344.  
  345. static int parse_response (response)
  346. char *response;
  347. {
  348.     char *p;                                          /* temp character pointer    */
  349.     register int i;                                /* array pointer             */
  350.  
  351.     for (i = 0; mdm_resps[i].resp != NULL; i++)        /* scan through array        */
  352.     {
  353.         p = mdm_resps[i].resp;                       /* point at possible
  354.                                                           * response */
  355.         if (strnicmp (response, p, strlen (p)) == 0)                  /* if a match,               */
  356.             return ((int) (mdm_resps[i].disp));                  /* return disposition of it  */
  357.     }
  358.     
  359.     if (fax_connect && strnicmp (response, fax_connect, strlen(fax_connect) == 0))
  360.         return (int)FAX;
  361.         
  362.     return (IGNORE);                                    /* ignore all unknowns        */
  363. }
  364.  
  365.  
  366. /*
  367.  * given the Modem connect string work out the baud rate, MNP, etc
  368.  * work out whether Janus is allowed
  369.  */
  370.  
  371. void setModemValues(char *s)
  372. {
  373.     unsigned int baudrate;
  374.  
  375.     if ((s == NULL) || (*s == '\0'))          /* if nothing there,          */
  376.     {
  377.         baudrate = 300;                           /* say that it's 300 baud    */
  378.     }
  379.     else
  380.     {
  381.         baudrate = atoi(s);                   /* else do baudrate fallback */
  382.  
  383.         /* For 1200/75 split speed modems and "Connect 212" */
  384.  
  385.         if ((baudrate == 1275) || (baudrate == 7512)
  386.             ||    (baudrate == 75) || (baudrate == 212) || (baudrate == 12))
  387.             baudrate = 1200;
  388.  
  389.         /* For "Connect 103" */
  390.  
  391.         if (baudrate == 103)
  392.             baudrate = 300;
  393.     }
  394.  
  395.     while (isdigit (*s))                    /* Get past digits           */
  396.         ++s;
  397.     s = skip_blanks(s);                        /* Get rid of blanks          */
  398.  
  399. #ifdef NEW    /* HSTV42  03.09.1990 */
  400.     if (*s != '\0')
  401.     {
  402.        if (strnicmp (s, "/None", 5) == 0)
  403.           *s = '\0';
  404.     }
  405. #endif
  406.     if (*s != '\0')                         /* We have "reliable" info.  */
  407.     {                                               
  408.         strcpy (mdm_reliable, s);            /* Copy in the info          */
  409.         can_Janus (mdm_reliable);            /* Set the flag for Janus      */
  410.     }
  411.  
  412.     if (baudrate)
  413.         set_baud (baudrate, 1);
  414. }
  415.  
  416. /*
  417.  * Wait for modem response
  418.  * ths is time in milliseconds to wait
  419.  */
  420.  
  421. int modem_response (int ths)
  422. {
  423.     long end_time;                                    /* holds time at end of 2min */
  424.     char *response;                                    /* pointer to modem response */
  425.     char *c;                                        /* miscellaneous pointer      */
  426.     int result = IGNORE;                            /* result code               */
  427.  
  428.     /* If this modem doesn't differentiate between RING and RINGING */
  429.     if (modemring)
  430.         mdm_resps[0].disp = IGNORE;
  431.  
  432.     end_time = timerset ((long)ths);                /* arm the timeout             */
  433.     while ((result == IGNORE)                        /* until success or failure, */
  434.         && (!timeup (end_time))                     /* or out of time,             */
  435.         && (!KEYPRESS ()))                            /* or user gets impatient      */
  436.     {
  437.         response = get_response (end_time);         /* get a response             */
  438.         result = parse_response (response);         /* parse, determine status     */
  439.         time_release ();
  440.     }
  441.  
  442.     if (result == CONNECTED || result == FAX)        /* Got to be a CONNECT msg     */
  443.     {
  444.         mdm_reliable[0] = '\0';                        /* Start with nothing          */
  445.  
  446.         if (strnicmp (response, "connect", 7) == 0)    /* if this is a CONNECT,     */
  447.         {
  448.             c = skip_blanks (&response[7]);            /* get past the blanks       */
  449.  
  450.             setModemValues(c);
  451.         }
  452.         else
  453.         if(strnicmp(response, "v.23", 4) == 0)
  454.         {
  455.             int baudrate = 1200;
  456.             set_baud (baudrate, 1);
  457.             mdm_reliable[0] = 0;
  458.             /* can_Janus(mdm_reliable); */
  459.         }
  460.  
  461.         if (result == CONNECTED) MNP_Filter ();
  462.     }
  463.     return (result);                                /* timeout or failure or OK  */
  464. }
  465.  
  466. void mdm_cmd_string (mdm_cmd, dospace)
  467. char *mdm_cmd;
  468. int dospace;
  469. {
  470.     register char *c;
  471.  
  472.     if (mdm_cmd == NULL)                                  /* defense from shit           */
  473.         return;
  474.  
  475.     for (c = mdm_cmd; *c; c++)
  476.     {
  477.         if (dospace || (*c && !isspace (*c)))                          /* don't output spaces       */
  478.             mdm_cmd_char (*c);                              /* output the next character */
  479.     }
  480. }
  481.  
  482. static void empty_delay ()
  483. {
  484.     long t;
  485.  
  486.     t = timerset (500);
  487.     while ((!OUT_EMPTY ()) && (!timeup (t)))
  488.         time_release ();                               /* wait for output to finish */
  489.  
  490.     if (!OUT_EMPTY ())
  491.     {
  492.         MDM_DISABLE ();
  493.         (void) Cominit (port_ptr);
  494.         MDM_ENABLE (lock_baud && (btypes[baud].rate_value >= lock_baud) ? max_baud.rate_mask : btypes[baud].rate_mask);
  495.         DTR_ON ();
  496.         CLEAR_OUTBOUND ();
  497.         CLEAR_INBOUND ();
  498.         if (un_attended && fullscreen)
  499.         {
  500.             sb_dirty ();
  501.             sb_show ();
  502.         }
  503.     }
  504. }
  505.  
  506. void mdm_cmd_char (outchr)
  507. int outchr;
  508. {
  509.  
  510.     switch (outchr)
  511.     {
  512.     case '-':                                        /* if it's a dash (phone no) */
  513.         return;                                      /* ignore it                  */
  514.  
  515.     case '|':                                        /* if the CR character,      */
  516.         outchr = CR;                                    /* substitute a real CR here */
  517.         break;
  518.  
  519.     case '~':                                        /* if the "delay" character, */
  520.         empty_delay ();                              /* wait for buffer to clear, */
  521.         timer (10);                                  /* then wait 1 second          */
  522.         return;                                      /* and return                  */
  523.  
  524.     case '^':                                         /* Raise DTR                  */
  525.         empty_delay ();                              /* wait for buffer to clear, */
  526.         DTR_ON ();                                      /* Turn on DTR               */
  527.         return;                                      /* and return                  */
  528.  
  529.     case 'v':                                         /* Lower DTR             */
  530.         empty_delay ();                              /* wait for buffer to clear, */
  531.         DTR_OFF ();                                  /* Turn off DTR              */
  532.         return;                                      /* and return                  */
  533.  
  534.     case '`':                                         /* Short delay          */
  535.         timer (1);                                      /* short pause, .1 second    */
  536.         return;                                      /* and return                  */
  537.  
  538.     default:
  539.         break;
  540.     }
  541.  
  542.     SENDBYTE ((unsigned char) outchr);                /* then write the character  */
  543.  
  544.     if (outchr == CR)                                     /* if it was a CR,           */
  545.     {
  546.         empty_delay ();
  547.         timer (1);                                         /* allow .1 sec line quiet   */
  548.     }
  549.     else if (slowmodem)
  550.     {
  551.         timer (1);                                         /* wait .1 sec for output      */
  552.     }
  553. }
  554.  
  555. void mdm_hangup ()
  556. {
  557.  
  558.     /*
  559.     * First, if a dial command is in progress, try to get the modem to abort
  560.     * it...
  561.         */
  562.  
  563.     CLEAR_OUTBOUND ();
  564.     CLEAR_INBOUND ();
  565.  
  566.     if (un_attended && fullscreen)
  567.     {
  568.         do_ready (msgtxt[M_READY_HANGUP]);
  569.     }
  570.     else
  571.     {
  572.         status_line (msgtxt[M_MODEM_HANGUP]);              /* Tell what we are doing */
  573.     }
  574.  
  575.     mdm_init (modem_init);                            /* re-initialize the modem     */
  576.     timer (5);                                        /* Wait another .5 sec         */
  577.  
  578.     /*set_xy ("");*/
  579.     CLEAR_INBOUND ();                                 /* then flush input and exit */
  580. }
  581.  
  582. void mdm_init (str)
  583. char *str;
  584. {
  585.     CLEAR_OUTBOUND ();
  586.     CLEAR_INBOUND ();
  587.     if (init_setup != NULL)
  588.     {
  589.         (void) set_baud (max_baud.rate_value, 0);
  590.         mdm_cmd_string (init_setup, 1);
  591.     }
  592.     else
  593.     {
  594.         mdm_cmd_char (CR);                                    /* output a CR, then         */
  595. #ifdef NEW /* FASTMODEM  10.09.1989 */
  596.       hang_up ();
  597. #else
  598.         DTR_OFF ();                                        /* Drop DTR to hangup        */
  599.         timer (10);                                        /* Hold it down for 1 sec    */
  600. #endif
  601.         DTR_ON ();                                            /* Raise DTR,                 */
  602.         timer (5);                                      /* Then hold it up for .5
  603.                                                           * sec */
  604.         (void) set_baud (max_baud.rate_value, 0);
  605.  
  606.         mdm_cmd_char (' ');                                /* output a space            */
  607.         mdm_cmd_char (CR);                                    /* then another CR             */
  608.     }
  609.     mdm_cmd_string (str, 0);                      /* then the modem init
  610.                                                       * string */
  611. #ifdef NEW    /* NOOK  01.09.1990 */
  612.    timer (10);                                     /* Hold DTR for 1 sec more  */
  613. #else
  614.     timer (5);                                        /* Hold DTR for .5 sec more  */
  615. #endif
  616.     CLEAR_INBOUND ();                                 /* then flush input and exit */
  617. }
  618.  
  619. void send_break (t)
  620. int t;
  621. {
  622.     long t1;
  623.  
  624.     t1 = timerset ((long)t);
  625.     do_break (1);
  626.     while (!timeup (t1))
  627.         time_release ();
  628.     do_break (0);
  629. }
  630.  
  631. void exit_DTR ()
  632. {
  633.     if (!leave_dtr_high)
  634.         DTR_OFF ();
  635. }
  636.  
  637. #define MNP_QTIME 300            /* 2 Second quiet time */
  638. #define MNP_MAXTIME 1000        /* 10 Seconds Maximum */
  639.  
  640. void MNP_Filter ()
  641. {
  642.     long t, t1;
  643.     int c;
  644.     BOOLEAN flag = FALSE;        /* Only allow one message to be displayed */
  645.  
  646.     /*
  647.      * Wait up to a second for CARRIER to appear since it gets
  648.      * here straight after CONNECT
  649.      */
  650.  
  651.     t = timerset (100);      /* at most a one second delay    */
  652.  
  653.     while (!CARRIER && !timeup (t))
  654.         ;
  655.  
  656.     t1 = timerset (MNP_QTIME);        /* Quiet time needed */
  657.     t = timerset (MNP_MAXTIME);     /* Overall timer */
  658.  
  659.     /*
  660.      * Loop for either:
  661.      *    10 seconds (t)
  662.      *    1 second of quiet time (t1)
  663.      *    user abort (keypress)
  664.      */
  665.  
  666.     while (CARRIER && !timeup (t) && !timeup(t1))
  667.     {
  668.         if(KEYPRESS())            /* User abort */
  669.         {
  670.             DTR_OFF();
  671.             break;
  672.         }
  673.  
  674.         /*
  675.          * If there are any characters from the modem then reset the
  676.          * quiet timer
  677.          */
  678.         
  679.         if ((c = PEEKBYTE ()) != -1)
  680.         {
  681.             TIMED_READ(0);
  682.  
  683.             /* If we get an MNP or v.42 character, eat it and wait for clear line */
  684.  
  685.             if ((c != 0) && ((strchr (BadChars, c) != NULL) || (strchr (BadChars, c&0x7f) != NULL)))
  686.             {
  687.                 t1 = timerset (MNP_QTIME);
  688.                 if(!flag)
  689.                     status_line (msgtxt[M_FILTER]);
  690.                 flag = TRUE;
  691.             }
  692.         }
  693.     }
  694. }
  695.  
  696. #ifdef NEW /* FASTMODEM  10.09.1989 */
  697. void hang_up ()
  698. {
  699.     long t;
  700.  
  701.     t = timerset(30);  /* max 3 seconds */
  702.     DTR_OFF ();
  703.     while (CARRIER && !timeup(t))
  704.        time_release ();
  705.     timer(2);
  706. }
  707. #endif
  708.  
  709.