Annotation of coherent/e/bin/ckermit/ckudia.c, revision 1.1

1.1     ! root        1: #ifndef NODIAL
        !             2: char *dialv = "Dial Command, 5A(046) 2 Nov 92";
        !             3: 
        !             4: /*  C K U D I A         --  Module for automatic modem dialing. */
        !             5: 
        !             6: /*
        !             7:   Copyright (C) 1985, 1992, Trustees of Columbia University in the City of New
        !             8:   York.  Permission is granted to any individual or institution to use this
        !             9:   software as long as it is not sold for profit.  This copyright notice must be
        !            10:   retained.  This software may not be included in commercial products without
        !            11:   written permission of Columbia University.
        !            12: 
        !            13:   Original (version 1, 1985) author: Herm Fischer, Encino, CA.
        !            14:   Contributed to Columbia University in 1985 for inclusion in C-Kermit 4.0.
        !            15:   Author and maintainer since 1985: Frank da Cruz, Columbia University,
        !            16:   [email protected].
        !            17: 
        !            18:   Contributions by many others throughout the years, including: Fernando
        !            19:   Cabral, John Chmielewski, Joe Doupnik, Richard Hill, Larry Jacobs, Eric
        !            20:   Jones, Tom Kloos, Bob Larson, Peter Mauzey, Joe Orost, Kevin O'Gorman, Kai
        !            21:   Uwe Rommel, Dan Schullman, Warren Tucker, and others too numerous to list
        !            22:   here (but see acknowledgements in ckcmai.c).
        !            23: 
        !            24:   This module calls externally defined system-dependent functions for
        !            25:   communications i/o, as defined in CKCPLM.DOC, the C-Kermit Program Logic
        !            26:   Manual, and thus should be portable to all systems that implement those
        !            27:   functions, and where alarm() and signal() work as they do in UNIX.
        !            28: */
        !            29: 
        !            30: /*
        !            31:   To add support for another modem, do the following, all in this module:
        !            32: 
        !            33:   1. Define a modem-type number symbol (n_XXX) for it.
        !            34: 
        !            35:   2. Adjust MAX_MDM to the new number of modem types.
        !            36: 
        !            37:   3. Create a MDMINF structure for it.
        !            38: 
        !            39:   4. Add the address of the MDMINF structure to the ptrtab[] array,
        !            40:      according to the numerical value of the modem-type number.
        !            41: 
        !            42:   5. Add the user-visible (SET MODEM) name and corresponding modem
        !            43:      number to the mdmtab[] array, in alphabetical order by modem-name string.
        !            44: 
        !            45:   6. Read through the code and add modem-specific sections as necessary.
        !            46: 
        !            47:   NOTE: The MINIDIAL symbol is used to build this module to include support
        !            48:   for only a minimum number of standard and/or generally useful modem types,
        !            49:   namely Hayes, CCITT V.25bis, "Unknown", and None.  When adding support for
        !            50:   a new modem type, keep it outside of the MINIDIAL sections.
        !            51: */
        !            52: 
        !            53: #include "ckcdeb.h"
        !            54: #ifndef MAC
        !            55: #include <signal.h>
        !            56: #endif /* MAC */
        !            57: #include "ckcasc.h"
        !            58: #include "ckcker.h"
        !            59: #include "ckucmd.h"
        !            60: #include "ckcnet.h"
        !            61: 
        !            62: #ifndef ZILOG
        !            63: #include <setjmp.h>                    /* Longjumps */
        !            64: #else
        !            65: #include <setret.h>
        !            66: #endif /* ZILOG */
        !            67: 
        !            68: #ifdef MAC
        !            69: #define signal msignal
        !            70: #define SIGTYP long
        !            71: #define alarm malarm
        !            72: #define SIG_IGN 0
        !            73: #define SIGALRM 1
        !            74: #define SIGINT 2
        !            75: SIGTYP (*msignal(int type, SIGTYP (*func)(int)))(int);
        !            76: #endif /* MAC */
        !            77: 
        !            78: int                                    /* SET DIAL parameters */
        !            79:   dialhng = 1,                         /* DIAL HANGUP, default is ON */
        !            80:   dialdpy = 0,                         /* DIAL DISPLAY, default is OFF */
        !            81:   mdmspd  = 1,                         /* DIAL SPEED-MATCHING (1 = ON) */
        !            82:   dialtmo = 0,                         /* DIAL TIMEOUT */
        !            83:   dialksp = 0,                         /* DIAL KERMIT-SPOOF */
        !            84:   dialmnp = 0,                         /* DIAL MNP-ENABLE */
        !            85: #ifdef NOMDMHUP
        !            86:   dialmhu = 0;                         /* DIAL MODEM-HANGUP */
        !            87: #else
        !            88:   dialmhu = 1;                         /* DIAL MODEM-HANGUP */
        !            89: #endif /* NOMDMHUP */
        !            90: 
        !            91: char *dialdir = NULL;                  /* DIAL DIRECTORY, default none */
        !            92: char *dialini = NULL;                  /* DIAL INIT-STRING, default none */
        !            93: char *dialcmd = NULL;                  /* DIAL DIAL-COMMAND, default none */
        !            94: char *dialnpr = NULL;                  /* DIAL NUMBER-PREFIX, ditto */
        !            95: FILE * dialfd = NULL;                  /* File descriptor of dial directory */
        !            96: 
        !            97: #ifndef MINIDIAL
        !            98: /*
        !            99:   Telebit model codes:
        !           100: 
        !           101:   ATI  Model Numbers           Examples
        !           102:   ---  -------------           --------
        !           103:   123                          Telebit in "total Hayes-1200" emulation mode
        !           104:   960                          Telebit in Conventional Command (Hayes) mode
        !           105:   961  RA12C                   IBM PC internal original Trailblazer
        !           106:   962  RA12E                   External original Trailblazer
        !           107:   963  RM12C                   Rackmount original Trailblazer
        !           108:   964  T18PC                   IBM PC internal Trailblazer-Plus (TB+)
        !           109:   965  T18SA, T2SAA, T2SAS     External TB+, T1600, T2000, T3000, WB, and later
        !           110:   966  T18RMM                  Rackmount TB+
        !           111:   967  T2MC                    IBM PS/2 internal TB+
        !           112:   968  T1000                   External T1000
        !           113:   969  ?                       Qblazer
        !           114:   971  T2500                   External T2500
        !           115:   972  T2500                   Rackmount T2500
        !           116: */
        !           117: 
        !           118: /* Telebit model codes */
        !           119: 
        !           120: #define TB_UNK  0                      /* Unknown Telebit model */
        !           121: #define TB_BLAZ 1                      /* Original TrailBlazer */
        !           122: #define TB_PLUS        2                       /* TrailBlazer Plus */
        !           123: #define TB_1000 3                      /* T1000 */
        !           124: #define TB_1500 4                      /* T1500 */
        !           125: #define TB_1600 5                      /* T1600 */
        !           126: #define TB_2000 6                      /* T2000 */
        !           127: #define TB_2500 7                      /* T2500 */
        !           128: #define TB_3000 8                      /* T3000 */
        !           129: #define TB_QBLA 9                      /* Qblazer */
        !           130: #define TB_WBLA 10                     /* WorldBlazer */
        !           131: #define TB__MAX 10                     /* Highest number */
        !           132: 
        !           133: char *tb_name[] = {                    /* Array of model names */
        !           134:     "Unknown",                         /* TB_UNK  */
        !           135:     "TrailBlazer",                     /* TB_BLAZ */
        !           136:     "TrailBlazer-Plus",                        /* TB_PLUS */
        !           137:     "T1000",                           /* TB_1000 */
        !           138:     "T1500",                           /* TB_1500 */
        !           139:     "T1600",                           /* TB_1600 */
        !           140:     "T2000",                           /* TB_2000 */
        !           141:     "T2500",                           /* TB_2500 */
        !           142:     "T3000",                           /* TB_3000 */
        !           143:     "Qblazer",                         /* TB_QBLA */
        !           144:     "WorldBlazer",                     /* TB_WBLA */
        !           145:     ""
        !           146: };
        !           147: #endif /* MINIDIAL */
        !           148: 
        !           149: extern int flow, local, mdmtyp, quiet, backgrd, parity, seslog, network;
        !           150: extern int carrier, duplex;
        !           151: #ifdef NETCONN
        !           152: extern int ttnproto;
        !           153: #endif /* NETCONN */
        !           154: extern CHAR stchr;
        !           155: extern long speed;
        !           156: extern char ttname[], sesfil[];
        !           157: 
        !           158: /*
        !           159:  * Failure reasons for use with the 'longjmp' exit.
        !           160:  */
        !           161: #define F_time         1               /* timeout */
        !           162: #define F_int          2               /* interrupt */
        !           163: #define F_modem                3               /* modem-detected failure */
        !           164: #define F_minit                4               /* cannot initialize modem */
        !           165: 
        !           166: static int mymdmtyp;                   /* Local copy of modem type. */
        !           167: static int n1 = F_time;
        !           168: 
        !           169: _PROTOTYP (static int ddinc, (int) );
        !           170: _PROTOTYP (int dialhup, (void) );
        !           171: _PROTOTYP (int getok, (int,int) );
        !           172: _PROTOTYP (char * getdws, (int) );
        !           173: _PROTOTYP (static VOID ttslow, (char *s, int millisec) );
        !           174: _PROTOTYP (VOID xcpy, (char *to, char *from, unsigned len) );
        !           175: _PROTOTYP (static VOID waitfor, (char *s) );
        !           176: _PROTOTYP (static VOID dialoc, (char c) );
        !           177: _PROTOTYP (static int didweget, (char *s, char *r) );
        !           178: _PROTOTYP (static VOID spdchg, (long s) );
        !           179: _PROTOTYP (static VOID tbati3, (int n) );
        !           180: 
        !           181: #define MDMINF struct mdminf
        !           182: 
        !           183: MDMINF         /* structure for modem-specific information */
        !           184:     {
        !           185:     int                dial_time;      /* time modem allows for dialing (secs) */
        !           186:     char       *pause_chars;   /* character(s) to tell modem to pause */
        !           187:     int                pause_time;     /* time associated with pause chars (secs) */
        !           188:     char       *wake_str;      /* string to wakeup modem & put in cmd mode */
        !           189:     int                wake_rate;      /* delay between wake_str characters (msecs) */
        !           190:     char       *wake_prompt;   /* string prompt after wake_str */
        !           191:     char       *dmode_str;     /* string to put modem in dialing mode */
        !           192:     char       *dmode_prompt;  /* string prompt for dialing mode */
        !           193:     char       *dial_str;      /* dialing string, with "%s" for number */
        !           194:     int                dial_rate;      /* delay between dialing characters (msecs) */
        !           195:     int                esc_time;       /* guard time on escape sequence (msecs) */
        !           196:     char       *esc_str;       /* escape sequence */
        !           197:     char       *hup_str;       /* hangup string */
        !           198:     _PROTOTYP( int (*ok_fn), (int,int) ); /* func to read response string */
        !           199:     };
        !           200: 
        !           201: /*
        !           202:  * Define symbolic modem numbers.
        !           203:  *
        !           204:  * The numbers MUST correspond to the ordering of entries
        !           205:  * within the ptrtab array, and start at one (1).
        !           206:  *
        !           207:  * It is assumed that there are relatively few of these
        !           208:  * values, and that the high(er) bytes of the value may
        !           209:  * be used for modem-specific mode information.
        !           210:  *
        !           211:  * REMEMBER that only the first eight characters of these
        !           212:  * names are guaranteed to be unique.
        !           213:  */
        !           214: 
        !           215: #ifdef MINIDIAL                                /* Minimum dialer support */
        !           216:                                        /* Only for CCITT, HAYES, and UNK */
        !           217: #define                n_CCITT          1
        !           218: #define                n_HAYES          2
        !           219: #define                n_UNKNOWN        3
        !           220: #define                MAX_MDM          3      /* Number of modem types */
        !           221: 
        !           222: #else                                  /* Full-blown dialer support */
        !           223: 
        !           224: #define                n_ATTDTDM        1
        !           225: #define         n_ATTISN         2
        !           226: #define                n_ATTMODEM       3
        !           227: #define                n_CCITT          4
        !           228: #define                n_CERMETEK       5
        !           229: #define                n_DF03           6
        !           230: #define                n_DF100          7
        !           231: #define                n_DF200          8
        !           232: #define                n_GDC            9
        !           233: #define                n_HAYES         10
        !           234: #define                n_PENRIL        11
        !           235: #define                n_RACAL         12
        !           236: #define                n_UNKNOWN       13
        !           237: #define                n_USROBOT       14
        !           238: #define                n_VENTEL        15
        !           239: #define                n_CONCORD       16
        !           240: #define                n_ATTUPC        17      /* aka UNIX PC and ATT7300 */
        !           241: #define                n_ROLM          18      /* Rolm CBX DCM */
        !           242: #define                n_MICROCOM      19
        !           243: #define         n_HST           20
        !           244: #define         n_TELEBIT       21      /* Telebits of all kinds */
        !           245: #define         n_DIGITEL       22     /* Digitel DT-22 (CCITT variant) */
        !           246: #define                MAX_MDM         22      /* Number of modem types */
        !           247: 
        !           248: #endif /* MINIDIAL */
        !           249: 
        !           250: /*
        !           251:  * Declare modem "variant" numbers for any of the above for which it is
        !           252:  * necessary to note various operational modes, using the second byte
        !           253:  * of a modem number.
        !           254:  *
        !           255:  * It is assumed that such modem modes share the same modem-specific
        !           256:  * information (see MDMINF structure) but may differ in some of the actions
        !           257:  * that are performed.
        !           258:  */
        !           259: 
        !           260: /*  Warning - this is starting to get kind of hokey... */
        !           261: 
        !           262: #define DIAL_NV 256
        !           263: #define n_HAYESNV ( n_HAYES   | DIAL_NV )
        !           264: 
        !           265: #ifndef MINIDIAL
        !           266: #define DIAL_PEP 512
        !           267: #define DIAL_V32 1024
        !           268: #define DIAL_V42 2048
        !           269: #define DIAL_SLO 4096
        !           270: #define n_TBPEP   ( n_TELEBIT | DIAL_PEP )
        !           271: #define n_TB3     ( n_TELEBIT | DIAL_V32 )
        !           272: #define n_TBNV    ( n_TELEBIT | DIAL_NV )
        !           273: #define n_TBPNV   ( n_TELEBIT | DIAL_NV | DIAL_PEP )
        !           274: #define n_TB3NV   ( n_TELEBIT | DIAL_NV | DIAL_V32 )
        !           275: #define n_TB4     ( n_TELEBIT | DIAL_V42 )
        !           276: #define n_TBS     ( n_TELEBIT | DIAL_SLO )
        !           277: #define n_TB4NV   ( n_TELEBIT | DIAL_NV | DIAL_V42 )
        !           278: #define n_TBSNV   ( n_TELEBIT | DIAL_NV | DIAL_SLO )
        !           279: #endif /* MINIDIAL */
        !           280: 
        !           281: /*
        !           282:  * Declare structures containing modem-specific information.
        !           283:  *
        !           284:  * REMEMBER that only the first SEVEN characters of these
        !           285:  * names are guaranteed to be unique.
        !           286:  */
        !           287: 
        !           288: #ifndef MINIDIAL
        !           289: static
        !           290: MDMINF ATTISN =                                /* AT&T ISN Network */
        !           291:     {
        !           292:     30,                                        /* Dial time */
        !           293:     "",                                        /* Pause characters */
        !           294:     0,                                 /* Pause time */
        !           295:     "\015\015\015\015",                        /* Wake string */
        !           296:     900,                               /* Wake rate */
        !           297:     "DIAL",                            /* Wake prompt */
        !           298:     "",                                        /* dmode_str */
        !           299:     "",                                        /* dmode_prompt */
        !           300:     "%s\015",                          /* dial_str */
        !           301:     0,                                 /* dial_rate */
        !           302:     0,                                 /* esc_time */
        !           303:     "",                                        /* esc_str */
        !           304:     "",                                        /* hup_str */
        !           305:     NULL                               /* ok_fn */
        !           306:     };
        !           307: 
        !           308: static
        !           309: MDMINF ATTMODEM =      /* information for AT&T switched-network modems */
        !           310:                        /* "Number" following "dial" can include: p's and
        !           311:                         * t's to indicate pulse or tone (default) dialing,
        !           312:                         * + for wait for dial tone, , for pause, r for
        !           313:                         * last number dialed, and, except for 2224B, some
        !           314:                         * comma-delimited options like o12=y, before number.
        !           315: 
        !           316:  * "Important" options for the modems:
        !           317:  *
        !           318:  *     All:            Except for 2224B, enable option 12 for "transparent
        !           319:  *                     data," o12=y.  If a computer port used for both
        !           320:  *                     incoming and outgoing calls is connected to the
        !           321:  *                     modem, disable "enter interactive mode on carriage
        !           322:  *                     return," EICR.  The Kermit "dial" command can
        !           323:  *                     function with EIA leads standard, EIAS.
        !           324:  *
        !           325:  *     2212C:          Internal hardware switches at their default
        !           326:  *                     positions (four rockers down away from numbers)
        !           327:  *                     unless EICR is not wanted (rocker down at the 4).
        !           328:  *                     For EIAS, rocker down at the 1.
        !           329:  *
        !           330:  *     2224B:          Front-panel switch position 1 must be up (at the 1,
        !           331:  *                     closed).  Disable EICR with position 2 down.
        !           332:  *                     For EIAS, position 4 down.
        !           333:  *                     All switches on the back panel down.
        !           334:  *
        !           335:  *     2224CEO:        All front-panel switches down except either 5 or 6.
        !           336:  *                     Enable interactive flow control with o16=y.
        !           337:  *                     Select normal asynchronous mode with o34=0 (zero).
        !           338:  *                     Disable EICR with position 3 up.  For EIAS, 1 up.
        !           339:  *                     Reset the modem after changing switches.
        !           340:  *
        !           341:  *     2296A:          If option 00 (zeros) is present, use o00=0.
        !           342:  *                     Enable interactive flow control with o16=y.
        !           343:  *                     Select normal asynchronous mode with o34=0 (zero).
        !           344:  *                      (available in Microcom Networking version, but
        !           345:  *                      not necessarily other models of the 2296A).
        !           346:  *                     Enable modem-port flow control (if available) with
        !           347:  *                     o42=y.  Enable asynchronous operation with o50=y.
        !           348:  *                     Disable EICR with o69=n.  For EIAS, o66=n, using
        !           349:  *                     front panel.
        !           350:  */
        !           351:     {
        !           352:     20,                        /* dial_time */
        !           353:     ",",               /* pause_chars */
        !           354:     2,                 /* pause_time */
        !           355:     "+",               /* wake_str */
        !           356:     0,                 /* wake_rate */
        !           357:     "",                        /* wake_prompt */
        !           358:     "",                        /* dmode_str */
        !           359:     "",                        /* dmode_prompt */
        !           360:     "at%s\015",                /* dial_str */
        !           361:     0,                 /* dial_rate */
        !           362:     0,                 /* esc_time */
        !           363:     "",                        /* esc_str */
        !           364:     "",                        /* hup_str */
        !           365:     NULL                       /* ok_fn */
        !           366:     };
        !           367: 
        !           368: static
        !           369: MDMINF ATTDTDM =       /* information for AT&T Digital Terminal Data Module
        !           370:  *                     For dialing: KYBD switch down, others usually up. */
        !           371:     {
        !           372:     20,                        /* dial_time */
        !           373:     "",                        /* pause_chars */
        !           374:     0,                 /* pause_time */
        !           375:     "",                        /* wake_str */
        !           376:     0,                 /* wake_rate */
        !           377:     "",                        /* wake_prompt */
        !           378:     "",                        /* dmode_str */
        !           379:     "",                        /* dmode_prompt */
        !           380:     "%s\015",          /* dial_str */          /* not used */
        !           381:     0,                 /* dial_rate */
        !           382:     0,                 /* esc_time */
        !           383:     "",                        /* esc_str */
        !           384:     "",                        /* hup_str */
        !           385:     NULL               /* ok_fn */
        !           386:     };
        !           387: #endif /* MINIDIAL */
        !           388: 
        !           389: static
        !           390: MDMINF CCITT =                         /* CCITT V.25bis autodialer */
        !           391: /*
        !           392:   According to V.25bis:
        !           393:   . Even parity is required for giving commands to the modem.
        !           394:   . Commands might or might not echo.
        !           395:   . Responses ("Indications") from the modem are terminated by CR and LF.
        !           396:   . Call setup is accomplished by:
        !           397:     - DTE raises DTR (V.24 circuit 108)              [ttopen() does this]
        !           398:     - Modem raises CTS (V.24 circuit 106)            [C-Kermit ignores this]
        !           399:     - DTE issues a call request command ("CRN")
        !           400:     - Modem responds with "VAL" ("command accepted")
        !           401:     - If the call is completed:
        !           402:         modem responds with "CNX" ("call connected");
        !           403:         modem turns CTS (106) OFF;
        !           404:         modem turns DSR (107) ON;
        !           405:       else:
        !           406:         modem responds with "CFI <parameter>" ("call failure indication").
        !           407:   . To clear a call, the DTE turns DTR (108) OFF.
        !           408:   . There is no mention of the Carrier Detect circuit (109) in the standard.
        !           409:   . There is no provision for "escaping back" to the modem's command mode.
        !           410: 
        !           411:   It is not known whether there exists in real life a pure V.25bis modem.
        !           412:   If there is, this code has never been tested on it.  See the Digitel entry.
        !           413: */
        !           414:     {
        !           415:     40,                        /* dial_time -- programmable -- */
        !           416:     ",:",              /* pause_chars -- "," waits for programmable time */
        !           417:                         /* ":" waits for dial tone */
        !           418:     10,                        /* pause_time (seconds, just a guess) */
        !           419:     "",                        /* wake_str (none) */
        !           420:     200,               /* wake_rate (msec) */
        !           421:     "VAL",             /* wake_prompt */
        !           422:     "",                        /* dmode_str (none) */
        !           423:     "",                        /* dmode_prompt (none) */
        !           424:     "CRN%s\015",        /* dial_str */
        !           425:     200,               /* dial_rate (msec) */
        !           426:     0,                 /* No esc_time */
        !           427:     "",                        /* No esc_str  */
        !           428:     "",                        /* No hup_str  */
        !           429:     NULL               /* No ok_fn    */
        !           430:     };
        !           431: 
        !           432: #ifndef MINIDIAL       /* Don't include the following if -DMINIDIAL ... */
        !           433: 
        !           434: static
        !           435: MDMINF CERMETEK =      /* Information for "Cermetek Info-Mate 212 A" modem */
        !           436:     {
        !           437:     20,                        /* dial_time */
        !           438:     "BbPpTt",          /* pause_chars */
        !           439:     0,                 /* pause_time */        /** unknown -- DS **/
        !           440:     "  XY\016R\015",   /* wake_str */
        !           441:     200,               /* wake_rate */
        !           442:     "",                        /* wake_prompt */
        !           443:     "",                        /* dmode_str */
        !           444:     NULL,              /* dmode_prompt */
        !           445:     "\016D '%s'\015",  /* dial_str */
        !           446:     200,               /* dial_rate */
        !           447:     0,                 /* esc_time */
        !           448:     "",                        /* esc_str */
        !           449:     "",                        /* hup_str */
        !           450:     NULL               /* ok_fn */
        !           451:     };
        !           452: 
        !           453: static
        !           454: MDMINF DF03 =          /* information for "DEC DF03-AC" modem */
        !           455:     {
        !           456:     27,                        /* dial_time */
        !           457:     "=",               /* pause_chars */       /* wait for second dial tone */
        !           458:     15,                        /* pause_time */
        !           459:     "\001\002",                /* wake_str */
        !           460:     0,                 /* wake_rate */
        !           461:     "",                        /* wake_prompt */
        !           462:     "",                        /* dmode_str */
        !           463:     NULL,              /* dmode_prompt */
        !           464:     "%s",              /* dial_str */
        !           465:     0,                 /* dial_rate */
        !           466:     0,                 /* esc_time */
        !           467:     "",                        /* esc_str */
        !           468:     "",                        /* hup_str */
        !           469:     NULL               /* ok_fn */
        !           470:     };
        !           471: 
        !           472: static
        !           473: MDMINF DF100 =         /* information for "DEC DF100-series" modem */
        !           474:                        /*
        !           475:                         * The telephone "number" can include "P"s and/or "T"s
        !           476:                         * within it to indicate that subsequent digits are
        !           477:                         * to be dialed using pulse or tone dialing.  The
        !           478:                         * modem defaults to pulse dialing.  You may modify
        !           479:                         * the dial string below to explicitly default all
        !           480:                         * dialing to pulse or tone, but doing so prevents
        !           481:                         * the use of phone numbers that you may have stored
        !           482:                         * in the modem's memory.
        !           483:                         */
        !           484:     {
        !           485:     30,                        /* dial_time */
        !           486:     "=",               /* pause_chars */       /* wait for second dial tone */
        !           487:     15,                        /* pause_time */
        !           488:     "\001",            /* wake_str */
        !           489:     0,                 /* wake_rate */
        !           490:     "",                        /* wake_prompt */
        !           491:     "",                        /* dmode_str */
        !           492:     NULL,              /* dmode_prompt */
        !           493:     "%s#",             /* dial_str */
        !           494:     0,                 /* dial_rate */
        !           495:     0,                 /* esc_time */
        !           496:     "",                        /* esc_str */
        !           497:     "",                        /* hup_str */
        !           498:     NULL               /* ok_fn */
        !           499:     };
        !           500: 
        !           501: static
        !           502: MDMINF DF200 =         /* information for "DEC DF200-series" modem */
        !           503:                        /*
        !           504:                         * The telephone "number" can include "P"s and/or "T"s
        !           505:                         * within it to indicate that subsequent digits are
        !           506:                         * to be dialed using pulse or tone dialing.  The
        !           507:                         * modem defaults to pulse dialing.  You may modify
        !           508:                         * the dial string below to explicitly default all
        !           509:                         * dialing to pulse or tone, but doing so prevents
        !           510:                         * the use of phone numbers that you may have stored
        !           511:                         * in the modem's memory.
        !           512:                         */
        !           513:     {
        !           514:     30,                        /* dial_time */
        !           515:     "=W",              /* pause_chars */       /* =: second tone; W: 5 secs */
        !           516:     15,                        /* pause_time */        /* worst case */
        !           517:     "\002",            /* wake_str */          /* allow stored number usage */
        !           518:     0,                 /* wake_rate */
        !           519:     "",                        /* wake_prompt */
        !           520:     "",                        /* dmode_str */
        !           521:     NULL,              /* dmode_prompt */
        !           522:     "%s!",             /* dial_str */
        !           523:     0,                 /* dial_rate */
        !           524:     0,                 /* esc_time */
        !           525:     "",                        /* esc_str */
        !           526:     "",                        /* hup_str */
        !           527:     NULL               /* ok_fn */
        !           528:     };
        !           529: 
        !           530: static
        !           531: MDMINF DIGITEL =        /* Digitel DT-22 CCITT variant used in Brazil */
        !           532: /*
        !           533:   Attempts to adhere strictly to the V.25bis specification do not produce good
        !           534:   results in real life.  The modem for which this code was developed: (a)
        !           535:   ignores parity; (b) sometimes terminates responses with LF CR instead of CR
        !           536:   LF; (c) has a Hayes-like escape sequence; (d) supports a hangup ("HUP")
        !           537:   command.  Information from Fernando Cabral in Brasilia.
        !           538: */
        !           539:     {
        !           540:     40,                        /* dial_time -- programmable -- */
        !           541:     ",:",              /* pause_chars -- "," waits for programmable time */
        !           542:                         /* ":" waits for dial tone */
        !           543:     10,                        /* pause_time (seconds, just a guess) */
        !           544:     "HUP\015",          /* wake_str (Not Standard CCITT) */
        !           545:     200,               /* wake_rate (msec) */
        !           546:     "VAL",             /* wake_prompt */
        !           547:     "",                        /* dmode_str (none) */
        !           548:     "",                        /* dmode_prompt (none) */
        !           549:     "CRN%s\015",        /* dial_str */
        !           550:     200,               /* dial_rate (msec) */
        !           551:     1100,              /* esc_time (Not Standard CCITT) */
        !           552:     "+++",             /* esc_str  (Not Standard CCITT) */
        !           553:     "HUP\015",         /* hup_str  (Not Standard CCITT) */
        !           554:     getok              /* ok_fn */
        !           555:     };
        !           556: 
        !           557: static
        !           558: MDMINF GDC =           /* information for "GeneralDataComm 212A/ED" modem */
        !           559:     {
        !           560:     32,                        /* dial_time */
        !           561:     "%",               /* pause_chars */
        !           562:     3,                 /* pause_time */
        !           563:     "\015\015",                /* wake_str */
        !           564:     500,               /* wake_rate */
        !           565:     "$",               /* wake_prompt */
        !           566:     "D\015",           /* dmode_str */
        !           567:     ":",               /* dmode_prompt */
        !           568:     "T%s\015",         /* dial_str */
        !           569:     0,                 /* dial_rate */
        !           570:     0,                 /* esc_time */
        !           571:     "",                        /* esc_str */
        !           572:     "",                        /* hup_str */
        !           573:     NULL               /* ok_fn */
        !           574:     };
        !           575: #endif /* MINIDIAL */
        !           576: 
        !           577: static
        !           578: MDMINF HAYES =         /* Information for Hayes and Hayes-like modems */
        !           579:     {
        !           580:     35,                        /* dial_time */
        !           581:     ",",               /* pause_chars */
        !           582:     2,                 /* pause_time */
        !           583:     "ATQ0\015",                /* wake_str */
        !           584: /*
        !           585:   Note: Other wake_str's are possible here.  For a Hayes 2400 that is to
        !           586:   be used for both in and out calls, AT&F&D3 might be best.  For out calls
        !           587:   only, maybe AT&F&D2.  See Hayes 2400 manual.
        !           588: */
        !           589:     0,                 /* wake_rate */
        !           590:     "",                        /* wake_prompt */
        !           591:     "",                        /* dmode_str */
        !           592:     "",                        /* dmode_prompt */
        !           593:     "ATD%s\015",       /* dial_str, note: user can supply D or T */
        !           594:     0,                 /* dial_rate */
        !           595:     1100,              /* esc_time */
        !           596:     "+++",             /* esc_str */
        !           597:     "ATQ0H0\015",      /* hup_str */
        !           598:     getok              /* ok_fn */
        !           599:     };
        !           600: 
        !           601: #ifndef MINIDIAL
        !           602: 
        !           603: static
        !           604: MDMINF PENRIL =                /* information for "Penril" modem */
        !           605:     {
        !           606:     50,                        /* dial_time */
        !           607:     "",                        /* pause_chars */       /** unknown -- HF **/
        !           608:     0,                 /* pause_time */
        !           609:     "\015\015",                /* wake_str */
        !           610:     300,               /* wake_rate */
        !           611:     ">",               /* wake_prompt */
        !           612:     "k\015",           /* dmode_str */
        !           613:     ":",               /* dmode_prompt */
        !           614:     "%s\015",          /* dial_str */
        !           615:     0,                 /* dial_rate */
        !           616:     0,                 /* esc_time */
        !           617:     "",                        /* esc_str */
        !           618:     "",                        /* hup_str */
        !           619:     NULL               /* ok_fn */
        !           620:     };
        !           621: 
        !           622: static
        !           623: MDMINF RACAL =         /* information for "Racal Vadic" modem, e.g. VA4492E */
        !           624:     {
        !           625:     35,                        /* dial_time (manual says modem is hardwired to 60) */
        !           626:     "Kk",              /* pause_chars */
        !           627:     5,                 /* pause_time */
        !           628:     "\005\015",                /* wake_str, ^E^M */
        !           629:     50,                        /* wake_rate */
        !           630:     "*",               /* wake_prompt */
        !           631:     "D\015",           /* dmode_str */
        !           632:     "?",               /* dmode_prompt */
        !           633:     "%s\015",          /* dial_str */
        !           634:     0,                 /* dial_rate */
        !           635:     1100,              /* esc_time */
        !           636:     "\003\004",                /* esc_str, ^C^D (this actually hangs up) */
        !           637:     "\005",            /* hup_str, ^E (this goes back to command mode) */
        !           638:     NULL               /* ok_fn */
        !           639:     };
        !           640: #endif /* MINIDIAL */
        !           641: 
        !           642: /*
        !           643:   The intent of the "unknown" modem is to allow KERMIT to support
        !           644:   unknown modems by having the user type the entire autodial sequence
        !           645:   (possibly including control characters, etc.) as the "phone number".
        !           646:   The protocol and other characteristics of this modem are unknown, with
        !           647:   some "reasonable" values being chosen for some of them.  The only way to
        !           648:   detect if a connection is made is to look for carrier.
        !           649: */
        !           650: static
        !           651: MDMINF UNKNOWN =       /* information for "Unknown" modem */
        !           652:     {
        !           653:     30,                        /* dial_time */
        !           654:     "",                        /* pause_chars */
        !           655:     0,                 /* pause_time */
        !           656:     "",                        /* wake_str */
        !           657:     0,                 /* wake_rate */
        !           658:     "",                        /* wake_prompt */
        !           659:     "",                        /* dmode_str */
        !           660:     NULL,              /* dmode_prompt */
        !           661:     "%s\015",          /* dial_str */
        !           662:     0,                 /* dial_rate */
        !           663:     0,                 /* esc_time */
        !           664:     "",                        /* esc_str */
        !           665:     "",                        /* hup_str */
        !           666:     NULL               /* ok_fn */
        !           667:     };
        !           668: 
        !           669: #ifndef MINIDIAL
        !           670: 
        !           671: static
        !           672: MDMINF USROBOT =       /* information for "US Robotics 212A" modem */
        !           673:     {
        !           674:     30,                        /* dial_time */
        !           675:     ",",               /* pause_chars */
        !           676:     2,                 /* pause_time */
        !           677:     "ATS2=01\015",     /* wake_str */
        !           678:     0,                 /* wake_rate */
        !           679:     "OK\015",          /* wake_prompt */
        !           680:     "",                        /* dmode_str */
        !           681:     NULL,              /* dmode_prompt */
        !           682:     "ATTD%s\015",      /* dial_str */
        !           683:     0,                 /* dial_rate */
        !           684:     0,                 /* esc_time */
        !           685:     "",                        /* esc_str */
        !           686:     "",                        /* hup_str */
        !           687:     NULL               /* ok_fn */
        !           688:     };
        !           689: 
        !           690: #ifdef COMMENT
        !           691: /* Reportedly this does not work at all. */
        !           692: static
        !           693: MDMINF VENTEL =                /* information for "Ventel" modem */
        !           694:     {
        !           695:     20,                        /* dial_time */
        !           696:     "%",               /* pause_chars */
        !           697:     5,                 /* pause_time */
        !           698:     "\015\015\015",    /* wake_str */
        !           699:     300,               /* wake_rate */
        !           700:     "$",               /* wake_prompt */
        !           701:     "",                        /* dmode_str */
        !           702:     NULL,              /* dmode_prompt */
        !           703:     "<K\015%s\015>",    /* dial_str (was "<K%s\r>") */
        !           704:     0,                 /* dial_rate */
        !           705:     0,                 /* esc_time */
        !           706:     "",                        /* esc_str */
        !           707:     "",                        /* hup_str */
        !           708:     NULL               /* ok_fn */
        !           709:     };
        !           710: #else
        !           711: /* and this does. */
        !           712: static
        !           713: MDMINF VENTEL =                /* information for "Ventel" modem */
        !           714:     {
        !           715:     20,                        /* dial_time */
        !           716:     "%",               /* pause_chars */
        !           717:     5,                 /* pause_time */
        !           718:     "\015\015\015",    /* wake_str */
        !           719:     300,               /* wake_rate */
        !           720:     "$",               /* wake_prompt */
        !           721:     "K\015",           /* dmode_str (was "") */
        !           722:     "Number to call: ",        /* dmode_prompt (was NULL) */
        !           723:     "%s\015",          /* dial_str (was "<K%s\r>") */
        !           724:     0,                 /* dial_rate */
        !           725:     0,                 /* esc_time */
        !           726:     "",                        /* esc_str */
        !           727:     "",                        /* hup_str */
        !           728:     NULL               /* ok_fn */
        !           729:     };
        !           730: #endif /* COMMENT */
        !           731: 
        !           732: static
        !           733: MDMINF CONCORD =       /* Info for Condor CDS 220 2400b modem */
        !           734:     {
        !           735:     35,                        /* dial_time */
        !           736:     ",",               /* pause_chars */
        !           737:     2,                 /* pause_time */
        !           738:     "\015\015",                /* wake_str */
        !           739:     20,                        /* wake_rate */
        !           740:     "CDS >",           /* wake_prompt */
        !           741:     "",                        /* dmode_str */
        !           742:     NULL,              /* dmode_prompt */
        !           743:     "<D M%s\015>",     /* dial_str */
        !           744:     0,                 /* dial_rate */
        !           745:     0,                 /* esc_time */
        !           746:     "",                        /* esc_str */
        !           747:     "",                        /* hup_str */
        !           748:     NULL               /* ok_fn */
        !           749:     };
        !           750: 
        !           751: static
        !           752: MDMINF ATTUPC = /* dummy information for "ATT7300/Unix PC" internal modem */
        !           753:     {
        !           754:     30,                        /* dial_time */
        !           755:     "",                        /* pause_chars */
        !           756:     0,                 /* pause_time */
        !           757:     "",                        /* wake_str */
        !           758:     0,                 /* wake_rate */
        !           759:     "",                        /* wake_prompt */
        !           760:     "",                        /* dmode_str */
        !           761:     NULL,              /* dmode_prompt */
        !           762:     "%s\015",          /* dial_str */
        !           763:     0,                 /* dial_rate */
        !           764:     0,                 /* esc_time */
        !           765:     "",                        /* esc_str */
        !           766:     "",                        /* hup_str */
        !           767:     NULL               /* ok_fn */
        !           768:     };
        !           769: 
        !           770: static
        !           771: MDMINF ROLM =          /* IBM / Siemens / Rolm 8000, 9000, 9751 CBX */
        !           772:     {
        !           773:     60,                        /* dial_time */
        !           774:     "",                        /* pause_chars */
        !           775:     0,                 /* pause_time */
        !           776:     "\015\015",                /* wake_str */
        !           777:     5,                 /* wake_rate */
        !           778:     "MODIFY?",         /* wake_prompt */
        !           779:     "",                        /* dmode_str */
        !           780:     "",                        /* dmode_prompt */
        !           781:     "CALL %s\015",     /* dial_str */
        !           782:     0,                 /* dial_rate */
        !           783:     0,                 /* esc_time */
        !           784:     "",                        /* esc_str */
        !           785:     "",                        /* hup_str */
        !           786:     NULL               /* ok_fn */
        !           787:     };
        !           788: 
        !           789: static
        !           790: MDMINF MICROCOM =      /* information for "Microcom" modems in native mode */
        !           791:                        /* (long answer only) */
        !           792:     {
        !           793:     35,                        /* dial_time */
        !           794:     ",!@",             /* pause_chars (! and @ aren't pure pauses) */
        !           795:     3,                 /* pause_time */
        !           796:     "\015",            /* wake_str */
        !           797:     100,               /* wake_rate */
        !           798:     "!",               /* wake_prompt */
        !           799:     "",                        /* dmode_str */
        !           800:     NULL,              /* dmode_prompt */
        !           801:     "d%s\015",         /* dial_str */
        !           802:     0,                 /* dial_rate */
        !           803:     0,                 /* esc_time */
        !           804:     "",                        /* esc_str */
        !           805:     "",                        /* hup_str */
        !           806:     NULL               /* ok_fn */
        !           807:     };
        !           808: 
        !           809: static
        !           810: MDMINF HST =           /* information for Courier HST modem */
        !           811:     {
        !           812:     35,                        /* dial_time */
        !           813:     ",",               /* pause_chars */
        !           814:     2,                 /* pause_time */
        !           815:     "ATQ0S2=43X7&B1&M4\015", /* wake_str */
        !           816:     0,                 /* wake_rate */
        !           817:     "OK\015",          /* wake_prompt */
        !           818:     "",                        /* dmode_str */
        !           819:     "",                        /* dmode_prompt */
        !           820:     "ATD%s\015",       /* dial_str */
        !           821:     0,                 /* dial_rate */
        !           822:     1100,              /* esc_time */
        !           823:     "+++",             /* esc_str */
        !           824:     "ATQ0H0\015",      /* hup_str */
        !           825:     getok              /* ok_fn */
        !           826:     };
        !           827: 
        !           828: static
        !           829: MDMINF TELEBIT =       /* information for Telebits */
        !           830:     {
        !           831:     60,                        /* dial_time */
        !           832:     ",",               /* pause_chars */
        !           833:     2,                 /* pause_time */
        !           834: /*
        !           835:   NOTE: The wake_string MUST contain the I command (model query), and otherwise
        !           836:   must contain commands that work on ALL Telebit models.  Here we ensure that
        !           837:   result codes are returned (Q0), and ask for extended result codes (X1), and
        !           838:   ensure that the escape sequence is +++ and it is enabled.  And also, make
        !           839:   sure the final character is not a digit (whose echo might be mistaken for a
        !           840:   result code).  The Ctrl-Q and multiple A's are recommended by Telebit.
        !           841: */
        !           842:     "\021AAAATQ0X1S12=50 S2=43 I\015", /* wake_str. */
        !           843:     100,               /* wake_rate = 100 msec */
        !           844:     "OK\015",          /* wake_prompt */
        !           845:     "",                        /* dmode_str */
        !           846:     "",                        /* dmode_prompt */
        !           847:     "ATD%s\015",       /* dial_str, Note: no T or P */
        !           848:     80,                        /* dial_rate */
        !           849:     1100,              /* esc_time (guard time) */
        !           850:     "+++",             /* esc_str */
        !           851:     "ATQ0H0\015",      /* hup_str */
        !           852:     getok              /* ok_fn */
        !           853:     };
        !           854: #endif /* MINIDIAL */
        !           855: 
        !           856: /*
        !           857:  * Declare table for converting modem numbers to information pointers.
        !           858:  *
        !           859:  * The entries MUST be in ascending order by modem number, without any
        !           860:  * "gaps" in the numbers, and starting from one (1).
        !           861:  *
        !           862:  * This table should NOT include entries for the "variant" modem numbers,
        !           863:  * since they share the same information as the normal value.
        !           864:  */
        !           865: static
        !           866: MDMINF *ptrtab[] = {
        !           867: #ifdef MINIDIAL
        !           868:     &CCITT,
        !           869:     &HAYES,
        !           870:     &UNKNOWN
        !           871: #else
        !           872:     &ATTDTDM,
        !           873:     &ATTISN,
        !           874:     &ATTMODEM,
        !           875:     &CCITT,
        !           876:     &CERMETEK,
        !           877:     &DF03,
        !           878:     &DF100,
        !           879:     &DF200,
        !           880:     &GDC,
        !           881:     &HAYES,
        !           882:     &PENRIL,
        !           883:     &RACAL,
        !           884:     &UNKNOWN,
        !           885:     &USROBOT,
        !           886:     &VENTEL,
        !           887:     &CONCORD,
        !           888:     &ATTUPC,
        !           889:     &ROLM,
        !           890:     &MICROCOM,
        !           891:     &HST,
        !           892:     &TELEBIT,
        !           893:     &DIGITEL
        !           894: #endif /* MINIDIAL */
        !           895: };
        !           896: /*
        !           897:  * Declare modem names and associated numbers for command parsing,
        !           898:  * and also for doing number-to-name translation.
        !           899:  *
        !           900:  * The entries must be in alphabetical order by modem name.
        !           901:  */
        !           902: struct keytab mdmtab[] = {
        !           903: #ifndef MINIDIAL
        !           904:     "attdtdm",         n_ATTDTDM,      0,
        !           905:     "attisn",           n_ATTISN,       0,
        !           906:     "attmodem",                n_ATTMODEM,     0,
        !           907:     "att7300",         n_ATTUPC,       0,
        !           908: #endif /* MINIDIAL */
        !           909:     "ccitt-v25bis",    n_CCITT,        0,
        !           910: #ifndef MINIDIAL
        !           911:     "cermetek",                n_CERMETEK,     0,
        !           912:     "concord",         n_CONCORD,      0,
        !           913:     "df03-ac",         n_DF03,         0,
        !           914:     "df100-series",    n_DF100,        0,
        !           915:     "df200-series",    n_DF200,        0,
        !           916:     "digitel-dt22",    n_DIGITEL,      0,
        !           917: #endif /* MINIDIAL */
        !           918:     "direct",          0,              CM_INV, /* Synonym for NONE */
        !           919: #ifndef MINIDIAL
        !           920:     "gdc-212a/ed",     n_GDC,          0,
        !           921:     "gendatacomm",     n_GDC,          CM_INV, /* Synonym for GDC */
        !           922: #endif /* MINIDIAL */
        !           923:     "hayes",           n_HAYES,        0,
        !           924: #ifndef MINIDIAL
        !           925:     "hst-courier",      n_HST,          0,
        !           926:     "microcom",                n_MICROCOM,     0,
        !           927: #endif /* MINIDIAL */
        !           928:     "none",             0,              0,
        !           929: #ifndef MINIDIAL
        !           930:     "penril",          n_PENRIL,       0,
        !           931:     "pep-telebit",      n_TBPEP,        0,
        !           932:     "racalvadic",      n_RACAL,        0,
        !           933:     "rolm",            n_ROLM,         0,
        !           934:     "slow-telebit",     n_TBS,         0,
        !           935:     "telebit",          n_TELEBIT,      0,
        !           936: #endif /* MINIDIAL */
        !           937:     "unknown",         n_UNKNOWN,      0,
        !           938: #ifndef MINIDIAL
        !           939:     "usrobotics-212a", n_USROBOT,      0,
        !           940:     "v32-telebit",      n_TB3,         0,
        !           941:     "v42-telebit",      n_TB4,         0,
        !           942:     "ventel",          n_VENTEL,       0
        !           943: #endif /* MINIDIAL */
        !           944: };
        !           945: int nmdm = (sizeof(mdmtab) / sizeof(struct keytab)); /* Number of modems */
        !           946: 
        !           947: #define CONNECTED 1                    /* For completion status */
        !           948: #define FAILED   2
        !           949: 
        !           950: static
        !           951: char *F_reason[5] = {                  /* Failure reasons for message */
        !           952:     "Unknown", "Timeout", "Interrupt", "Modem", "Initialize" };
        !           953: 
        !           954: static int tries = 0;
        !           955: static int mdmecho = 0;        /* assume modem does not echo */
        !           956: static int augmdmtyp;  /* "augmented" modem type, to handle modem modes */
        !           957: 
        !           958: static char *p;                /* For command strings & messages */
        !           959: 
        !           960: #define LBUFL 100
        !           961: #ifdef DYNAMIC
        !           962: static char *lbuf = NULL;
        !           963: #else
        !           964: static char lbuf[LBUFL];
        !           965: #endif /* DYNAMIC */
        !           966: 
        !           967: #define RBUFL 63
        !           968: static char rbuf[RBUFL+1];     /* Modem response buffer */
        !           969: 
        !           970: static jmp_buf sjbuf;
        !           971: 
        !           972: static SIGTYP (*savalrm)();    /* For saving alarm handler */
        !           973: static SIGTYP (*savint)();     /* For saving interrupt handler */
        !           974: 
        !           975: #ifndef MINIDIAL
        !           976: int tbmodel = 0;               /* Telebit modem model */
        !           977: 
        !           978: char *
        !           979: gtbmodel() {                   /* Function to return name of Telebit model */
        !           980:     if (tbmodel < 0 || tbmodel > TB__MAX) tbmodel = TB_UNK;
        !           981:     return(tb_name[tbmodel]);
        !           982: }
        !           983: 
        !           984: VOID
        !           985: xcpy(to,from,len)              /* Copy the given number of bytes */
        !           986:     register char *to, *from;
        !           987:     register unsigned len; {
        !           988:        while (len--) *to++ = *from++;
        !           989: }
        !           990: #endif /* MINIDIAL */
        !           991: 
        !           992: SIGTYP
        !           993: dialtime(foo) int foo; {               /* Timer interrupt handler */
        !           994:     n1 = F_time;                       /* Failure reason = timeout */
        !           995: 
        !           996: #ifdef __EMX__
        !           997:     signal(SIGALRM, SIG_ACK);          /* Needed for OS/2 */
        !           998: #endif /* __EMX__ */
        !           999: 
        !          1000: #ifdef OSK                             /* OS-9 */
        !          1001: /*
        !          1002:   We are in an intercept routine but do not perform a F$RTE (done implicitly
        !          1003:   by RTS), so we have to decrement the sigmask as F$RTE does.  Warning:
        !          1004:   longjump only restores the CPU registers, NOT the FPU registers.  So, don't
        !          1005:   use FPU at all or at least don't use common FPU (double or float) register
        !          1006:   variables.
        !          1007: */
        !          1008:     sigmask(-1);
        !          1009: #endif /* OSK */
        !          1010: 
        !          1011:     longjmp( sjbuf, F_time );
        !          1012: }
        !          1013: 
        !          1014: SIGTYP
        !          1015: dialint(foo) int foo; {                        /* Keyboard interrupt handler */
        !          1016:     n1 = F_int;
        !          1017: #ifdef __EMX__
        !          1018:     signal(SIGINT, SIG_ACK);           /* Needed for OS/2 */
        !          1019: #endif /* __EMX__ */
        !          1020: #ifdef OSK                             /* OS-9, see comment in dialtime() */
        !          1021:     sigmask(-1);
        !          1022: #endif /* OSK */
        !          1023:     longjmp( sjbuf, F_int );
        !          1024: }
        !          1025: 
        !          1026: /*
        !          1027:   Routine to read a character from communication device, handling TELNET
        !          1028:   protocol negotiations in case we're connected to the modem through a
        !          1029:   TCP/IP TELNET modem server.
        !          1030: */
        !          1031: static int
        !          1032: ddinc(n) int n; {
        !          1033:     int c;
        !          1034: 
        !          1035: #ifdef TNCODE
        !          1036:     int done = 0;
        !          1037:     while (!done) {
        !          1038:        c = ttinc(n);
        !          1039:        debug(F000,"ddinc","",c);
        !          1040:        if (c < 0) return(c);
        !          1041:        if (c == IAC && network && ttnproto == NP_TELNET) {
        !          1042:            switch (tn_doop((CHAR)(c & 0xff),duplex,ttinc)) {
        !          1043:              case 2: duplex = 0; continue;
        !          1044:              case 1: duplex = 1;
        !          1045:              default: continue;
        !          1046:            }
        !          1047:        } else done = 1;
        !          1048:     }
        !          1049:     return(c & 0xff);
        !          1050: #else
        !          1051:     return(ttinc(n));
        !          1052: #endif /* TNCODE */
        !          1053: }
        !          1054: 
        !          1055: static VOID
        !          1056: ttslow(s,millisec) char *s; int millisec; { /* Output s-l-o-w-l-y */
        !          1057:     for (; *s; s++) {
        !          1058:        ttoc(*s);
        !          1059:        msleep(millisec);
        !          1060:     }
        !          1061: }
        !          1062: 
        !          1063: /*
        !          1064:  * Wait for a string of characters.
        !          1065:  *
        !          1066:  * The characters are waited for individually, and other characters may
        !          1067:  * be received "in between".  This merely guarantees that the characters
        !          1068:  * ARE received, and in the order specified.
        !          1069:  */
        !          1070: static VOID
        !          1071: waitfor(s) char *s; {
        !          1072:     CHAR c, x;
        !          1073:     while ( c = *s++ ) {               /* while more characters remain... */
        !          1074:        do {                            /* wait for the character */
        !          1075:            x = ddinc(0) & 0177;
        !          1076:            debug(F000,"dial waitfor got","",x);
        !          1077:            if (dialdpy) {
        !          1078:                if (x != LF) conoc(x);
        !          1079:                if (x == CR) conoc(LF);
        !          1080:            }
        !          1081:        } while ( x != c);
        !          1082:     }
        !          1083: }
        !          1084: 
        !          1085: static int
        !          1086: didweget(s,r) char *s, *r; {   /* Looks in string s for response r */
        !          1087:     int lr = (int)strlen(r);   /*  0 means not found, 1 means found it */
        !          1088:     int i;
        !          1089:     debug(F110,"didweget",r,0);
        !          1090:     debug(F110," in",s,0);
        !          1091:     for (i = (int)strlen(s)-lr; i >= 0; i--)
        !          1092:        if ( s[i] == r[0] ) if ( !strncmp(s+i,r,lr) ) return( 1 );
        !          1093:     return( 0 );
        !          1094: }
        !          1095: 
        !          1096: 
        !          1097: /* R E S E T -- Reset alarms, etc. on exit. */
        !          1098: 
        !          1099: static VOID
        !          1100: dreset() {
        !          1101:     alarm(0);
        !          1102:     signal(SIGALRM,savalrm);           /* restore alarm handler */
        !          1103:     signal(SIGINT,savint);             /* restore interrupt handler */
        !          1104: }
        !          1105: 
        !          1106: /*
        !          1107:   Call this routine when the modem reports that it has connected at a certain
        !          1108:   speed, giving that speed as the argument.  If the connection speed is not
        !          1109:   the same as Kermit's current communication speed, AND the modem interface
        !          1110:   speed is not locked (i.e. DIAL SPEED-MATCHING is not ON), then change the
        !          1111:   device speed to the one given.
        !          1112: */
        !          1113: static VOID
        !          1114: #ifdef CK_ANSIC
        !          1115: spdchg(long s)
        !          1116: #else
        !          1117: spdchg(s) long s;
        !          1118: #endif /* CK_ANSIC */
        !          1119: /* spdchg */ {
        !          1120:     int s2;
        !          1121:     if (!mdmspd)                       /* If modem interface speed locked, */
        !          1122:       return;                          /*  don't do this. */
        !          1123:     if (speed != s) {                  /* Speeds differ? */
        !          1124:        s2 = s / 10L;                   /* Convert to cps expressed as int */
        !          1125:        if (ttsspd(s2) < 0) {           /* Change speed. */
        !          1126:            printf(" Warning: speed change to %ld failed.\r\n",s);
        !          1127:        } else {
        !          1128:            printf(" Speed changed to %ld.\r\n",s);
        !          1129:            speed = s;                  /* Update global speed variable */
        !          1130:        }
        !          1131:     }
        !          1132: }
        !          1133: 
        !          1134: /*
        !          1135:   Display all characters received from modem dialer through this routine,
        !          1136:   for consistent handling of carriage returns and linefeeds.
        !          1137: */
        !          1138: static VOID
        !          1139: #ifdef CK_ANSIC
        !          1140: dialoc(char c)
        !          1141: #else
        !          1142: dialoc(c) char c;
        !          1143: #endif /* CK_ANSIC */
        !          1144: { /* dialoc */                 /* Dial Output Character */
        !          1145:     if (dialdpy) {
        !          1146:        if (c != LF) conoc(c);          /* Don't echo LF */
        !          1147:        if (c == CR) conoc(LF);         /* Echo CR as CRLF */
        !          1148:     }
        !          1149: }
        !          1150: 
        !          1151: #ifndef MINIDIAL
        !          1152: /*
        !          1153:   tbati3() -- Routine to find out Telebit model when ATI reports "965"
        !          1154:   or "971". This routine sends another query, ATI3, to get further info
        !          1155:   to narrow down the model number.  Argument is ATI response as integer.
        !          1156:   Result: sets tbmodel variable to Telebit model.
        !          1157: */
        !          1158: static VOID
        !          1159: tbati3(n) int n; {
        !          1160:     int status;
        !          1161:     ttflui();                          /* Flush input buffer */
        !          1162:     ttslow("ATI3\015",100);            /* Send ATI3<CR> */
        !          1163:     status = getok(5,0);               /* Get OK response, nonstrict */
        !          1164:     if (status < 1) {                  /* ERROR or timeout */
        !          1165:        tbmodel = TB_UNK;
        !          1166:        debug(F111,"tbati3 fails",rbuf,status);
        !          1167:        return;
        !          1168:     }
        !          1169:     debug(F110,"tbati3 rbuf",rbuf,0);
        !          1170: 
        !          1171: /* Got a good response, check the model info */
        !          1172: 
        !          1173:     if (n == 965) {                    /* "965" - various models. */
        !          1174:        if (didweget(rbuf,"T1600")) {
        !          1175:            tbmodel = TB_1600;                  /* T1600 */
        !          1176:        } else if (didweget(rbuf,"T3000")) {
        !          1177:            tbmodel = TB_3000;                  /* T3000 */
        !          1178:        } else if (didweget(rbuf,"World")) {
        !          1179:            tbmodel = TB_WBLA;                  /* WorldBlazer */
        !          1180:        } else if (didweget(rbuf,"Version B") || /* TrailBlazer-Plus models */
        !          1181:                   didweget(rbuf,"TBSA") ||
        !          1182:                   didweget(rbuf,"TBRM") ||
        !          1183:                   didweget(rbuf,"DC")) {       /* Ven-Tel EC18K */
        !          1184:            tbmodel = TB_PLUS;
        !          1185:        } else tbmodel = TB_UNK;                /* Others: Unknown */
        !          1186: 
        !          1187:     } else if (n == 971) {             /* "971" could be T1500 or T1600. */
        !          1188:        if (didweget(rbuf,"T1500"))
        !          1189:          tbmodel = TB_1500;
        !          1190:        else tbmodel = TB_2500;
        !          1191:     }                                  /* Other, don't change tbmodel. */
        !          1192: }
        !          1193: #endif /* MINIDIAL */
        !          1194: 
        !          1195: 
        !          1196: /*  C K D I A L         --  Dial up the remote system */
        !          1197: 
        !          1198: /* Returns 1 if call completed, 0 otherwise */
        !          1199: 
        !          1200: static int waitct, mdmwait, mdmstat = 0;
        !          1201: 
        !          1202: int
        !          1203: ckdial(telnbr) char *telnbr; {
        !          1204: 
        !          1205:     char c, c2;
        !          1206:     char errmsg[50], *erp;             /* for error messages */
        !          1207:     char fullnum[100];                 /* for full (prefixed) phone number */
        !          1208:     MDMINF *pmdminf;                   /* pointer to modem-specific info */
        !          1209:     int x, m, n = F_time;
        !          1210:     char *s, *pc, *ws;
        !          1211: 
        !          1212:     long conspd;
        !          1213:     char *cptr;
        !          1214: 
        !          1215:     mymdmtyp = mdmtyp;                 /* Make local copy of modem type */
        !          1216: 
        !          1217: #ifndef MINIDIAL
        !          1218:     tbmodel = TB_UNK;                  /* Initialize Telebit model */
        !          1219: #endif /* MINIDIAL */
        !          1220: 
        !          1221:     if (mymdmtyp < 1) {
        !          1222:        if (network)
        !          1223:          printf("Please SET HOST first, and then SET MODEM\n");
        !          1224:        else
        !          1225:          printf("Sorry, you must SET MODEM first\n");
        !          1226:        return(0);
        !          1227:     }
        !          1228:     if (!local) {
        !          1229:        printf("Sorry, you must SET LINE or SET HOST first\n");
        !          1230:        return(0);
        !          1231:     }
        !          1232:     if (!network && speed < 0L) {
        !          1233:        printf("Sorry, you must SET SPEED first\n");
        !          1234:        return(0);
        !          1235:     }
        !          1236:     debug(F110,"dial number",telnbr,0);
        !          1237:     debug(F110,"dial prefix",(dialnpr ? dialnpr : ""), 0);
        !          1238: 
        !          1239: /* Add prefix to phone number */
        !          1240: 
        !          1241:     if (dialnpr && *dialnpr) {
        !          1242:        sprintf(fullnum,"%s%s",(dialnpr ? dialnpr : ""),telnbr);
        !          1243:        telnbr = fullnum;
        !          1244:     }
        !          1245:     debug(F110,"prefixed number", telnbr, 0);
        !          1246: 
        !          1247: #ifdef DYNAMIC
        !          1248:     if (!(lbuf = malloc(LBUFL+1))) {    /* Allocate input line buffer */
        !          1249:        printf("Sorry, DIAL memory buffer can't be allocated\n");
        !          1250:        return(0);
        !          1251:     }
        !          1252: #endif /* DYNAMIC */
        !          1253: 
        !          1254:     if (ttopen(ttname,&local,mymdmtyp,0) < 0) { /* Open, no carrier wait */
        !          1255:        erp = errmsg;
        !          1256:        sprintf(erp,"Sorry, can't open %s",ttname);
        !          1257:        perror(errmsg);
        !          1258:        return(0);
        !          1259:     }
        !          1260: 
        !          1261: /* Condition console terminal and communication line */
        !          1262: 
        !          1263:     /* Place line into "clocal" dialing state, */
        !          1264:     /* important mainly for System V UNIX.     */
        !          1265: 
        !          1266:     if (ttpkt(speed,FLO_DIAL,parity) < 0) {
        !          1267:        ttclos(0);                      /* If ttpkt fails do all this... */
        !          1268:        if (ttopen(ttname,&local,mymdmtyp,0) < 0) {
        !          1269:            erp = errmsg;
        !          1270:            sprintf(erp,"Sorry, can't reopen %s",ttname);
        !          1271:            perror(errmsg);
        !          1272:            return(0);
        !          1273:        }                               /* And try again. */
        !          1274:        if (ttpkt(speed,FLO_DIAL,parity) < 0) {
        !          1275:            printf("Sorry, Can't condition communication line\n");
        !          1276:            printf("Try 'set line %s' again\n",ttname);
        !          1277:            return(0);
        !          1278:        }
        !          1279:     }
        !          1280:     msleep(500);
        !          1281: 
        !          1282:     pmdminf = ptrtab[ (mymdmtyp & 0xff) -1 ]; /* set pointer to modem info */
        !          1283:     augmdmtyp = mymdmtyp;              /* initialize "augmented" modem type */
        !          1284:     mymdmtyp &= 0xff;                  /* major modem type */
        !          1285: 
        !          1286:     /* Interdigit waits for tone dial */
        !          1287: 
        !          1288:     if (dialtmo < 1) {                 /* Automatic computation. */
        !          1289:        waitct = 1 * (int)strlen(telnbr) ; /* Compute worst case dial time */
        !          1290:        waitct += pmdminf->dial_time;   /* dialtone + completion wait times */
        !          1291:        for (s = telnbr; *s; s++) {     /* add in pause characters time */
        !          1292:            for (p=pmdminf->pause_chars; *p; p++)
        !          1293:              if (*s == *p) {
        !          1294:                  waitct += pmdminf->pause_time;
        !          1295:                  break;
        !          1296:              }
        !          1297:        }
        !          1298: #ifndef MINIDIAL
        !          1299:        if (augmdmtyp == n_TBPEP || augmdmtyp == n_TBPNV) {
        !          1300:            waitct += 30;       /* Longer connect wait for PEP call */
        !          1301:        }
        !          1302: #endif /* MINIDIAL */
        !          1303:     } else {                           /* User-specified timeout */
        !          1304:        waitct = dialtmo;
        !          1305:     }
        !          1306: /*
        !          1307:   waitct is our alarm() timer.
        !          1308:   mdmwait is how long we tell the modem to wait for carrier.
        !          1309:   We set mdmwait to be 1 second less than waitct, to increase the
        !          1310:   chance that we get a response from the modem before timing out.
        !          1311: */
        !          1312:     if (waitct < 0) waitct = 0;
        !          1313:     mdmwait = (waitct > 5) ? waitct - 5 : waitct;
        !          1314: 
        !          1315:     for (m = 0; m < nmdm; m++) {       /* Look up modem type. */
        !          1316:        if (mdmtab[m].kwval == mymdmtyp) {
        !          1317:            break;
        !          1318:        }
        !          1319:     }
        !          1320:     if (!quiet && !backgrd) {          /* Print information messages. */
        !          1321:        printf(" Dialing: %s\n", telnbr);
        !          1322:        if (network) {
        !          1323:            printf(" Via modem server: %s, modem-dialer: %s\n",
        !          1324:                   ttname, (m >= nmdm ? "(unknown)" : mdmtab[m].kwd) );
        !          1325:        } else {
        !          1326:            printf(" Device: %s, modem-dialer: %s",
        !          1327:                   ttname, (m >= nmdm ? "(unknown)" : mdmtab[m].kwd) );
        !          1328:            if (speed > -1L)
        !          1329:              printf(", speed: %ld\n", speed);
        !          1330:            else
        !          1331:              printf(", speed: (unknown)\n", speed);
        !          1332:        }
        !          1333:        printf(" Dial timeout: %d seconds\n",waitct);
        !          1334:        printf(
        !          1335: #ifdef MAC
        !          1336:               " Type Command-. to cancel dialing\n"
        !          1337: #else
        !          1338: #ifdef UNIX
        !          1339:               " To cancel: type your interrupt character (normally Ctrl-C)\n"
        !          1340: #else
        !          1341:               " To cancel: type Ctrl-C\n"
        !          1342: #endif /* UNIX */
        !          1343: #endif /* MAC */
        !          1344:               );
        !          1345:     }
        !          1346:     debug(F111,"ckdial",ttname,(int) (speed / 10L));
        !          1347:     debug(F101,"ckdial timeout","",waitct);
        !          1348: 
        !          1349: /* Hang up the modem (in case it wasn't "on hook") */
        !          1350: /* But only if SET DIAL HANGUP ON... */
        !          1351: 
        !          1352:     if (dialhup() < 0) {
        !          1353:        debug(F100,"ckdial dialhup failed","",0);
        !          1354: #ifndef MINIDIAL
        !          1355:        if (mymdmtyp == n_TELEBIT)      /* Telebit might need a BREAK */
        !          1356:          ttsndb();                     /*  first. */
        !          1357: #endif /* MINIDIAL */
        !          1358:        if (dialhng) {                  /* If it failed, */
        !          1359:            ttclos(0);                  /* close and reopen the device. */
        !          1360:             if (ttopen(ttname,&local,mymdmtyp,0) < 0) {
        !          1361:                printf("Sorry, Can't hang up communication device\n");
        !          1362:                printf("Try 'set line %s' again\n",ttname);
        !          1363:                return(0);
        !          1364:            }
        !          1365:        }
        !          1366:     }
        !          1367: #ifndef MINIDIAL
        !          1368:     if (augmdmtyp == n_ROLM)           /* Don't start talking to Rolm */
        !          1369:       msleep(500);                     /* too soon... */
        !          1370: #endif /* MINIDIAL */
        !          1371: 
        !          1372: /*
        !          1373:   Establish jump vector, or handle "failure" jumps.
        !          1374:   longjmp() sets global failure reason, n1.
        !          1375: */
        !          1376:     if (setjmp(sjbuf)) {               /* if a "failure jump" was taken... */
        !          1377:        n = n1;
        !          1378:        alarm(0);                       /* disable timeouts */
        !          1379:        if (setjmp(sjbuf)) {            /* failure while handling failure */
        !          1380:            printf ("%s failure while handling failure.\n", F_reason[n1]);
        !          1381:        } else {                        /* first (i.e., non-nested) failure */
        !          1382:            signal(SIGALRM, dialtime);  /* be sure to catch signals */
        !          1383: #ifdef MAC
        !          1384:            signal(SIGINT, dialint);
        !          1385: #else /* MAC */
        !          1386: #ifdef OSK
        !          1387:            if (signal(SIGINT, SIG_IGN) != (SIGTYP (*)()) SIG_IGN)
        !          1388:                signal(SIGINT, dialint);
        !          1389: #else
        !          1390:            if (signal(SIGINT, SIG_IGN) != SIG_IGN)
        !          1391:                signal(SIGINT, dialint);
        !          1392: #endif /* OS9 */
        !          1393: #endif /* MAC */
        !          1394:            alarm(10);                  /* Be sure to exit this section */
        !          1395:        }
        !          1396:        switch (n) {                    /* Type of failure */
        !          1397:            case F_time: {              /* Timed out */
        !          1398:                printf ("DIAL TIMEOUT interval expired.\n");
        !          1399:                if (mymdmtyp == n_HAYES
        !          1400: #ifndef MINIDIAL
        !          1401:                    || mymdmtyp == n_TELEBIT || mymdmtyp == n_HST
        !          1402: #endif /* MINIDIAL */
        !          1403:                    )
        !          1404:                  ttoc('\015');         /* Send CR to interrupt dialing */
        !          1405:                  /* some hayes modems don't fail with BUSY on busy lines */
        !          1406:                debug(F110,"dial","timeout",0);
        !          1407:                break;
        !          1408:            }
        !          1409:            case F_int: {               /* Dialing interrupted */
        !          1410:                printf ("Dialing interrupted.\n");
        !          1411:                debug(F110,"dial","interrupted",0);
        !          1412:                if (mymdmtyp == n_HAYES
        !          1413: #ifndef MINIDIAL
        !          1414:                    || mymdmtyp == n_TELEBIT || mymdmtyp == n_HST
        !          1415: #endif /* MINIDIAL */
        !          1416:                    )
        !          1417:                  ttoc('\015');         /* Send CR to interrupt dialing */
        !          1418:                break;
        !          1419:            }
        !          1420:            case F_modem: {             /* Modem detected a failure */
        !          1421:                printf ("Call failed (\"");
        !          1422:                for (pc = lbuf; *pc; pc++)
        !          1423:                  if (isprint(*pc))
        !          1424:                    putchar(*pc);       /* Display printable reason */
        !          1425:                printf ("\").\n");
        !          1426:                debug(F110,"dial",lbuf,0);
        !          1427:                break;
        !          1428:            }
        !          1429:            case F_minit: {             /* Cannot initialize modem */
        !          1430:                printf ("Can't initialize modem.\n");
        !          1431:                debug(F110,"dial","modem init",0);
        !          1432:                break;
        !          1433:            }
        !          1434:        }
        !          1435:        dreset();                       /* reset alarms, etc. */
        !          1436: #ifdef DYNAMIC
        !          1437:        if (lbuf) free(lbuf);
        !          1438: #endif /* DYNAMIC */
        !          1439:        return(0);                      /* exit with failure code */
        !          1440:     }
        !          1441: 
        !          1442: /* Set timer and interrupt handlers. */
        !          1443: 
        !          1444:     alarm(0);                          /* No alarms yet. */
        !          1445: #ifdef MAC
        !          1446:     savint = signal(SIGINT, dialint);  /* And terminal interrupt handler. */
        !          1447: #else /* MAC */
        !          1448: #ifdef OSK
        !          1449:     if ((savint = signal(SIGINT,SIG_IGN)) != (SIGTYP (*)()) SIG_IGN)
        !          1450:       signal(SIGINT,dialint);
        !          1451: #else
        !          1452:     if ((savint = signal(SIGINT,SIG_IGN)) != SIG_IGN )
        !          1453:       signal(SIGINT,dialint);
        !          1454: #endif /* OS-9 */
        !          1455: #endif /* MAC */
        !          1456: 
        !          1457: /* Put modem in command mode. */
        !          1458: 
        !          1459: switch (augmdmtyp) {                   /* Send the wakeup string */
        !          1460: 
        !          1461: #ifdef ATT7300
        !          1462:        case n_ATTUPC: {
        !          1463: /*
        !          1464:   For ATT7300/Unix PC's with their special internal modem.  Timeout
        !          1465:   and user interrupts are enabled during dialing.  attdial() is in
        !          1466:   file ckutio.c.  - jrd
        !          1467: */
        !          1468: _PROTOTYP( int attdial, (char *, long, char *) );
        !          1469:             savalrm = signal(SIGALRM,dialtime); /* Set alarm handler. */
        !          1470:            alarm(waitct);                      /* do alarm properly */
        !          1471:            if (attdial(ttname,speed,telnbr)) { /* dial internal modem */
        !          1472:                dreset();                       /* reset alarms, etc. */
        !          1473:                printf(" Call failed.\r\n");
        !          1474:                dialhup();                      /* Hangup the call */
        !          1475: #ifdef DYNAMIC
        !          1476:                if (lbuf) free(lbuf);
        !          1477: #endif /* DYNAMIC */
        !          1478:                return(0);                      /* return failure */
        !          1479:            }
        !          1480:            dreset();                           /* reset alarms, etc. */
        !          1481:            ttpkt(speed,FLO_DIAX,parity);       /* cancel dialing ioctl */
        !          1482:            if (!quiet && !backgrd) {
        !          1483:                if (dialdpy) printf("\n");
        !          1484:                printf(" Call complete.\07\r\n");
        !          1485:            }
        !          1486: #ifdef DYNAMIC
        !          1487:             if (lbuf) free(lbuf);
        !          1488: #endif /* DYNAMIC */
        !          1489:            return(1);   /* no conversation with modem to complete dialing */
        !          1490:        }
        !          1491: #endif /* ATT7300 */
        !          1492: 
        !          1493: /*
        !          1494:   For Hayes modem command language, figure out if modem is giving verbose
        !          1495:   or digit result codes.
        !          1496: */
        !          1497:     case n_HAYES:
        !          1498:     case n_HAYESNV:
        !          1499: #ifndef MINIDIAL
        !          1500:     case n_HST:
        !          1501:        if (augmdmtyp == n_HST)
        !          1502:          m = 255;
        !          1503:        else
        !          1504: #endif /* MINIDIAL */
        !          1505:          m = 60;                       /* Maximum value for S7 */
        !          1506:        ws = dialini ? dialini : HAYES.wake_str;
        !          1507:        for (tries = 4; tries > 0; tries--) {
        !          1508:            ttslow(ws,pmdminf->wake_rate);
        !          1509:            mdmstat = getok(4,1);
        !          1510:            if (mdmstat > 0) break;
        !          1511:            sleep(1);                   /* Wait before retrying */
        !          1512:        }
        !          1513:        if (mdmstat > 0) {              /* Initialized OK. */
        !          1514:            char hbuf[10];
        !          1515: /*
        !          1516:   Now tell the modem about our dial timeout.  For Hayes 1200, the maximum
        !          1517:   is 60 seconds.  For Hayes 2400 (the manual says) it is 30 seconds, but I'm
        !          1518:   not sure I believe this (I don't have one handy to see for myself).
        !          1519:   If you give the modem a value larger than its maximum, it sets the timeout
        !          1520:   to its maximum.  The manual does not say what happens when the value is 0,
        !          1521:   but experimentation shows that it allows the modem to wait forever, in
        !          1522:   which case Kermit will time out at the desired time.
        !          1523: */
        !          1524: /*
        !          1525:   Note by Kai Uwe Rommel:
        !          1526:   This is not acceptable for general use of the hayes modem type with other
        !          1527:   compatible modems. Most other modems allow a range of 1..255 while 0 is
        !          1528:   invalid on several modems. Let it be the user's responsibility to make
        !          1529:   sure a valid value is used. Higher values are desirable for users with
        !          1530:   rotary dialing and with high speed modems, where protocol negotiation takes
        !          1531:   quite a long time.
        !          1532: */
        !          1533: #ifdef COMMENT
        !          1534:            if (mdmwait > m)            /* If larger than maximum, */
        !          1535:              mdmwait = 0;              /* make it infinite. */
        !          1536: #else
        !          1537:            if (mdmwait > 255)          /* If larger than maximum, */
        !          1538:              mdmwait = 255;            /* make it maximum. */
        !          1539: #endif /* COMMENT */
        !          1540: 
        !          1541:            sprintf(hbuf,"ATS7=%d%c",mdmwait,13); /* S7 = Carrier wait time */
        !          1542:            ttslow(hbuf,pmdminf->wake_rate); /* Set it. */
        !          1543:            mdmstat = getok(4,1);       /* Get response from modem */
        !          1544:            debug(F101,"S7 mdmstat","",mdmstat);
        !          1545:            break;                      /* Errors here are not fatal */
        !          1546:        }
        !          1547:        /* modem-initialization failure */
        !          1548:        n1 = (mdmstat == 0) ? F_minit : F_modem;
        !          1549:        longjmp( sjbuf, n1 );
        !          1550: 
        !          1551: #ifndef MINIDIAL
        !          1552: 
        !          1553: /*
        !          1554:   Telebit modems fall into two basic groups: old and new.  The functions and
        !          1555:   command sets are different between the two groups, and also vary by specific
        !          1556:   models within each group, and even by firmware ROM revision number.  Read
        !          1557:   ckcker.bwr for details.
        !          1558: 
        !          1559:   Commands used by C-Kermit include:
        !          1560: 
        !          1561:     Old       New            Meaning
        !          1562:     -------   --------       ----------------------------------------
        !          1563:     Q0        Q0             Enable result codes.
        !          1564:     X1        X1             Extended result codes.
        !          1565:     X1        X1             Extended result codes + BUSY, NO DIALTONE, etc.
        !          1566:     I         I              Model number inquiry.
        !          1567:     I3        I3             Additional model information inquiry.
        !          1568:     S12=50    S12=50         Escape sequence guard time (1 sec).
        !          1569:     S2=43     S2=43          Escape character is '+'.
        !          1570:     S7=xx     S7=xx          DIAL TIMEOUT, calculated or SET by user.
        !          1571:     S48=0     S48=0          7-bit data (Kermit's PARITY is not NONE).
        !          1572:     S48=1     S48=1          8-bit data (Kermit's PARITY is NONE).
        !          1573:     S50=0     S50=0          Automatic speed & protocol determination.
        !          1574:     S50=3     S50=3          2400/1200/300 bps.
        !          1575:     S50=6     S50=6          V.32 (9600 bps).
        !          1576:     S50=255   S50=255        PEP mode.
        !          1577:     S110=1    S190=1 S191=7  Allow compression in PEP mode.
        !          1578:     S51=?     S51=?          DTE interface speed (left alone by Kermit).
        !          1579:     S54=3     S61=0 S63=0    Pass BREAK signal (always).
        !          1580:     S58=2     S58=2          RTS/CTS flow control if Kermit's FLOW is RTS/CTS.
        !          1581:     S58=?     S58=?          S58 unchanged if Kermit's FLOW is not RTS/CTS.
        !          1582:     S68=255   S68=255        Use flow control specified by S58 (always).
        !          1583:     S95=0     S180=0         MNP disabled (SET DIAL MNP-ENABLE OFF)
        !          1584:     S95=2     S180=3         MNP, fallback to direct (also as V.42 fallback)
        !          1585:     S97=1     S180=2         Enable V.42 (LAPM) error correction
        !          1586:     S98=3                    Enable compression in both directions
        !          1587:     S106=1                   V.42bis compression enable
        !          1588: 
        !          1589: For Kermit Spoof (same commands for all models that support it):
        !          1590: 
        !          1591:     S111=0                   No Kermit spoofing
        !          1592:     S111=10                  Kermit with no parity
        !          1593:     S111=11                  Kermit with odd parity
        !          1594:     S111=12                  Kermit with even parity
        !          1595:     S111=13                  Kermit with mark parity
        !          1596:     S111=14                  Kermit with space parity
        !          1597:     S112=??                  Kermit's start-of-packet character (stchr).
        !          1598: */
        !          1599:     case n_TELEBIT:                    /* Telebits... */
        !          1600:     case n_TBPEP:
        !          1601:     case n_TB3:
        !          1602:     case n_TB4:
        !          1603:     case n_TBS:
        !          1604:     case n_TBNV:
        !          1605:     case n_TBPNV:
        !          1606:     case n_TB3NV:
        !          1607:     case n_TB4NV:
        !          1608:     case n_TBSNV: {
        !          1609:        int S111;                       /* Telebit Kermit spoof register */
        !          1610:        char tbcmdbuf[64];              /* Telebit modem command buffer */
        !          1611:        char *mnpstr = "";              /* Pointer to MNP-enable string */
        !          1612:        char *dprstr = "";              /* Pointer to dial protocol string */
        !          1613: /*
        !          1614:   If user defined a DIAL INIT-STRING, send that now, otherwise send built-in
        !          1615:   Telebit string.  Try up to 4 times to get OK or 0 response from modem.
        !          1616:   NOTE: The default init string *must* be independent of Telebit model.
        !          1617: */
        !          1618:        ws = dialini ? dialini : TELEBIT.wake_str;
        !          1619:        debug(F110,"ckdial telebit init string",ws,0);
        !          1620:        for (tries = 4; tries > 0; tries--) {
        !          1621:            ttsndb();                   /* Begin by sending BREAK */
        !          1622:            ttslow(ws,pmdminf->wake_rate); /* Send wakeup string */
        !          1623:            mdmstat = getok(5,0);       /* Get modem's response */
        !          1624:            if (mdmstat) break;         /* If response OK, done */
        !          1625:            msleep(300);                /* Otherwise, sleep 1/3 second */
        !          1626:            dialhup();                  /* Hang up */
        !          1627:            ttflui();                   /* Flush input buffer and try again */
        !          1628:        }
        !          1629:        if (mdmstat < 1) {              /* If we didn't get a response */
        !          1630:            n1 = F_minit;               /* fail, reason = can't initialize */
        !          1631:            longjmp( sjbuf, F_minit );
        !          1632:        }
        !          1633:        if (!dialini) {                 /* If using built-in init strings... */
        !          1634: /*
        !          1635:   Try to get the model number.  It should be in the getok() response buffer,
        !          1636:   rbuf[], because the Telebit init string asks for it with the "I" command.
        !          1637:   If the model number is 965, we have to make another query to narrow it down.
        !          1638: */
        !          1639:            if (didweget(rbuf,"962") || /* Check model number */
        !          1640:                didweget(rbuf,"961") ||
        !          1641:                didweget(rbuf,"963")) {
        !          1642:                tbmodel = TB_BLAZ;      /* Trailblazer */
        !          1643:            } else if (didweget(rbuf,"972")) {
        !          1644:                tbmodel = TB_2500;      /* T2500 */
        !          1645:            } else if (didweget(rbuf,"968")) {
        !          1646:                tbmodel = TB_1000;      /* T1000 */
        !          1647:            } else if (didweget(rbuf,"966") ||
        !          1648:                       didweget(rbuf,"967") ||
        !          1649:                       didweget(rbuf,"964")) {
        !          1650:                tbmodel = TB_PLUS;      /* Trailblazer-Plus */
        !          1651:            } else if (didweget(rbuf,"969")) {
        !          1652:                tbmodel = TB_QBLA;      /* Qblazer */
        !          1653:            } else if (didweget(rbuf,"965")) { /* Most new models */
        !          1654:                tbati3(965);            /* Go find out */
        !          1655:            } else if (didweget(rbuf,"971")) { /* T1500 or T2500 */
        !          1656:                tbati3(971);            /* Go find out */
        !          1657:            } else if (didweget(rbuf,"123") || didweget(rbuf,"960")) {
        !          1658:                tbmodel = TB_UNK;       /* Telebit in Hayes mode */
        !          1659:            }
        !          1660:            debug(F111,"Telebit model",tb_name[tbmodel],tbmodel);
        !          1661:            if (dialdpy)
        !          1662:              printf("Telebit model: %s\n",tb_name[tbmodel]);
        !          1663:            ttflui();
        !          1664: /*
        !          1665:   Dial timeout.  S7 is set to the DIAL TIMEOUT value, or else to 255 if the
        !          1666:   dial timeout is greater than 255, which is the maximum value for Telebits.
        !          1667:   S7 can't be set to 0 on Telebits -- it gives an error.
        !          1668: */
        !          1669:            if (mdmwait > 255)          /* If dial timeout too big */
        !          1670:              mdmwait = 255;            /* make it as big as possible. */
        !          1671: /*
        !          1672:   Flow control.  If C-Kermit's FLOW-CONTROL is RTS/CTS, then we set this on
        !          1673:   the modem too.  Unfortunately, many versions of UNIX only allow RTS/CTS
        !          1674:   to be set outside of Kermit (e.g. by selecting a special device name).
        !          1675:   In that case, Kermit doesn't know that it should set RTS/CTS on the modem,
        !          1676:   in which case the user can add the appropriate Telebit command with
        !          1677:   SET DIAL DIAL-COMMAND.
        !          1678: */
        !          1679:            if (flow == FLO_RTSC) {     /* RTS/CTS active in Kermit */
        !          1680:                sprintf(tbcmdbuf,
        !          1681:                        "ATS7=%d S48=%d S50=0 S58=2 S68=255\015",
        !          1682:                        mdmwait, parity ? 0 : 1);
        !          1683:            } else
        !          1684:              sprintf(tbcmdbuf,         /* Otherwise, don't touch modem's */
        !          1685:                      "ATS7=%d S48=%d S50=0 S68=255\015", /* flow control */
        !          1686:                      mdmwait, parity ? 0 : 1);           /* setting. */
        !          1687:            s = tbcmdbuf;
        !          1688:            debug(F110,"ckdial Telebit init step 2",s,0);
        !          1689:            for (tries = 4; tries > 0; tries--) {
        !          1690:                ttslow(s,pmdminf->wake_rate);
        !          1691:                mdmstat = getok(5,1);
        !          1692:                if (mdmstat) break;
        !          1693:                msleep(500);
        !          1694:                ttflui();
        !          1695:            }
        !          1696:            if (mdmstat < 1) {
        !          1697:                n1 = F_minit;
        !          1698:                longjmp( sjbuf, F_minit ); /* Failed. */
        !          1699:            }
        !          1700: /*
        !          1701:   Model-dependent items, but constant per model.
        !          1702: */
        !          1703:            switch(tbmodel) {
        !          1704:              case TB_BLAZ:
        !          1705:              case TB_PLUS:             /* TrailBlazer-Plus */
        !          1706:              case TB_1000:             /* T1000 */
        !          1707:              case TB_2000:             /* T2000 */
        !          1708:              case TB_2500:             /* T2500 */
        !          1709: #ifdef COMMENT
        !          1710: /* Code from edit 183 told modem to follow RS-232 wrt CD and DTR */
        !          1711:                /* DTR, CD, follow RS-232, pass BREAK */
        !          1712:                sprintf(tbcmdbuf,"ATS52=1 S53=4 S54=3\015");
        !          1713: #else
        !          1714: /* But everybody agreed we should not touch modem's CD and DTR settings. */
        !          1715:                /* Just pass BREAK */
        !          1716:                sprintf(tbcmdbuf,"ATS54=3\015");
        !          1717: #endif /* COMMENT */
        !          1718:                break;
        !          1719:              case TB_1600:             /* T1600 */
        !          1720:              case TB_3000:             /* T3000 */
        !          1721:              case TB_WBLA:             /* WorldBlazer */
        !          1722:              case TB_QBLA:             /* Qblazer */
        !          1723: #ifdef COMMENT
        !          1724: /* Code from edit 183 */
        !          1725:                /* Follow RS-232, No CONNECT suffix, pass BREAK */
        !          1726:                sprintf(tbcmdbuf,"AT&C1&D2&Q0 S59=0 S61=0 S63=0\015");
        !          1727: #else
        !          1728: /* Everybody agrees we should not touch modem's CD and DTR settings. */
        !          1729: /* Also no more &Q0, no more S59=0 (doesn't matter, so don't touch). */
        !          1730: /* So this section now deals only with treatment of BREAK. */
        !          1731: /* Here we also raise the result code from X1 to X2, which allows */
        !          1732: /* the T1600, T3000, and WB to supply NO DIALTONE, BUSY, RRING, and DIALING. */
        !          1733: /* X2 means something else on the other models. */
        !          1734:                /* Transmit BREAK in sequence, raise result code. */
        !          1735:                sprintf(tbcmdbuf,"ATX2 S61=0 S63=0\015");
        !          1736: #endif /* COMMENT */
        !          1737:                break;
        !          1738:              default:                  /* Others, do nothing */
        !          1739:                tbcmdbuf[0] = NUL;
        !          1740:                break;
        !          1741:            }
        !          1742:            s = tbcmdbuf;
        !          1743:            if (*s) {
        !          1744:                debug(F110,"ckdial Telebit init step 3",s,0);
        !          1745:                for (tries = 4; tries > 0; tries--) {
        !          1746:                    ttslow(s,pmdminf->wake_rate);
        !          1747:                    mdmstat = getok(5,1);
        !          1748:                    if (mdmstat) break;
        !          1749:                    msleep(500);
        !          1750:                    ttflui();
        !          1751:                }
        !          1752:                if (mdmstat < 1) {
        !          1753:                    n1 = F_minit;
        !          1754:                    longjmp( sjbuf, F_minit ); /* Failed. */
        !          1755:                }
        !          1756:            } else debug(F100,"ckdial Telebit init step 3 skipped","",0);
        !          1757: 
        !          1758: /* Error correction, MNP or V.42 */
        !          1759: 
        !          1760:            if (augmdmtyp & DIAL_V42) { /* User wants V.42 */
        !          1761:                switch (tbmodel) {      /* which implies fallback to MNP. */
        !          1762:                  case TB_PLUS:         /* BC7.00 and up firmware */
        !          1763:                  case TB_2000:         /* now really the same as TB+ ? */
        !          1764:                  case TB_2500:         /* LAPM+compress->MNP->direct */
        !          1765:                    mnpstr = "S50=0 S95=2 S97=1 S98=3 S106=1";
        !          1766:                    break;
        !          1767:                  case TB_1600:
        !          1768:                  case TB_3000:
        !          1769:                  case TB_WBLA:
        !          1770:                  case TB_QBLA:
        !          1771: #ifdef COMMENT
        !          1772:                    mnpstr = "S180=2 S181=0"; /* V.42, fallback = lock speed */
        !          1773: #else
        !          1774: /* Better not to mess with S181, let it be used however user has it set. */
        !          1775: /* S180=2 allows fallback to MNP, S180=1 disallows fallback to MNP. */
        !          1776:                    mnpstr = "S180=2";  /* V.42 */
        !          1777: #endif /* COMMENT */
        !          1778:                    break;
        !          1779:                  default:
        !          1780:                    if (dialdpy)
        !          1781:                      printf("V.42 not supported by this Telebit model\n");
        !          1782:                }
        !          1783:            } else {                    /* Handle DIAL MNP-ENABLE setting */
        !          1784:                switch (tbmodel) {
        !          1785:                  case TB_BLAZ:         /* TrailBlazer */
        !          1786:                  case TB_PLUS:         /* TrailBlazer-Plus */
        !          1787:                  case TB_1000:         /* T1000 */
        !          1788:                  case TB_2000:         /* T2000 */
        !          1789:                  case TB_2500:         /* T2500 */
        !          1790:                    mnpstr = dialmnp ? "S95=2" : "S95=0"; /* ON, OFF */
        !          1791:                    break;
        !          1792:                  case TB_1600:         /* T1600 */
        !          1793:                  case TB_3000:         /* T3000 */
        !          1794:                  case TB_WBLA:         /* WorldBlazer */
        !          1795:                  case TB_QBLA:         /* Qblazer */
        !          1796:                    mnpstr = dialmnp ? "S180=3" : "S180=0"; /* ON, OFF */
        !          1797:                    /* (Leave S181 fallback method alone) */
        !          1798:                    break;
        !          1799:                  default:
        !          1800:                    mnpstr = "";
        !          1801:                }
        !          1802:            }
        !          1803: 
        !          1804: /* Dialing protocol */
        !          1805: 
        !          1806:            dprstr = "";        /* Initialize dialing protocol string */
        !          1807:            p = "";             /* and message string */
        !          1808:            switch (augmdmtyp) {
        !          1809:              case n_TELEBIT:           /* Start at highest and work down */
        !          1810:               case n_TBNV:
        !          1811:                        p = "standard";
        !          1812:                switch (tbmodel) {      /* First group starts with PEP */
        !          1813:                  case TB_BLAZ:         /* TrailBlazer */
        !          1814:                  case TB_PLUS:         /* TrailBlazer-Plus */
        !          1815:                  case TB_1000:         /* T1000 */
        !          1816:                  case TB_2000:         /* T2000 */
        !          1817:                  case TB_2500:         /* T2500 */
        !          1818:                    dprstr = "S50=0 S110=1"; /* PEP, compression allowed. */
        !          1819:                    break;
        !          1820:                  case TB_WBLA:         /* WorldBlazer has PEP */
        !          1821:                    dprstr = "S50=0 S190=1 S191=7"; /* PEP, */
        !          1822:                    break;                          /* compression allowed. */
        !          1823:                  case TB_1600:         /* T1600 doesn't have PEP */
        !          1824:                  case TB_3000:         /* T3000 doesn't */
        !          1825:                  case TB_QBLA:         /* Qblazer doesn't*/
        !          1826:                  default:
        !          1827:                    dprstr = "S50=0";   /* No PEP available */
        !          1828:                    break;
        !          1829:                }
        !          1830:                break;
        !          1831: 
        !          1832:              case n_TBS:               /* Telebit up to 2400 Baud */
        !          1833:              case n_TBSNV:             /* i.e. "Slow mode". */
        !          1834:                p = "300/1200/2400 Baud"; /* Leave S90 alone assuming it is */
        !          1835:                dprstr = "S50=3";         /* already set for V.22 vs 212A */
        !          1836:                break;
        !          1837:              case n_TB3:               /* Telebit V.32 */
        !          1838:              case n_TB3NV:
        !          1839:                if (tbmodel == TB_3000 || tbmodel == TB_1600 ||
        !          1840:                    tbmodel == TB_2500 || tbmodel == TB_WBLA) {
        !          1841:                    p = "V.32";
        !          1842:                    /* Note: we don't touch S51 (interface speed) here. */
        !          1843:                    /* We're already talking to the modem, and the modem */
        !          1844:                    /* SHOULD be able to make a V.32 call no matter what */
        !          1845:                    /* its interface speed is.  (In practice, however, */
        !          1846:                    /* that is not always true.) */
        !          1847:                    dprstr = "S50=6";
        !          1848:                } else if (dialdpy)
        !          1849:                  printf("V.32 not supported by this Telebit model.\n");
        !          1850:                break;
        !          1851:              case n_TBPEP:             /* Force PEP Protocol */
        !          1852:               case n_TBPNV:
        !          1853:                if (tbmodel != TB_1600 && /* Models that don't support PEP */
        !          1854:                    tbmodel != TB_3000 &&
        !          1855:                    tbmodel != TB_QBLA) {
        !          1856:                    p = "PEP";
        !          1857:                    if (tbmodel == TB_WBLA) /* WorldBlazer */
        !          1858:                      dprstr = "S50=255 S190=1 S191=7";
        !          1859:                    else if (tbmodel != TB_1000)
        !          1860:                      dprstr = "S50=255 S110=1"; /* TrailBlazer, etc. */
        !          1861:                    else dprstr = "S50=255"; /* T1000, no compression */
        !          1862:                } else if (dialdpy)
        !          1863:                  printf("PEP not supported by this Telebit model.\n");
        !          1864:                break;
        !          1865:            }
        !          1866: 
        !          1867: /* Kermit Spoof */
        !          1868: 
        !          1869:            if (dialksp) {
        !          1870:                p = "Kermit Spoof";
        !          1871:                switch (parity) {       /* S111 value depends on parity */
        !          1872:                  case 'e': S111 = 12; break;
        !          1873:                  case 'm': S111 = 13; break;
        !          1874:                  case 'o': S111 = 11; break;
        !          1875:                  case 's': S111 = 14; break;
        !          1876:                  case 0:
        !          1877:                  default:  S111 = 10; break;
        !          1878: 
        !          1879:                }
        !          1880: #ifdef COMMENT
        !          1881: /*
        !          1882:   This code forced the use of PEP mode if DIAL KERMIT-SPOOF was ON, which
        !          1883:   prevented successful connection if the other modem did not support PEP.
        !          1884: */
        !          1885:                if (tbmodel == TB_BLAZ || /* Must force PEP on old models */
        !          1886:                    tbmodel == TB_PLUS ||
        !          1887:                    tbmodel == TB_1000 ||
        !          1888:                    tbmodel == TB_2000 ||
        !          1889:                    tbmodel == TB_2500)
        !          1890:                  sprintf(tbcmdbuf,"AT%s %s S50=255 S111=%d S112=%d\015",
        !          1891:                          mnpstr,dprstr,S111,stchr);
        !          1892:                /* PEP is not required on T1500, T1600, T3000, and WB */
        !          1893:                /* (but MNP is, but that is user's responsibility).   */
        !          1894:                else
        !          1895: #endif /* COMMENT */
        !          1896:                  if (tbmodel != TB_QBLA)
        !          1897:                  sprintf(tbcmdbuf,"AT%s %s S111=%d S112=%d\015",
        !          1898:                          mnpstr,dprstr,S111,stchr);
        !          1899:                else {                  /* Qblazer has no Kermit spoof */
        !          1900:                    sprintf(tbcmdbuf,"AT%s %s\015", mnpstr,dprstr);
        !          1901:                    p = "No Kermit Spoof";
        !          1902:                    if (dialdpy)
        !          1903:                      printf("Kermit Spoof not supported by Qblazer\n");
        !          1904:                }
        !          1905:            } else {                    /* No Kermit spoof */
        !          1906:                p = "No Kermit Spoof";
        !          1907:                sprintf(tbcmdbuf,"AT%s %s %s\015",
        !          1908:                        mnpstr, dprstr,
        !          1909:                        (tbmodel == TB_QBLA) ? "" : "S111=0 S112=0");
        !          1910:            }
        !          1911:            s = tbcmdbuf;
        !          1912:            debug(F111,"ckdial Telebit config",p,speed);
        !          1913:            debug(F110,"ckdial Telebit init step 4",s,0);
        !          1914:            if (*s) {
        !          1915:                for (tries = 4; tries > 0; tries--) {
        !          1916:                    ttslow(s,pmdminf->wake_rate);
        !          1917:                    mdmstat = getok(5,1);
        !          1918:                    if (mdmstat) break;
        !          1919:                    msleep(500);
        !          1920:                    ttflui();
        !          1921:                }
        !          1922:                debug(F101,"ckdial telebit init mdmstat","",mdmstat);
        !          1923:                if (mdmstat < 1) {
        !          1924:                    n1 = F_minit;
        !          1925:                    longjmp(sjbuf, F_minit);
        !          1926:                }
        !          1927:            }
        !          1928:        }
        !          1929:        /* Done with Telebit protocols, remove bits from modem type */
        !          1930:        /* Except nonverbal bit */
        !          1931:        augmdmtyp &= ~(DIAL_PEP|DIAL_V32|DIAL_V42|DIAL_SLO);
        !          1932:        debug(F101,"ckdial Telebit augmdmtyp","",augmdmtyp);
        !          1933:        break;
        !          1934:     }
        !          1935: 
        !          1936:     case n_MICROCOM:                   /* Interdigit waits for tone dial */
        !          1937:         {
        !          1938:            jmp_buf savejmp;
        !          1939:            alarm(0);
        !          1940:            savalrm = signal(SIGALRM,dialtime); /* Set alarm handler. */
        !          1941:            xcpy((char *)savejmp, (char *)sjbuf, sizeof savejmp);
        !          1942:            if (setjmp(sjbuf)) {
        !          1943:                /* try the autobaud sequence */
        !          1944:                xcpy((char *)sjbuf, (char *)savejmp, sizeof savejmp);
        !          1945:                alarm(5);
        !          1946:                ttslow("44445", MICROCOM.wake_rate);
        !          1947:                waitfor(MICROCOM.wake_str);
        !          1948:            } else {
        !          1949:                alarm(2);
        !          1950:                ws = dialini ? dialini : MICROCOM.wake_str;
        !          1951:                ttslow(ws, MICROCOM.wake_rate);
        !          1952:                waitfor(ws);
        !          1953: #ifdef COMMENT
        !          1954: /*
        !          1955:   Kermit spoof for Microcom modems.  Untested.
        !          1956:   This is reportedly the way to do it for QX/3296c, QX/4232hs, QX/4232bis,
        !          1957:   and QX/9624c.  The effect on other models is unknown.
        !          1958: */
        !          1959:                ws = dialksp ? "APM1\015" : "APM0\015"; /* Kermit spoof */
        !          1960:                ttslow(ws, MICROCOM.wake_rate);
        !          1961:                waitfor(ws);
        !          1962: #endif /* COMMENT */
        !          1963:                alarm(0);
        !          1964:                signal(SIGALRM,savalrm); /* Set alarm handler. */
        !          1965:                xcpy((char *)sjbuf, (char *)savejmp, sizeof savejmp);
        !          1966:            }
        !          1967:        }
        !          1968:        break;
        !          1969: 
        !          1970:     case n_ATTDTDM:            /* DTDM requires BREAK to wake up */
        !          1971:        ttsndb();               /* Send BREAK */
        !          1972:        break;                  /* ttsndb() defined in ckutio.c */
        !          1973: 
        !          1974: #endif /* MINIDIAL */
        !          1975: 
        !          1976:     default:                   /* Place modem into command mode */
        !          1977:        ws = dialini ? dialini : pmdminf->wake_str;
        !          1978:        if (ws && (int)strlen(ws) > 0) {
        !          1979:            debug(F111,"ckdial default, wake string", ws, pmdminf->wake_rate);
        !          1980:            ttslow(ws, pmdminf->wake_rate);
        !          1981:        } else debug(F100,"ckdial no wake_str","",0);
        !          1982:        if (pmdminf->wake_prompt && (int)strlen(pmdminf->wake_prompt) > 0) {
        !          1983:            debug(F110,"ckdial default, waiting for wake_prompt",
        !          1984:                  pmdminf->wake_prompt,0);
        !          1985:            savalrm = signal(SIGALRM,dialtime);
        !          1986:            alarm(10);
        !          1987:            waitfor(pmdminf->wake_prompt);
        !          1988:        } else debug(F100,"ckdial no wake_prompt","",0);
        !          1989:        break;
        !          1990:     }
        !          1991:     alarm(0);                          /* Turn off alarm */
        !          1992:     signal(SIGALRM,savalrm);           /* Restore alarm handler. */
        !          1993:     debug(F100,"ckdial got wake prompt","",0);
        !          1994:     msleep(500);                       /* Allow settling time */
        !          1995: 
        !          1996: #ifndef MINIDIAL
        !          1997: 
        !          1998: /* Enable/disable MNP (Telebit already done above) */
        !          1999: 
        !          2000:     switch (augmdmtyp) {
        !          2001:       case n_HST:
        !          2002:        if (dialmnp)
        !          2003:          ttslow("AT&K2\015",pmdminf->wake_rate);
        !          2004:        else
        !          2005:          ttslow("AT&K0\015",pmdminf->wake_rate);
        !          2006:        getok(5,1);                     /* Get response */
        !          2007:        break;
        !          2008: 
        !          2009:      /* Add others here ... */
        !          2010: 
        !          2011:       default:
        !          2012:        break;
        !          2013:     }
        !          2014: #endif /* MINIDIAL */
        !          2015: 
        !          2016: /* Put modem into dialing mode, if the modem requires it. */
        !          2017: 
        !          2018:     if (pmdminf->dmode_str && *(pmdminf->dmode_str)) {
        !          2019:        ttslow(pmdminf->dmode_str, pmdminf->dial_rate);
        !          2020:        savalrm = signal(SIGALRM,dialtime);
        !          2021:        alarm(10);
        !          2022:        if (pmdminf->dmode_prompt) { /* Wait for prompt, if any expected */
        !          2023:            waitfor(pmdminf->dmode_prompt);
        !          2024:            msleep(300);
        !          2025:        }
        !          2026:        alarm(0);                /* Turn off alarm on dialing prompts */
        !          2027:        signal(SIGALRM,savalrm); /* Restore alarm */
        !          2028:        ttflui();                /* Clear out stuff from waking modem up */
        !          2029:     }
        !          2030: 
        !          2031: /* Dial the number.  First form the dialing string. */
        !          2032: 
        !          2033:     sprintf(lbuf, dialcmd ? dialcmd : pmdminf->dial_str, telnbr);
        !          2034:     debug(F110,"dialing",lbuf,0);
        !          2035:     ttslow(lbuf,pmdminf->dial_rate);   /* Send the dialing string */
        !          2036: 
        !          2037:     savalrm = signal(SIGALRM,dialtime);        /* Time to allow for connecting */
        !          2038:     x = alarm(waitct);                 /* This much time... */
        !          2039:     debug(F101,"ckdial old alarm","",x);
        !          2040:     debug(F101,"ckdial waitct","",waitct);
        !          2041: 
        !          2042: #ifndef MINIDIAL
        !          2043:     switch (augmdmtyp) {
        !          2044:     case n_RACAL:         /* Acknowledge printout of dialing string */
        !          2045:       sleep(3);
        !          2046:       ttflui();
        !          2047:       ttoc('\015');
        !          2048:       break;
        !          2049:     case n_VENTEL:
        !          2050:       waitfor("\012\012"); /* Ignore the first two strings */
        !          2051:       break;
        !          2052:     default:
        !          2053:       break;
        !          2054:     }
        !          2055: #endif /* MINIDIAL */
        !          2056: 
        !          2057: /* Check for connection */
        !          2058: 
        !          2059:     mdmstat = 0;                       /* No status yet */
        !          2060:     strcpy(lbuf,"No Connection");      /* Default reason for failure */
        !          2061:     debug(F101,"dial awaiting response, augmdmtyp","",augmdmtyp);
        !          2062:     while (mdmstat == 0) {
        !          2063:        switch (augmdmtyp) {
        !          2064:          default:
        !          2065:            for (n = -1; n < LBUFL-1; ) { /* Accumulate response */
        !          2066:                c2 = ddinc(0);          /* Read a character, blocking */
        !          2067:                if (c2 == 0 || c2 == -1) /* Ignore NULs and errors */
        !          2068:                  continue;             /* (Timeout will handle errors) */
        !          2069:                else                    /* Real character, keep it */
        !          2070:                  lbuf[++n] = c2 & 0177;
        !          2071:                dialoc(lbuf[n]);        /* Maybe echo it  */
        !          2072:                 if (augmdmtyp == n_CCITT) { /* V.25 bis dialing... */
        !          2073: /*
        !          2074:   This assumes that V.25bis indications are all at least 3 characters long
        !          2075:   and are terminated by either CRLF or LFCR.
        !          2076: */
        !          2077:                    if (n < 3) continue;
        !          2078:                    if ((lbuf[n] == CR) && (lbuf[n-1] == LF)) break;
        !          2079:                    if ((lbuf[n] == LF) && (lbuf[n-1] == CR)) break;
        !          2080:                }
        !          2081: #ifndef MINIDIAL
        !          2082:                  else if (augmdmtyp == n_DIGITEL) {
        !          2083:                    if ((lbuf[n] == CR) && (lbuf[n-1] == LF) ||
        !          2084:                        (lbuf[n] == LF) && (lbuf[n-1] == CR))
        !          2085:                      break;
        !          2086:                    else
        !          2087:                      continue;
        !          2088:                }
        !          2089: #endif /* MINIDIAL */
        !          2090:                  else {                /* All others, break on CR or LF */
        !          2091:                    if ( lbuf[n] == CR || lbuf[n] == LF ) break;
        !          2092:                }
        !          2093:            }
        !          2094:            lbuf[++n] = '\0';           /* Terminate response from modem */
        !          2095:            debug(F111,"dial modem response",lbuf,n);
        !          2096:            if (n) {                    /* If one or more characters present */
        !          2097:                switch (augmdmtyp) {    /* check for modem response message. */
        !          2098: #ifndef MINIDIAL
        !          2099:                  case n_ATTMODEM:
        !          2100:                    /* Careful - "Connected" / "Not Connected" */
        !          2101:                    if (didweget(lbuf,"Busy") ||
        !          2102:                        didweget(lbuf,"Not connected") ||
        !          2103:                        didweget(lbuf,"Not Connected") ||
        !          2104:                        didweget(lbuf,"No dial tone") ||
        !          2105:                        didweget(lbuf,"No Dial Tone") ||
        !          2106:                        didweget(lbuf,"No answer") ||
        !          2107:                        didweget(lbuf,"No Answer"))
        !          2108:                        mdmstat = FAILED;
        !          2109:                    else if (didweget(lbuf,"Answered") ||
        !          2110:                        didweget(lbuf,"Connected"))
        !          2111:                        mdmstat = CONNECTED;
        !          2112:                    break;
        !          2113: 
        !          2114:                  case n_ATTISN:
        !          2115:                    if (didweget(lbuf,"ANSWERED"))
        !          2116:                        mdmstat = CONNECTED;
        !          2117:                    else if (didweget(lbuf,"BUSY") ||
        !          2118:                        didweget(lbuf,"DISCONNECT") ||
        !          2119:                        didweget(lbuf,"NO ANSWER") ||
        !          2120:                        didweget(lbuf,"WRONG ADDRESS"))
        !          2121:                        mdmstat = FAILED;
        !          2122:                    break;
        !          2123: 
        !          2124:                  case n_ATTDTDM:
        !          2125:                    if (didweget(lbuf,"ANSWERED"))
        !          2126:                        mdmstat = CONNECTED;
        !          2127:                    else if (didweget(lbuf,"BUSY") ||
        !          2128:                        didweget(lbuf,"CHECK OPTIONS") ||
        !          2129:                        didweget(lbuf,"DISCONNECTED") ||
        !          2130:                        didweget(lbuf,"DENIED"))
        !          2131:                        mdmstat = FAILED;
        !          2132: #ifdef DEBUG
        !          2133: #ifdef ATT6300
        !          2134:                    else if (deblog && didweget(lbuf,"~~"))
        !          2135:                        mdmstat = CONNECTED;
        !          2136: #endif /* ATT6300 */
        !          2137: #endif /* DEBUG */
        !          2138:                    break;
        !          2139: #endif /* MINIDIAL */
        !          2140: 
        !          2141:                  case n_CCITT:                 /* CCITT V.25bis */
        !          2142: #ifndef MINIDIAL
        !          2143:                  case n_DIGITEL:               /* or Digitel variant */
        !          2144: #endif /* MINIDIAL */
        !          2145:                    if (didweget(lbuf,"VAL")) { /* Dial command confirmation */
        !          2146: #ifndef MINIDIAL
        !          2147:                        if (augmdmtyp == n_CCITT)
        !          2148: #endif /* MINIDIAL */
        !          2149:                          continue;             /* Go back and read more */
        !          2150: #ifndef MINIDIAL
        !          2151: /* Digitel doesn't give an explicit connect confirmation message */
        !          2152:                        else {
        !          2153:                            int n;
        !          2154:                            for (n = -1; n < LBUFL-1; ) {
        !          2155:                                lbuf[++n] = c2 = ddinc(0) & 0177;
        !          2156:                                dialoc(lbuf[n]);
        !          2157:                                if ((lbuf[n] == CR) && (lbuf[n-1] == LF) ||
        !          2158:                                    (lbuf[n] == LF) && (lbuf[n-1] == CR))
        !          2159:                                  break;
        !          2160:                            }
        !          2161:                            mdmstat = CONNECTED; /* Assume we're connected */
        !          2162:                            if (dialdpy && carrier != CAR_OFF) {
        !          2163:                                sleep(1);       /* Wait a second */
        !          2164:                                n = ttgmdm();   /* Try to read modem signals */
        !          2165:                                if ((n > -1) && (n & BM_DCD == 0))
        !          2166:                                  printf("Warning: No Carrier\n");
        !          2167:                            }
        !          2168:                      }
        !          2169: #endif /* MINIDIAL */
        !          2170:                    } else if (didweget(lbuf,"CNX")) { /* Connected */
        !          2171:                        mdmstat = CONNECTED;
        !          2172:                     } else if (didweget(lbuf, "INV")) {
        !          2173:                        mdmstat = FAILED;       /* Command error */
        !          2174:                        strcpy(lbuf,"INV");
        !          2175:                    } else if (didweget(lbuf,"CFI")) { /* Call Failure */
        !          2176: #ifdef COMMENT
        !          2177: /*
        !          2178:   V.25 bis says that the failure reason comes on the same line, so
        !          2179:   we don't need to read any more characters here.
        !          2180: */
        !          2181:                        for (n = 0; n < LBUFL-1; n++) { /* Read reason */
        !          2182:                            lbuf[n] = c2 = (ddinc(0) & 0177);
        !          2183:                             if (c2 == LF) /* Modem answers LF CR */
        !          2184:                              continue;
        !          2185:                            dialoc(lbuf[n]);
        !          2186:                            if (lbuf[n] == CR || lbuf[n] == LF) break;
        !          2187:                        }
        !          2188: #endif /* COMMENT */
        !          2189:                        if (didweget(lbuf,"AB")) /* Interpret reason code */
        !          2190:                          strcpy(lbuf,"AB: Timed out");
        !          2191:                        else if (didweget(lbuf,"CB"))
        !          2192:                          strcpy(lbuf,"CB: Local DCE Busy");
        !          2193:                        else if (didweget(lbuf,"ET"))
        !          2194:                          strcpy(lbuf,"ET: Busy");
        !          2195:                        else if (didweget(lbuf, "NS"))
        !          2196:                          strcpy(lbuf,"NS: Number not stored");
        !          2197:                        else if (didweget(lbuf,"NT"))
        !          2198:                          strcpy(lbuf,"NT: No answer");
        !          2199:                        else if (didweget(lbuf,"RT"))
        !          2200:                          strcpy(lbuf,"RT: Ring tone");
        !          2201:                        else if (didweget(lbuf,"PV"))
        !          2202:                          strcpy(lbuf,"PV: Parameter value error");
        !          2203:                        else if (didweget(lbuf,"PS"))
        !          2204:                          strcpy(lbuf,"PS: Parameter syntax error");
        !          2205:                        else if (didweget(lbuf,"MS"))
        !          2206:                          strcpy(lbuf,"MS: Message syntax error");
        !          2207:                        else if (didweget(lbuf,"CU"))
        !          2208:                          strcpy(lbuf,"CU: Command unknown");
        !          2209:                        else if (didweget(lbuf,"FC"))
        !          2210:                          strcpy(lbuf,"FC: Forbidden call");
        !          2211:                        mdmstat = FAILED;
        !          2212:                    } else if (didweget(lbuf,"INC")) { /* Incoming Call */
        !          2213:                        strcpy(lbuf,"INC: Incoming call");
        !          2214:                        mdmstat = FAILED;
        !          2215:                    } else if (didweget(lbuf,"DLC")) { /* Delayed Call */
        !          2216:                        strcpy(lbuf,"DLC: Delayed call");
        !          2217:                        mdmstat = FAILED;
        !          2218:                    } else              /* Response was probably an echo. */
        !          2219: #ifndef MINIDIAL
        !          2220:                      if (augmdmtyp == n_CCITT)
        !          2221: #endif /* MINIDIAL */
        !          2222:                        continue;
        !          2223: #ifndef MINIDIAL
        !          2224:                      else      /* Digitel: If no error, then connect. */
        !          2225:                        mdmstat = CONNECTED;
        !          2226: #endif /* MINIDIAL */
        !          2227:                    break;
        !          2228: 
        !          2229: #ifndef MINIDIAL
        !          2230:                  case n_CERMETEK:
        !          2231:                    if (didweget(lbuf,"\016A")) {
        !          2232:                        mdmstat = CONNECTED;
        !          2233:                        ttslow("\016U 1\015",200); /* make transparent*/
        !          2234:                    }
        !          2235:                    break;
        !          2236: 
        !          2237:                  case n_DF100:      /* DF100 has short response codes */
        !          2238:                    if (strcmp(lbuf,"A") == 0)
        !          2239:                        mdmstat = CONNECTED; /* Attached */
        !          2240:                    else if (strcmp(lbuf,"N") == 0 || /* No Ans or Dialtone */
        !          2241:                             strcmp(lbuf,"E") == 0 || /* Error */
        !          2242:                             strcmp(lbuf,"R") == 0) { /* Ready */
        !          2243:                        mdmstat = FAILED;
        !          2244:                        break;
        !          2245:                    }
        !          2246:                    /* otherwise fall thru... */
        !          2247: 
        !          2248:                  case n_DF200:
        !          2249:                    if (didweget(lbuf,"Attached"))
        !          2250:                        mdmstat = CONNECTED;
        !          2251:                    /*
        !          2252:                     * The DF100 will respond with "Attached" even if DTR
        !          2253:                     * and/or carrier are not present.  Another reason to
        !          2254:                     * (also) wait for carrier?
        !          2255:                     */
        !          2256:                    else if (didweget(lbuf,"Busy") ||
        !          2257:                        didweget(lbuf,"Disconnected") ||
        !          2258:                        didweget(lbuf,"Error") ||
        !          2259:                        didweget(lbuf,"No answer") ||
        !          2260:                        didweget(lbuf,"No dial tone") ||
        !          2261:                        didweget(lbuf,"Speed:"))
        !          2262:                        mdmstat = FAILED;
        !          2263:                    /*
        !          2264:                     * It appears that the "Speed:..." response comes after an
        !          2265:                     * "Attached" response, so this is never seen.  HOWEVER,
        !          2266:                     * it would be very handy to detect this and temporarily
        !          2267:                     * reset the speed, since it's a nuisance otherwise.
        !          2268:                     * If we wait for some more input from the modem, how do
        !          2269:                     * we know if it's from the remote host or the modem?
        !          2270:                     * Carrier reportedly doesn't get set until after the
        !          2271:                     * "Speed:..." response (if any) is sent.  Another reason
        !          2272:                     * to (also) wait for carrier.
        !          2273:                     */
        !          2274:                    break;
        !          2275: 
        !          2276:                  case n_GDC:
        !          2277:                    if (didweget(lbuf,"ON LINE"))
        !          2278:                        mdmstat = CONNECTED;
        !          2279:                    else if (didweget(lbuf,"NO CONNECT"))
        !          2280:                        mdmstat = FAILED;
        !          2281:                    break;
        !          2282: 
        !          2283:                  case n_USROBOT:
        !          2284:                  case n_HST:
        !          2285:                  case n_TELEBIT:
        !          2286: #endif /* MINIDIAL */
        !          2287:                  case n_HAYES:
        !          2288:                    if (mdmspd && !network) {
        !          2289:                        s = lbuf;
        !          2290:                        while (*s != '\0' && *s != 'C') s++;
        !          2291:                        cptr = (*s == 'C') ? s : NULL;
        !          2292:                        conspd = 0L;
        !          2293:                        if ((cptr != NULL) && !strncmp(cptr,"CONNECT ",8)) {
        !          2294:                            if ((int)strlen(cptr) < 9) /* Just CONNECT, */
        !          2295:                              conspd = 300L;      /* use 300 bps */
        !          2296:                            else if (isdigit(*(cptr+8))) /* not CONNECT FAST */
        !          2297:                              conspd = atol(cptr + 8); /* CONNECT nnnn */
        !          2298:                            if (conspd != speed) {
        !          2299:                                if ((conspd / 10L) > 0) {
        !          2300:                                    if (ttsspd((int) (conspd / 10L)) < 0) {
        !          2301:                                       printf(" Can't change speed to %lu\r\n",
        !          2302:                                               conspd);
        !          2303:                                    } else {
        !          2304:                                        speed = conspd;
        !          2305:                                        mdmstat = CONNECTED;
        !          2306:                                        if ( !quiet && !backgrd )
        !          2307:                                          printf(" Speed changed to %lu\r\n",
        !          2308:                                                 conspd);
        !          2309:                                    }
        !          2310:                                }
        !          2311:                            } /* Expanded to handle any conceivable speed */
        !          2312:                        }
        !          2313:                    }
        !          2314: #ifndef MINIDIAL
        !          2315:                    if (mymdmtyp == n_TELEBIT) {
        !          2316:                        if (didweget(lbuf,"CONNECT FAST/KERM")) {
        !          2317:                            mdmstat = CONNECTED;
        !          2318:                            if (!quiet && !backgrd) printf("FAST/KERM ");
        !          2319:                            break;
        !          2320:                        }
        !          2321:                    }
        !          2322: #endif /* MINIDIAL */
        !          2323:                    if (didweget(lbuf,"RRING") ||
        !          2324:                        didweget(lbuf,"RINGING") ||
        !          2325:                        didweget(lbuf,"DIALING")) {
        !          2326:                        mdmstat = 0;
        !          2327:                    } else if (didweget(lbuf,"CONNECT")) {
        !          2328:                        mdmstat = CONNECTED;
        !          2329:                    } else if (didweget(lbuf,"NO CARRIER") ||
        !          2330:                        didweget(lbuf,"NO DIALTONE") ||
        !          2331:                        didweget(lbuf,"NO DIAL TONE") ||
        !          2332:                        didweget(lbuf,"BUSY") ||
        !          2333:                        didweget(lbuf,"NO ANSWER") ||
        !          2334:                        didweget(lbuf,"VOICE") ||
        !          2335:                        didweget(lbuf,"RING") ||
        !          2336:                        didweget(lbuf,"ERROR")) {
        !          2337:                        mdmstat = FAILED;
        !          2338:                    }
        !          2339:                    break;
        !          2340: #ifndef MINIDIAL
        !          2341:                  case n_PENRIL:
        !          2342:                    if (didweget(lbuf,"OK"))
        !          2343:                        mdmstat = CONNECTED;
        !          2344:                    else if (didweget(lbuf,"BUSY") ||
        !          2345:                        didweget(lbuf,"NO RING"))
        !          2346:                        mdmstat = FAILED;
        !          2347:                    break;
        !          2348:                  case n_RACAL:
        !          2349:                    if (didweget(lbuf,"ON LINE"))
        !          2350:                        mdmstat = CONNECTED;
        !          2351:                    else if (didweget(lbuf,"FAILED CALL"))
        !          2352:                        mdmstat = FAILED;
        !          2353:                    break;
        !          2354:                  case n_ROLM:
        !          2355:                    if (didweget(lbuf,"CALLING"))
        !          2356:                        mdmstat = 0;
        !          2357:                    else if (didweget(lbuf,"COMPLETE"))
        !          2358:                        mdmstat = CONNECTED;
        !          2359:                    else if (didweget(lbuf,"FAILED") ||
        !          2360:                        didweget(lbuf,"NOT AVAILABLE") ||
        !          2361:                        didweget(lbuf,"LACKS PERMISSION") ||
        !          2362:                        didweget(lbuf,"NOT A DATALINE") ||
        !          2363:                        didweget(lbuf,"INVALID GROUP NAME") ||
        !          2364:                        didweget(lbuf,"BUSY") ||
        !          2365:                        didweget(lbuf,"ABANDONDED") ||
        !          2366:                        didweget(lbuf,"DOES NOT ANSWER") ||
        !          2367:                        didweget(lbuf,"INVALID DATA LINE NUMBER"))
        !          2368:                        mdmstat = FAILED;
        !          2369:                    break;
        !          2370:                  case n_VENTEL:
        !          2371:                    if (didweget(lbuf,"ONLINE!") ||
        !          2372:                        didweget(lbuf,"Online!"))
        !          2373:                        mdmstat = CONNECTED;
        !          2374:                    else if (didweget(lbuf,"BUSY") ||
        !          2375:                        didweget(lbuf,"DEAD PHONE") ||
        !          2376:                        didweget(lbuf,"Busy"))
        !          2377:                        mdmstat = FAILED;
        !          2378:                    break;
        !          2379:                  case n_CONCORD:
        !          2380:                    if (didweget(lbuf,"INITIATING"))
        !          2381:                        mdmstat = CONNECTED;
        !          2382:                    else if (didweget(lbuf,"BUSY") ||
        !          2383:                        didweget(lbuf,"CALL FAILED"))
        !          2384:                        mdmstat = FAILED;
        !          2385:                    break;
        !          2386:                  case n_MICROCOM:
        !          2387:                    /* "RINGBACK" means phone line ringing, continue */
        !          2388:                    if (didweget(lbuf,"NO CONNECT") ||
        !          2389:                        didweget(lbuf,"BUSY") ||
        !          2390:                        didweget(lbuf,"NO DIALTONE") ||
        !          2391:                        didweget(lbuf,"COMMAND ERROR") ||
        !          2392:                        didweget(lbuf,"IN USE"))
        !          2393:                        mdmstat = FAILED;
        !          2394:                    else if (didweget(lbuf,"CONNECT"))
        !          2395:                        mdmstat = CONNECTED;
        !          2396:                        /* trailing speed ignored */
        !          2397:                    break;
        !          2398: #endif /* MINIDIAL */
        !          2399:                }
        !          2400:            }
        !          2401:            break;
        !          2402: 
        !          2403: #ifndef MINIDIAL
        !          2404:        case n_DF03:                    /* because response lacks CR or NL */
        !          2405:            c = ddinc(0) & 0177;
        !          2406:            dialoc(c);
        !          2407:            debug(F000,"dial df03 got","",c);
        !          2408:            if ( c == 'A' ) mdmstat = CONNECTED;
        !          2409:            if ( c == 'B' ) mdmstat = FAILED;
        !          2410:            break;
        !          2411: 
        !          2412:        case n_TBNV:                    /* Hayeslike modems in digit */
        !          2413:        case n_TB3NV                    /* response mode... */:
        !          2414:        case n_TBPNV:
        !          2415:        case n_TB4NV:
        !          2416:        case n_TBSNV:
        !          2417: #endif /* MINIDIAL */
        !          2418:        case n_HAYESNV:
        !          2419: 
        !          2420: /*
        !          2421:   The method for reading Hayes numeric result codes has been totally
        !          2422:   redone as of 5A(174) to account for all of the following.  Not all have
        !          2423:   been tested, and others probably need to be added.
        !          2424: 
        !          2425:   Hayes numeric result codes (Hayes 1200 and higher):
        !          2426:      0 = OK
        !          2427:      1 = CONNECT at 300 bps (or 1200 bps on Hayes 1200 with basic code set)
        !          2428:      2 = RING
        !          2429:      3 = NO CARRIER
        !          2430:      4 = ERROR (in command line)
        !          2431:      5 = CONNECT 1200 (extended code set)
        !          2432:   Hayes 2400 and higher:
        !          2433:      6 = NO DIALTONE
        !          2434:      7 = BUSY
        !          2435:      8 = NO ANSWER
        !          2436:      9 = (there is no 9)
        !          2437:     10 = CONNECT 2400
        !          2438:   Reportedly, the codes for Hayes V.32 modems are:
        !          2439:     1x = CONNECT <suffix>
        !          2440:     5x = CONNECT 1200 <suffix>
        !          2441:     9x = CONNECT 2400 <suffix>
        !          2442:    11x = CONNECT 4800 <suffix>
        !          2443:    12x = CONNECT 9600 <suffix>
        !          2444:   Where:
        !          2445:     x:   suffix:
        !          2446:     R  = RELIABLE
        !          2447:     RC = RELIABLE COMPRESSED
        !          2448:     L  = LAPM
        !          2449:     LC = LAPM COMPRESSED
        !          2450:   And for Telebits, all the above, except no suffix in numeric mode, plus:
        !          2451:     11 = CONNECT 4800
        !          2452:     12 = CONNECT 9600
        !          2453:     13 = CONNECT 14400
        !          2454:     14 = CONNECT 19200
        !          2455:     15 = CONNECT 38400
        !          2456:     16 = CONNECT 57600
        !          2457:     20 = CONNECT 300/REL  (= MNP)
        !          2458:     22 = CONNECT 1200/REL (= MNP)
        !          2459:     23 = CONNECT 2400/REL (= MNP)
        !          2460:     46 = CONNECT 7512  (i.e. 75/1200)
        !          2461:     47 = CONNECT 1275  (i.e. 1200/75)
        !          2462:     48 = CONNECT 7200
        !          2463:     49 = CONNECT 12000
        !          2464:     50 = CONNECT FAST (not on T1600/3000)
        !          2465:     52 = RRING
        !          2466:     53 = DIALING
        !          2467:     54 = NO PROMPTTONE
        !          2468:     61 = CONNECT FAST/KERM (Kermit spoof)
        !          2469:     70 = CONNECT FAST/COMP (PEP + compression)
        !          2470:     71 = CONNECT FAST/KERM/COMP (PEP + compression + Kermit spoof)
        !          2471: */
        !          2472: #define NBUFL 8
        !          2473:            {                           /* Nonverbal response code handler */
        !          2474:            char nbuf[NBUFL+1];         /* Response buffer */
        !          2475:            int i, j;                   /* Buffer pointers */
        !          2476:            debug(F101,"RESPONSE mdmecho","",mdmecho);
        !          2477:            if (mdmecho) {              /* Sponge up dialing string echo. */
        !          2478:                while (1) {
        !          2479:                    c = ddinc(0) & 0x7f;
        !          2480:                    debug(F000,"SPONGE","",c);
        !          2481:                    dialoc(c);
        !          2482:                    if (c == CR) break;
        !          2483:                }
        !          2484:            }
        !          2485:            while (mdmstat == 0) {      /* Read response */
        !          2486:                for (i = 0; i < NBUFL; i++) /* Clear the buffer */
        !          2487:                  nbuf[i] = '\0';
        !          2488:                i = 0;                  /* Reset the buffer pointer. */
        !          2489:                c = ddinc(0) & 0177;    /* Get first digit of response. */
        !          2490:                                        /* using an untimed, blocking read. */
        !          2491:                debug(F000,"RESPONSE-A","",c);
        !          2492:                dialoc(c);              /* Echo it if requested. */
        !          2493:                if (!isdigit(c))        /* If not a digit, keep looking. */
        !          2494:                  continue;
        !          2495:                nbuf[i++] = c;          /* Got first digit, save it. */
        !          2496:                while (c != CR && i < 8) { /* Now read characters up to CR */
        !          2497:                    x = ddinc(0) & 0177; /* Get a character. */
        !          2498:                    c = (char) x;       /* Got it OK. */
        !          2499:                    debug(F000,"RESPONSE-C","",c);
        !          2500:                    if (c != CR)        /* If it's not a carriage return, */
        !          2501:                      nbuf[i++] = c;    /*  save it. */
        !          2502:                    dialoc(c);          /* Echo it. */
        !          2503:                }
        !          2504:                nbuf[i] = '\0';         /* Done, terminate the buffer. */
        !          2505:                debug(F111,"dial hayesnv lbuf",lbuf,n);
        !          2506:                debug(F111,"dial hayesnv got",nbuf,i);
        !          2507:                /*
        !          2508:                  Separate any non-numeric suffix from the numeric result code
        !          2509:                  with a null.
        !          2510:                */
        !          2511:                for (j = i-1; (j > -1) && !isdigit(nbuf[j]); j--)
        !          2512:                  nbuf[j+1] = nbuf[j];
        !          2513:                j++;
        !          2514:                nbuf[j++] = '\0';
        !          2515:                debug(F110,"dial hayesnv numeric",nbuf,0);
        !          2516:                debug(F111,"dial hayesnv suffix ",nbuf+j,j);
        !          2517:                if ((int)strlen(nbuf) > 3) /* Probably phone number echoing. */
        !          2518:                  continue;
        !          2519:                /*
        !          2520:                  Now read and interpret the results...
        !          2521:                */
        !          2522:                i = atoi(nbuf);         /* Convert to integer */
        !          2523:                switch (i) {
        !          2524:                  case 1:               /* CONNECT */
        !          2525:                    mdmstat = CONNECTED; /* Could be any speed */
        !          2526:                    break;
        !          2527:                  case 2:               /* RING */
        !          2528:                    if (dialdpy) printf("\r\n Local phone is ringing!\r\n");
        !          2529:                    mdmstat = FAILED;
        !          2530:                    break;
        !          2531:                  case 3:               /* NO CARRIER */
        !          2532:                    if (dialdpy) printf("\r\n No Carrier.\r\n");
        !          2533:                    mdmstat = FAILED;
        !          2534:                    break;
        !          2535:                  case 4:               /* ERROR */
        !          2536:                    if (dialdpy) printf("\r\n Modem Command Error.\r\n");
        !          2537:                    mdmstat = FAILED;
        !          2538:                    break;
        !          2539:                  case 5:               /* CONNECT 1200 */
        !          2540:                    spdchg(1200L);      /* Change speed if necessary. */
        !          2541:                    mdmstat = CONNECTED;
        !          2542:                    break;
        !          2543:                  case 6:               /* NO DIALTONE */
        !          2544:                    if (dialdpy) printf("\r\n No Dialtone.\r\n");
        !          2545:                    mdmstat = FAILED;
        !          2546:                    break;
        !          2547:                  case 7:               /* BUSY */
        !          2548:                    if (dialdpy) printf("\r\n Busy.\r\n");
        !          2549:                    mdmstat = FAILED;
        !          2550:                    break;
        !          2551:                  case 8:               /* NO ANSWER */
        !          2552:                    if (dialdpy) printf("\r\n No Answer.\r\n");
        !          2553:                    mdmstat = FAILED;
        !          2554:                    break;
        !          2555:                  case 9:               /* CONNECT 2400 */
        !          2556:                  case 10:
        !          2557:                    spdchg(2400L);      /* Change speed if necessary. */
        !          2558:                    mdmstat = CONNECTED;
        !          2559:                    break;
        !          2560:                  case 11:              /* CONNECT 4800 */
        !          2561:                    spdchg(4800L);
        !          2562:                    mdmstat = CONNECTED;
        !          2563:                    break;
        !          2564:                  case 12:              /* CONNECT 9600 */
        !          2565:                    spdchg(9600L);
        !          2566:                    mdmstat = CONNECTED;
        !          2567:                    break;
        !          2568:                  case 13:              /* CONNECT 14400 */
        !          2569:                    spdchg(14400L);
        !          2570:                    mdmstat = CONNECTED;
        !          2571:                    break;
        !          2572:                  case 14:
        !          2573:                    spdchg(19200L);     /* CONNECT 19200 */
        !          2574:                    mdmstat = CONNECTED;
        !          2575:                    break;
        !          2576:                  case 15:              /* CONNECT 34800 */
        !          2577:                    spdchg(38400L);
        !          2578:                    mdmstat = CONNECTED;
        !          2579:                    break;
        !          2580:                  case 16:              /* CONNECT 57600 */
        !          2581:                    spdchg(57600L);
        !          2582:                    mdmstat = CONNECTED;
        !          2583:                    break;
        !          2584:                  case 20:              /* CONNECT 300/REL */
        !          2585:                    spdchg(300L);
        !          2586:                    mdmstat = CONNECTED;
        !          2587:                    break;
        !          2588:                  case 22:              /* CONNECT 1200/REL */
        !          2589:                    spdchg(1200L);
        !          2590:                    mdmstat = CONNECTED;
        !          2591:                    break;
        !          2592:                  case 23:              /* CONNECT 2400/REL */
        !          2593:                    spdchg(2400L);
        !          2594:                    mdmstat = CONNECTED;
        !          2595:                    break;
        !          2596:                  case 46:              /* CONNECT 7512 */
        !          2597:                    spdchg(8880L);      /* 75/1200 split speed */
        !          2598:                    mdmstat = CONNECTED; /* (special C-Kermit code) */
        !          2599:                    break;
        !          2600:                  case 47:              /* CONNECT 1200/75 */
        !          2601:                    mdmstat = CONNECTED; /* Speed not supported by Kermit */
        !          2602:                    printf("CONNECT 1200/75 - Not support by C-Kermit\r\n");
        !          2603:                    break;
        !          2604:                  case 48:              /* CONNECT 7200 */
        !          2605:                    spdchg(7200L);
        !          2606:                    mdmstat = CONNECTED;
        !          2607:                    break;
        !          2608:                  case 49:              /* CONNECT 12000 */
        !          2609:                    spdchg(12000L);
        !          2610:                    mdmstat = CONNECTED;
        !          2611:                    break;
        !          2612: #ifndef MINIDIAL
        !          2613:                  case 50:              /* CONNECT FAST */
        !          2614:                    if (mymdmtyp == n_TELEBIT) /* Early models only */
        !          2615:                      mdmstat = CONNECTED;
        !          2616:                    break;
        !          2617:                  case 52:              /* RRING */
        !          2618:                    if (mymdmtyp == n_TELEBIT)
        !          2619:                      if (dialdpy) printf(" Ringing...\r\n");
        !          2620:                    break;
        !          2621:                  case 53:              /* DIALING */
        !          2622:                    if (mymdmtyp == n_TELEBIT)
        !          2623:                      if (dialdpy) printf(" Dialing...\r\n");
        !          2624:                    break;
        !          2625:                  case 54:              /* NO PROMPTTONE */
        !          2626:                    if (mymdmtyp == n_TELEBIT) {
        !          2627:                        if (dialdpy) printf("\r\n No Prompttone.\r\n");
        !          2628:                        mdmstat = FAILED;
        !          2629:                    }
        !          2630:                    break;
        !          2631:                  case 61:              /* Various Telebit PEP modes */
        !          2632:                  case 62:
        !          2633:                  case 63:
        !          2634:                  case 70:
        !          2635:                  case 71:
        !          2636:                  case 72:
        !          2637:                  case 73:
        !          2638:                    if (mymdmtyp == n_TELEBIT) /* Early models only */
        !          2639:                      mdmstat = CONNECTED;
        !          2640:                    break;
        !          2641: #endif /* MINIDIAL */
        !          2642:                  default:
        !          2643:                    break;
        !          2644:                }
        !          2645:            }
        !          2646:            if (mdmstat == CONNECTED && nbuf[j] != '\0') {
        !          2647:                if (dialdpy) {
        !          2648:                    printf("\r\n");
        !          2649:                    if (nbuf[j] == 'R') printf("RELIABLE");
        !          2650:                    if (nbuf[j] == 'L') printf("LAPM");
        !          2651:                    if (nbuf[j+1] == 'C') printf(" COMPRESSED");
        !          2652:                    printf("\r\n");
        !          2653:                }
        !          2654:            }
        !          2655:        }
        !          2656:         break;
        !          2657: 
        !          2658:        case n_UNKNOWN: {
        !          2659:                int x, y = waitct;
        !          2660:                mdmstat = FAILED;       /* Assume failure. */
        !          2661:                while (y-- > -1) {
        !          2662:                    x = ttchk();
        !          2663:                    if (x > 0) {
        !          2664:                        if (x > LBUFL) x = LBUFL;
        !          2665:                        x = ttxin(x,(CHAR *)lbuf);
        !          2666:                        if ((x > 0) && dialdpy) conol(lbuf);
        !          2667:                    }
        !          2668:                    x = ttgmdm();       /* Try to read modem signals */
        !          2669:                    if (x < 0) break;   /* Can't, fail. */
        !          2670:                    if (x & BM_DCD) {   /* Got signals OK.  Carrier present? */
        !          2671:                        mdmstat = CONNECTED; /* Yes, done. */
        !          2672:                        break;
        !          2673:                    }                   /* No, keep waiting. */
        !          2674:                    sleep(1);
        !          2675:                }
        !          2676:                break;
        !          2677:            }
        !          2678:        }                               /* switch (augmdmtyp) */
        !          2679:     }                                  /* while (mdmstat == 0) */
        !          2680:     x = alarm(0);                      /* Turn off alarm. */
        !          2681:     debug(F101,"ckdial alarm off","",x);
        !          2682:     if ( mdmstat != CONNECTED ) {      /* Modem-detected failure */
        !          2683:        n1 = F_modem;
        !          2684:        longjmp( sjbuf, F_modem );      /* Exit (with reason in lbuf) */
        !          2685:     }
        !          2686:     msleep(1000);                      /* In case DTR blinks  */
        !          2687:     alarm(3);                          /* Precaution in case of trouble */
        !          2688:     debug(F110,"dial","succeeded",0);
        !          2689: #ifndef MINIDIAL
        !          2690:     if (augmdmtyp != n_ROLM)           /* Rolm has wierd modem signaling */
        !          2691: #endif /* MINIDIAL */
        !          2692:       ttpkt(speed,FLO_DIAX,parity);    /* Cancel dialing state ioctl */
        !          2693:     dreset();                          /* Reset alarms, etc. */
        !          2694:     if (!quiet && !backgrd)
        !          2695:       printf (" Call complete.\07\n");
        !          2696: #ifdef DYNAMIC
        !          2697:     if (lbuf) free(lbuf);
        !          2698: #endif /* DYNAMIC */
        !          2699:     return(1);                         /* Return successfully */
        !          2700: }
        !          2701: 
        !          2702: /*
        !          2703:   getok() - wait up to n seconds for OK (0) or ERROR (4) response from modem.
        !          2704:   Use with Hayeslike or CCITT modems for reading the reply to a nondialing
        !          2705:   command.
        !          2706: 
        !          2707:   Second argument says whether to be strict about numeric result codes, i.e.
        !          2708:   to require they be preceded by CR or else be the first character in the
        !          2709:   response, e.g. to prevent the ATH0<CR> echo from looking like a valid
        !          2710:   response.  Strict == 0 is needed for ATI on Telebit, which can return the
        !          2711:   model number concatenated with the numeric response code, e.g. "9620"
        !          2712:   ("962" is the model number, "0" is the response code).  getok() Returns:
        !          2713: 
        !          2714:    0 if it timed out,
        !          2715:    1 if it succeeded,
        !          2716:   -1 on modem command, i/o, or other error.
        !          2717: */
        !          2718: static jmp_buf okbuf;                  /* Jump-buf for getok(). */
        !          2719: 
        !          2720: SIGTYP
        !          2721: oktimo(foo) int foo; {                 /* Alarm handler for getok(). */
        !          2722: #ifdef OSK                             /* OS-9, see comment in dialtime(). */
        !          2723:     sigmask(-1);
        !          2724: #endif /* OSK */
        !          2725:     longjmp(okbuf,1);
        !          2726: }
        !          2727: 
        !          2728: int
        !          2729: getok(n, strict) int n, strict; {
        !          2730:     CHAR c;
        !          2731:     int i, x, status, oldalarm;
        !          2732:     SIGTYP (*saval)();                 /* For saving alarm handler locally */
        !          2733: 
        !          2734:     mdmecho = 0;                       /* Assume no echoing of commands */
        !          2735:     saval = signal(SIGALRM,oktimo);    /* Set response timer, */
        !          2736:     oldalarm = alarm(n);               /* saving old one. */
        !          2737:     if (setjmp(okbuf)) {               /* Timed out. */
        !          2738:        alarm(oldalarm);                /* Restore old alarm */
        !          2739:        if (saval) signal(SIGALRM,saval); /* and alarm handler */
        !          2740:        debug(F100,"getok timeout","",0);
        !          2741:        ttflui();                       /* Flush input buffer */
        !          2742:        return(0);                      /* and return timeout indication */
        !          2743: 
        !          2744:     } else if (augmdmtyp == n_CCITT    /* CCITT, easy... */
        !          2745: #ifndef MINIDIAL
        !          2746:               || augmdmtyp == n_DIGITEL /* Digitel, ditto. */
        !          2747: #endif /* MINIDIAL */
        !          2748:               ) {
        !          2749:        waitfor("VAL");
        !          2750:         return(1);
        !          2751: 
        !          2752:     } else {                           /* Hayes & friends, start here... */
        !          2753:        status = 0;                     /* No status yet. */
        !          2754:        for (x = 0; x < RBUFL; x++)     /* Initialize response buffer */
        !          2755:          rbuf[x] = SP;                 /*  to all spaces */
        !          2756:        rbuf[RBUFL] = NUL;              /* and terminate with NUL. */
        !          2757:        while (status == 0) {           /* While no status... */
        !          2758:            x = ddinc(0);               /* Read a character */
        !          2759:            if (x < 0) {                /* I/O error */
        !          2760:                alarm(oldalarm);        /* Turn off alarm */
        !          2761:                if (saval) signal(SIGALRM,saval); /* and restore handler. */
        !          2762:                return(-1);             /* Return error code. */
        !          2763:            }
        !          2764:            debug(F101,"getok ddinc","",x); /* Got a character. */
        !          2765:            c = x & 0x7f;               /* Get low order 7 bits */
        !          2766:            if (!c)                     /* Don't deposit NULs */
        !          2767:              continue;                 /* or else didweget() won't work */
        !          2768:            if (dialdpy) conoc((char)c); /* Echo it if requested */
        !          2769:            for (i = 0; i < RBUFL-1; i++) /* Rotate buffer */
        !          2770:              rbuf[i] = rbuf[i+1];
        !          2771:            rbuf[RBUFL-1] = c;          /* Deposit character at end */
        !          2772:            debug(F000,"getok:",rbuf,(int) c); /* Log it */
        !          2773:            switch (c) {                /* Interpret it. */
        !          2774:              case CR:                  /* Got a carriage return. */
        !          2775:                switch(rbuf[RBUFL-2]) { /* Look at character before it. */
        !          2776:                  case '0':             /* 0 = OK numeric response */
        !          2777:                    if (!strict ||
        !          2778:                        rbuf[RBUFL-3] == CR || rbuf[RBUFL-3] == SP) {
        !          2779:                        augmdmtyp |= DIAL_NV; /* OR in the "nonverbal" bit. */
        !          2780:                        status = 1;     /* Good response */
        !          2781:                    }
        !          2782:                    break;
        !          2783:                  case '4':             /* 4 = ERROR numeric response */
        !          2784:                    if (!strict ||
        !          2785:                        rbuf[RBUFL-3] == CR || rbuf[RBUFL-3] == SP) {
        !          2786:                        augmdmtyp |= DIAL_NV; /* OR in the nonverbal bit. */
        !          2787:                        status = -1;    /* Bad command */
        !          2788:                    }
        !          2789:                    break;
        !          2790:                }
        !          2791:                if (dialdpy && (augmdmtyp & DIAL_NV)) /* If numeric results, */
        !          2792:                  conoc(LF);              /* echo a linefeed too. */
        !          2793:                break;
        !          2794:              case LF:                  /* Got a linefeed. */
        !          2795:                /*
        !          2796:                  Note use of explicit octal codes in the string for
        !          2797:                  CR and LF.  We want real CR and LF here, not whatever
        !          2798:                  the compiler happens to define \r and \n as...
        !          2799:                */
        !          2800:                if (!strcmp(rbuf+RBUFL-4,"OK\015\012")) /* Good response */
        !          2801:                  status = 1;
        !          2802:                else if (!strcmp(rbuf+RBUFL-7,"ERROR\015\012")) /* Error */
        !          2803:                  status = -1;
        !          2804:                augmdmtyp &= ~(DIAL_NV); /* Turn off the nonverbal bit */
        !          2805:                break;
        !          2806:              /* Check whether modem echoes its commands... */
        !          2807:              case 't':                 /* Got little t */
        !          2808:                if (!strcmp(rbuf+RBUFL-3,"\015at") || /* See if it's "at" */
        !          2809:                    !strcmp(rbuf+RBUFL-3," at"))
        !          2810:                    mdmecho = 1;
        !          2811:                debug(F111,"MDMECHO-t",rbuf+RBUFL-2,mdmecho);
        !          2812:                break;
        !          2813:              case 'T':                 /* Got Big T */
        !          2814:                if (!strcmp(rbuf+RBUFL-3,"\015AT") ||   /* See if it's "AT" */
        !          2815:                    !strcmp(rbuf+RBUFL-3," AT"))
        !          2816:                    mdmecho = 1;
        !          2817:                debug(F111,"MDMECHO-T",rbuf+RBUFL-3,mdmecho);
        !          2818:                break;
        !          2819:              default:                  /* Other characters, accumulate. */
        !          2820:                status = 0;
        !          2821:                break;
        !          2822:            }
        !          2823:        }
        !          2824:        debug(F101,"getok returns","",status);
        !          2825:        alarm(oldalarm);                /* Restore previous alarm */
        !          2826:        if (saval) signal(SIGALRM,saval); /* and handler */
        !          2827:        ttflui();                       /* Flush input buffer */
        !          2828:        return(status);                 /* Return status */
        !          2829:     }
        !          2830: }
        !          2831: 
        !          2832: /* Maybe hang up the phone, depending on various SET DIAL parameters. */
        !          2833: 
        !          2834: int
        !          2835: dialhup() {
        !          2836:     int x = 0;
        !          2837:     if (dialhng) {                     /* DIAL HANGUP ON? */
        !          2838:        x = mdmhup();                   /* Try modem-specific method first */
        !          2839:        debug(F101,"dialhup mdmhup","",x);
        !          2840:        if (x > 0) {                    /* If it worked, */
        !          2841:            if (dialdpy)
        !          2842:              printf(" Modem hangup OK\r\n"); /* fine. */
        !          2843:        } else if (network) {           /* If we're telnetted to */
        !          2844:            if (dialdpy)                /* a modem server, just print a msg */
        !          2845:              printf(" Warning: modem hangup failed\r\n"); /* don't hangup! */
        !          2846:            return(0);
        !          2847:        } else {                        /* Otherwise */
        !          2848:            x = tthang();               /* Tell the OS to turn off DTR. */
        !          2849:            if (dialdpy) {              /* DIAL DISPLAY ON? */
        !          2850:                if (x > 0)              /* Yes, tell results from tthang() */
        !          2851:                  printf(" Hangup OK\r\n");
        !          2852:                else if (x == 0)
        !          2853:                  printf(" Hangup skipped\r\n");
        !          2854:                else
        !          2855:                  perror(" Hangup error");
        !          2856:            }
        !          2857:        }
        !          2858:     } else if (dialdpy) printf(" Hangup skipped\r\n"); /* DIAL HANGUP OFF */
        !          2859:     return(x);
        !          2860: }
        !          2861: 
        !          2862: /*
        !          2863:   M D M H U P  --
        !          2864: 
        !          2865:   Sends escape sequence to modem, then sends its hangup command.  Returns:
        !          2866:    0: If modem type is 0 (direct serial connection),
        !          2867:       or if modem type is < 0 (network connection),
        !          2868:       or if no action taken because DIAL MODEM-HANGUP is OFF)
        !          2869:         or because no hangup string for current modem type,
        !          2870:       or C-Kermit is in remote mode,
        !          2871:       or if action taken but there was no positive response from modem;
        !          2872:    1: Success: modem is in command state and acknowledged the hangup command;
        !          2873:   -1: On modem command error.
        !          2874: */
        !          2875: int
        !          2876: mdmhup() {
        !          2877: #ifdef MDMHUP
        !          2878:     MDMINF *p;                         /* Modem info structure pointer */
        !          2879:     int m, x = 0;
        !          2880: 
        !          2881:     if (dialmhu == 0 || local == 0)    /* If DIAL MODEM-HANGUP is OFF, */
        !          2882:       return(0);                       /*  or not in local mode, fail. */
        !          2883: 
        !          2884: #ifdef OS2
        !          2885: /*
        !          2886:   In OS/2, if CARRIER is OFF, and there is indeed no carrier signal, any
        !          2887:   attempt to do i/o at this point can hang the program.  This might be true
        !          2888:   for other operating systems too.
        !          2889: */
        !          2890:     if (!network) {                    /* Not a network connection */
        !          2891:        m = ttgmdm();                   /* Get modem signals */
        !          2892:        if ((m > -1) && (m & BM_DCD == 0)) /* Check for carrier */
        !          2893:          return(0);                    /* No carrier, skip the rest */
        !          2894:     }
        !          2895: #endif /* OS2 */
        !          2896: 
        !          2897:     m = mdmtyp & 0xff;                 /* Get basic modem type (no bits!). */
        !          2898:     if ((m < 1) || (m > MAX_MDM))      /* If modem type not in range, */
        !          2899:       return(0);                       /*  fail. */
        !          2900:     p = ptrtab[m-1];                   /* Get modem info pointer */
        !          2901:     if (!(p->hup_str) || !*(p->hup_str)) { /* No hangup string? */
        !          2902:        debug(F100,"mdmhup no hup_str","",0); /* No, */
        !          2903:        return(0);                      /*  fail. */
        !          2904:     } else {
        !          2905:        debug(F110,"mdmhup hup_str",p->hup_str,0); /* Yes. */
        !          2906:        if (p->esc_str && *(p->esc_str)) { /* Have escape sequence? */
        !          2907:            debug(F110,"mdmhup esc_str",p->esc_str,0);
        !          2908:            debug(F101,"mdmhup esc_time","",p->esc_time);
        !          2909:            if (ttpkt(speed,FLO_DIAL,parity) < 0) /* Condition line */
        !          2910:              return(-1);               /*  for dialing. */
        !          2911:            if (p->esc_time)            /* If we have a guard time */
        !          2912:              msleep(p->esc_time);      /* Pause for guard time */
        !          2913: #ifdef NETCONN
        !          2914:            /* Send modem's escape sequence */
        !          2915:            if (network) {              /* Must catch errors here. */
        !          2916:                if (ttol((CHAR *)(p->esc_str),(int)strlen(p->esc_str)) < 0)
        !          2917:                  return(-1);
        !          2918:            } else {
        !          2919:                ttslow(p->esc_str,p->wake_rate); /* Send escape sequence */
        !          2920:            }
        !          2921: #else
        !          2922:            ttslow(p->esc_str,p->wake_rate); /* Send escape sequence */
        !          2923: #endif /* NETCONN */
        !          2924:            if (p->esc_time)            /* Pause for guard time again */
        !          2925:              msleep(p->esc_time);
        !          2926:            msleep(500);                /* Wait half a sec for echoes. */
        !          2927:            ttflui();                   /* Flush response or echo, if any */
        !          2928:        }
        !          2929: #ifdef NETCONN
        !          2930:            /* Send modem's hangup command */
        !          2931:            if (network) {              /* Must catch errors here. */
        !          2932:                if (ttol((CHAR *)(p->hup_str),(int)strlen(p->hup_str)) < 0)
        !          2933:                  return(-1);
        !          2934:            } else {
        !          2935:                ttslow(p->hup_str,p->wake_rate);
        !          2936:            }
        !          2937: #else
        !          2938:        ttslow(p->hup_str,p->wake_rate); /* Now Send hangup string */
        !          2939: #endif /* NETCONN */
        !          2940:        if (p->ok_fn) {                 /* Look for OK response */
        !          2941:            x = (*(p->ok_fn))(3,1);     /* Give it 3 seconds, be strict. */
        !          2942:            debug(F101,"mdmhup hangup response","",x);
        !          2943:        } else {                        /* No OK function, */
        !          2944:            x = 1;                      /* so assume it worked */
        !          2945:            debug(F101,"mdmhup no ok_fn","",x);
        !          2946:        }
        !          2947:        return(x);                      /* Return OK function's return code. */
        !          2948:     }
        !          2949: #else                                  /* MDMHUP not defined. */
        !          2950:     return(0);                         /* Always fail. */
        !          2951: #endif /* MDMHUP */
        !          2952: }
        !          2953: 
        !          2954: char *                                 /* Let external routines ask */
        !          2955: getdws(mdmtyp) int mdmtyp; {           /* about dial init-string. */
        !          2956:     MDMINF * p;
        !          2957:     if ((mdmtyp & 0xff) < 1 || (mdmtyp & 0xff) > MAX_MDM)
        !          2958:       return("");
        !          2959:     p = ptrtab[(mdmtyp & 0xff) -1];
        !          2960:     return(dialini ? dialini : p->wake_str);
        !          2961: }
        !          2962: 
        !          2963: char *
        !          2964: getdcs(mdmtyp) int mdmtyp; {           /* Same deal for dial-command */
        !          2965:     MDMINF * p;
        !          2966:     if ((mdmtyp & 0xff) < 1 || (mdmtyp & 0xff) > MAX_MDM)
        !          2967:       return("");
        !          2968:     p = ptrtab[(mdmtyp & 0xff) -1];
        !          2969:     return(dialcmd ? dialcmd : p->dial_str);
        !          2970: }
        !          2971: 
        !          2972: #else /* NODIAL */
        !          2973: 
        !          2974: char *dialv = "Dial Command Disabled";
        !          2975: 
        !          2976: int                                    /* To allow NODIAL versions to */
        !          2977: mdmhup() {                             /* call mdmhup(), so calls to  */
        !          2978:     return(0);                         /* mdmhup() need not be within */
        !          2979: }                                      /* #ifndef NODIAL conditionals */
        !          2980: 
        !          2981: #endif /* NODIAL */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.