Annotation of researchv10dc/lbin/kermit/ckudia.c, revision 1.1

1.1     ! root        1: char *dialv = "Dial Command, V2.0(009) 24 Jan 88";
        !             2: 
        !             3: /*  C K U D I A  --  Dialing program for connection to remote system */
        !             4: 
        !             5: /*
        !             6:  Author: Herm Fischer (HFISCHER@USC-ECLB)
        !             7:  Contributed to Columbia University for inclusion in C-Kermit.
        !             8:  Copyright (C) 1985, Herman Fischer, 16400 Ventura Blvd, Encino CA 91436
        !             9:  Permission is granted to any individual or institution to use, copy, or
        !            10:  redistribute this software so long as it is not sold for profit, provided this
        !            11:  copyright notice is retained. 
        !            12: 
        !            13:  ------
        !            14: 
        !            15:  This module should work under all versions of Unix.  It calls externally
        !            16:  defined system-depended functions for i/o, but depends upon the existence
        !            17:  of various modem control functions.
        !            18: 
        !            19:  This module, and the supporting routines in the ckutio.c module, assume
        !            20:  that the computer and modem properly utilize the following data communi-
        !            21:  cations signals (that means one should prepare the modem to use, not
        !            22:  circumvent, these signals):
        !            23: 
        !            24:      Data Terminal Ready:  This signal is asserted by the computer
        !            25:      when Kermit is about to ask the modem to dial a call, and is
        !            26:      removed when Kermit wishes to have the modem hang up a call.
        !            27:      The signal is asserted both while Kermit is asking the modem
        !            28:      to dial a specific number, and after connection, while Kermit
        !            29:      is in a data exchange mode.  
        !            30: 
        !            31:      Carrier detect:  This signal must be asserted by the modem when
        !            32:      a carrier is detected from a remote modem on a communications
        !            33:      circuit.  It must be removed by the modem when the circuit
        !            34:      disconnects or is hung up.  (Carrier detect is ignored while
        !            35:      Kermit is asking the modem to dial the call, because there is
        !            36:      no consistant usage of this signal during the dialing phase
        !            37:      among different modem manufacturers.)
        !            38: 
        !            39: */
        !            40: 
        !            41: /*
        !            42:  * Modifications:
        !            43:  *
        !            44:  *     21-Jul-85       Fixed failure returns hanging on no carrier signal
        !            45:  *                     Requires tthang change too (ckutio.c revision)
        !            46:  *                                                     -- Herm Fischer
        !            47:  *
        !            48:  *     28-Jun-85       Fixed bug with defaulting the modem-failure message
        !            49:  *                     in lbuf.
        !            50:  *                                                     -- Dan Schullman
        !            51:  *
        !            52:  *     27-Jun-85       Merged in code from Joe Orost at Berkeley for
        !            53:  *                     supporting the US Robotics modem, which included
        !            54:  *                     changing the single characters in MDMINF into
        !            55:  *                     multi-character strings and modifying waitFor.
        !            56:  *                                                     -- Dan Schullman
        !            57:  *
        !            58:  *     26-Jun-85       Allow interrupts to be used to abort dialing,
        !            59:  *                     and ring the bell when a connection is made.
        !            60:  *                     Reorganized some of the failure paths to use the
        !            61:  *                     same code, and now close the line on failures.
        !            62:  *                     Allow use of stored numbers with the DF100 and
        !            63:  *                     DF200 modems.  Handlers now declared after the
        !            64:  *                     call to setjmp.
        !            65:  *                                                     -- Dan Schullman
        !            66:  *
        !            67:  *     24-May-85       DF03, DF100-series, DF200-series, and "unknown" modem
        !            68:  *                     support added.  Also restructured the various data
        !            69:  *                     tables, fixed some bugs related to missing data and
        !            70:  *                     missing case labels, and modified the failure message
        !            71:  *                     to display the "reason" given by the modem.
        !            72:  *                                                     -- Dan Schullman
        !            73:  *     16-Mar-87       Support for the ATT7300 UNIX PC internal modem was
        !            74:  *                     added.
        !            75:  *                                                     -- Richard E. Hill
        !            76:  */
        !            77: 
        !            78: /*
        !            79:  * To add support for another modem, do the following:
        !            80:  *
        !            81:  *     Define a modem number symbol (n_XXX) for it, keeping the list
        !            82:  *     in alphabetical and numerical order, and renumbering the values
        !            83:  *     as necessary.
        !            84:  *
        !            85:  *     Create a MDMINF structure for it, again keeping the list alphabetical
        !            86:  *     for sanity's sake.
        !            87:  *
        !            88:  *     Add the address of the MDMINF structure to the ptrtab array, again
        !            89:  *     in alphabetical and numerical order.
        !            90:  *
        !            91:  *     Add the "user visible" modem name and corresponding modem number to
        !            92:  *     the mdmtab array, again in alphabetical order.
        !            93:  *
        !            94:  *     Read through the code and add modem-specific sections as necessary.
        !            95:  */
        !            96: 
        !            97: /*
        !            98:  * The intent of the "unknown" modem is hopefully to allow KERMIT to support
        !            99:  * unknown modems by having the user type the entire autodial sequence
        !           100:  * (possibly including control characters, etc.) as the "phone number".
        !           101:  * The only reason that the CONNECT command cannot be used to do this is
        !           102:  * that a remote line cannot normally be opened unless carrier is present.
        !           103:  *
        !           104:  * The protocol and other characteristics of this modem are unknown, with
        !           105:  * some "reasonable" values being chosen for some of them.  The only way to
        !           106:  * detect if a connection is made is to look for carrier present.
        !           107:  *
        !           108:  * SUPPORT IS CURRENTLY ONLY PARTIALLY SKETCHED OUT FOR THIS.  ALSO, IT
        !           109:  * SHOULD PERHAPS BE HANDLED MUCH EARLIER, SIMPLY READING USER INPUT AND
        !           110:  * SENDING IT TO THE MODEM AND ECHOING MODEM RESPONSES BACK TO THE USER,
        !           111:  * ALL THE TIME LOOKING FOR CARRIER.  OF COURSE, THE PROBLEM THEN BECOMES
        !           112:  * ONE OF ALLOWING THE USER TO ABORT THE DIALING.  WE COULD CHOOSE SOME
        !           113:  * PHRASE THAT WOULD PRESUMABLY NEVER BE A PART OF A VALID AUTODIAL SEQUENCE
        !           114:  * (E.G., "QUIT" and "quit"). -- DS
        !           115:  */
        !           116: #include "ckcdeb.h"
        !           117: #include <stdio.h>
        !           118: #include <ctype.h>
        !           119: #include <signal.h>
        !           120: #include "ckcker.h"
        !           121: #include "ckucmd.h"
        !           122: 
        !           123: #ifndef ZILOG
        !           124: #include <setjmp.h>                    /* Longjumps */
        !           125: #else
        !           126: #include <setret.h>
        !           127: #endif
        !           128: 
        !           129: extern int flow, local, mdmtyp, quiet, speed, parity, seslog;
        !           130: extern char ttname[], sesfil[];
        !           131: 
        !           132: #define        MDMINF  struct mdminf
        !           133: 
        !           134: MDMINF         /* structure for modem-specific information */
        !           135:     {
        !           136:     int                dial_time;      /* time modem allows for dialing (secs) */
        !           137:     char       *pause_chars;   /* character(s) to tell modem to pause */
        !           138:     int                pause_time;     /* time associated with pause chars (secs) */
        !           139:     char       *wake_str;      /* string to wakeup modem & put in cmd mode */
        !           140:     int                wake_rate;      /* delay between wake_str characters (msecs) */
        !           141:     char       *wake_prompt;   /* string prompt after wake_str */
        !           142:     char       *dmode_str;     /* string to put modem in dialing mode */
        !           143:     char       *dmode_prompt;  /* string prompt for dialing mode */
        !           144:     char       *dial_str;      /* dialing string, with "%s" for number */
        !           145:     int                dial_rate;      /* delay between dialing characters (msecs) */
        !           146:     };
        !           147: 
        !           148: /*
        !           149:  * Define symbolic modem numbers.
        !           150:  *
        !           151:  * The numbers MUST correspond to the ordering of entries
        !           152:  * within the ptrtab array, and start at one (1).
        !           153:  *
        !           154:  * It is assumed that there are relatively few of these
        !           155:  * values, and that the high(er) bytes of the value may
        !           156:  * be used for modem-specific mode information.
        !           157:  *
        !           158:  * REMEMBER that only the first eight characters of these
        !           159:  * names are guaranteed to be unique.
        !           160:  */
        !           161: 
        !           162: #define                n_CERMETEK       1
        !           163: #define                n_DF03           2
        !           164: #define                n_DF100          3
        !           165: #define                n_DF200          4
        !           166: #define                n_GDC            5
        !           167: #define                n_HAYES          6
        !           168: #define                n_PENRIL         7
        !           169: #define                n_RACAL          8
        !           170: #define                n_UNKNOWN        9
        !           171: #define                n_USROBOT       10
        !           172: #define                n_VENTEL        11
        !           173: #define         n_CONCORD       12
        !           174: #define                n_ATT7300       13      /* added for PC7300 */
        !           175: 
        !           176: /*
        !           177:  * Declare modem "variant" numbers for any of the above for which it is
        !           178:  * necessary to note various operational modes, using the second byte
        !           179:  * of a modem number.
        !           180:  *
        !           181:  * It is assumed that such modem modes share the same modem-specific
        !           182:  * information (see MDMINF structure) but may differ in some of the actions
        !           183:  * that are performed.
        !           184:  */
        !           185: #define                n_HAYESNV       ( n_HAYES + ( 1<<8 ) )
        !           186: 
        !           187: /*
        !           188:  * Declare structures containing modem-specific information.
        !           189:  *
        !           190:  * REMEMBER that only the first SEVEN characters of these
        !           191:  * names are guaranteed to be unique.
        !           192:  */
        !           193: 
        !           194: static
        !           195: MDMINF CERMETEK =      /* information for "Cermetek Info-Mate 212 A" modem */
        !           196:     {
        !           197:     20,                        /* dial_time */
        !           198:     "BbPpTt",          /* pause_chars */
        !           199:     0,                 /* pause_time */        /** unknown -- DS **/
        !           200:     "  XY\016R\r",     /* wake_str */
        !           201:     200,               /* wake_rate */
        !           202:     "",                        /* wake_prompt */
        !           203:     "",                        /* dmode_str */
        !           204:     "",                        /* dmode_prompt */
        !           205:     "\016D '%s'\r",    /* dial_str */
        !           206:     200                        /* dial_rate */
        !           207:     };
        !           208: 
        !           209: static
        !           210: MDMINF DF03 =          /* information for "DEC DF03-AC" modem */
        !           211:     {
        !           212:     27,                        /* dial_time */
        !           213:     "=",               /* pause_chars */       /* wait for second dial tone */
        !           214:     15,                        /* pause_time */
        !           215:     "\001\002",                /* wake_str */
        !           216:     0,                 /* wake_rate */
        !           217:     "",                        /* wake_prompt */
        !           218:     "",                        /* dmode_str */
        !           219:     "",                        /* dmode_prompt */
        !           220:     "%s",              /* dial_str */
        !           221:     0                  /* dial_rate */
        !           222:     };
        !           223: 
        !           224: static
        !           225: MDMINF DF100 =         /* information for "DEC DF100-series" modem */
        !           226:                        /*
        !           227:                         * The telephone "number" can include "P"s and/or "T"s
        !           228:                         * within it to indicate that subsequent digits are
        !           229:                         * to be dialed using pulse or tone dialing.  The
        !           230:                         * modem defaults to pulse dialing.  You may modify
        !           231:                         * the dial string below to explicitly default all
        !           232:                         * dialing to pulse or tone, but doing so prevents
        !           233:                         * the use of phone numbers that you may have stored
        !           234:                         * in the modem's memory.
        !           235:                         */
        !           236:     {
        !           237:     30,                        /* dial_time */
        !           238:     "=",               /* pause_chars */       /* wait for second dial tone */
        !           239:     15,                        /* pause_time */
        !           240:     "\001",            /* wake_str */
        !           241:     0,                 /* wake_rate */
        !           242:     "",                        /* wake_prompt */
        !           243:     "",                        /* dmode_str */
        !           244:     "",                        /* dmode_prompt */
        !           245:     "%s#",             /* dial_str */
        !           246:     0                  /* dial_rate */
        !           247:     };
        !           248: 
        !           249: static
        !           250: MDMINF DF200 =         /* information for "DEC DF200-series" modem */
        !           251:                        /*
        !           252:                         * The telephone "number" can include "P"s and/or "T"s
        !           253:                         * within it to indicate that subsequent digits are
        !           254:                         * to be dialed using pulse or tone dialing.  The
        !           255:                         * modem defaults to pulse dialing.  You may modify
        !           256:                         * the dial string below to explicitly default all
        !           257:                         * dialing to pulse or tone, but doing so prevents
        !           258:                         * the use of phone numbers that you may have stored
        !           259:                         * in the modem's memory.
        !           260:                         */
        !           261:     {
        !           262:     30,                        /* dial_time */
        !           263:     "=W",              /* pause_chars */       /* =: second tone; W: 5 secs */
        !           264:     15,                        /* pause_time */        /* worst case */
        !           265:     "\002",            /* wake_str */          /* allow stored number usage */
        !           266:     0,                 /* wake_rate */
        !           267:     "",                        /* wake_prompt */
        !           268:     "",                        /* dmode_str */
        !           269:     "",                        /* dmode_prompt */
        !           270:     "%s!",             /* dial_str */
        !           271:     0                  /* dial_rate */
        !           272:     };
        !           273: 
        !           274: static
        !           275: MDMINF GDC =           /* information for "GeneralDataComm 212A/ED" modem */
        !           276:     {
        !           277:     32,                        /* dial_time */
        !           278:     "%",               /* pause_chars */
        !           279:     3,                 /* pause_time */
        !           280:     "\r\r",            /* wake_str */
        !           281:     500,               /* wake_rate */
        !           282:     "$",               /* wake_prompt */
        !           283:     "D\r",             /* dmode_str */
        !           284:     ":",               /* dmode_prompt */
        !           285:     "T%s\r",           /* dial_str */
        !           286:     0                  /* dial_rate */
        !           287:     };
        !           288: 
        !           289: static
        !           290: MDMINF HAYES =         /* information for "Hayes" modem */
        !           291:     {
        !           292:     35,                        /* dial_time */
        !           293:     ",",               /* pause_chars */
        !           294:     2,                 /* pause_time */
        !           295:     "AT\r",            /* wake_str */
        !           296:     0,                 /* wake_rate */
        !           297:     "",                        /* wake_prompt */
        !           298:     "",                        /* dmode_str */
        !           299:     "",                        /* dmode_prompt */
        !           300:     "AT D %s\r",       /* dial_str */
        !           301:     0                  /* dial_rate */
        !           302:     };
        !           303: 
        !           304: static
        !           305: MDMINF PENRIL =                /* information for "Penril" modem */
        !           306:     {
        !           307:     50,                        /* dial_time */
        !           308:     "",                        /* pause_chars */       /** unknown -- HF **/
        !           309:     0,                 /* pause_time */
        !           310:     "\r\r",            /* wake_str */
        !           311:     300,               /* wake_rate */
        !           312:     ">",               /* wake_prompt */
        !           313:     "k\r",             /* dmode_str */
        !           314:     ":",               /* dmode_prompt */
        !           315:     "%s\r",            /* dial_str */
        !           316:     0                  /* dial_rate */
        !           317:     };
        !           318: 
        !           319: static
        !           320: MDMINF RACAL =         /* information for "Racal Vadic" modem */
        !           321:     {
        !           322:     35,                        /* dial_time */
        !           323:     "Kk",              /* pause_chars */
        !           324:     5,                 /* pause_time */
        !           325:     "\005\r",          /* wake_str */
        !           326:     50,                        /* wake_rate */
        !           327:     "*",               /* wake_prompt */
        !           328:     "D\r",             /* dmode_str */
        !           329:     "?",               /* dmode_prompt */
        !           330:     "%s\r",            /* dial_str */
        !           331:     0                  /* dial_rate */
        !           332:     };
        !           333: 
        !           334: static
        !           335: MDMINF UNKNOWN =       /* information for "Unknown" modem */
        !           336:     {
        !           337:     30,                        /* dial_time */
        !           338:     "",                        /* pause_chars */
        !           339:     0,                 /* pause_time */
        !           340:     "",                        /* wake_str */
        !           341:     0,                 /* wake_rate */
        !           342:     "",                        /* wake_prompt */
        !           343:     "",                        /* dmode_str */
        !           344:     "",                        /* dmode_prompt */
        !           345:     "%s\r",            /* dial_str */
        !           346:     0                  /* dial_rate */
        !           347:     };
        !           348: 
        !           349: static
        !           350: MDMINF USROBOT =       /* information for "US Robotics 212A" modem */
        !           351:     {
        !           352:     30,                        /* dial_time */
        !           353:     ",",               /* pause_chars */
        !           354:     2,                 /* pause_time */
        !           355:     "ATS2=01\r",       /* wake_str */
        !           356:     0,                 /* wake_rate */
        !           357:     "OK\r",            /* wake_prompt */
        !           358:     "",                        /* dmode_str */
        !           359:     "",                        /* dmode_prompt */
        !           360:     "ATTD%s\r",                /* dial_str */
        !           361:     0                  /* dial_rate */
        !           362:     };
        !           363: 
        !           364: static
        !           365: MDMINF VENTEL =                /* information for "Ventel" modem */
        !           366:     {
        !           367:     20,                        /* dial_time */
        !           368:     "%",               /* pause_chars */
        !           369:     5,                 /* pause_time */
        !           370:     "\r\r\r",          /* wake_str */
        !           371:     300,               /* wake_rate */
        !           372:     "$",               /* wake_prompt */
        !           373:     "",                        /* dmode_str */
        !           374:     "",                        /* dmode_prompt */
        !           375:     "<K%s\r>",         /* dial_str */
        !           376:     0                  /* dial_rate */
        !           377:     };
        !           378: 
        !           379: static
        !           380: MDMINF CONCORD =       /* Info for Condor CDS 220 2400b modem */
        !           381:     {
        !           382:     35,                        /* dial_time */
        !           383:     ",",               /* pause_chars */
        !           384:     2,                 /* pause_time */
        !           385:     "\r\r",            /* wake_str */
        !           386:     20,                        /* wake_rate */
        !           387:     "CDS >",           /* wake_prompt */
        !           388:     "",                        /* dmode_str */
        !           389:     "",                        /* dmode_prompt */
        !           390:     "<D M%s\r>",       /* dial_str */
        !           391:     0                  /* dial_rate */
        !           392:     };
        !           393: 
        !           394: static
        !           395: MDMINF ATT7300 =       /* dummy information for "ATT7300" internal modem */
        !           396:     {
        !           397:     30,                        /* dial_time */
        !           398:     "",                        /* pause_chars */
        !           399:     0,                 /* pause_time */
        !           400:     "",                        /* wake_str */
        !           401:     0,                 /* wake_rate */
        !           402:     "",                        /* wake_prompt */
        !           403:     "",                        /* dmode_str */
        !           404:     "",                        /* dmode_prompt */
        !           405:     "%s\r",            /* dial_str */
        !           406:     0                  /* dial_rate */
        !           407:     };
        !           408: 
        !           409: /*
        !           410:  * Declare table for converting modem numbers to information pointers.
        !           411:  *
        !           412:  * The entries MUST be in ascending order by modem number, without any
        !           413:  * "gaps" in the numbers, and starting from one (1).
        !           414:  *
        !           415:  * This table should NOT include entries for the "variant" modem numbers,
        !           416:  * since it is assumed that they share the same information as the normal
        !           417:  * value.
        !           418:  */
        !           419: static
        !           420: MDMINF *ptrtab[] =
        !           421:     {
        !           422:     &CERMETEK,
        !           423:     &DF03,
        !           424:     &DF100,
        !           425:     &DF200,
        !           426:     &GDC,
        !           427:     &HAYES,
        !           428:     &PENRIL,
        !           429:     &RACAL,
        !           430:     &UNKNOWN,
        !           431:     &USROBOT,
        !           432:     &VENTEL,
        !           433:     &CONCORD,
        !           434:     &ATT7300
        !           435:     };
        !           436: 
        !           437: /*
        !           438:  * Declare modem names and associated numbers for command parsing,
        !           439:  * and also for doing number-to-name translation.
        !           440:  *
        !           441:  * The entries MUST be in alphabetical order by modem name.
        !           442:  */
        !           443: struct keytab mdmtab[] =
        !           444:     {
        !           445:     "att7300",          n_ATT7300,      0,
        !           446:     "cermetek",                n_CERMETEK,     0,
        !           447:     "concord",          n_CONCORD,      0,
        !           448:     "df03-ac",         n_DF03,         0,
        !           449:     "df100-series",    n_DF100,        0,
        !           450:     "df200-series",    n_DF200,        0,
        !           451:     "direct",          0,              0,
        !           452:     "gendatacomm",     n_GDC,          0,
        !           453:     "hayes",           n_HAYES,        0,
        !           454:     "penril",          n_PENRIL,       0,
        !           455:     "racalvadic",      n_RACAL,        0,
        !           456:     "unknown",         n_UNKNOWN,      0,
        !           457:     "usrobotics-212a", n_USROBOT,      0,
        !           458:     "ventel",          n_VENTEL,       0
        !           459:     };
        !           460: 
        !           461: int nmdm = (sizeof(mdmtab) / sizeof(struct keytab));   /* number of modems */
        !           462: 
        !           463: #define DIALING 4              /* for ttpkt parameter */
        !           464: #define CONNECT 5
        !           465: 
        !           466: #define CONNECTED 1            /* for completion status */
        !           467: #define FAILED   2
        !           468: 
        !           469: /*
        !           470:  * Failure reasons for use with the 'longjmp' exit.
        !           471:  */
        !           472: #define        F_time          1       /* timeout */
        !           473: #define F_int          2       /* interrupt */
        !           474: #define        F_modem         3       /* modem-detected failure */
        !           475: #define        F_minit         4       /* cannot initialize modem */
        !           476: 
        !           477: static
        !           478: char *F_reason[5] = {          /* failure reasons for message */
        !           479:     "Unknown",  "Timeout", "Interrupt", "Modem", "Initialize" };
        !           480: 
        !           481: static int tries = 0;
        !           482: 
        !           483: #define LBUFL 100
        !           484: static char lbuf[LBUFL];
        !           485: 
        !           486: static jmp_buf sjbuf;
        !           487: 
        !           488: static SIGTYP (*savAlrm)();    /* for saving alarm handler */
        !           489: static SIGTYP (*savInt)();     /* for saving interrupt handler */
        !           490: 
        !           491: dialtime() {                   /* timer interrupt handler */
        !           492:     longjmp( sjbuf, F_time );
        !           493: }
        !           494: 
        !           495: dialint()                      /* user-interrupt handler */
        !           496:     {
        !           497:     longjmp( sjbuf, F_int );
        !           498:     }
        !           499: 
        !           500: static
        !           501: ttolSlow(s,millisec) char *s; int millisec; {  /* output s-l-o-w-l-y */
        !           502:     for (; *s; s++) {
        !           503:        ttoc(*s);
        !           504:        msleep(millisec);
        !           505:        }
        !           506:     }
        !           507: 
        !           508: /*
        !           509:  * Wait for a string of characters.
        !           510:  *
        !           511:  * The characters are waited for individually, and other characters may
        !           512:  * be received "in between".  This merely guarantees that the characters
        !           513:  * ARE received, and in the order specified.
        !           514:  */
        !           515: static
        !           516: waitFor(s) char *s;
        !           517:     {
        !           518:     CHAR c;
        !           519:     while ( c = *s++ )                 /* while more characters remain... */
        !           520:        while ( ( ttinc(0) & 0177 ) != c ) ;    /* wait for the character */
        !           521:     }
        !           522: 
        !           523: static
        !           524: didWeGet(s,r) char *s, *r; {   /* Looks in string s for response r */
        !           525:     int lr = strlen(r);                /*  0 means not found, 1 means found it */
        !           526:     int i;
        !           527:     for (i = strlen(s)-lr; i >= 0; i--)
        !           528:        if ( s[i] == r[0] ) if ( !strncmp(s+i,r,lr) ) return( 1 );
        !           529:     return( 0 );           
        !           530: }
        !           531: 
        !           532: 
        !           533: /* R E S E T -- Reset alarms, etc. on exit. */
        !           534: 
        !           535: static
        !           536: reset ()
        !           537:     {
        !           538:     alarm(0);
        !           539:     signal(SIGALRM,savAlrm);           /* restore alarm handler */
        !           540:     signal(SIGINT,savInt);             /* restore interrupt handler */
        !           541:     }
        !           542: 
        !           543: 
        !           544: 
        !           545: /*  C K D I A L  --  Dial up the remote system */
        !           546: 
        !           547: ckdial(telnbr) char *telnbr; {
        !           548: 
        !           549:     char c;
        !           550:     char *i, *j;
        !           551:     int waitct, status;
        !           552:     char errmsg[50], *erp;
        !           553:     MDMINF *pmdminf;   /* pointer to modem-specific info */
        !           554:     int augmdmtyp;     /* "augmented" modem type, to handle modem modes */
        !           555:     int mdmEcho = 0;   /* assume modem does not echo */
        !           556:     int n, n1;
        !           557:     char *pc;          /* pointer to a character */
        !           558: 
        !           559:        if (!mdmtyp) {
        !           560:            printf("Sorry, you must 'set modem' first\n");
        !           561:            return(-2);
        !           562:        }
        !           563:        if (!local) {
        !           564:            printf("Sorry, you must 'set line' first\n");
        !           565:            return(-2);
        !           566:        }
        !           567:        if (speed < 0) {
        !           568:            printf("Sorry, you must 'set speed' first\n");
        !           569:            return(-2);
        !           570:         }
        !           571: 
        !           572: #ifdef ATT7300
        !           573: /*
        !           574:    The following if-statement added by R.E.Hill to handle the internal
        !           575:    modem available on the ATT PC7300 computer and other ATT systems which
        !           576:    uses internal modems activated by system routines - "dial" & "undial"
        !           577: */
        !           578:         if (mdmtyp == n_ATT7300) {
        !           579:            if (attdial(ttname,speed,telnbr)) return (-2);
        !           580:            if ( ! quiet ) printf ("call completed.\07\r\n");
        !           581:            return(0);
        !           582:        }
        !           583: #endif /* ATT7300 */
        !           584: 
        !           585:        if (ttopen(ttname,&local,mdmtyp) < 0) { /* Open, no carrier wait */
        !           586:            erp = errmsg;
        !           587:            sprintf(erp,"Sorry, can't open %s",ttname);
        !           588:            perror(errmsg);
        !           589:            return(-2);
        !           590:        }
        !           591:        pmdminf = ptrtab[mdmtyp-1];     /* set pointer to modem info */ 
        !           592:        augmdmtyp = mdmtyp;             /* initialize "augmented" modem type */
        !           593: 
        !           594: /* cont'd... */
        !           595: 
        !           596: 
        !           597:                                        /* interdigit waits for tone dial */
        !           598: /* ...dial, cont'd */
        !           599: 
        !           600: 
        !           601:        waitct = 1*strlen(telnbr) ;     /* compute time to dial worst case */
        !           602:        waitct += pmdminf->dial_time;   /* dialtone + completion wait times */
        !           603:        for (i=telnbr; *i; i++)         /* add in pause characters time */
        !           604:            for (j=pmdminf->pause_chars; *j; j++)
        !           605:                if (*i == *j) {
        !           606:                    waitct += pmdminf->pause_time; 
        !           607:                    break;
        !           608:                    }
        !           609: 
        !           610:        printf("Dialing thru %s, speed %d, number %s.\r\n",ttname,speed,telnbr);
        !           611:        printf("The timeout for completing the call is %d seconds.\r\n",waitct);
        !           612:        printf("Type the interrupt character to cancel the dialing.\r\n");
        !           613: 
        !           614: /* Hang up the modem (in case it wasn't "on hook") */
        !           615: 
        !           616:        if ( tthang() < 0 ) {
        !           617:            printf("Sorry, Can't hang up tty line\n");
        !           618:            return(-2);
        !           619:            }
        !           620: 
        !           621: /* Condition console terminal and communication line */            
        !           622:                                /* place line into "clocal" dialing state */
        !           623:        if ( ttpkt(speed,DIALING,parity) < 0 )  {
        !           624:            printf("Sorry, Can't condition communication line\n");
        !           625:            return(-2);
        !           626:        }
        !           627: 
        !           628: /*
        !           629:  * Establish jump vector, or handle "failure" jumps.
        !           630:  */
        !           631: 
        !           632:     if ( n = setjmp(sjbuf) )           /* if a "failure jump" was taken... */
        !           633:        {
        !           634:        alarm ( 0 );                    /* disable timeouts */
        !           635:        if ( n1 = setjmp(sjbuf) )       /* failure while handling failure */
        !           636:            {
        !           637:            printf ( "%s failure while handling failure.\r\n", F_reason[n1] );
        !           638:            }
        !           639:        else                            /* first (i.e., non-nested) failure */
        !           640:            {
        !           641:            signal ( SIGALRM, dialtime );       /* be sure to catch signals */
        !           642:            if ( signal ( SIGINT, SIG_IGN ) != SIG_IGN ) 
        !           643:                signal ( SIGINT, dialint );
        !           644:            alarm ( 5 );                /* be sure to get out of this section */
        !           645:            ttclos ();                  /* hangup and close the line */
        !           646:            }
        !           647:        switch ( n )                    /* type of failure */
        !           648:            {
        !           649:            case F_time:                /* timed out */
        !           650:                {
        !           651:                printf ( "No connection made within the allotted time.\r\n" );
        !           652:                break;
        !           653:                }
        !           654:            case F_int:                 /* dialing interrupted */
        !           655:                {
        !           656:                printf ( "Dialing interrupted.\r\n" );
        !           657:                break;
        !           658:                }
        !           659:            case F_modem:               /* modem detected a failure */
        !           660:                {
        !           661:                printf ( "Failed (\"" );
        !           662:                for ( pc=lbuf; *pc; pc++ )
        !           663:                    if ( isprint(*pc) )
        !           664:                        putchar(*pc);   /* display printable reason */ 
        !           665:                printf ( "\").\r\n" );
        !           666:                break;
        !           667:                }
        !           668:            case F_minit:               /* cannot initialize modem */
        !           669:                {
        !           670:                printf ( "Cannot initialize modem.\r\n" );
        !           671:                break;
        !           672:                }
        !           673:            }
        !           674:        reset ();                       /* reset alarms, etc. */
        !           675:        return ( -2 );                  /* exit with failure code */
        !           676:        }
        !           677: 
        !           678: /*
        !           679:  * Set timer and interrupt handlers.
        !           680:  */
        !           681: 
        !           682:     savAlrm = signal(SIGALRM,dialtime);        /* set alarm handler */
        !           683:     if ( ( savInt = signal ( SIGINT, SIG_IGN ) ) != SIG_IGN )
        !           684:        signal ( SIGINT, dialint );     /* set int handler if not ignored */
        !           685:     alarm(10);                 /* give modem 10 seconds to wake up */
        !           686: 
        !           687:     ttflui();                  /* flush input buffer if any */
        !           688: 
        !           689: /*
        !           690:  * Put modem in command mode.
        !           691:  */
        !           692: 
        !           693: #define OKAY 1                 /* modem attention attempt status */
        !           694: #define IGNORE 2
        !           695: #define GOT_O -2
        !           696: #define GOT_A -3
        !           697: 
        !           698: switch (augmdmtyp) {
        !           699:     case n_HAYES:
        !           700:     case n_HAYESNV:
        !           701:        while(tries++ < 4) {
        !           702:            ttol( HAYES.wake_str, strlen(HAYES.wake_str) );     /* wakeup */
        !           703:            status = 0;
        !           704:            while ( status <= 0 ) {
        !           705:                switch (ttinc(0) & 0177) {
        !           706:                    case 'A':                   /* echoing, ignore */
        !           707:                        status = GOT_A;
        !           708:                        break;
        !           709:                    case 'T':
        !           710:                        if (status == GOT_A) {
        !           711:                            mdmEcho = 1;        /* expect echoing later */
        !           712:                            status = 0;
        !           713:                            break;
        !           714:                        }
        !           715:                        status = IGNORE;
        !           716:                        break;
        !           717:                    case '\n':
        !           718:                    case '\r':
        !           719:                        status = 0;
        !           720:                        break;
        !           721:                    case '0':                   /* numeric result code */
        !           722:                        augmdmtyp = n_HAYESNV;  /* nonverbal result codes */
        !           723:                        status = OKAY;
        !           724:                        break;
        !           725:                    case 'O':                   /* maybe English result code*/
        !           726:                        status = GOT_O;
        !           727:                        break;
        !           728:                    case 'K':
        !           729:                        if (status == GOT_O) {
        !           730:                            augmdmtyp = n_HAYES;
        !           731:                            status = OKAY;
        !           732:                            break;
        !           733:                        }                       /* else its default anyway */
        !           734:                    default:
        !           735:                        status = IGNORE;
        !           736:                        break;
        !           737:                    }
        !           738:                }
        !           739:            if (status == OKAY) break;
        !           740:            if (status == IGNORE) ttflui();
        !           741:            sleep(1);           /* wait before retrying */
        !           742:        }
        !           743:         if (status != 0) break;
        !           744:        longjmp( sjbuf, F_minit );      /* modem-initialization failure */
        !           745: 
        !           746: /* cont'd... */
        !           747: 
        !           748:                                        /* interdigit waits for tone dial */
        !           749: /* ...dial, cont'd */
        !           750: 
        !           751:     default:                   /* place modem into command mode */
        !           752:        ttolSlow(pmdminf->wake_str, pmdminf->wake_rate);
        !           753:        waitFor(pmdminf->wake_prompt);
        !           754:        break;
        !           755:     }
        !           756:     alarm(0);                  /* turn off alarm */
        !           757:     msleep(500);               /* give things settling time */
        !           758:     alarm(10);                 /* alarm on dialing prompts */
        !           759: 
        !           760:                
        !           761: /* Dial the number */
        !           762: 
        !           763:                                /* put modem into dialing mode */
        !           764:     ttolSlow(pmdminf->dmode_str, pmdminf->dial_rate);  
        !           765:     if (pmdminf->dmode_prompt) {       /* wait for prompt, if any expected */
        !           766:        waitFor(pmdminf->dmode_prompt);
        !           767:        msleep(300);
        !           768:        }
        !           769: 
        !           770:     alarm(0);                  /* turn off alarm on dialing prompts */
        !           771:     alarm(waitct);             /* time to allow for connecting */
        !           772:     ttflui();                  /* clear out stuff from waking modem up */
        !           773:     sprintf(lbuf, pmdminf->dial_str, telnbr); /* form dialing string */
        !           774:     ttolSlow(lbuf,pmdminf->dial_rate); /* send dialing string */
        !           775: 
        !           776:     if (augmdmtyp == n_RACAL) {        /* acknowledge printout of dialing string */
        !           777:        sleep(3);
        !           778:        ttflui();
        !           779:        ttoc('\r');
        !           780:        }
        !           781: 
        !           782: /* cont'd... */
        !           783: 
        !           784: 
        !           785:                                        /* interdigit waits for tone dial */
        !           786: /* ...dial, cont'd */
        !           787: 
        !           788: 
        !           789: /* Check for connection */
        !           790: 
        !           791: /*
        !           792:  * I believe we also need to look for carrier in order to determine if a
        !           793:  * connection has been made.  In fact, for many we may only want to look for
        !           794:  * the "failure" responses in order to short-circuit the timeout, and let
        !           795:  * carrier be the determination of whether a connection has been made. -- DS
        !           796:  */
        !           797: 
        !           798:     status = 0;
        !           799:     strcpy(lbuf,"No Connection");      /* default failure reason */
        !           800:     while (status == 0) {
        !           801:       switch (augmdmtyp) {
        !           802:        default:
        !           803:            for (n=0; n < LBUFL; n++) { /* accumulate response */
        !           804:                lbuf[n] = (ttinc(0) & 0177); 
        !           805:                if ( lbuf[n] == '\r' || lbuf[n] == '\n' ) break;
        !           806:                }
        !           807:            lbuf[n] = '\0';             /* terminate response from modem */
        !           808:            if (n) {                    /* if one or more characters present */
        !           809:                switch (augmdmtyp) {
        !           810:                  case n_CERMETEK:
        !           811:                    if (didWeGet(lbuf,"\016A")) {       
        !           812:                        status = CONNECTED;
        !           813:                        ttolSlow("\016U 1\r",200);      /* make transparent*/
        !           814:                        }
        !           815:                    break;
        !           816:                  case n_DF100:      /* DF100 won't generate some of these */
        !           817:                  case n_DF200:
        !           818:                    if (didWeGet(lbuf,"Attached")) status = CONNECTED;
        !           819:                    /*
        !           820:                     * The DF100 will respond with "Attached" even if DTR
        !           821:                     * and/or carrier are not present.  Another reason to
        !           822:                     * (also) wait for carrier?
        !           823:                     */
        !           824:                    if (didWeGet(lbuf,"Busy")) status = FAILED;
        !           825:                    if (didWeGet(lbuf,"Disconnected")) status = FAILED;
        !           826:                    if (didWeGet(lbuf,"Error")) status = FAILED;
        !           827:                    if (didWeGet(lbuf,"No answer")) status = FAILED;
        !           828:                    if (didWeGet(lbuf,"No dial tone")) status = FAILED;
        !           829:                    if (didWeGet(lbuf,"Speed:")) status = FAILED;
        !           830:                    /*
        !           831:                     * It appears that the "Speed:..." response comes after an
        !           832:                     * "Attached" response, so this is never seen.  HOWEVER,
        !           833:                     * it would be very handy to detect this and temporarily
        !           834:                     * reset the speed, since it's a nuiscance otherwise.
        !           835:                     * If we wait for some more input from the modem, how do
        !           836:                     * we know if it's from the remote host or the modem?
        !           837:                     * Carrier reportedly doesn't get set until after the
        !           838:                     * "Speed:..." response (if any) is sent.  Another reason
        !           839:                     * to (also) wait for carrier.
        !           840:                     */
        !           841:                    break;
        !           842:                  case n_GDC:
        !           843:                    if (didWeGet(lbuf,"ON LINE")) status = CONNECTED;
        !           844:                    if (didWeGet(lbuf,"NO CONNECT")) status = FAILED;
        !           845:                    break;
        !           846:                  case n_HAYES:
        !           847:                  case n_USROBOT:
        !           848:                    if (didWeGet(lbuf,"CONNECT")) status = CONNECTED;
        !           849:                    if (didWeGet(lbuf,"NO CARRIER")) status = FAILED;
        !           850:                    break;
        !           851:                  case n_PENRIL:
        !           852:                    if (didWeGet(lbuf,"OK")) status = CONNECTED;
        !           853:                    if (didWeGet(lbuf,"BUSY")) status = FAILED;
        !           854:                    if (didWeGet(lbuf,"NO RING")) status = FAILED;
        !           855:                    break;
        !           856:                  case n_RACAL:
        !           857:                    if (didWeGet(lbuf,"ON LINE")) status = CONNECTED;
        !           858:                    if (didWeGet(lbuf,"FAILED CALL")) status = FAILED;
        !           859:                    break;
        !           860:                  case n_VENTEL:
        !           861:                    if (didWeGet(lbuf,"ONLINE!")) status = CONNECTED;
        !           862:                    if (didWeGet(lbuf,"BUSY")) status = FAILED;
        !           863:                    if (didWeGet(lbuf,"DEAD PHONE")) status = FAILED;
        !           864:                    break;
        !           865:                  case n_CONCORD:
        !           866:                    if (didWeGet(lbuf,"INITIATING")) status = CONNECTED;
        !           867:                    if (didWeGet(lbuf,"BUSY")) status = FAILED;
        !           868:                    if (didWeGet(lbuf,"CALL FAILED")) status = FAILED;
        !           869:                    break;
        !           870:                }
        !           871:            }
        !           872:            break;
        !           873: 
        !           874:        case n_DF03:                    /* because response lacks CR or NL */
        !           875:            c = ttinc(0) & 0177;
        !           876:            if ( c == 'A' ) status = CONNECTED;
        !           877:            if ( c == 'B' ) status = FAILED;
        !           878:            break;
        !           879: 
        !           880:        case n_HAYESNV:
        !           881:            c = ttinc(0) & 0177;
        !           882:            if (mdmEcho) {              /* sponge up dialing string */
        !           883:                mdmEcho = c!='\r';      /* until return is echoed */
        !           884:                break;
        !           885:                }
        !           886:            if (c == '1') status = CONNECTED;
        !           887:            if (c == '3') status = FAILED;
        !           888:            if (c == '5') status = CONNECTED;
        !           889:            break;
        !           890: 
        !           891:        case n_UNKNOWN:
        !           892:            /** SHOULD WAIT FOR CARRIER OR TIMEOUT -- DS **/
        !           893:            break;
        !           894:        }                               /* switch (augmdmtyp) */
        !           895:     }                                  /* while status == 0 */
        !           896:     alarm(0);                          /* turn off alarm on connecting */
        !           897:     if ( status != CONNECTED )         /* modem-detected failure */
        !           898:        longjmp( sjbuf, F_modem );      /* exit (with reason in lbuf) */
        !           899:     alarm(3);                          /* precaution in case of trouble */
        !           900:     ttpkt(speed,CONNECT,parity);       /* cancel dialing state ioctl */
        !           901:     reset ();                          /* reset alarms, etc. */
        !           902:     if ( ! quiet )
        !           903:        printf ( "Call completed.\07\r\n" );
        !           904:     return ( 0 );                      /* return, and presumably connect */
        !           905: }

unix.superglobalmegacorp.com

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