Annotation of 43BSD/contrib/kermit/ckudia.c, revision 1.1

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

unix.superglobalmegacorp.com

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