home *** CD-ROM | disk | FTP | other *** search
/ Crawly Crypt Collection 2 / crawlyvol2.bin / program / c / bts314b4 / mdm_proc.c < prev    next >
C/C++ Source or Header  |  1994-01-08  |  19KB  |  703 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( void )
  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( char *phnum )
  181. {
  182.     int k;
  183.  
  184.     if ((k = dial_modem (phnum)) <= 0)
  185.     {
  186.         mdm_hangup ();
  187.     }
  188.  
  189.     if ((un_attended || doing_poll) && fullscreen)
  190.     {
  191.         ++hist.calls_made;
  192.         sb_move (historywin, HIST_ATT_ROW, HIST_COL);
  193.         (void) sprintf (junk, "%-4d", hist.calls_made);
  194.         sb_puts (historywin, (unsigned char *) junk);
  195.     }
  196.  
  197.     predial = normprefix;
  198.     postdial = normsuffix;
  199.  
  200.     return (k);
  201. }
  202.  
  203. static void phone_translate (number, translated)
  204. char *number;
  205. char *translated;
  206. {
  207.     PN_TRNS *p;
  208.     int suffix_position;    /* Position in number to test for Suffix */
  209.  
  210.     (void) strcpy (translated, number);
  211.     for (p = pn_head; p != NULL; p = p->next)
  212.     {
  213.         suffix_position = (int) (strlen (number) - p->suflen);
  214.         if (suffix_position < 0) suffix_position = 0;
  215.         
  216.         if (strncmp (p->prenum, number, p->prelen) == 0 &&
  217.             strncmp (p->sufnum, number + suffix_position, p->suflen) == 0
  218.            )
  219.         {
  220.             *(number + suffix_position) = '\0';
  221.             (void) sprintf (translated, "%s%s%s", p->prematch, &(number[p->prelen]), p->sufmatch);
  222.             break;
  223.         }
  224.     }
  225. }
  226.  
  227. static int dial_modem (char *number)
  228. {
  229.     int resp;
  230.     long t;
  231.     char translated[50];
  232.  
  233.     if (!*number)
  234.     {
  235.         status_line (msgtxt[M_BAD_NUMBER], Pretty_Addr_Str (&called_addr));
  236.         return (1);
  237.     }
  238.     
  239.     janus_OK = 0;
  240.     phone_translate (number, translated);
  241.     if (translated[0] == '\"')                            /* If it's a script          */
  242.         return (do_script (translated));               /* then do it that way        */
  243.  
  244.     status_line (msgtxt[M_DIALING_NUMBER], translated);
  245.     if (un_attended && fullscreen)
  246.     {
  247.         do_ready (msgtxt[M_READY_DIALING]);
  248.     }
  249.  
  250.     /* First of all, if we have something, don't hang up on the guy! */
  251.     if (!no_collide && CHAR_AVAIL ())
  252.         return (-1);
  253.  
  254.     if (dial_setup != NULL)
  255.     {
  256.         mdm_cmd_string (dial_setup, 1);
  257.     }
  258.     else
  259.     {
  260. #ifdef NEW /* FASTMODEM  10.09.1989 */
  261.       hang_up ();
  262. #else
  263.         DTR_OFF ();                                        /* drop DTR to reset modem    */
  264.         timer (20);                                        /* leave it down 2 seconds    */
  265. #endif
  266.         DTR_ON ();                                            /* then raise DTR again      */
  267.         timer (5);                                            /* and wait .5 sec for modem */
  268.     }
  269.  
  270.     if (!no_collide && CHAR_AVAIL ())            /* If we have something here, return */
  271.         return (-1);
  272.  
  273.     mdm_cmd_string (predial, 0);                /* transmit the dial prefix  */
  274.     mdm_cmd_string (translated, 0);             /* then the phone number     */
  275.     mdm_cmd_string (postdial, 0);                /* finally the dial suffix     */
  276.     if (no_collide)
  277.         CLEAR_INBOUND ();                        /* Throw out all echo to this point  */
  278.     mdm_cmd_char (CR);                            /* terminate the string      */
  279.  
  280.     resp = modem_response (7500);
  281.     if (resp)                                    /* we got a good response,     */
  282.     {
  283.         if (resp == 3)                            /* Incoming ring to be processed higher up */
  284.             return (-1);
  285.  
  286. #ifdef NEW    /* Why waste 2 seconds waiting for character? */
  287.         t = timerset(200);
  288.         while(!timeup(t) && !CARRIER && !KEYPRESS())
  289.             time_release ();
  290. #else
  291.         t = timerset (200);                             /* Wait up to 20 seconds      */
  292.         while (!timeup (t))
  293.         {                                               /* If carrier detect, AND    */
  294. #ifdef NEW    /* AbortCall SWG 24 June 91 */
  295.             if (KEYPRESS() || ((CHAR_AVAIL ()) && CARRIER))                      /* some sign of life, */
  296. #else
  297.             if ((CHAR_AVAIL ()) && CARRIER)                      /* some sign of life, */
  298. #endif
  299.                 break;                                           /* leave early...            */
  300.         }
  301. #endif
  302.         return ((int) CARRIER);                               /* Carrier should be on now  */
  303.     }
  304.     return (0);                                    /* no good */
  305. }
  306.  
  307. static char *get_response (long end_time)
  308. {
  309.     static char response_string[30];
  310.     char *p = response_string;                        /* points to character cell  */
  311.     char c;                                        /* current modem character    */
  312.     int count = 0;                                    /* count of characters         */
  313.  
  314.     while ((count < 50)                                /* until we have 50 chars,    */
  315.         && (!timeup (end_time))                     /* or out of time,             */
  316.         && (!KEYPRESS ()))                             /* or user gets impatient      */
  317.     {
  318.         if (!CHAR_AVAIL ())                                 /* if nothing ready yet,     */
  319.         {
  320.             time_release ();
  321.             continue;                                           /* just process timeouts     */
  322.         }
  323.         c = (char) (MODEM_IN () & 0xff);                   /* get a character            */
  324.         if (c == '\r' || c == '\n')                         /* if a line ending          */
  325.         {
  326.             if (count != 0)                                      /* and we have something,      */
  327.                 break;                                           /* get out                    */
  328.             else continue;                                      /* otherwise just keep going */
  329.         }
  330.         *p++ = c;                                          /* store the character       */
  331.         ++count;                                           /* increment the counter     */
  332.     }
  333.     *p = '\0';                                        /* terminate the new string  */
  334.  
  335.     if (count != 0 && strnicmp (response_string, "AT", 2))
  336.     {
  337.         fancy_str (response_string);                    /* make it pretty            */
  338.         status_line ("#%s", response_string);             /* pop it out on the screen  */
  339.     }
  340.  
  341.     return (response_string);                         /* return the pointer          */
  342. }
  343.  
  344. static int parse_response (response)
  345. char *response;
  346. {
  347.     char *p;                                          /* temp character pointer    */
  348.     register int i;                                /* array pointer             */
  349.  
  350.     for (i = 0; mdm_resps[i].resp != NULL; i++)        /* scan through array        */
  351.     {
  352.         p = mdm_resps[i].resp;                       /* point at possible
  353.                                                           * response */
  354.         if (strnicmp (response, p, strlen (p)) == 0)                  /* if a match,               */
  355.             return ((int) (mdm_resps[i].disp));                  /* return disposition of it  */
  356.     }
  357.     
  358.     if (fax_connect && strnicmp (response, fax_connect, strlen(fax_connect) == 0))
  359.         return (int)FAX;
  360.         
  361.     return (IGNORE);                                    /* ignore all unknowns        */
  362. }
  363.  
  364.  
  365. /*
  366.  * given the Modem connect string work out the baud rate, MNP, etc
  367.  * work out whether Janus is allowed
  368.  */
  369.  
  370. void setModemValues( char *s )
  371. {
  372.     unsigned int baudrate;
  373.  
  374.     if ((s == NULL) || (*s == '\0'))          /* if nothing there,          */
  375.     {
  376.         baudrate = 300;                           /* say that it's 300 baud    */
  377.     }
  378.     else
  379.     {
  380.         baudrate = atoi(s);                   /* else do baudrate fallback */
  381.  
  382.         /* For 1200/75 split speed modems and "Connect 212" */
  383.  
  384.         if ((baudrate == 1275) || (baudrate == 7512)
  385.             ||    (baudrate == 75) || (baudrate == 212) || (baudrate == 12))
  386.             baudrate = 1200;
  387.  
  388.         /* For "Connect 103" */
  389.  
  390.         if (baudrate == 103)
  391.             baudrate = 300;
  392.     }
  393.  
  394.     while (isdigit (*s))                    /* Get past digits           */
  395.         ++s;
  396.     s = skip_blanks(s);                        /* Get rid of blanks          */
  397.  
  398. #ifdef NEW    /* HSTV42  03.09.1990 */
  399.     if (*s != '\0')
  400.     {
  401.        if (strnicmp (s, "/None", 5) == 0)
  402.           *s = '\0';
  403.     }
  404. #endif
  405.     if (*s != '\0')                         /* We have "reliable" info.  */
  406.     {                                               
  407.         strcpy (mdm_reliable, s);            /* Copy in the info          */
  408.         can_Janus (mdm_reliable);            /* Set the flag for Janus      */
  409.     }
  410.  
  411.     if (baudrate)
  412.         set_baud (baudrate, 1);
  413. }
  414.  
  415. /*
  416.  * Wait for modem response
  417.  * ths is time in milliseconds to wait
  418.  */
  419.  
  420. int modem_response( int ths )
  421. {
  422.     long end_time;                                    /* holds time at end of 2min */
  423.     char *response;                                    /* pointer to modem response */
  424.     char *c;                                        /* miscellaneous pointer      */
  425.     int result = IGNORE;                            /* result code               */
  426.  
  427.     /* If this modem doesn't differentiate between RING and RINGING */
  428.     if (modemring)
  429.         mdm_resps[0].disp = IGNORE;
  430.  
  431.     end_time = timerset ((long)ths);                /* arm the timeout             */
  432.     while ((result == IGNORE)                        /* until success or failure, */
  433.         && (!timeup (end_time))                     /* or out of time,             */
  434.         && (!KEYPRESS ()))                            /* or user gets impatient      */
  435.     {
  436.         response = get_response (end_time);         /* get a response             */
  437.         result = parse_response (response);         /* parse, determine status     */
  438.         time_release ();
  439.     }
  440.  
  441.     if (result == CONNECTED || result == FAX)        /* Got to be a CONNECT msg     */
  442.     {
  443.         mdm_reliable[0] = '\0';                        /* Start with nothing          */
  444.  
  445.         if (strnicmp (response, "connect", 7) == 0)    /* if this is a CONNECT,     */
  446.         {
  447.             c = skip_blanks (&response[7]);            /* get past the blanks       */
  448.  
  449.             setModemValues(c);
  450.         }
  451.         else
  452.         if(strnicmp(response, "v.23", 4) == 0)
  453.         {
  454.             int baudrate = 1200;
  455.             set_baud (baudrate, 1);
  456.             mdm_reliable[0] = 0;
  457.             /* can_Janus(mdm_reliable); */
  458.         }
  459.  
  460.         if (result == CONNECTED) MNP_Filter ();
  461.     }
  462.     return (result);                                /* timeout or failure or OK  */
  463. }
  464.  
  465. void mdm_cmd_string( char *mdm_cmd, int dospace )
  466. {
  467.     register char *c;
  468.  
  469.     if (mdm_cmd == NULL)                                  /* defense from shit           */
  470.         return;
  471.  
  472.     for (c = mdm_cmd; *c; c++)
  473.     {
  474.         if (dospace || (*c && !isspace (*c)))                          /* don't output spaces       */
  475.             mdm_cmd_char (*c);                              /* output the next character */
  476.     }
  477. }
  478.  
  479. static void empty_delay( void )
  480. {
  481.     long t;
  482.  
  483.     t = timerset (500);
  484.     while ((!OUT_EMPTY ()) && (!timeup (t)))
  485.         time_release ();                               /* wait for output to finish */
  486.  
  487.     if (!OUT_EMPTY ())
  488.     {
  489.         MDM_DISABLE ();
  490.         (void) Cominit (port_ptr);
  491.         MDM_ENABLE (lock_baud && (btypes[baud].rate_value >= lock_baud) ? max_baud.rate_mask : btypes[baud].rate_mask);
  492.         DTR_ON ();
  493.         CLEAR_OUTBOUND ();
  494.         CLEAR_INBOUND ();
  495.         if (un_attended && fullscreen)
  496.         {
  497.             sb_dirty ();
  498.             sb_show ();
  499.         }
  500.     }
  501. }
  502.  
  503. void mdm_cmd_char( int outchr )
  504. {
  505.  
  506.     switch (outchr)
  507.     {
  508.     case '-':                                        /* if it's a dash (phone no) */
  509.         return;                                      /* ignore it                  */
  510.  
  511.     case '|':                                        /* if the CR character,      */
  512.         outchr = CR;                                    /* substitute a real CR here */
  513.         break;
  514.  
  515.     case '~':                                        /* if the "delay" character, */
  516.         empty_delay ();                              /* wait for buffer to clear, */
  517.         timer (10);                                  /* then wait 1 second          */
  518.         return;                                      /* and return                  */
  519.  
  520.     case '^':                                         /* Raise DTR                  */
  521.         empty_delay ();                              /* wait for buffer to clear, */
  522.         DTR_ON ();                                      /* Turn on DTR               */
  523.         return;                                      /* and return                  */
  524.  
  525.     case 'v':                                         /* Lower DTR             */
  526.         empty_delay ();                              /* wait for buffer to clear, */
  527.         DTR_OFF ();                                  /* Turn off DTR              */
  528.         return;                                      /* and return                  */
  529.  
  530.     case '`':                                         /* Short delay          */
  531.         timer (1);                                      /* short pause, .1 second    */
  532.         return;                                      /* and return                  */
  533.  
  534.     default:
  535.         break;
  536.     }
  537.  
  538.     SENDBYTE ((unsigned char) outchr);                /* then write the character  */
  539.  
  540.     if (outchr == CR)                                     /* if it was a CR,           */
  541.     {
  542.         empty_delay ();
  543.         timer (1);                                         /* allow .1 sec line quiet   */
  544.     }
  545.     else if (slowmodem)
  546.     {
  547.         timer (1);                                         /* wait .1 sec for output      */
  548.     }
  549. }
  550.  
  551. void mdm_hangup( void )
  552. {
  553.  
  554.     /*
  555.     * First, if a dial command is in progress, try to get the modem to abort
  556.     * it...
  557.         */
  558.  
  559.     CLEAR_OUTBOUND ();
  560.     CLEAR_INBOUND ();
  561.  
  562.     if (un_attended && fullscreen)
  563.     {
  564.         do_ready (msgtxt[M_READY_HANGUP]);
  565.     }
  566.     else
  567.     {
  568.         status_line (msgtxt[M_MODEM_HANGUP]);              /* Tell what we are doing */
  569.     }
  570.  
  571.     mdm_init (modem_init);                            /* re-initialize the modem     */
  572.     timer (5);                                        /* Wait another .5 sec         */
  573.  
  574.     /*set_xy ("");*/
  575.     CLEAR_INBOUND ();                                 /* then flush input and exit */
  576. }
  577.  
  578. void mdm_init( char *str )
  579. {
  580.     CLEAR_OUTBOUND ();
  581.     CLEAR_INBOUND ();
  582.     if (init_setup != NULL)
  583.     {
  584.         (void) set_baud (max_baud.rate_value, 0);
  585.         mdm_cmd_string (init_setup, 1);
  586.     }
  587.     else
  588.     {
  589.         mdm_cmd_char (CR);                                    /* output a CR, then         */
  590. #ifdef NEW /* FASTMODEM  10.09.1989 */
  591.       hang_up ();
  592. #else
  593.         DTR_OFF ();                                        /* Drop DTR to hangup        */
  594.         timer (10);                                        /* Hold it down for 1 sec    */
  595. #endif
  596.         DTR_ON ();                                            /* Raise DTR,                 */
  597.         timer (5);                                      /* Then hold it up for .5
  598.                                                           * sec */
  599.         (void) set_baud (max_baud.rate_value, 0);
  600.  
  601.         mdm_cmd_char (' ');                                /* output a space            */
  602.         mdm_cmd_char (CR);                                    /* then another CR             */
  603.     }
  604.     mdm_cmd_string (str, 0);                      /* then the modem init
  605.                                                       * string */
  606. #ifdef NEW    /* NOOK  01.09.1990 */
  607.    timer (10);                                     /* Hold DTR for 1 sec more  */
  608. #else
  609.     timer (5);                                        /* Hold DTR for .5 sec more  */
  610. #endif
  611.     CLEAR_INBOUND ();                                 /* then flush input and exit */
  612. }
  613.  
  614. void send_break( int t)
  615. {
  616.     long t1;
  617.  
  618.     t1 = timerset ((long)t);
  619.     do_break (1);
  620.     while (!timeup (t1))
  621.         time_release ();
  622.     do_break (0);
  623. }
  624.  
  625. void exit_DTR( void )
  626. {
  627.     if (!leave_dtr_high)
  628.         DTR_OFF ();
  629. }
  630.  
  631. #define MNP_QTIME 300            /* 2 Second quiet time */
  632. #define MNP_MAXTIME 1000        /* 10 Seconds Maximum */
  633.  
  634. void MNP_Filter( void )
  635. {
  636.     long t, t1;
  637.     int c;
  638.     BOOLEAN flag = FALSE;        /* Only allow one message to be displayed */
  639.  
  640.     /*
  641.      * Wait up to a second for CARRIER to appear since it gets
  642.      * here straight after CONNECT
  643.      */
  644.  
  645.     t = timerset (100);      /* at most a one second delay    */
  646.  
  647.     while (!CARRIER && !timeup (t))
  648.         ;
  649.  
  650.     t1 = timerset (MNP_QTIME);        /* Quiet time needed */
  651.     t = timerset (MNP_MAXTIME);     /* Overall timer */
  652.  
  653.     /*
  654.      * Loop for either:
  655.      *    10 seconds (t)
  656.      *    1 second of quiet time (t1)
  657.      *    user abort (keypress)
  658.      */
  659.  
  660.     while (CARRIER && !timeup (t) && !timeup(t1))
  661.     {
  662.         if(KEYPRESS())            /* User abort */
  663.         {
  664.             DTR_OFF();
  665.             break;
  666.         }
  667.  
  668.         /*
  669.          * If there are any characters from the modem then reset the
  670.          * quiet timer
  671.          */
  672.         
  673.         if ((c = PEEKBYTE ()) != -1)
  674.         {
  675.             TIMED_READ(0);
  676.  
  677.             /* If we get an MNP or v.42 character, eat it and wait for clear line */
  678.  
  679.             if ((c != 0) && ((strchr (BadChars, c) != NULL) || (strchr (BadChars, c&0x7f) != NULL)))
  680.             {
  681.                 t1 = timerset (MNP_QTIME);
  682.                 if(!flag)
  683.                     status_line (msgtxt[M_FILTER]);
  684.                 flag = TRUE;
  685.             }
  686.         }
  687.     }
  688. }
  689.  
  690. #ifdef NEW /* FASTMODEM  10.09.1989 */
  691. void hang_up( void )
  692. {
  693.     long t;
  694.  
  695.     t = timerset(30);  /* max 3 seconds */
  696.     DTR_OFF ();
  697.     while (CARRIER && !timeup(t))
  698.        time_release ();
  699.     timer(2);
  700. }
  701. #endif
  702.  
  703.