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