source: trunk/third/kermit/ckudia.c @ 10780

Revision 10780, 171.6 KB checked in by brlewis, 27 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r10779, which included commits to RCS files with non-trunk default branches.
Line 
1#include "ckcsym.h"
2#ifndef NOLOCAL
3#ifndef NODIAL
4#ifndef NOICP
5
6char *dialv = "Dial Command, 6.0.091, 6 Sep 96";
7
8#ifndef NOOLDMODEMS        /* Unless instructed otherwise, */
9#define OLDMODEMS          /* keep support for old modems. */
10#endif /* NOOLDMODEMS */
11
12#ifndef M_OLD              /* Hide old modem keywords in SET MODEM table. */
13#define M_OLD 0            /* Define as to CM_INV to make them invisible. */
14#endif /* M_OLD */
15
16/*  C K U D I A  --  Module for automatic modem dialing. */
17
18/*
19  Copyright (C) 1985, 1996, Trustees of Columbia University in the City of New
20  York.  The C-Kermit software may not be, in whole or in part, licensed or
21  sold for profit as a software product itself, nor may it be included in or
22  distributed with commercial products or otherwise distributed by commercial
23  concerns to their clients or customers without written permission of the
24  Office of Kermit Development and Distribution, Columbia University.  This
25  copyright notice must not be removed, altered, or obscured.
26*/
27
28/*
29  Authors:
30
31  Original (version 1, 1985) author: Herm Fischer, Encino, CA.
32  Contributed to Columbia University in 1985 for inclusion in C-Kermit 4.0.
33  Author and maintainer since 1985: Frank da Cruz, Columbia University,
34  fdc@columbia.edu.
35
36  Contributions by many others throughout the years, including: Jeffrey
37  Altman, Mark Berryman, Fernando Cabral, John Chmielewski, Joe Doupnik,
38  Richard Hill, Larry Jacobs, Eric Jones, Tom Kloos, Bob Larson, Peter Mauzey,
39  Joe Orost, Kevin O'Gorman, Kai Uwe Rommel, Dan Schullman, Warren Tucker, and
40  others too numerous to list here (but see acknowledgements in ckcmai.c).
41*/
42
43/*
44  Entry points:
45    ckdial(char * number)   Dial a number or answer a call
46    dialhup()               Hang up a dialed connection
47    mdmhup()                Use modem commands to hang up
48
49  All other routines are static.
50  Don't call dialhup() or mdmhup() without first calling ckdial().
51*/
52
53/*
54  This module calls externally defined system-dependent functions for
55  communications i/o, as described in CKCPLM.DOC, the C-Kermit Program Logic
56  Manual, and thus should be portable to all systems that implement those
57  functions, and where alarm() and signal() work as they do in UNIX.
58
59  TO ADD SUPPORT FOR ANOTHER MODEM, do the following, all in this module:
60
61  1. Define a modem-type number symbol (n_XXX) for it, the next highest one.
62
63  2. Adjust MAX_MDM to the new number of modem types.
64
65  3. Create a MDMINF structure for it.  NOTE: The wake_str should include
66     all invariant setup info, e.g. enable result codes, BREAK transparency,
67     modulation negotiation, etc.  See ckcker.h for MDMINF struct definition.
68
69  4. Add the address of the MDMINF structure to the modemp[] array,
70     according to the numerical value of the modem-type number.
71
72  5. Add the user-visible (SET MODEM) name and corresponding modem number
73     to the mdmtab[] array, in alphabetical order by modem-name string.
74
75  6. Read through the code and add any modem-specific sections as necessary.
76     For most modern Hayes-compatible modems, no specific code will be
77     needed.
78
79  NOTE: The MINIDIAL symbol is used to build this module to include support
80  for only a minimum number of standard and/or generally useful modem types,
81  namely Hayes, CCITT V.25bis, "Unknown", and None.  When adding support for
82  a new modem type, keep it outside of the MINIDIAL sections.
83*/
84
85#include "ckcdeb.h"
86#ifndef MAC
87#include <signal.h>
88#endif /* MAC */
89#include "ckcasc.h"
90#include "ckcker.h"
91#include "ckucmd.h"
92#include "ckcnet.h"
93#include "ckuusr.h"
94
95#ifdef OS2ONLY
96#define INCL_VIO                        /* Needed for ckocon.h */
97#include <os2.h>
98#include "ckocon.h"
99#endif /* OS2ONLY */
100
101#ifdef NT
102#include "cknwin.h"
103#endif /* NT */
104#ifdef OS2
105#include "ckowin.h"
106#endif /* OS2 */
107
108#ifndef ZILOG
109#ifdef NT
110#include <setjmpex.h>
111#else /* NT */
112#include <setjmp.h>
113#endif /* NT */
114#else
115#include <setret.h>
116#endif /* ZILOG */
117
118#include "ckcsig.h"        /* C-Kermit signal processing */
119
120#ifdef MAC
121#define signal msignal
122#define SIGTYP long
123#define alarm malarm
124#define SIG_IGN 0
125#define SIGALRM 1
126#define SIGINT  2
127SIGTYP (*msignal(int type, SIGTYP (*func)(int)))(int);
128#endif /* MAC */
129
130#ifdef AMIGA
131#define signal asignal
132#define alarm aalarm
133#define SIGALRM (_NUMSIG+1)
134#define SIGTYP void
135SIGTYP (*asignal(int type, SIGTYP (*func)(int)))(int);
136unsigned aalarm(unsigned);
137#endif /* AMIGA */
138
139#ifdef STRATUS
140/*
141  VOS doesn't have alarm(), but it does have some things we can work with.
142  However, we have to catch all the signals in one place to do this, so
143  we intercept the signal() routine and call it from our own replacement.
144*/
145#define signal vsignal
146#define alarm valarm
147SIGTYP (*vsignal(int type, SIGTYP (*func)(int)))(int);
148int valarm(int interval);
149#ifdef putchar
150#undef putchar
151#endif /* putchar */
152#define putchar(x) conoc(x)
153#ifdef getchar
154#undef getchar
155#endif /* getchar */
156#define getchar(x) coninc(0)
157#endif /* STRATUS */
158
159#ifdef OS2
160#ifdef putchar
161#undef putchar
162#endif /* putchar */
163#define putchar(x) conoc(x)
164#endif /* OS2 */
165
166#ifdef BIGBUFOK /* Only for verions that are not tight on memory */
167
168char * dialmsg[] = {                    /* DIAL status strings */
169
170    /* Keyed to numbers defined in ckcker.h -- keep in sync! */
171
172    "DIAL succeeded",                       /*  0 */
173    "Modem type not specified",             /*  1 */
174    "Communication device not specified",   /*  2 */
175    "Communication device can't be opened", /*  3 */
176    "Speed not specified",                  /*  4 */
177    "Pre-DIAL hangup failed",               /*  5 */
178    "Internal error",                       /*  6 */
179    "Device input/output error",            /*  7 */
180    "DIAL TIMEOUT expired",                 /*  8 */
181    "Interrupted by user",                  /*  9 */
182    "Modem not ready",                      /* 10 */
183    "Partial dial OK",                      /* 11 */
184    "Dial directory lookup error",          /* 12 */
185    NULL,                                   /* 13 */
186    NULL,                                   /* 14 */
187    NULL,                                   /* 15 */
188    NULL,                                   /* 16 */
189    NULL,                                   /* 17 */
190    NULL,                                   /* 18 */
191    NULL,                                   /* 19 */
192    "Modem command error",                  /* 20 */
193    "Failure to initialize modem",          /* 21 */
194    "Phone busy",                           /* 22 */
195    "No carrier",                           /* 23 */
196    "No dialtone",                          /* 24 */
197    "Incoming call",                        /* 25 */
198    "No answer",                            /* 26 */
199    "Disconnected",                         /* 27 */
200    "Answered by voice",                    /* 28 */
201    "Access denied / forbidden call",       /* 29 */
202    "Blacklisted",                          /* 30 */
203    "Delayed",                              /* 31 */
204    "Fax connection",                       /* 32 */
205    NULL                                    /* 33 */
206};
207#endif /* BIGBUFOK */
208
209#ifndef NOSPL
210char modemmsg[80];                      /* DIAL response from modem */
211#endif /* NOSPL */
212
213#ifdef NTSIG
214extern int TlsIndex;
215#endif /* NTSIG */
216
217int                                     /* SET DIAL parameters */
218  dialhng = 1,                          /* DIAL HANGUP, default is ON */
219  dialdpy = 0,                          /* DIAL DISPLAY, default is OFF */
220  mdmspd  = 0,                          /* DIAL SPEED-MATCHING (0 = OFF) */
221  dialtmo = 0,                          /* DIAL TIMEOUT */
222  dialatmo = -1,                        /* ANSWER TIMEOUT */
223  dialksp = 0,                          /* DIAL KERMIT-SPOOF, 0 = OFF */
224#ifdef NOMDMHUP
225  dialmhu = 0;                          /* DIAL MODEM-HANGUP, 0 = OFF */
226#else
227  dialmhu = 1;                          /* DIAL MODEM-HANGUP */
228#endif /* NOMDMHUP */
229
230int
231  dialec = 0,                           /* DIAL ERROR-CORRECTION */
232  dialdc = 0,                           /* DIAL COMPRESSION  */
233  dialfc = FLO_AUTO,                    /* DIAL FLOW-CONTROL */
234  dialmth = XYDM_D,                     /* DIAL METHOD */
235  dialesc = 0;                          /* DIAL ESCAPE */
236
237int telephony = 0;                      /* Command-line '-T' option */
238
239long dialmax = 0L,                      /* Modem's max interface speed */
240  dialcapas  = 0L;                      /* Modem's capabilities */
241
242int dialsta = DIA_UNK;                  /* Detailed return code (ckuusr.h) */
243
244int is_rockwell = 0;
245int is_hayeshispd = 0;
246
247char *dialdir[MAXDDIR];                 /* DIAL DIRECTORY filename array */
248int   ndialdir = 0;                     /* How many dial directories */
249char *dialini = NULL;                   /* DIAL INIT-STRING, default none */
250char *dialmstr = NULL;                  /* DIAL MODE-STRING, default none */
251char *dialmprmt = NULL;                 /* DIAL MODE-PROMPT, default none */
252char *dialcmd = NULL;                   /* DIAL DIAL-COMMAND, default none */
253char *dialnpr = NULL;                   /* DIAL PREFIX, ditto */
254char *diallac = NULL;                   /* DIAL LOCAL-AREA-CODE, ditto */
255char *diallcc = NULL;                   /* DIAL LOCAL-COUNTRY-CODE, ditto */
256char *dialixp = NULL;                   /* DIAL INTL-PREFIX */
257char *dialixs = NULL;                   /* DIAL INTL-SUFFIX */
258char *dialldp = NULL;                   /* DIAL LD-PREFIX */
259char *diallds = NULL;                   /* DIAL LD-SUFFIX */
260char *dialpxx = NULL;                   /* DIAL PBX-EXCHANGE */
261char *dialpxi = NULL;                   /* DIAL INTERNAL-PREFIX */
262char *dialpxo = NULL;                   /* DIAL OUTSIDE-PREFIX */
263char *dialsfx = NULL;                   /* DIAL SUFFIX */
264char *dialtfp = NULL;                   /* DIAL TOLL-FREE-PREFIX */
265extern char * d_name;
266extern char * dialtfc[];
267extern int ntollfree;
268char *dialname  = NULL;                 /* Descriptive name for modem */
269char *dialdcon  = NULL;                 /* DC ON command */
270char *dialdcoff = NULL;                 /* DC OFF command */
271char *dialecon  = NULL;                 /* EC ON command */
272char *dialecoff = NULL;                 /* EC OFF command */
273char *dialaaon  = NULL;                 /* Autoanswer ON command */
274char *dialaaoff = NULL;                 /* Autoanswer OFF command */
275char *dialhcmd  = NULL;                 /* Hangup command */
276char *dialhwfc  = NULL;                 /* Hardware flow control command */
277char *dialswfc  = NULL;                 /* (Local) software f.c. command */
278char *dialnofc  = NULL;                 /* No (Local) flow control command */
279char *dialtone  = NULL;                 /* Command to force tone dialing */
280char *dialpulse = NULL;                 /*  ..to force pulse dialing */
281char *mdmname   = NULL;
282
283#ifndef MINIDIAL
284/*
285  Telebit model codes:
286
287  ATI  Model Numbers           Examples
288  ---  -------------           --------
289  123                          Telebit in "total Hayes-1200" emulation mode
290  960                          Telebit in Conventional Command (Hayes) mode
291  961  RA12C                   IBM PC internal original Trailblazer
292  962  RA12E                   External original Trailblazer
293  963  RM12C                   Rackmount original Trailblazer
294  964  T18PC                   IBM PC internal Trailblazer-Plus (TB+)
295  965  T18SA, T2SAA, T2SAS     External TB+, T1600, T2000, T3000, WB, and later
296  966  T18RMM                  Rackmount TB+
297  967  T2MC                    IBM PS/2 internal TB+
298  968  T1000                   External T1000
299  969  ?                       Qblazer
300  970                          Qblazer Plus
301  971  T2500                   External T2500
302  972  T2500                   Rackmount T2500
303*/
304
305/* Telebit model codes */
306
307#define TB_UNK  0                       /* Unknown Telebit model */
308#define TB_BLAZ 1                       /* Original TrailBlazer */
309#define TB_PLUS 2                       /* TrailBlazer Plus */
310#define TB_1000 3                       /* T1000 */
311#define TB_1500 4                       /* T1500 */
312#define TB_1600 5                       /* T1600 */
313#define TB_2000 6                       /* T2000 */
314#define TB_2500 7                       /* T2500 */
315#define TB_3000 8                       /* T3000 */
316#define TB_QBLA 9                       /* Qblazer */
317#define TB_WBLA 10                      /* WorldBlazer */
318#define TB__MAX 10                      /* Highest number */
319
320char *tb_name[] = {                     /* Array of model names */
321    "Unknown",                          /* TB_UNK  */
322    "TrailBlazer",                      /* TB_BLAZ */
323    "TrailBlazer-Plus",                 /* TB_PLUS */
324    "T1000",                            /* TB_1000 */
325    "T1500",                            /* TB_1500 */
326    "T1600",                            /* TB_1600 */
327    "T2000",                            /* TB_2000 */
328    "T2500",                            /* TB_2500 */
329    "T3000",                            /* TB_3000 */
330    "Qblazer",                          /* TB_QBLA */
331    "WorldBlazer",                      /* TB_WBLA */
332    ""
333};
334#endif /* MINIDIAL */
335
336extern int flow, local, mdmtyp, quiet, backgrd, parity, seslog, network;
337extern int carrier, duplex, mdmsav;
338#ifdef NETCONN
339extern int ttnproto;
340#endif /* NETCONN */
341extern CHAR stchr;
342extern long speed;
343extern char ttname[], sesfil[];
344
345/*  Failure codes  */
346
347#define F_TIME          1               /* timeout */
348#define F_INT           2               /* interrupt */
349#define F_MODEM         3               /* modem-detected failure */
350#define F_MINIT         4               /* cannot initialize modem */
351
352static
353#ifdef OS2
354 volatile
355#endif /* OS2 */
356 int fail_code =  0;                    /* Default failure reason. */
357
358static int func_code;                   /* 0 = dialing, nonzero = answering */
359static int partial;
360static int mymdmtyp = 0;
361
362#define DW_NOTHING      0               /* What we are doing */
363#define DW_INIT         1
364#define DW_DIAL         2
365
366static int dial_what = DW_NOTHING;      /* Nothing at first. */
367static int nonverbal = 0;               /* Hayes in numeric response mode */
368static MDMINF * mp;
369static CHAR escbuf[6];
370static long mdmcapas;
371
372_PROTOTYP (static VOID dreset, (void) );
373_PROTOTYP (static int (*xx_ok), (int,int) );
374_PROTOTYP (static int ddinc, (int) );
375_PROTOTYP (int dialhup, (void) );
376_PROTOTYP (static int getok, (int,int) );
377_PROTOTYP (char * ck_time, (void) );
378_PROTOTYP (static VOID ttslow, (char *, int) );
379#ifdef COMMENT
380_PROTOTYP (static VOID xcpy, (char *, char *, unsigned int) );
381#endif /* COMMENT */
382_PROTOTYP (static VOID waitfor, (char *) );
383_PROTOTYP (static VOID dialoc, (char) );
384_PROTOTYP (static int didweget, (char *, char *) );
385_PROTOTYP (static VOID spdchg, (long) );
386#ifndef MINIDIAL
387#ifdef OLDTBCODE
388_PROTOTYP (static VOID tbati3, (int) );
389#endif /* OLDTBCODE */
390#endif /* MINIDIAL */
391_PROTOTYP (static int dialfail, (int) );
392_PROTOTYP (static VOID gethrw, (void) );
393_PROTOTYP (static VOID gethrn, (void) );
394
395/*
396 * Define symbolic modem numbers.
397 *
398 * The numbers MUST correspond to the ordering of entries
399 * within the modemp array, and start at one (1).
400 *
401 * It is assumed that there are relatively few of these
402 * values, and that the high(er) bytes of the value may
403 * be used for modem-specific mode information.
404 *
405 * REMEMBER that only the first eight characters of these
406 * names are guaranteed to be unique.
407 */
408
409#ifdef MINIDIAL                         /* Minimum dialer support */
410                                        /* Only for CCITT, HAYES, and UNK */
411#define         n_CCITT          1      /* CCITT/ITU-T V.25bis */
412#define         n_HAYES          2      /* Hayes 2400 */
413#define         n_UNKNOWN        3      /* Unknown */
414#define         n_UDEF           4      /* User-Defined */
415#define         MAX_MDM          4      /* Number of modem types */
416
417#else                                   /* Full-blown dialer support */
418
419#define         n_ATTDTDM        1
420#define         n_ATTISN         2
421#define         n_ATTMODEM       3
422#define         n_CCITT          4
423#define         n_CERMETEK       5
424#define         n_DF03           6
425#define         n_DF100          7
426#define         n_DF200          8
427#define         n_GDC            9
428#define         n_HAYES         10
429#define         n_PENRIL        11
430#define         n_RACAL         12
431#define         n_UNKNOWN       13
432#define         n_VENTEL        14
433#define         n_CONCORD       15
434#define         n_ATTUPC        16      /* aka UNIX PC and ATT7300 */
435#define         n_ROLM          17      /* Rolm CBX DCM */
436#define         n_MICROCOM      18      /* Microcoms in SX command mode */
437#define         n_USR           19      /* Modern USRs */
438#define         n_TELEBIT       20      /* Telebits of all kinds */
439#define         n_DIGITEL       21      /* Digitel DT-22 (CCITT variant) */
440
441#define         n_H_1200        22      /* Hayes 1200 */
442#define         n_H_ULTRA       23      /* Hayes Ultra and maybe Optima */
443#define         n_H_ACCURA      24      /* Hayes Accura and maybe Optima */
444#define         n_PPI           25      /* Practical Peripherals */
445#define         n_DATAPORT      26      /* AT&T Dataport */
446#define         n_BOCA          27      /* Boca */
447#define         n_MOTOROLA      28      /* Motorola Fastalk or Lifestyle */
448#define         n_DIGICOMM      29      /* Digicomm Connection */
449#define         n_DYNALINK      30      /* Dynalink 1414VE */
450#define         n_INTEL         31      /* Intel 14400 Faxmodem */
451#define         n_UCOM_AT       32      /* Microcoms in AT mode */
452#define         n_MULTI         33      /* Multitech MT1432 */
453#define         n_SUPRA         34      /* SupraFAXmodem */
454#define         n_ZOLTRIX       35      /* Zoltrix */
455#define         n_ZOOM          36      /* Zoom */
456#define         n_ZYXEL         37      /* ZyXEL */
457#define         n_TAPI          38      /* Microsoft Windows dialer */
458#define         n_TBNEW         39      /* Newer Telebit models */
459#define         n_MAXTECH       40      /* MaxTech XM288EA */
460#define         n_UDEF          41      /* User-Defined */
461#define         n_RWV32         42      /* Generic Rockwell V.32 */
462#define         n_RWV32B        43      /* Generic Rockwell V.32bis */
463#define         n_RWV34         44      /* Generic Rockwell V.34 */
464#define         n_MWAVE         45      /* IBM Mwave Adapter */
465#define         n_TELEPATH      46      /* Gateway Telepath */
466#define         n_MICROLINK     47      /* MicroLink modems */
467#define         n_CARDINAL      48      /* Cardinal modems */
468#define         MAX_MDM         48      /* Number of modem types */
469
470#endif /* MINIDIAL */
471
472int dialudt = n_UDEF;                   /* Number of user-defined type */
473
474/* BEGIN MDMINF STRUCT DEFINITIONS */
475
476/*
477  Declare structures containing modem-specific information.
478  REMEMBER that only the first SEVEN characters of these names are
479  guaranteed to be unique.
480
481  First declare the three types that are allowed for MINIDIAL versions.
482*/
483static
484MDMINF CCITT =                          /* CCITT / ITU-T V.25bis autodialer */
485/*
486  According to V.25bis:
487  . Even parity is required for giving commands to the modem.
488  . Commands might or might not echo.
489  . Responses ("Indications") from the modem are terminated by CR and LF.
490  . Call setup is accomplished by:
491    - DTE raises DTR (V.24 circuit 108)              [ttopen() does this]
492    - Modem raises CTS (V.24 circuit 106)            [C-Kermit ignores this]
493    - DTE issues a call request command ("CRN")
494    - Modem responds with "VAL" ("command accepted")
495    - If the call is completed:
496        modem responds with "CNX" ("call connected");
497        modem turns CTS (106) OFF;
498        modem turns DSR (107) ON;
499      else:
500        modem responds with "CFI <parameter>" ("call failure indication").
501  . To clear a call, the DTE turns DTR (108) OFF.
502  . There is no mention of the Carrier Detect circuit (109) in the standard.
503  . There is no provision for "escaping back" to the modem's command mode.
504
505  It is not known whether there exists in real life a pure V.25bis modem.
506  If there is, this code has never been tested on it.  See the Digitel entry.
507*/
508    {
509    "CCITT / ITU-T V.25bis autodialer",
510    "",                 /* pulse command */
511    "",                 /* tone command */
512    40,                 /* dial_time -- programmable -- */
513    ",:",               /* pause_chars -- "," waits for programmable time */
514                        /* ":" waits for dial tone */
515    10,                 /* pause_time (seconds, just a guess) */
516    "",                 /* wake_str (none) */
517    200,                /* wake_rate (msec) */
518    "VAL",              /* wake_prompt */
519    "",                 /* dmode_str (none) */
520    "",                 /* dmode_prompt (none) */
521    "CRN%s\015",        /* dial_str */
522    200,                /* dial_rate (msec) */
523    0,                  /* No esc_time */
524    0,                  /* No esc_char  */
525    "",                 /* No hup_str  */
526    "",                 /* hwfc_str */
527    "",                 /* swfc_str */
528    "",                 /* nofc_str */
529    "",                 /* ec_on_str */
530    "",                 /* ec_off_str */
531    "",                 /* dc_on_str */
532    "",                 /* dc_off_str */
533    "",                 /* aa_on_str */
534    "",                 /* aa_off_str */
535    "",                 /* sb_on_str */
536    "",                 /* sb_off_str */
537    0L,                 /* max_speed */
538    CKD_V25,            /* capas */
539    NULL                /* No ok_fn    */
540};
541
542static
543MDMINF HAYES =                          /* Hayes 2400 and compatible modems */
544    {
545    "Hayes Smartmodem 2400 and compatibles",
546    "ATP\015",                          /* pulse command */
547    "ATT\015",                          /* tone command */
548    35,                                 /* dial_time */
549    ",",                                /* pause_chars */
550    2,                                  /* pause_time */
551#ifdef OS2
552    "ATQ0&S0&C1&D2\015",                /* wake_str */
553#else
554    "ATQ0\015",                         /* wake_str */
555#endif /* OS2 */
556    0,                                  /* wake_rate */
557    "OK\015",                           /* wake_prompt */
558    "",                                 /* dmode_str */
559    "",                                 /* dmode_prompt */
560    "ATD%s\015",                        /* dial_str, user supplies D or T */
561    0,                                  /* dial_rate */
562    1100,                               /* esc_time */
563    43,                                 /* esc_char */
564    "ATQ0H0\015",                       /* hup_str */
565    "",                                 /* hwfc_str */
566    "",                                 /* swfc_str */
567    "",                                 /* nofc_str */
568    "",                                 /* ec_on_str */
569    "",                                 /* ec_off_str */
570    "",                                 /* dc_on_str */
571    "",                                 /* dc_off_str */
572    "ATS0=1\015",                       /* aa_on_str */
573    "ATS0=0\015",                       /* aa_off_str */
574    "",                                 /* sb_on_str */
575    "",                                 /* sb_off_str */
576    2400L,                              /* max_speed */
577    CKD_AT,                             /* capas */
578    getok                               /* ok_fn */
579};
580
581/*
582  The intent of the "unknown" modem is to allow KERMIT to support
583  unknown modems by having the user type the entire autodial sequence
584  (possibly including control characters, etc.) as the "phone number".
585  The protocol and other characteristics of this modem are unknown, with
586  some "reasonable" values being chosen for some of them.  The only way to
587  detect if a connection is made is to look for carrier.
588*/
589static
590MDMINF UNKNOWN =                        /* Information for "Unknown" modem */
591    {
592    "Unknown",                          /* name */
593    "",                                 /* pulse command */
594    "",                                 /* tone command */
595    30,                                 /* dial_time */
596    "",                                 /* pause_chars */
597    0,                                  /* pause_time */
598    "",                                 /* wake_str */
599    0,                                  /* wake_rate */
600    "",                                 /* wake_prompt */
601    "",                                 /* dmode_str */
602    NULL,                               /* dmode_prompt */
603    "%s\015",                           /* dial_str */
604    0,                                  /* dial_rate */
605    0,                                  /* esc_time */
606    0,                                  /* esc_char */
607    "",                                 /* hup_str */
608    "",                                 /* hwfc_str */
609    "",                                 /* swfc_str */
610    "",                                 /* nofc_str */
611    "",                                 /* ec_on_str */
612    "",                                 /* ec_off_str */
613    "",                                 /* dc_on_str */
614    "",                                 /* dc_off_str */
615    "",                                 /* aa_on_str */
616    "",                                 /* aa_off_str */
617    "",                                 /* sb_on_str */
618    "",                                 /* sb_off_str */
619    0L,                                 /* max_speed */
620    0,                                  /* capas */
621    NULL                                /* ok_fn */
622};
623
624#ifndef MINIDIAL
625static
626MDMINF ATTISN =                         /* AT&T ISN Network */
627    {
628    "",                                 /* pulse command */
629    "",                                 /* tone command */
630    "AT&T ISN Network",
631    30,                                 /* Dial time */
632    "",                                 /* Pause characters */
633    0,                                  /* Pause time */
634    "\015\015\015\015",                 /* Wake string */
635    900,                                /* Wake rate */
636    "DIAL",                             /* Wake prompt */
637    "",                                 /* dmode_str */
638    "",                                 /* dmode_prompt */
639    "%s\015",                           /* dial_str */
640    0,                                  /* dial_rate */
641    0,                                  /* esc_time */
642    0,                                  /* esc_char */
643    "",                                 /* hup_str */
644    "",                                 /* hwfc_str */
645    "",                                 /* swfc_str */
646    "",                                 /* nofc_str */
647    "",                                 /* ec_on_str */
648    "",                                 /* ec_off_str */
649    "",                                 /* dc_on_str */
650    "",                                 /* dc_off_str */
651    "",                                 /* aa_on_str */
652    "",                                 /* aa_off_str */
653    "",                                 /* sb_on_str */
654    "",                                 /* sb_off_str */
655    0L,                                 /* max_speed */
656    0,                                  /* capas */
657    NULL                                /* ok_fn */
658};
659
660static
661MDMINF ATTMODEM =       /* information for AT&T switched-network modems */
662                        /* "Number" following "dial" can include: p's and
663                         * t's to indicate pulse or tone (default) dialing,
664                         * + for wait for dial tone, , for pause, r for
665                         * last number dialed, and, except for 2224B, some
666                         * comma-delimited options like o12=y, before number.
667
668 * "Important" options for the modems:
669 *
670 *      All:            Except for 2224B, enable option 12 for "transparent
671 *                      data," o12=y.  If a computer port used for both
672 *                      incoming and outgoing calls is connected to the
673 *                      modem, disable "enter interactive mode on carriage
674 *                      return," EICR.  The Kermit "dial" command can
675 *                      function with EIA leads standard, EIAS.
676 *
677 *      2212C:          Internal hardware switches at their default
678 *                      positions (four rockers down away from numbers)
679 *                      unless EICR is not wanted (rocker down at the 4).
680 *                      For EIAS, rocker down at the 1.
681 *
682 *      2224B:          Front-panel switch position 1 must be up (at the 1,
683 *                      closed).  Disable EICR with position 2 down.
684 *                      For EIAS, position 4 down.
685 *                      All switches on the back panel down.
686 *
687 *      2224CEO:        All front-panel switches down except either 5 or 6.
688 *                      Enable interactive flow control with o16=y.
689 *                      Select normal asynchronous mode with o34=0 (zero).
690 *                      Disable EICR with position 3 up.  For EIAS, 1 up.
691 *                      Reset the modem after changing switches.
692 *
693 *      2296A:          If option 00 (zeros) is present, use o00=0.
694 *                      Enable interactive flow control with o16=y.
695 *                      Select normal asynchronous mode with o34=0 (zero).
696 *                      (available in Microcom Networking version, but
697 *                      not necessarily other models of the 2296A).
698 *                      Enable modem-port flow control (if available) with
699 *                      o42=y.  Enable asynchronous operation with o50=y.
700 *                      Disable EICR with o69=n.  For EIAS, o66=n, using
701 *                      front panel.
702 */
703    {
704   "AT&T switched-network modems",
705    "",                                 /* pulse command */
706    "",                                 /* tone command */
707    20,                                 /* dial_time */
708    ",",                                /* pause_chars */
709    2,                                  /* pause_time */
710    "+",                                /* wake_str */
711    0,                                  /* wake_rate */
712    "",                                 /* wake_prompt */
713    "",                                 /* dmode_str */
714    "",                                 /* dmode_prompt */
715    "at%s\015",                         /* dial_str */
716    0,                                  /* dial_rate */
717    0,                                  /* esc_time */
718    0,                                  /* esc_char */
719    "",                                 /* hup_str */
720    "",                                 /* hwfc_str */
721    "",                                 /* swfc_str */
722    "",                                 /* nofc_str */
723    "",                                 /* ec_on_str */
724    "",                                 /* ec_off_str */
725    "",                                 /* dc_on_str */
726    "",                                 /* dc_off_str */
727    "",                                 /* aa_on_str */
728    "",                                 /* aa_off_str */
729    "",                                 /* sb_on_str */
730    "",                                 /* sb_off_str */
731    0L,                                 /* max_speed */
732    CKD_AT,                             /* capas */
733    NULL                                /* ok_fn */
734};
735
736static
737MDMINF ATTDTDM = /* AT&T Digital Terminal Data Module  */
738                 /* For dialing: KYBD switch down, others usually up. */
739    {
740    "AT&T Digital Terminal Data Module",
741    "",                                 /* pulse command */
742    "",                                 /* tone command */
743    20,                                 /* dial_time */
744    "",                                 /* pause_chars */
745    0,                                  /* pause_time */
746    "",                                 /* wake_str */
747    0,                                  /* wake_rate */
748    "",                                 /* wake_prompt */
749    "",                                 /* dmode_str */
750    "",                                 /* dmode_prompt */
751    "%s\015",                           /* dial_str */
752    0,                                  /* dial_rate */
753    0,                                  /* esc_time */
754    0,                                  /* esc_char */
755    "",                                 /* hup_str */
756    "",                                 /* hwfc_str */
757    "",                                 /* swfc_str */
758    "",                                 /* nofc_str */
759    "",                                 /* ec_on_str */
760    "",                                 /* ec_off_str */
761    "",                                 /* dc_on_str */
762    "",                                 /* dc_off_str */
763    "",                                 /* aa_on_str */
764    "",                                 /* aa_off_str */
765    "",                                 /* sb_on_str */
766    "",                                 /* sb_off_str */
767    0L,                                 /* max_speed */
768    0,                                  /* capas */
769    NULL                                /* ok_fn */
770};
771
772static
773MDMINF DIGITEL =        /* Digitel DT-22 CCITT variant used in Brazil */
774/*
775  Attempts to adhere strictly to the V.25bis specification do not produce good
776  results in real life.  The modem for which this code was developed: (a)
777  ignores parity; (b) sometimes terminates responses with LF CR instead of CR
778  LF; (c) has a Hayes-like escape sequence; (d) supports a hangup ("HUP")
779  command.  Information from Fernando Cabral in Brasilia.
780*/
781    {
782    "Digitel DT-22 CCITT dialer",
783    "",                         /* pulse command */
784    "",                         /* tone command */
785    40,                         /* dial_time -- programmable -- */
786    ",:",               /* pause_chars -- "," waits for programmable time */
787                        /* ":" waits for dial tone */
788    10,                 /* pause_time (seconds, just a guess) */
789    "HUP\015",          /* wake_str (Not Standard CCITT) */
790    200,                /* wake_rate (msec) */
791    "VAL",              /* wake_prompt */
792    "",                 /* dmode_str (none) */
793    "",                 /* dmode_prompt (none) */
794    "CRN%s\015",        /* dial_str */
795    200,                /* dial_rate (msec) */
796    1100,               /* esc_time (Not Standard CCITT) */
797    43,                 /* esc_char  (Not Standard CCITT) */
798    "HUP\015",          /* hup_str  (Not Standard CCITT) */
799    "",                                 /* hwfc_str */
800    "",                                 /* swfc_str */
801    "",                                 /* nofc_str */
802    "",                                 /* ec_on_str */
803    "",                                 /* ec_off_str */
804    "",                                 /* dc_on_str */
805    "",                                 /* dc_off_str */
806    "",                                 /* aa_on_str */
807    "",                                 /* aa_off_str */
808    "",                                 /* sb_on_str */
809    "",                                 /* sb_off_str */
810    0L,                                 /* max_speed */
811    CKD_V25,                            /* capas */
812    getok                               /* ok_fn */
813};
814
815static
816MDMINF H_1200 =         /* Hayes 1200 and compatible modems */
817    {
818    "Hayes Smartmodem 1200 and compatibles",
819    "ATP\015",                          /* pulse command */
820    "ATT\015",                          /* tone command */
821    35,                                 /* dial_time */
822    ",",                                /* pause_chars */
823    2,                                  /* pause_time */
824    "ATQ0\015",                         /* wake_str */
825    0,                                  /* wake_rate */
826    "OK\015",                           /* wake_prompt */
827    "",                                 /* dmode_str */
828    "",                                 /* dmode_prompt */
829    "ATD%s\015",                        /* dial_str */
830    0,                                  /* dial_rate */
831    1100,                               /* esc_time */
832    43,                                 /* esc_char */
833    "ATQ0H0\015",                       /* hup_str */
834    "",                                 /* hwfc_str */
835    "",                                 /* swfc_str */
836    "",                                 /* nofc_str */
837    "",                                 /* ec_on_str */
838    "",                                 /* ec_off_str */
839    "",                                 /* dc_on_str */
840    "",                                 /* dc_off_str */
841    "ATS0=1\015",                       /* aa_on_str */
842    "ATS0=0\015",                       /* aa_off_str */
843    "",                                 /* sb_on_str */
844    "",                                 /* sb_off_str */
845    1200L,                              /* max_speed */
846    CKD_AT,                             /* capas */
847    getok                               /* ok_fn */
848};
849
850static
851MDMINF H_ULTRA =                        /* Hayes high-speed */
852    {
853    "Hayes Ultra/Optima/Accura 96/144/288", /* U,O,A */
854    "ATP\015",                          /* pulse command */
855    "ATT\015",                          /* tone command */
856    35,                                 /* dial_time */
857    ",",                                /* pause_chars */
858    2,                                  /* pause_time */
859#ifdef OS2
860    "ATQ0X4N1Y0&S0&C1&D2S37=0S82=128\015", /* wake_str */
861#else
862    "ATQ0X4N1Y0S37=0S82=128\015",       /* wake_str */
863#endif /* OS2 */
864    0,                                  /* wake_rate */
865    "OK\015",                           /* wake_prompt */
866    "",                                 /* dmode_str */
867    "",                                 /* dmode_prompt */
868    "ATD%s\015",                        /* dial_str */
869    0,                                  /* dial_rate */
870    1100,                               /* esc_time */
871    43,                                 /* esc_char */
872    "ATQ0H0\015",                       /* hup_str */
873    "AT&K3\015",                        /* hwfc_str */   /* OK for U,O */
874    "AT&K4\015",                        /* swfc_str */   /* OK for U,O */
875    "AT&K0\015",                        /* nofc_str */   /* OK for U,O */
876    "AT&Q5S36=7S48=7\015",              /* ec_on_str */  /* OK for U,O */
877    "AT&Q0\015",                        /* ec_off_str */ /* OK for U,O */
878    "ATS46=2\015",                      /* dc_on_str */
879    "ATS46=0\015",                      /* dc_off_str */
880    "ATS0=1\015",                       /* aa_on_str */
881    "ATS0=0\015",                       /* aa_off_str */
882    "",                                 /* sb_on_str */
883    "",                                 /* sb_off_str */
884    115200L,                            /* max_speed */  /* (varies) */
885    CKD_AT|CKD_SB|CKD_EC|CKD_DC|CKD_HW|CKD_SW, /* capas */
886    getok                               /* ok_fn */
887};
888
889static
890MDMINF H_ACCURA =                       /* Hayes Accura */
891    {                                   /* GUESSING IT'S LIKE ULTRA & OPTIMA */
892    "Hayes Accura",
893    "ATP\015",                          /* pulse command */
894    "ATT\015",                          /* tone command */
895    35,                                 /* dial_time */
896    ",",                                /* pause_chars */
897    2,                                  /* pause_time */
898#ifdef OS2
899    "ATQ0X4N1Y0&S0&C1&D2S37=0S82=128\015", /* wake_str */
900#else
901    "ATQ0X4N1Y0S37=0S82=128\015",       /* wake_str */
902#endif /* OS2 */
903    0,                                  /* wake_rate */
904    "OK\015",                           /* wake_prompt */
905    "",                                 /* dmode_str */
906    "",                                 /* dmode_prompt */
907    "ATD%s\015",                        /* dial_str */
908    0,                                  /* dial_rate */
909    1100,                               /* esc_time */
910    43,                                 /* esc_char */
911    "ATQ0H0\015",                       /* hup_str */
912    "AT&K3\015",                        /* hwfc_str */
913    "AT&K4\015",                        /* swfc_str */
914    "AT&K0\015",                        /* nofc_str */
915    "AT&Q5S36=7S48=7\015",              /* ec_on_str */
916    "AT&Q0\015",                        /* ec_off_str */
917    "ATS46=2\015",                      /* dc_on_str */
918    "ATS46=0\015",                      /* dc_off_str */
919    "ATS0=1\015",                       /* aa_on_str */
920    "ATS0=0\015",                       /* aa_off_str */
921    "",                                 /* sb_on_str */
922    "",                                 /* sb_off_str */
923    115200L,                            /* max_speed */  /* (varies) */
924    CKD_AT|CKD_SB|CKD_EC|CKD_DC|CKD_HW|CKD_SW, /* capas */
925    getok                               /* ok_fn */
926};
927
928static
929MDMINF PPI =                            /* Practical Peripherals  */
930    {
931    "Practical Peripherals V.22bis or higher with V.42 and V.42bis",
932    "ATP\015",                          /* pulse command */
933    "ATT\015",                          /* tone command */
934    35,                                 /* dial_time */
935    ",",                                /* pause_chars */
936    2,                                  /* pause_time */
937#ifdef COMMENT
938/* In newer models S82 (BREAK handling) was eliminated, causing an error. */
939#ifdef OS2
940    "ATQ0X4N1&S0&C1&D2S37=0S82=128\015", /* wake_str */
941#else
942    "ATQ0X4N1S37=0S82=128\015",         /* wake_str */
943#endif /* OS2 */
944#else /* So now we use Y0 instead */
945#ifdef OS2
946    "ATQ0X4N1&S0&C1&D2Y0S37=0\015",     /* wake_str */
947#else
948    "ATQ0X4N1Y0S37=0\015",              /* wake_str */
949#endif /* OS2 */
950#endif /* COMMENT */
951    0,                                  /* wake_rate */
952    "OK\015",                           /* wake_prompt */
953    "",                                 /* dmode_str */
954    "",                                 /* dmode_prompt */
955    "ATD%s\015",                        /* dial_str */
956    0,                                  /* dial_rate */
957    1100,                               /* esc_time */
958    43,                                 /* esc_char */
959    "ATQ0H0\015",                       /* hup_str */
960    "AT&K3\015",                        /* hwfc_str */
961    "AT&K4\015",                        /* swfc_str */
962    "AT&K0\015",                        /* nofc_str */
963    "AT&Q5S36=7S48=7\015",              /* ec_on_str */
964    "AT&Q0S36=0S48=128\015",            /* ec_off_str */
965    "ATS46=2\015",                      /* dc_on_str */
966    "ATS46=0\015",                      /* dc_off_str */
967    "ATS0=1\015",                       /* aa_on_str */
968    "ATS0=0\015",                       /* aa_off_str */
969    "",                                 /* sb_on_str  */
970    "",                                 /* sb_off_str  */
971    115200L,                            /* max_speed */
972    CKD_AT|CKD_SB|CKD_EC|CKD_DC|CKD_HW|CKD_SW, /* capas */
973    getok                               /* ok_fn */
974};
975
976static
977MDMINF DATAPORT =                       /* AT&T Dataport  */
978    {
979    "AT&T / Paradyne DataPort V.32 or higher",
980    "ATP\015",                          /* pulse command */
981    "ATT\015",                          /* tone command */
982    35,                                 /* dial_time */
983    ",",                                /* pause_chars */
984    2,                                  /* pause_time */
985    /*
986       Note: S41=0 (use highest modulation) omitted, since it is not
987       supported on the V.32 and lower models.  So let's not touch it.
988    */
989#ifdef OS2
990    "ATQ0E1X6&Q0S78=0\015",             /* wake_str */
991#else
992    "ATQ0E1X6&S0&C1&D2&Q0S78=0\015",    /* wake_str */
993#endif /* OS2 */
994    0,                                  /* wake_rate */
995    "OK\015",                           /* wake_prompt */
996    "",                                 /* dmode_str */
997    "",                                 /* dmode_prompt */
998    "ATD%s\015",                        /* dial_str */
999    0,                                  /* dial_rate */
1000    1100,                               /* esc_time */
1001    43,                                 /* esc_char */
1002    "ATQ0H0\015",                       /* hup_str */
1003    "AT\\Q3\015",                       /* hwfc_str */
1004    "AT\\Q1\\X0\015",                   /* swfc_str */
1005    "AT\\Q0\015",                       /* nofc_str */
1006    "AT\\N7\015",                       /* ec_on_str */
1007    "AT\\N0\015",                       /* ec_off_str */
1008    "AT%C1\015",                        /* dc_on_str */
1009    "AT%C0\015",                        /* dc_off_str */
1010    "ATS0=1\015",                       /* aa_on_str */
1011    "ATS0=0\015",                       /* aa_off_str */
1012    "",                                 /* sb_on_str */
1013    "",                                 /* sb_off_str */
1014    57600L,                             /* max_speed */
1015    CKD_AT|CKD_SB|CKD_EC|CKD_DC|CKD_HW|CKD_SW, /* capas */
1016    getok                               /* ok_fn */
1017};
1018
1019static
1020MDMINF UCOM_AT =                        /* Microcom DeskPorte FAST ES 28.8 */
1021    {
1022    "Microcom DeskPorte FAST 28.8",
1023    "ATP\015",                          /* pulse command */
1024    "ATT\015",                          /* tone command */
1025    35,                                 /* dial_time */
1026    ",",                                /* pause_chars */
1027    2,                                  /* pause_time */
1028#ifdef OS2
1029    "ATQ0X4\\N0F0&S0&C1&D2\\K5\015",    /* wake_str */
1030#else
1031    "ATQ0X4F0\\K5\015",                 /* wake_str */
1032#endif /* OS2 */
1033    0,                                  /* wake_rate */
1034    "OK\015",                           /* wake_prompt */
1035    "",                                 /* dmode_str */
1036    "",                                 /* dmode_prompt */
1037    "ATD%s\015",                        /* dial_str */
1038    0,                                  /* dial_rate */
1039    1100,                               /* esc_time */
1040    43,                                 /* esc_char */
1041    "ATQ0H0\015",                       /* hup_str */
1042    "AT\\Q3\015",                       /* hwfc_str */
1043    "AT\\Q1\015",                       /* swfc_str */
1044    "AT\\H0\\Q0\015",                   /* nofc_str */
1045    "AT\\N3\015",                       /* ec_on_str */
1046    "AT\015",                           /* ec_off_str */
1047    "AT%C3\015",                        /* dc_on_str */
1048    "AT%C0\015",                        /* dc_off_str */
1049    "ATS0=1\015",                       /* aa_on_str */
1050    "ATS0=0\015",                       /* aa_off_str */
1051    "AT-J0\015",                        /* sb_on_str */
1052    "AT-J1\015",                        /* sb_off_str */
1053    115200L,                            /* max_speed */
1054    CKD_AT|CKD_SB|CKD_EC|CKD_DC|CKD_HW|CKD_SW, /* capas */
1055    getok                               /* ok_fn */
1056};
1057
1058static
1059MDMINF ZOOM =                           /* Zoom Telephonics V.32bis  */
1060    {
1061    "Zoom Telephonics V.32bis",
1062    "ATP\015",                          /* pulse command */
1063    "ATT\015",                          /* tone command */
1064    35,                                 /* dial_time */
1065    ",",                                /* pause_chars */
1066    2,                                  /* pause_time */
1067#ifdef OS2
1068    "ATQ0E1N1W1X4&S0&C1&D2S82=128S95=47\015", /* wake_str */
1069#else
1070    "ATQ0E1N1W1X4S82=128S95=47\015",    /* wake_str */
1071#endif /* OS2 */
1072    0,                                  /* wake_rate */
1073    "OK\015",                           /* wake_prompt */
1074    "",                                 /* dmode_str */
1075    "",                                 /* dmode_prompt */
1076    "ATD%s\015",                        /* dial_str */
1077    0,                                  /* dial_rate */
1078    1100,                               /* esc_time */
1079    43,                                 /* esc_char */
1080    "ATQ0H0\015",                       /* hup_str */
1081    "AT&K3\015",                        /* hwfc_str */
1082    "AT&K4\015",                        /* swfc_str */
1083    "AT&K0\015",                        /* nofc_str */
1084    "AT&Q5S36=7S48=7\015",              /* ec_on_str */
1085    "AT&Q0\015",                        /* ec_off_str */
1086    "ATS46=138\015",                    /* dc_on_str */
1087    "ATS46=136\015",                    /* dc_off_str */
1088    "ATS0=1\015",                       /* aa_on_str */
1089    "ATS0=0\015",                       /* aa_off_str */
1090    "",                                 /* sb_on_str */
1091    "",                                 /* sb_off_str */
1092    57600L,                             /* max_speed */
1093    CKD_AT|CKD_SB|CKD_EC|CKD_DC|CKD_HW|CKD_SW, /* capas */
1094    getok                               /* ok_fn */
1095};
1096
1097static
1098MDMINF ZYXEL =                          /* ZyXEL U-Series */
1099    {
1100    "ZyXEL U-Series V.32bis or higher",
1101    "ATP\015",                          /* pulse command */
1102    "ATT\015",                          /* tone command */
1103    35,                                 /* dial_time */
1104    ",",                                /* pause_chars */
1105    2,                                  /* pause_time */
1106#ifdef OS2
1107    "ATQ0E1&S0&C1&D2&N0X5&Y1\015",      /* wake_str */
1108#else
1109    "ATQ0E1&N0X5&Y1\015",               /* wake_str */
1110#endif /* OS2 */
1111    0,                                  /* wake_rate */
1112    "OK\015",                           /* wake_prompt */
1113    "",                                 /* dmode_str */
1114    "",                                 /* dmode_prompt */
1115    "ATD%s\015",                        /* dial_str */
1116    0,                                  /* dial_rate */
1117    1100,                               /* esc_time */
1118    43,                                 /* esc_char */
1119    "ATQ0H0\015",                       /* hup_str */
1120    "AT&H3\015",                        /* hwfc_str */
1121    "AT&H4\015",                        /* swfc_str */
1122    "AT&H0\015",                        /* nofc_str */
1123    "AT&K3\015",                        /* ec_on_str */
1124    "AT&K0\015",                        /* ec_off_str */
1125    "AT&K4\015",                        /* dc_on_str */
1126    "AT&K3\015",                        /* dc_off_str */
1127    "ATS0=1\015",                       /* aa_on_str */
1128    "ATS0=0\015",                       /* aa_off_str */
1129    "",                                 /* sb_on_str */
1130    "",                                 /* sb_off_str */
1131    57600L,                             /* max_speed */
1132    CKD_AT|CKD_SB|CKD_EC|CKD_DC|CKD_HW|CKD_SW, /* capas */
1133    getok                               /* ok_fn */
1134};
1135
1136static
1137MDMINF ZOLTRIX =                        /* Zoltrix */
1138    {
1139    "Zoltrix V.32bis and V.34 modems with Rockwell ACI chipset",
1140    "ATP\015",                          /* pulse command */
1141    "ATT\015",                          /* tone command */
1142    35,                                 /* dial_time */
1143    ",",                                /* pause_chars */
1144    2,                                  /* pause_time */
1145#ifdef OS2
1146   "ATQ0E1F0W1X4Y0&S0&C1&D2\\K5S82=128S95=41\015", /* wake_str */
1147#else
1148   "ATQ0E1F0W1X4Y0\\K5S82=128S95=41\015", /* wake_str */
1149#endif /* OS2 */
1150    0,                                  /* wake_rate */
1151    "OK\015",                           /* wake_prompt */
1152    "",                                 /* dmode_str */
1153    "",                                 /* dmode_prompt */
1154    "ATD%s\015",                        /* dial_str */
1155    0,                                  /* dial_rate */
1156    1100,                               /* esc_time */
1157    43,                                 /* esc_char */
1158    "ATQ0H0\015",                       /* hup_str */
1159    "AT&K3\015",                        /* hwfc_str */
1160    "AT&K4S32=17S33=19\015",            /* swfc_str */
1161    "AT&K0\015",                        /* nofc_str */
1162    "AT\\N3\015",                       /* ec_on_str */
1163    "AT\\N1\015",                       /* ec_off_str */
1164    "ATS46=138%C3\015",                 /* dc_on_str */
1165    "ATS46=136%C0\015",                 /* dc_off_str */
1166    "ATS0=1\015",                       /* aa_on_str */
1167    "ATS0=0\015",                       /* aa_off_str */
1168    "AT\\N0\015",                       /* sb_on_str */
1169    "AT&Q0\015",                        /* sb_off_str */
1170    57600L,                             /* max_speed */
1171    CKD_AT|CKD_SB|CKD_EC|CKD_DC|CKD_HW|CKD_SW, /* capas */
1172    getok                               /* ok_fn */
1173};
1174
1175static
1176MDMINF MOTOROLA = {                     /* Motorola FasTalk II or Lifestyle */
1177/*
1178  "\E" and "\X" commands removed - Motorola Lifestyle doesn't have them.
1179     \E0 = Don't echo while online
1180     \X0 = Process Xon/Xoff but don't pass through
1181*/
1182    "Motorola FasTalk II or Lifestyle", /* Name */
1183    "ATP\015",                          /* pulse command */
1184    "ATT\015",                          /* tone command */
1185    35,                                 /* dial_time */
1186    ",",                                /* pause_chars */
1187    2,                                  /* pause_time */
1188#ifdef OS2
1189    "ATQ0E1X4&S0&C1&D2\\K5\\V1\015",    /* wake_str */
1190#else
1191    "ATQ0E1X4\\K5\\V1\015",             /* wake_str */
1192#endif /* OS2 */
1193    0,                                  /* wake_rate */
1194    "OK\015",                           /* wake_prompt */
1195    "",                                 /* dmode_str */
1196    "",                                 /* dmode_prompt */
1197    "ATD%s\015",                        /* dial_str */
1198    0,                                  /* dial_rate */
1199    1100,                               /* esc_time */
1200    43,                                 /* esc_char */
1201    "ATQ0H0\015",                       /* hup_str */
1202    "AT\\Q3\015",                       /* hwfc_str */
1203    "AT\\Q1\015",                       /* swfc_str */
1204    "AT\\Q0\015",                       /* nofc_str */
1205    "AT\\N6\015",                       /* ec_on_str */
1206    "AT\\N1\015",                       /* ec_off_str */
1207    "AT%C1\015",                        /* dc_on_str */
1208    "AT%C0\015",                        /* dc_off_str */
1209    "ATS0=1\015",                       /* aa_on_str */
1210    "ATS0=0\015",                       /* aa_off_str */
1211    "AT\\J0\015",                       /* sb_on_str */
1212    "AT\\J1\015",                       /* sb_off_str */
1213    57600L,                             /* max_speed */
1214    CKD_AT|CKD_SB|CKD_EC|CKD_DC|CKD_HW|CKD_SW, /* capas */
1215    getok                               /* ok_fn */
1216};
1217
1218static
1219MDMINF BOCA =                           /* Boca */
1220    {
1221    "BOCA 14.4 Faxmodem",
1222    "ATP\015",                          /* pulse command */
1223    "ATT\015",                          /* tone command */
1224    35,                                 /* dial_time */
1225    ",",                                /* pause_chars */
1226    2,                                  /* pause_time */
1227#ifdef OS2
1228    "ATQ0E1F1N1W1&S0&C1&D2\\K5S37=11S82=128S95=47X4\015", /* wake_str */
1229#else
1230    "ATQ0E1F1N1W1\\K5S37=11S82=128S95=47X4\015", /* wake_str */
1231#endif /* OS2 */
1232    0,                                  /* wake_rate */
1233    "OK\015",                           /* wake_prompt */
1234    "",                                 /* dmode_str */
1235    "",                                 /* dmode_prompt */
1236    "ATD%s\015",                        /* dial_str */
1237    0,                                  /* dial_rate */
1238    1100,                               /* esc_time */
1239    43,                                 /* esc_char */
1240    "ATQ0H0\015",                       /* hup_str */
1241    "AT&K3\015",                        /* hwfc_str */
1242    "AT&K4\015",                        /* swfc_str */
1243    "AT&K0\015",                        /* nofc_str */
1244    "AT\\N3S36=7S48=7\015",             /* ec_on_str */
1245    "AT\\N1\015",                       /* ec_off_str */
1246    "ATS46=138\015",                    /* dc_on_str */
1247    "ATS46=136\015",                    /* dc_off_str */
1248    "ATS0=1\015",                       /* aa_on_str */
1249    "ATS0=0\015",                       /* aa_off_str */
1250    "",                                 /* sb_on_str */
1251    "",                                 /* sb_off_str */
1252    57600L,                             /* max_speed */
1253    CKD_AT|CKD_SB|CKD_EC|CKD_DC|CKD_HW|CKD_SW, /* capas */
1254    getok                               /* ok_fn */
1255};
1256
1257static
1258MDMINF INTEL =                          /* Intel */
1259    {
1260    "Intel High-Speed Faxmodem",
1261    "ATP\015",                          /* pulse command */
1262    "ATT\015",                          /* tone command */
1263    35,                                 /* dial_time */
1264    ",",                                /* pause_chars */
1265    2,                                  /* pause_time */
1266#ifdef OS2
1267    "ATQ0E1Y0X4&S0&C1&D2\\K1\\V2S25=50\015", /* wake_str */
1268#else
1269    "ATQ0E1Y0X4\\K1\\V2S25=50\015", /* wake_str */
1270#endif /* OS2 */
1271    0,                                  /* wake_rate */
1272    "OK\015",                           /* wake_prompt */
1273    "ATB1+FCLASS=0\015",                /* dmode_str */
1274    "OK\015",                           /* dmode_prompt */
1275    "ATD%s\015",                        /* dial_str */
1276    0,                                  /* dial_rate */
1277    1100,                               /* esc_time */
1278    43,                                 /* esc_char */
1279    "ATQ0H0\015",                       /* hup_str */
1280    "AT\\G1\\Q3\015",                   /* hwfc_str */
1281    "AT\\G1\\Q1\\X0\015",               /* swfc_str */
1282    "AT\\G0\015",                       /* nofc_str */
1283    "AT\\J0\\N3\"H3\015",               /* ec_on_str */
1284    "AT\\N1\015",                       /* ec_off_str */
1285    "AT%C1\015",                        /* dc_on_str */
1286    "AT%C0\015",                        /* dc_off_str */
1287    "ATS0=1\015",                       /* aa_on_str */
1288    "ATS0=0\015",                       /* aa_off_str */
1289    "",                                 /* sb_on_str */
1290    "",                                 /* sb_off_str */
1291    57600L,                             /* max_speed */
1292    CKD_AT|CKD_SB|CKD_EC|CKD_DC|CKD_HW|CKD_SW, /* capas */
1293    getok                               /* ok_fn */
1294};
1295
1296static
1297MDMINF MULTITECH =                      /* Multitech */
1298    {
1299    "Multitech MT1432 Series MultiModem II",
1300    "ATP\015",                          /* pulse command */
1301    "ATT\015",                          /* tone command */
1302    35,                                 /* dial_time */
1303    ",",                                /* pause_chars */
1304    2,                                  /* pause_time */
1305#ifdef OS2
1306    "ATQ0E1X4&S0&C1&D2&E8&Q0%E1#P0\015", /* wake_str */
1307#else
1308    "ATQ0E1X4&E8&Q0%E1#P0\015",         /* wake_str */
1309#endif /* OS2 */
1310    0,                                  /* wake_rate */
1311    "OK\015",                           /* wake_prompt */
1312    "",                                 /* dmode_str */
1313    "",                                 /* dmode_prompt */
1314    "ATD%s\015",                        /* dial_str */
1315    0,                                  /* dial_rate */
1316    1100,                               /* esc_time */
1317    43,                                 /* esc_char */
1318    "ATQ0H0\015",                       /* hup_str */
1319    "AT&E4&E7&E8&E11&E13\015",          /* hwfc_str */
1320    "AT&E5&E6&E8&E11&E13\015",          /* swfc_str */
1321    "AT&E3&E7&E8&E10&E12\015",          /* nofc_str */
1322    "AT&E1\015",                        /* ec_on_str */
1323    "AT#L0&E0\015",                     /* ec_off_str */
1324    "AT&E15\015",                       /* dc_on_str */
1325    "AT&E14\015",                       /* dc_off_str */
1326    "ATS0=1\015",                       /* aa_on_str */
1327    "ATS0=0\015",                       /* aa_off_str */
1328    "AT$BA0\015",                       /* sb_on_str (= "baud adjust off") */
1329    "AT$BA1\015",                       /* sb_off_str */
1330    57600L,                             /* max_speed */
1331    CKD_AT|CKD_SB|CKD_EC|CKD_DC|CKD_HW|CKD_SW, /* capas */
1332    getok                               /* ok_fn */
1333};
1334
1335static
1336MDMINF SUPRA =                          /* Supra */
1337    {
1338    "SupraFAXModem 144 or 288",
1339    "ATP\015",                          /* pulse command */
1340    "ATT\015",                          /* tone command */
1341    35,                                 /* dial_time */
1342    ",",                                /* pause_chars */
1343    2,                                  /* pause_time */
1344#ifdef OS2
1345    "ATQ0E1N1W0X4Y0&S0&C1&D2\\K5S82=128\015", /* wake_str */
1346#else
1347    "ATQ0E1N1W0X4Y0\\K5S82=128\015",    /* wake_str */
1348#endif /* OS2 */
1349    0,                                  /* wake_rate */
1350    "OK\015",                           /* wake_prompt */
1351    "",                                 /* dmode_str */
1352    "",                                 /* dmode_prompt */
1353    "ATD%s\015",                        /* dial_str */
1354    0,                                  /* dial_rate */
1355    1100,                               /* esc_time */
1356    43,                                 /* esc_char */
1357    "ATQ0H0\015",                       /* hup_str */
1358    "AT&K3\015",                        /* hwfc_str */
1359    "AT&K4\015",                        /* swfc_str */
1360    "AT&K0\015",                        /* nofc_str */
1361    "AT&Q5\\N3S48=7\015",               /* ec_on_str */
1362    "AT&Q0\\N1\015",                    /* ec_off_str */
1363    "AT%C1S46=138\015",                 /* dc_on_str */
1364    "AT%C0S46=136\015",                 /* dc_off_str */
1365    "ATS0=1\015",                       /* aa_on_str */
1366    "ATS0=0\015",                       /* aa_off_str */
1367    "",                                 /* sb_on_str */
1368    "",                                 /* sb_off_str */
1369    57600L,                             /* max_speed */
1370    CKD_AT|CKD_SB|CKD_EC|CKD_DC|CKD_HW|CKD_SW, /* capas */
1371    getok                               /* ok_fn */
1372};
1373
1374static
1375MDMINF MAXTECH =                        /* MaxTech */
1376    {
1377    "MaxTech XM288EA or GVC FAXModem",
1378    "ATP\015",                          /* pulse command */
1379    "ATT\015",                          /* tone command */
1380    35,                                 /* dial_time */
1381    ",",                                /* pause_chars */
1382    2,                                  /* pause_time */
1383#ifdef OS2
1384    "ATQ0E1X4Y0&S0&C1&D2&L0&M0\\K5\015", /* wake_str */
1385#else
1386    "ATQ0E1X4Y0&L0&M0\\K5\015",         /* wake_str */
1387#endif /* OS2 */
1388    0,                                  /* wake_rate */
1389    "OK\015",                           /* wake_prompt */
1390    "",                                 /* dmode_str */
1391    "",                                 /* dmode_prompt */
1392    "ATD%s\015",                        /* dial_str */
1393    0,                                  /* dial_rate */
1394    1100,                               /* esc_time */
1395    43,                                 /* esc_char */
1396    "ATQ0H0\015",                       /* hup_str */
1397    "AT\\Q3\015",                       /* hwfc_str */
1398    "AT\\Q1\\X0\015",                   /* swfc_str */
1399    "AT\\Q0\015",                       /* nofc_str */
1400    "AT\\N6\015",                       /* ec_on_str */
1401    "AT\\N0\015",                       /* ec_off_str */
1402    "AT\\N6%C1\015",                    /* dc_on_str */
1403    "AT\\N6%C0\015",                    /* dc_off_str */
1404    "ATS0=1\015",                       /* aa_on_str */
1405    "ATS0=0\015",                       /* aa_off_str */
1406    "",                                 /* sb_on_str */
1407    "",                                 /* sb_off_str */
1408    115200L,                            /* max_speed */
1409    CKD_AT|CKD_SB|CKD_EC|CKD_DC|CKD_HW|CKD_SW, /* capas */
1410    getok                               /* ok_fn */
1411};
1412
1413static
1414MDMINF ROLM =           /* IBM / Siemens / Rolm 8000, 9000, 9751 CBX DCM */
1415    {
1416    "IBM/Siemens/Rolm CBX Data Communications Module",
1417    "",                                 /* pulse command */
1418    "",                                 /* tone command */
1419    60,                                 /* dial_time */
1420    "",                                 /* pause_chars */
1421    0,                                  /* pause_time */
1422    "\015\015",                         /* wake_str */
1423    5,                                  /* wake_rate */
1424    "MODIFY?",                          /* wake_prompt */
1425    "",                                 /* dmode_str */
1426    "",                                 /* dmode_prompt */
1427    "CALL %s\015",                      /* dial_str */
1428    0,                                  /* dial_rate */
1429    0,                                  /* esc_time */
1430    0,                                  /* esc_char */
1431    "",                                 /* hup_str */
1432    "",                                 /* hwfc_str */
1433    "",                                 /* swfc_str */
1434    "",                                 /* nofc_str */
1435    "",                                 /* ec_on_str */
1436    "",                                 /* ec_off_str */
1437    "",                                 /* dc_on_str */
1438    "",                                 /* dc_off_str */
1439    "",                                 /* aa_on_str */
1440    "",                                 /* aa_off_str */
1441    "",                                 /* sb_on_str */
1442    "",                                 /* sb_off_str */
1443    19200L,                             /* max_speed */
1444    0,                                  /* capas */
1445    NULL                                /* ok_fn */
1446};
1447
1448static
1449MDMINF USR =                            /* USR Courier and Sportster modems */
1450    {
1451    "US Robotics Courier or Sportster",
1452    "ATP\015",                          /* pulse command */
1453    "ATT\015",                          /* tone command */
1454    35,                                 /* dial_time */
1455    ",",                                /* pause_chars */
1456    2,                                  /* pause_time */
1457#ifdef OS2
1458    "ATQ0X4&A3&S0&C1&D2&N0&Y3\015",     /* wake_str */
1459#else
1460    "ATQ0X4&A3&N0&Y3\015",              /* wake_str */
1461#endif /* OS2 */
1462    0,                                  /* wake_rate */
1463    "OK\015",                           /* wake_prompt */
1464    "",                                 /* dmode_str */
1465    "",                                 /* dmode_prompt */
1466    "ATD%s\015",                        /* dial_str */
1467    0,                                  /* dial_rate */
1468    1100,                               /* esc_time */
1469    43,                                 /* esc_char */
1470    "ATQ0H0\015",                       /* hup_str */
1471    "AT&H1&R2&I0\015",                  /* hwfc_str */
1472    "AT&H2&R1&I2\015",                  /* swfc_str */
1473    "AT&H0&R1&I0\015",                  /* nofc_str */
1474    "AT&M4&B1\015",                     /* ec_on_str */
1475    "AT&M0\015",                        /* ec_off_str */
1476    "AT&K1\015",                        /* dc_on_str */
1477    "AT&K0\015",                        /* dc_off_str */
1478    "ATS0=1\015",                       /* aa_on_str */
1479    "ATS0=0\015",                       /* aa_off_str */
1480    "",                                 /* sb_on_str */
1481    "",                                 /* sb_off_str */
1482    57600L,                             /* max_speed */
1483    CKD_AT|CKD_SB|CKD_EC|CKD_DC|CKD_HW|CKD_SW, /* capas */
1484    getok                               /* ok_fn */
1485};
1486
1487#ifdef OLDTBCODE
1488static
1489MDMINF TELEBIT =                        /* All Telebits */
1490    {
1491    "Telebit - all models",
1492    "ATP\015",                          /* pulse command */
1493    "ATT\015",                          /* tone command */
1494    60,                                 /* dial_time */
1495    ",",                                /* pause_chars */
1496    2,                                  /* pause_time */
1497/*
1498  NOTE: The wake_string MUST contain the I command (model query), and otherwise
1499  must contain commands that work on ALL Telebit models.  Here we ensure that
1500  result codes are returned (Q0), and ask for extended result codes (X1), and
1501  ensure that the escape sequence is +++ and it is enabled.  And also, make
1502  sure the final character is not a digit (whose echo might be mistaken for a
1503  result code).  The Ctrl-Q (\021) and multiple A's are recommended by Telebit.
1504*/
1505#ifdef OS2
1506    "\021AAAAATQ0X1&S0&C1&D2S12=50 S50=0 I\015", /* wake_str. */
1507#else
1508    "\021AAAAATQ0X1S12=50 S50=0 I\015", /* wake_str. */
1509#endif /* OS2 */
1510    100,                                /* wake_rate = 100 msec */
1511    "OK\015",                           /* wake_prompt */
1512    "",                                 /* dmode_str */
1513    "",                                 /* dmode_prompt */
1514    "ATD%s\015",                        /* dial_str, Note: no T or P */
1515    80,                                 /* dial_rate */
1516    1100,                               /* esc_time (guard time) */
1517    43,                                 /* esc_char */
1518    "ATQ0H0\015",                       /* hup_str */
1519    "ATS58=2S68=2\015",                 /* hwfc_str */
1520    "ATS58=3S68=3\015",                 /* swfc_str */
1521    "ATS58=0S68=0\015",                 /* nofc_str */
1522    "",                                 /* ec_on_str */
1523    "",                                 /* ec_off_str */
1524    "",                                 /* dc_on_str */
1525    "",                                 /* dc_off_str */
1526    "ATS0=1\015",                       /* aa_on_str */
1527    "ATS0=0\015",                       /* aa_off_str */
1528    "",                                 /* sb_on_str */
1529    "",                                 /* sb_off_str */
1530    0L,                                 /* max_speed */
1531    CKD_AT|CKD_SB|CKD_EC|CKD_DC|CKD_HW|CKD_SW|CKD_TB, /* capas */
1532    getok                               /* ok_fn */
1533};
1534
1535#else
1536
1537static
1538MDMINF OLDTB =                          /* Old Telebits */
1539    {
1540    "Telebit TrailBlazer, T1000, T1500, T2000, T2500",
1541    "ATP\015",                          /* pulse command */
1542    "ATT\015",                          /* tone command */
1543    60,                                 /* dial_time */
1544    ",",                                /* pause_chars */
1545    2,                                  /* pause_time */
1546#ifdef OS2
1547    "\021AAAAATQ0X1&S0&C1&D2S12=50S50=0S54=3\015", /* wake_str. */
1548#else
1549    "\021AAAAATQ0X1S12=50S50=0S54=3\015", /* wake_str. */
1550#endif /* OS2 */
1551    100,                                /* wake_rate = 100 msec */
1552    "OK\015",                           /* wake_prompt */
1553    "",                                 /* dmode_str */
1554    "",                                 /* dmode_prompt */
1555    "ATD%s\015",                        /* dial_str, Note: no T or P */
1556    80,                                 /* dial_rate */
1557    1100,                               /* esc_time (guard time) */
1558    43,                                 /* esc_char */
1559    "ATQ0H0\015",                       /* hup_str */
1560    "ATS58=2S68=2\015",                 /* hwfc_str */
1561    "ATS58=3S68=3S69=0\015",            /* swfc_str */
1562    "ATS58=0S68=0\015",                 /* nofc_str */
1563    "ATS66=1S95=2\015",                 /* ec_on_str */
1564    "ATS95=0\015",                      /* ec_off_str */
1565    "ATS110=1S96=1\015",                /* dc_on_str */
1566    "ATS110=0S96=0\015",                /* dc_off_str */
1567    "ATS0=1\015",                       /* aa_on_str */
1568    "ATS0=0\015",                       /* aa_off_str */
1569    "",                                 /* sb_on_str */
1570    "",                                 /* sb_off_str */
1571    19200L,                             /* max_speed */
1572    CKD_AT|CKD_SB|CKD_EC|CKD_DC|CKD_HW|CKD_SW|CKD_TB|CKD_KS, /* capas */
1573    getok                               /* ok_fn */
1574};
1575
1576static
1577MDMINF NEWTB =                          /* New Telebits */
1578    {
1579    "Telebit T1600, T3000, QBlazer, WorldBlazer, etc.",
1580    "ATP\015",                          /* pulse command */
1581    "ATT\015",                          /* tone command */
1582    60,                                 /* dial_time */
1583    ",",                                /* pause_chars */
1584    2,                                  /* pause_time */
1585#ifdef OS2
1586    "\021AAAAATQ0X2&S0&C1&D2S12=50S50=0S61=1S63=0\015", /* wake_str. */
1587#else
1588    "\021AAAAATQ0X2S12=50S50=0S61=1S63=0\015", /* wake_str. */
1589#endif /* OS2 */
1590    100,                                /* wake_rate = 100 msec */
1591    "OK\015",                           /* wake_prompt */
1592    "",                                 /* dmode_str */
1593    "",                                 /* dmode_prompt */
1594    "ATD%s\015",                        /* dial_str, Note: no T or P */
1595    80,                                 /* dial_rate */
1596    1100,                               /* esc_time (guard time) */
1597    43,                                 /* esc_char */
1598    "ATQ0H0\015",                       /* hup_str */
1599    "ATS58=2S68=2\015",                 /* hwfc_str */
1600    "ATS58=3S68=3\015",                 /* swfc_str */
1601    "ATS58=0S68=0\015",                 /* nofc_str */
1602    "ATS180=3\015",                     /* ec_on_str */
1603    "ATS180=0\015",                     /* ec_off_str */
1604    "ATS190=1\015",                     /* dc_on_str */
1605    "ATS190=0\015",                     /* dc_off_str */
1606    "ATS0=1\015",                       /* aa_on_str */
1607    "ATS0=0\015",                       /* aa_off_str */
1608    "",                                 /* sb_on_str */
1609    "",                                 /* sb_off_str */
1610    38400L,                             /* max_speed */
1611    CKD_AT|CKD_SB|CKD_EC|CKD_DC|CKD_HW|CKD_SW|CKD_TB|CKD_KS, /* capas */
1612    getok                               /* ok_fn */
1613};
1614#endif /* OLDTBCODE */
1615
1616static
1617MDMINF DUMMY = /* dummy information for modems that are handled elsewhere */
1618    {
1619    "(dummy)",
1620    "",                                 /* pulse command */
1621    "",                                 /* tone command */
1622    30,                                 /* dial_time */
1623    "",                                 /* pause_chars */
1624    0,                                  /* pause_time */
1625    "",                                 /* wake_str */
1626    0,                                  /* wake_rate */
1627    "",                                 /* wake_prompt */
1628    "",                                 /* dmode_str */
1629    NULL,                               /* dmode_prompt */
1630    "%s\015",                           /* dial_str */
1631    0,                                  /* dial_rate */
1632    0,                                  /* esc_time */
1633    0,                                  /* esc_char */
1634    "",                                 /* hup_str */
1635    "",                                 /* hwfc_str */
1636    "",                                 /* swfc_str */
1637    "",                                 /* nofc_str */
1638    "",                                 /* ec_on_str */
1639    "",                                 /* ec_off_str */
1640    "",                                 /* dc_on_str */
1641    "",                                 /* dc_off_str */
1642    "",                                 /* aa_on_str */
1643    "",                                 /* aa_off_str */
1644    "",                                 /* sb_on_str */
1645    "",                                 /* sb_off_str */
1646    0L,                                 /* max_speed */
1647    0,                                  /* capas */
1648    NULL                                /* ok_fn */
1649};
1650
1651static
1652MDMINF RWV32 =                          /* Generic Rockwell V.32 */
1653    {
1654    "Generic Rockwell V.32 modem",      /* ATI3, ATI4, and ATI6 for details */
1655    "ATP\015",                          /* pulse command */
1656    "ATT\015",                          /* tone command */
1657    35,                                 /* dial_time */
1658    ",",                                /* pause_chars */
1659    2,                                  /* pause_time */
1660#ifdef OS2
1661    "ATQ0X4W1Y0&S0&C1&D2%E2\\K5+FCLASS=0N1S37=0\015", /* wake_str */
1662#else
1663    "ATQ0X4W1Y0%E2\\K5+FCLASS=0N1S37=0\015", /* wake_str */
1664#endif /* OS2 */
1665    0,                                  /* wake_rate */
1666    "OK\015",                           /* wake_prompt */
1667    "",                                 /* dmode_str */
1668    "",                                 /* dmode_prompt */
1669    "ATD%s\015",                        /* dial_str */
1670    0,                                  /* dial_rate */
1671    1100,                               /* esc_time */
1672    43,                                 /* esc_char */
1673    "ATQ0H0\015",                       /* hup_str */
1674    "AT&K3\015",                        /* hwfc_str */
1675    "AT&K4S32=17S33=19\015",            /* swfc_str */
1676    "AT&K0\015",                        /* nofc_str */
1677    "AT&Q5\\N0\015",                    /* ec_on_str */
1678    "AT&Q0\\N1\015",                    /* ec_off_str */
1679    "AT%C1\015",                        /* dc_on_str */
1680    "AT%C0\015",                        /* dc_off_str */
1681    "ATS0=1\015",                       /* aa_on_str */
1682    "ATS0=0\015",                       /* aa_off_str */
1683    "",                                 /* sb_on_str */
1684    "",                                 /* sb_off_str */
1685    57600L,                             /* max_speed */
1686    CKD_AT|CKD_SB|CKD_EC|CKD_DC|CKD_HW|CKD_SW, /* capas */
1687    getok                               /* ok_fn */
1688};
1689
1690static
1691MDMINF RWV32B =                         /* Generic Rockwell V.32bis */
1692    {
1693    "Generic Rockwell V.32bis modem",   /* ATI3, ATI4, and ATI6 for details */
1694    "ATP\015",                          /* pulse command */
1695    "ATT\015",                          /* tone command */
1696    35,                                 /* dial_time */
1697    ",",                                /* pause_chars */
1698    2,                                  /* pause_time */
1699#ifdef OS2
1700    "ATQ0X4W1Y0&S0&C1&D2%E2\\K5+FCLASS=0N1S37=0\015", /* wake_str */
1701#else
1702    "ATQ0X4W1Y0%E2\\K5+FCLASS=0N1S37=0\015", /* wake_str */
1703#endif /* OS2 */
1704    0,                                  /* wake_rate */
1705    "OK\015",                           /* wake_prompt */
1706    "",                                 /* dmode_str */
1707    "",                                 /* dmode_prompt */
1708    "ATD%s\015",                        /* dial_str */
1709    0,                                  /* dial_rate */
1710    1100,                               /* esc_time */
1711    43,                                 /* esc_char */
1712    "ATQ0H0\015",                       /* hup_str */
1713    "AT&K3\015",                        /* hwfc_str */
1714    "AT&K4S32=17S33=19\015",            /* swfc_str */
1715    "AT&K0\015",                        /* nofc_str */
1716    "AT&Q5S36=7S48=7\\N3\015",          /* ec_on_str */
1717    "AT&Q0S48=128\\N1\015",             /* ec_off_str */
1718    "ATS46=138%C1\015",                 /* dc_on_str */
1719    "ATS46=136%C0\015",                 /* dc_off_str */
1720    "ATS0=1\015",                       /* aa_on_str */
1721    "ATS0=0\015",                       /* aa_off_str */
1722    "",                                 /* sb_on_str */
1723    "",                                 /* sb_off_str */
1724    57600L,                             /* max_speed */
1725    CKD_AT|CKD_SB|CKD_EC|CKD_DC|CKD_HW|CKD_SW, /* capas */
1726    getok                               /* ok_fn */
1727};
1728
1729static
1730MDMINF RWV34 =                          /* Generic Rockwell V.34 Data/Fax */
1731    {
1732    "Generic Rockwell V.34 modem",      /* ATI3, ATI4, and ATI6 for details */
1733    "ATP\015",                          /* pulse command */
1734    "ATT\015",                          /* tone command */
1735    35,                                 /* dial_time */
1736    ",",                                /* pause_chars */
1737    2,                                  /* pause_time */
1738#ifdef OS2
1739    "ATQ0X4W1Y0%E2&S0&C1&D2\\K5+FCLASS=0+MS=11,1\015", /* wake_str */
1740#else
1741    "ATQ0X4W1Y0%E2\\K5+FCLASS=0+MS=11,1\015", /* wake_str */
1742#endif /* OS2 */
1743    0,                                  /* wake_rate */
1744    "OK\015",                           /* wake_prompt */
1745    "",                                 /* dmode_str */
1746    "",                                 /* dmode_prompt */
1747    "ATD%s\015",                        /* dial_str */
1748    0,                                  /* dial_rate */
1749    1100,                               /* esc_time */
1750    43,                                 /* esc_char */
1751    "ATQ0H0\015",                       /* hup_str */
1752    "AT&K3\015",                        /* hwfc_str */
1753    "AT&K4S32=17S33=19\015",            /* swfc_str */
1754    "AT&K0\015",                        /* nofc_str */
1755    "AT&Q5S36=7S48=7\\N3\015",          /* ec_on_str */
1756    "AT&Q0S48=128\\N1\015",             /* ec_off_str */
1757    "ATS46=138%C1\015",                 /* dc_on_str */
1758    "ATS46=136%C0\015",                 /* dc_off_str */
1759    "ATS0=1\015",                       /* aa_on_str */
1760    "ATS0=0\015",                       /* aa_off_str */
1761    "",                                 /* sb_on_str */
1762    "",                                 /* sb_off_str */
1763    115200L,                            /* max_speed */
1764    CKD_AT|CKD_SB|CKD_EC|CKD_DC|CKD_HW|CKD_SW, /* capas */
1765    getok                               /* ok_fn */
1766};
1767
1768static
1769MDMINF MWAVE =                          /* IBM Mwave */
1770    {
1771    "IBM Mwave Adapter",
1772    "ATP\015",                          /* pulse command */
1773    "ATT\015",                          /* tone command */
1774    35,                                 /* dial_time */
1775    ",",                                /* pause_chars */
1776    2,                                  /* pause_time */
1777#ifdef OS2
1778    "ATQ0X4Y0&S0&C1&D2&M0&Q0&N1\\K3\\T0%E2S28=0\015", /* wake_str */
1779#else
1780    "ATQ0X4Y0&M0&Q0&N1&S0\\K3\\T0%E2S28=0\015", /* wake_str */
1781#endif /* OS2 */
1782    0,                                  /* wake_rate */
1783    "OK\015",                           /* wake_prompt */
1784    "",                                 /* dmode_str */
1785    "",                                 /* dmode_prompt */
1786    "ATD%s\015",                        /* dial_str */
1787    0,                                  /* dial_rate */
1788    1100,                               /* esc_time */
1789    43,                                 /* esc_char */
1790    "ATQ0H0\015",                       /* hup_str */
1791    "AT\\Q3\015",                       /* hwfc_str */
1792    "",                                 /* swfc_str (it doesn't!) */
1793    "AT\\Q0\015",                       /* nofc_str */
1794    "AT\\N7\015",                       /* ec_on_str */
1795    "AT\\N0\015",                       /* ec_off_str */
1796    "AT%C1\"H3\015",                    /* dc_on_str */
1797    "AT%C0\"H0\015",                    /* dc_off_str */
1798    "ATS0=1\015",                       /* aa_on_str */
1799    "ATS0=0\015",                       /* aa_off_str */
1800    "",                                 /* sb_on_str */
1801    "",                                 /* sb_off_str */
1802    57600L,                             /* max_speed */
1803    CKD_AT|CKD_SB|CKD_EC|CKD_DC|CKD_HW, /* capas */
1804    getok                               /* ok_fn */
1805};
1806
1807static
1808MDMINF TELEPATH =                       /* Gateway 2000 Telepath */
1809    {
1810    "Gateway 2000 Telepath II 28.8",
1811    "ATP\015",                          /* pulse command */
1812    "ATT\015",                          /* tone command */
1813    35,                                 /* dial_time */
1814    ",",                                /* pause_chars */
1815    2,                                  /* pause_time */
1816#ifdef OS2
1817    "ATQ0X4&S0&C1&D2&N0&Y2#CLS=0S13=0S15=0S19=0\015", /* wake_str */
1818#else
1819    "ATQ0X4&N0&Y1#CLS=0S13=0S15=0S19=0\015", /* wake_str */
1820#endif /* OS2 */
1821    0,                                  /* wake_rate */
1822    "OK\015",                           /* wake_prompt */
1823    "",                                 /* dmode_str */
1824    "",                                 /* dmode_prompt */
1825    "ATD%s\015",                        /* dial_str */
1826    0,                                  /* dial_rate */
1827    1100,                               /* esc_time */
1828    43,                                 /* esc_char */
1829    "ATQ0H0\015",                       /* hup_str */
1830    "AT&H1&R2\015",                     /* hwfc_str */
1831    "AT&H2&I2S22=17S23=19\015",         /* swfc_str */
1832    "AT&H0&I0&R1\015",                  /* nofc_str */
1833    "AT&M4&B1\015",                     /* ec_on_str -- also fixes speed */
1834    "AT&M0\015",                        /* ec_off_str */
1835    "AT&K1\015",                        /* dc_on_str */
1836    "AT&K0\015",                        /* dc_off_str */
1837    "ATS0=1\015",                       /* aa_on_str */
1838    "ATS0=0\015",                       /* aa_off_str */
1839    "",                                 /* sb_on_str */
1840    "",                                 /* sb_off_str */
1841    57600L,                             /* max_speed */
1842    CKD_AT|CKD_SB|CKD_EC|CKD_DC|CKD_HW, /* capas */
1843    getok                               /* ok_fn */
1844};
1845
1846static
1847MDMINF CARDINAL =                       /* Cardinal - based on Rockwell V.34 */
1848    {
1849    "Cardinal MVP288X Series",          /* ATI3, ATI4, and ATI6 for details */
1850    "ATP\015",                          /* pulse command */
1851    "ATT\015",                          /* tone command */
1852    35,                                 /* dial_time */
1853    ",",                                /* pause_chars */
1854    2,                                  /* pause_time */
1855#ifdef OS2
1856    "ATQ0X4W1Y0%E2&S0&C1&D2\\K5+FCLASS=0+MS=11,1\015", /* wake_str */
1857#else
1858    "ATQ0X4W1Y0%E2\\K5+FCLASS=0+MS=11,1\015", /* wake_str */
1859#endif /* OS2 */
1860    0,                                  /* wake_rate */
1861    "OK\015",                           /* wake_prompt */
1862    "",                                 /* dmode_str */
1863    "",                                 /* dmode_prompt */
1864    "ATD%s\015",                        /* dial_str */
1865    0,                                  /* dial_rate */
1866    1100,                               /* esc_time */
1867    43,                                 /* esc_char */
1868    "ATQ0H0\015",                       /* hup_str */
1869    "AT&K3\015",                        /* hwfc_str */
1870    "AT&K4S32=17S33=19\015",            /* swfc_str */
1871    "AT&K0\015",                        /* nofc_str */
1872    "AT&Q5S36=7S48=7\\N3\015",          /* ec_on_str */
1873    "AT&Q0S48=128\\N1\015",             /* ec_off_str */
1874    "ATS46=138%C1\015",                 /* dc_on_str */
1875    "ATS46=136%C0\015",                 /* dc_off_str */
1876    "ATS0=1\015",                       /* aa_on_str */
1877    "ATS0=0\015",                       /* aa_off_str */
1878    "",                                 /* sb_on_str */
1879    "",                                 /* sb_off_str */
1880    115200L,                            /* max_speed */
1881    CKD_AT|CKD_SB|CKD_EC|CKD_DC|CKD_HW|CKD_SW, /* capas */
1882    getok                               /* ok_fn */
1883};
1884
1885/*
1886  Now the "old" modems, all grouped together, and also within
1887  "if not defined MINIDIAL"...
1888*/
1889#ifdef OLDMODEMS
1890
1891static
1892MDMINF CERMETEK =       /* Information for "Cermetek Info-Mate 212 A" modem */
1893    {
1894    "Cermetek Info-Mate 212 A",
1895    "",                                 /* pulse command */
1896    "",                                 /* tone command */
1897    20,                                 /* dial_time */
1898    "BbPpTt",                           /* pause_chars */
1899    0,                                  /* pause_time */
1900    "  XY\016R\015",                    /* wake_str */
1901    200,                                /* wake_rate */
1902    "",                                 /* wake_prompt */
1903    "",                                 /* dmode_str */
1904    NULL,                               /* dmode_prompt */
1905    "\016D '%s'\015",                   /* dial_str */
1906    200,                                /* dial_rate */
1907    0,                                  /* esc_time */
1908    0,                                  /* esc_char */
1909    "",                                 /* hup_str */
1910    "",                                 /* hwfc_str */
1911    "",                                 /* swfc_str */
1912    "",                                 /* nofc_str */
1913    "",                                 /* ec_on_str */
1914    "",                                 /* ec_off_str */
1915    "",                                 /* dc_on_str */
1916    "",                                 /* dc_off_str */
1917    "",                                 /* aa_on_str */
1918    "",                                 /* aa_off_str */
1919    "",                                 /* sb_on_str */
1920    "",                                 /* sb_off_str */
1921    1200L,                              /* max_speed */
1922    0,                                  /* capas */
1923    NULL                                /* ok_fn */
1924};
1925
1926static
1927MDMINF DF03 =           /* information for "DEC DF03-AC" modem */
1928    {
1929    "Digital DF03-AC",
1930    "",                                 /* pulse command */
1931    "",                                 /* tone command */
1932    27,                                 /* dial_time */
1933    "=",                                /* pause_chars */
1934    15,                                 /* pause_time */
1935    "\001\002",                         /* wake_str */
1936    0,                                  /* wake_rate */
1937    "",                                 /* wake_prompt */
1938    "",                                 /* dmode_str */
1939    NULL,                               /* dmode_prompt */
1940    "%s",                               /* dial_str */
1941    0,                                  /* dial_rate */
1942    0,                                  /* esc_time */
1943    0,                                  /* esc_char */
1944    "",                                 /* hup_str */
1945    "",                                 /* hwfc_str */
1946    "",                                 /* swfc_str */
1947    "",                                 /* nofc_str */
1948    "",                                 /* ec_on_str */
1949    "",                                 /* ec_off_str */
1950    "",                                 /* dc_on_str */
1951    "",                                 /* dc_off_str */
1952    "",                                 /* aa_on_str */
1953    "",                                 /* aa_off_str */
1954    "",                                 /* sb_on_str */
1955    "",                                 /* sb_off_str */
1956    0L,                                 /* max_speed */
1957    0,                                  /* capas */
1958    NULL                                /* ok_fn */
1959};
1960
1961static
1962MDMINF DF100 =          /* information for "DEC DF100-series" modem */
1963                        /*
1964                         * The telephone "number" can include "P"s and/or "T"s
1965                         * within it to indicate that subsequent digits are
1966                         * to be dialed using pulse or tone dialing.  The
1967                         * modem defaults to pulse dialing.  You may modify
1968                         * the dial string below to explicitly default all
1969                         * dialing to pulse or tone, but doing so prevents
1970                         * the use of phone numbers that you may have stored
1971                         * in the modem's memory.
1972                         */
1973    {
1974    "Digital DF-100",
1975    "",                                 /* pulse command */
1976    "",                                 /* tone command */
1977    30,                                 /* dial_time */
1978    "=",                                /* pause_chars */
1979    15,                                 /* pause_time */
1980    "\001",                             /* wake_str */
1981    0,                                  /* wake_rate */
1982    "",                                 /* wake_prompt */
1983    "",                                 /* dmode_str */
1984    NULL,                               /* dmode_prompt */
1985    "%s#",                              /* dial_str */
1986    0,                                  /* dial_rate */
1987    0,                                  /* esc_time */
1988    0,                                  /* esc_char */
1989    "",                                 /* hup_str */
1990    "",                                 /* hwfc_str */
1991    "",                                 /* swfc_str */
1992    "",                                 /* nofc_str */
1993    "",                                 /* ec_on_str */
1994    "",                                 /* ec_off_str */
1995    "",                                 /* dc_on_str */
1996    "",                                 /* dc_off_str */
1997    "",                                 /* aa_on_str */
1998    "",                                 /* aa_off_str */
1999    "",                                 /* sb_on_str */
2000    "",                                 /* sb_off_str */
2001    0L,                                 /* max_speed */
2002    0,                                  /* capas */
2003    NULL                                /* ok_fn */
2004};
2005
2006static
2007MDMINF DF200 =          /* information for "DEC DF200-series" modem */
2008                        /*
2009                         * The telephone "number" can include "P"s and/or "T"s
2010                         * within it to indicate that subsequent digits are
2011                         * to be dialed using pulse or tone dialing.  The
2012                         * modem defaults to pulse dialing.  You may modify
2013                         * the dial string below to explicitly default all
2014                         * dialing to pulse or tone, but doing so prevents
2015                         * the use of phone numbers that you may have stored
2016                         * in the modem's memory.
2017                         */
2018    {
2019    "Digital DF-200",
2020    "",                 /* pulse command */
2021    "",                 /* tone command */
2022    30,                 /* dial_time */
2023    "=W",               /* pause_chars */       /* =: second tone; W: 5 secs */
2024    15,                 /* pause_time */        /* worst case */
2025    "\002",             /* wake_str */          /* allow stored number usage */
2026    0,                  /* wake_rate */
2027    "",                 /* wake_prompt */
2028    "",                 /* dmode_str */
2029    NULL,               /* dmode_prompt */
2030#ifdef COMMENT
2031    "%s!",              /* dial_str */
2032#else
2033    "   d %s\015",
2034#endif /* COMMENT */
2035    0,                                  /* dial_rate */
2036    0,                                  /* esc_time */
2037    0,                                  /* esc_char */
2038    "",                                 /* hup_str */
2039    "",                                 /* hwfc_str */
2040    "",                                 /* swfc_str */
2041    "",                                 /* nofc_str */
2042    "",                                 /* ec_on_str */
2043    "",                                 /* ec_off_str */
2044    "",                                 /* dc_on_str */
2045    "",                                 /* dc_off_str */
2046    "",                                 /* aa_on_str */
2047    "",                                 /* aa_off_str */
2048    "",                                 /* sb_on_str */
2049    "",                                 /* sb_off_str */
2050    0L,                                 /* max_speed */
2051    0,                                  /* capas */
2052    NULL                                /* ok_fn */
2053};
2054
2055static
2056MDMINF GDC =            /* information for "GeneralDataComm 212A/ED" modem */
2057    {
2058    "GeneralDataComm 212A/ED",
2059    "",                                 /* pulse command */
2060    "",                                 /* tone command */
2061    32,                                 /* dial_time */
2062    "%",                                /* pause_chars */
2063    3,                                  /* pause_time */
2064    "\015\015",                         /* wake_str */
2065    500,                                /* wake_rate */
2066    "$",                                /* wake_prompt */
2067    "D\015",                            /* dmode_str */
2068    ":",                                /* dmode_prompt */
2069    "T%s\015",                          /* dial_str */
2070    0,                                  /* dial_rate */
2071    0,                                  /* esc_time */
2072    0,                                  /* esc_char */
2073    "",                                 /* hup_str */
2074    "",                                 /* hwfc_str */
2075    "",                                 /* swfc_str */
2076    "",                                 /* nofc_str */
2077    "",                                 /* ec_on_str */
2078    "",                                 /* ec_off_str */
2079    "",                                 /* dc_on_str */
2080    "",                                 /* dc_off_str */
2081    "",                                 /* aa_on_str */
2082    "",                                 /* aa_off_str */
2083    "",                                 /* sb_on_str */
2084    "",                                 /* sb_off_str */
2085    1200L,                              /* max_speed */
2086    0,                                  /* capas */
2087    NULL                                /* ok_fn */
2088};
2089
2090static
2091MDMINF PENRIL =         /* information for "Penril" modem */
2092    {
2093    "Penril modem",
2094    "",                                 /* pulse command */
2095    "",                                 /* tone command */
2096    50,                                 /* dial_time */
2097    "",                                 /* pause_chars */
2098    0,                                  /* pause_time */
2099    "\015\015",                         /* wake_str */
2100    300,                                /* wake_rate */
2101    ">",                                /* wake_prompt */
2102    "k\015",                            /* dmode_str */
2103    ":",                                /* dmode_prompt */
2104    "%s\015",                           /* dial_str */
2105    0,                                  /* dial_rate */
2106    0,                                  /* esc_time */
2107    0,                                  /* esc_char */
2108    "",                                 /* hup_str */
2109    "",                                 /* hwfc_str */
2110    "",                                 /* swfc_str */
2111    "",                                 /* nofc_str */
2112    "",                                 /* ec_on_str */
2113    "",                                 /* ec_off_str */
2114    "",                                 /* dc_on_str */
2115    "",                                 /* dc_off_str */
2116    "",                                 /* aa_on_str */
2117    "",                                 /* aa_off_str */
2118    "",                                 /* sb_on_str */
2119    "",                                 /* sb_off_str */
2120    0L,                                 /* max_speed */
2121    0,                                  /* capas */
2122    NULL                                /* ok_fn */
2123};
2124
2125static
2126MDMINF RACAL =                          /* Racal Vadic VA4492E */
2127    {
2128    "Racal Vadic VA4492E",
2129    "",                                 /* pulse command */
2130    "",                                 /* tone command */
2131    35,                 /* dial_time (manual says modem is hardwired to 60) */
2132    "Kk",                               /* pause_chars */
2133    5,                                  /* pause_time */
2134    "\005\015",                         /* wake_str, ^E^M */
2135    50,                                 /* wake_rate */
2136    "*",                                /* wake_prompt */
2137    "D\015",                            /* dmode_str */
2138    "?",                                /* dmode_prompt */
2139    "%s\015",                           /* dial_str */
2140    0,                                  /* dial_rate */
2141    1100,                               /* esc_time */
2142    5,                                  /* esc_char, ^E */
2143    "\003\004",                         /* hup_str, ^C^D */
2144    0,                                  /* hwfc_str */
2145    "",                                 /* swfc_str */
2146    "",                                 /* nofc_str */
2147    "",                                 /* ec_on_str */
2148    "",                                 /* ec_off_str */
2149    "",                                 /* dc_on_str */
2150    "",                                 /* dc_off_str */
2151    "",                                 /* aa_on_str */
2152    "",                                 /* aa_off_str */
2153    "",                                 /* sb_on_str */
2154    "",                                 /* sb_off_str */
2155    0L,                                 /* max_speed */
2156    0,                                  /* capas */
2157    NULL                                /* ok_fn */
2158};
2159
2160static
2161MDMINF VENTEL =                         /* Information for Ven-Tel modem */
2162    {
2163    "Ven-Tel",
2164    "",                                 /* pulse command */
2165    "",                                 /* tone command */
2166    20,                                 /* dial_time */
2167    "%",                                /* pause_chars */
2168    5,                                  /* pause_time */
2169    "\015\015\015",                     /* wake_str */
2170    300,                                /* wake_rate */
2171    "$",                                /* wake_prompt */
2172    "K\015",                            /* dmode_str (was "") */
2173    "Number to call: ",                 /* dmode_prompt (was NULL) */
2174    "%s\015",                           /* dial_str (was "<K%s\r>") */
2175    0,                                  /* dial_rate */
2176    0,                                  /* esc_time */
2177    0,                                  /* esc_char */
2178    "",                                 /* hup_str */
2179    "",                                 /* hwfc_str */
2180    "",                                 /* swfc_str */
2181    "",                                 /* nofc_str */
2182    "",                                 /* ec_on_str */
2183    "",                                 /* ec_off_str */
2184    "",                                 /* dc_on_str */
2185    "",                                 /* dc_off_str */
2186    "",                                 /* aa_on_str */
2187    "",                                 /* aa_off_str */
2188    "",                                 /* sb_on_str */
2189    "",                                 /* sb_off_str */
2190    0L,                                 /* max_speed */
2191    0,                                  /* capas */
2192    NULL                                /* ok_fn */
2193};
2194
2195static
2196MDMINF CONCORD =        /* Info for Condor CDS 220 2400b modem */
2197    {
2198    "Concord Condor CDS 220 2400b",
2199    "",                                 /* pulse command */
2200    "",                                 /* tone command */
2201    35,                                 /* dial_time */
2202    ",",                                /* pause_chars */
2203    2,                                  /* pause_time */
2204    "\015\015",                         /* wake_str */
2205    20,                                 /* wake_rate */
2206    "CDS >",                            /* wake_prompt */
2207    "",                                 /* dmode_str */
2208    NULL,                               /* dmode_prompt */
2209    "<D M%s\015>",                      /* dial_str */
2210    0,                                  /* dial_rate */
2211    0,                                  /* esc_time */
2212    0,                                  /* esc_char */
2213    "",                                 /* hup_str */
2214    "",                                 /* hwfc_str */
2215    "",                                 /* swfc_str */
2216    "",                                 /* nofc_str */
2217    "",                                 /* ec_on_str */
2218    "",                                 /* ec_off_str */
2219    "",                                 /* dc_on_str */
2220    "",                                 /* dc_off_str */
2221    "",                                 /* aa_on_str */
2222    "",                                 /* aa_off_str */
2223    "",                                 /* sb_on_str */
2224    "",                                 /* sb_off_str */
2225    2400L,                              /* max_speed */
2226    0,                                  /* capas */
2227    NULL                                /* ok_fn */
2228};
2229#endif /* OLDMODEMS */
2230
2231static
2232MDMINF MICROCOM =       /* Microcom modems in native SX mode */
2233                        /* (long answer only) */
2234{
2235    "Microcom MNP modems in SX command mode",
2236    "DP\015",                           /* pulse command */
2237    "DT\015",                           /* tone command */
2238    35,                                 /* dial_time */
2239    ",!@",              /* pause_chars (! and @ aren't pure pauses) */
2240    3,                                  /* pause_time */
2241/*
2242  The following sets 8 bits, no parity, BREAK passthru, and SE0 disables the
2243  escape character, which is a single character with no guard time, totally
2244  unsafe, so we have no choice but to disable it.  Especially since, by
2245  default, it is Ctrl-A, which is Kermit's packet-start character.  We would
2246  change it to something else, which would enable "mdmhup()", but the user
2247  wouldn't know about it.  Very bad.  Note: SE1 sets it to Ctrl-A, SE2
2248  sets it to Ctrl-B, etc (1..31 allowed).  Also SE/Q sets it to "Q".
2249*/
2250    "SE0;S1P4;SBRK5\015",               /* wake_str */
2251    100,                                /* wake_rate */
2252    "!",                                /* wake_prompt */
2253    "",                                 /* dmode_str */
2254    NULL,                               /* dmode_prompt */
2255    "D%s\015",                          /* dial_str - number up to 39 chars */
2256    0,                                  /* dial_rate */
2257    0,                                  /* esc_time */
2258    0,                                  /* esc_char - we can't use this */
2259    "",                                 /* hup_str - it's "H" but can't use */
2260    "SF13\015",                         /* hwfc_str */
2261    "SF11\015",                         /* swfc_str */
2262    "SF10\015",                         /* nofc_str */
2263    "BAOFF;SMAUT\015",                  /* ec_on_str */
2264    "BAON;SMDIR\015",                   /* ec_off_str */
2265    "COMP1\015",                        /* dc_on_str */
2266    "COMP0\015",                        /* dc_off_str */
2267    "AA",                               /* aa_on_str */
2268    "",                                 /* aa_off_str */
2269    "",                                 /* sb_on_str */
2270    "",                                 /* sb_off_str */
2271    0L,                                 /* max_speed */
2272    CKD_SB|CKD_EC|CKD_DC|CKD_HW|CKD_SW|CKD_KS, /* capas */
2273    getok                               /* ok_fn */
2274};
2275
2276
2277static
2278MDMINF MICROLINK =                      /* MicroLink ... */
2279    {                                   /* 14.4TQ,TL,PC;28.8TQ,TQV;2440T/TR */
2280    "MicroLink 14.4 or 28.8",           /* ELSA GmbH, Aachen */
2281    "ATP\015",                          /* pulse command */
2282    "ATT\015",                          /* tone command */
2283    35,                                 /* dial_time */
2284    ",",                                /* pause_chars */
2285    2,                                  /* pause_time */
2286#ifdef OS2
2287    "ATQ0X4&S0\\D0&C1&D2\\K5\015",      /* wake_str */
2288#else
2289    "ATQ0X4\\K5\015",                   /* wake_str */
2290#endif /* OS2 */
2291    0,                                  /* wake_rate */
2292    "OK\015",                           /* wake_prompt */
2293    "",                                 /* dmode_str */
2294    "",                                 /* dmode_prompt */
2295    "ATD%s\015",                        /* dial_str */
2296    0,                                  /* dial_rate */
2297    1100,                               /* esc_time */
2298    43,                                 /* esc_char */
2299    "ATQ0H\015",                        /* hup_str */
2300    "AT\\Q3\015",                       /* hwfc_str */
2301    "AT\\Q1\\X0\015",                   /* swfc_str */
2302    "AT\\Q0\015",                       /* nofc_str */
2303    "AT\\N3\015",                       /* ec_on_str */
2304    "AT\\N0\015",                       /* ec_off_str */
2305    "AT%C3\015",                        /* dc_on_str */
2306    "AT%C0\015",                        /* dc_off_str */
2307    "ATS0=1\015",                       /* aa_on_str */
2308    "ATS0=0\015",                       /* aa_off_str */
2309    "\\J0",                             /* sb_on_str (?) */
2310    "",                                 /* sb_off_str */
2311    57600L,                             /* max_speed */
2312    CKD_AT|CKD_SB|CKD_EC|CKD_DC|CKD_HW, /* capas */
2313    getok                               /* ok_fn */
2314};
2315
2316
2317#endif /* MINIDIAL */
2318
2319/* END MDMINF STRUCT DEFINITIONS */
2320
2321/*
2322  Table to convert modem numbers to MDMINF struct pointers.
2323  The entries MUST be in ascending order by modem number, without any
2324  "gaps" in the numbers, and starting from one (1).
2325*/
2326
2327MDMINF *modemp[] = {
2328#ifdef MINIDIAL
2329    &CCITT,                             /*  1 */
2330    &HAYES,                             /*  2 */
2331    &UNKNOWN                            /*  3 */
2332#else
2333    &ATTDTDM,                           /*  1 */
2334    &ATTISN,                            /*  2 */
2335    &ATTMODEM,                          /*  3 */
2336    &CCITT,                             /*  4 */
2337#ifdef OLDMODEMS
2338    &CERMETEK,                          /*  5 */
2339    &DF03,                              /*  6 */
2340    &DF100,                             /*  7 */
2341    &DF200,                             /*  8 */
2342    &GDC,                               /*  9 */
2343#else
2344    NULL,
2345    NULL,
2346    NULL,
2347    NULL,
2348    NULL,
2349#endif /* OLDMODEMS */
2350    &HAYES,                             /* 10 */
2351#ifdef OLDMODEMS
2352    &PENRIL,                            /* 11 */
2353    &RACAL,                             /* 12 */
2354#else
2355    NULL,
2356    NULL,
2357#endif /* OLDMODEMS */
2358    &UNKNOWN,                           /* 13 */
2359#ifdef OLDMODEMS
2360    &VENTEL,                            /* 14 */
2361    &CONCORD,                           /* 15 */
2362#else
2363    NULL,
2364    NULL,
2365#endif /* OLDMODEMS */
2366    &DUMMY,                             /* 16 */
2367    &ROLM,                              /* 17 */
2368#ifdef OLDMODEMS
2369    &MICROCOM,                          /* 18 */
2370#else
2371    NULL,
2372#endif /* OLDMODEMS */
2373    &USR,                               /* 19 USR Courier and Sportster */
2374#ifdef OLDTBCODE
2375    &TELEBIT,
2376#else
2377    &OLDTB,                             /* 20 Old Telebits */
2378#endif /* OLDTBCODE */
2379    &DIGITEL,                           /* 21 Digitel CCITT */
2380    &H_1200,                            /* 22 Hayes 1200 */
2381    &H_ULTRA,                           /* 23 Hayes Ultra */
2382    &H_ACCURA,                          /* 24 Hayes Optima */
2383    &PPI,                               /* 25 PPI */
2384    &DATAPORT,                          /* 26 Dataport */
2385    &BOCA,                              /* 27 Boca */
2386    &MOTOROLA,                          /* 28 Motorola UDS MOTOROLA */
2387    NULL,                               /* 29 Digicomm */
2388    NULL,                               /* 30 Dynalink */
2389    &INTEL,                             /* 31 Intel */
2390    &UCOM_AT,                           /* 32 Microcom in AT mode */
2391    &MULTITECH,                         /* 33 Multitech */
2392    &SUPRA,                             /* 34 Supra */
2393    &ZOLTRIX,                           /* 35 Zoltrix */
2394    &ZOOM,                              /* 36 Zoom */
2395    &ZYXEL,                             /* 37 ZyXEL */
2396    &DUMMY,                             /* 38 TAPI */
2397#ifdef OLDTBCODE
2398    &TELEBIT,
2399#else
2400    &NEWTB,                             /* 39 New-Telebit */
2401#endif /* OLDTBCODE */
2402    &MAXTECH,                           /* 40 MaxTech */
2403    &DUMMY,                             /* 41 User-defined */
2404    &RWV32,                             /* 42 Rockwell V.32 */
2405    &RWV32B,                            /* 43 Rockwell V.32bis */
2406    &RWV34,                             /* 44 Rockwell V.34 */
2407    &MWAVE,                             /* 45 IBM Mwave */
2408    &TELEPATH,                          /* 46 Gateway 2000 Telepath II 28.8 */
2409    &MICROLINK,                         /* 47 MicroLink modems */
2410    &CARDINAL                           /* 48 Cardinal */
2411#endif /* MINIDIAL */
2412};
2413/*
2414 * Declare modem names and associated numbers for command parsing,
2415 * and also for doing number-to-name translation.
2416 *
2417 * The entries must be in alphabetical order by modem name.
2418 */
2419struct keytab mdmtab[] = {
2420#ifndef MINIDIAL
2421    "att-dataport",     n_DATAPORT,     0,
2422    "att-dtdm",         n_ATTDTDM,      0,
2423    "attdtdm",          n_ATTDTDM,      CM_INV, /* old name */
2424    "att-isn",          n_ATTISN,       0,
2425    "attisn",           n_ATTISN,       CM_INV, /* old name */
2426    "att-switched-net", n_ATTMODEM,     0,
2427    "attmodem",         n_ATTMODEM,     CM_INV, /* old name */
2428    "att-7300",         n_ATTUPC,       0,
2429    "att7300",          n_ATTUPC,       CM_INV, /* old name */
2430    "boca",             n_BOCA,         0,
2431#endif /* MINIDIAL */
2432    "ccitt-v25bis",     n_CCITT,        CM_INV, /* Name changed to ITU-T */
2433#ifndef MINIDIAL
2434    "cardinal",         n_CARDINAL,     0,
2435#ifdef OLDMODEMS
2436    "cermetek",         n_CERMETEK,     M_OLD,
2437    "concord",          n_CONCORD,      M_OLD,
2438#endif /* OLDMODEMS */
2439    "courier",          n_USR,          CM_INV,
2440    "dataport",         n_DATAPORT,     CM_INV, /* == att-dataport */
2441#ifdef OLDMODEMS
2442    "df03-ac",          n_DF03,         M_OLD,
2443    "df100-series",     n_DF100,        M_OLD,
2444    "df200-series",     n_DF200,        M_OLD,
2445#endif /* OLDMODEMS */
2446    "digitel-dt22",     n_DIGITEL,      0,
2447#endif /* MINIDIAL */
2448    "direct",           0,              CM_INV, /* Synonym for NONE */
2449#ifndef MINIDIAL
2450    "gateway-telepath", n_TELEPATH,     0,
2451#ifdef OLDMODEMS
2452    "gdc-212a/ed",      n_GDC,          M_OLD,
2453    "gendatacomm",      n_GDC,          CM_INV, /* Synonym for GDC */
2454#endif /* OLDMODEMS */
2455#endif /* MINIDIAL */
2456    "h",                n_HAYES,        CM_INV|CM_ABR,
2457    "ha",               n_HAYES,        CM_INV|CM_ABR,
2458    "hay",              n_HAYES,        CM_INV|CM_ABR,
2459    "haye",             n_HAYES,        CM_INV|CM_ABR,
2460    "hayes",            n_HAYES,        CM_INV|CM_ABR, /* Hayes 2400 */
2461#ifndef MINIDIAL
2462    "hayes-1200",       n_H_1200,       0,
2463#endif /* MINIDIAL */
2464    "hayes-2400",       n_HAYES,        0,
2465#ifndef MINIDIAL
2466    "hayes-high-speed", n_H_ACCURA,     0,
2467    "hayes-accura",     n_H_ACCURA,     CM_INV,
2468    "hayes-optima",     n_H_ACCURA,     CM_INV,
2469    "hayes-ultra",      n_H_ULTRA,      CM_INV,
2470    "hst-courier",      n_USR,          CM_INV, /* Synonym for COURIER */
2471    "intel",            n_INTEL,        0,
2472#endif /* MINIDIAL */
2473    "itu-t-v25bis",     n_CCITT,        0,      /* New name for CCITT */
2474#ifndef MINIDIAL
2475    "maxtech",          n_MAXTECH,      0,
2476    "mi",               n_MICROCOM,     CM_INV|CM_ABR,
2477    "mic",              n_MICROCOM,     CM_INV|CM_ABR,
2478    "micr",             n_MICROCOM,     CM_INV|CM_ABR,
2479    "micro",            n_MICROCOM,     CM_INV|CM_ABR,
2480    "microc",           n_MICROCOM,     CM_INV|CM_ABR,
2481    "microco",          n_MICROCOM,     CM_INV|CM_ABR,
2482    "microcom",         n_MICROCOM,     CM_INV|CM_ABR,
2483    "microcom-at-mode", n_UCOM_AT,      0, /* Microcom DeskPorte, etc */
2484    "microcom-sx-mode", n_MICROCOM,     0, /* Microcom AX,QX,SX, native mode */
2485    "microlink",        n_MICROLINK,    0,
2486    "motorola-fastalk", n_MOTOROLA,     0,
2487    "multitech",        n_MULTI,        0,
2488    "mwave",            n_MWAVE,        0,
2489#endif /* MINIDIAL */
2490    "none",             0,              0,
2491#ifndef MINIDIAL
2492#ifndef OLDTBCODE
2493    "old-telebit",      n_TELEBIT,      0,
2494#endif /* OLDTBCODE */
2495#ifdef OLDMODEMS
2496    "penril",           n_PENRIL,       M_OLD,
2497#endif /* OLDMODEMS */
2498    "ppi",              n_PPI,          0,
2499#ifdef OLDMODEMS
2500    "racalvadic",       n_RACAL,        M_OLD,
2501#endif /* OLDMODEMS */
2502    "rockwell-v32",     n_RWV32,        0,
2503    "rockwell-v32bis",  n_RWV32B,       0,
2504    "rockwell-v34",     n_RWV34,        0,
2505    "rolm-dcm",         n_ROLM,         0,
2506    "sportster",        n_USR,          CM_INV,
2507    "supra",            n_SUPRA,        0,
2508    "tapi",             n_TAPI,         CM_INV,
2509#ifndef OLDTBCODE
2510    "te",               n_TBNEW,        CM_INV|CM_ABR,
2511    "tel",              n_TBNEW,        CM_INV|CM_ABR,
2512    "telebit",          n_TBNEW,        0,
2513#else
2514    "te",               n_TELEBIT,      CM_INV|CM_ABR,
2515    "tel",              n_TELEBIT,      CM_INV|CM_ABR,
2516    "telebit",          n_TELEBIT,      0,
2517#endif /* OLDTBCODE */
2518    "telepath",         n_TELEPATH,     CM_INV,
2519#endif /* MINIDIAL */
2520    "unknown",          n_UNKNOWN,      0,
2521    "user-defined",     n_UDEF,         0,
2522#ifndef MINIDIAL
2523    "usr",              n_USR,          CM_INV|CM_ABR,
2524/* Keep the next one for backwards compatibility, but it's the same as H2400 */
2525    "usr-212a",         n_HAYES,        CM_INV,
2526    "usr-courier",      n_USR,          CM_INV,
2527    "usr-sportster",    n_USR,          CM_INV,
2528    "usrobotics",       n_USR,          0,
2529    "v25bis",           n_CCITT,        CM_INV, /* Name changed to ITU-T */
2530#ifdef OLDMODEMS
2531    "ventel",           n_VENTEL,       M_OLD,
2532#endif /* OLDMODEMS */
2533    "zoltrix",          n_ZOLTRIX,      0,
2534    "zoom",             n_ZOOM,         0,
2535    "zyxel",            n_ZYXEL,        0,
2536    "",                 0,              0
2537#endif /* MINIDIAL */
2538};
2539int nmdm = (sizeof(mdmtab) / sizeof(struct keytab)) - 1; /* Number of modems */
2540
2541#define CONNECTED 1                     /* For completion status */
2542#define D_FAILED  2
2543#define D_PARTIAL 3
2544
2545static int tries = 0;
2546static int mdmecho = 0; /* assume modem does not echo */
2547
2548static char *p;         /* For command strings & messages */
2549
2550#ifdef DYNAMIC
2551#define LBUFL 256
2552static char *lbuf = NULL;
2553#else
2554#define LBUFL 100
2555static char lbuf[LBUFL];
2556#endif /* DYNAMIC */
2557
2558#ifdef DYNAMIC
2559#define RBUFL 256
2560static char *rbuf = NULL;
2561#else
2562#define RBUFL 63
2563static char rbuf[RBUFL+1];
2564#endif /* DYNAMIC */
2565
2566#ifdef DYNAMIC
2567#define FULLNUML 256
2568char *fbuf = NULL;                      /* For full (prefixed) phone number */
2569#else
2570#define FULLNUML 100
2571char fbuf[FULLNUML];
2572#endif /* DYNAMIC */
2573
2574static ckjmpbuf sjbuf;
2575
2576#ifdef CK_ANSIC
2577static SIGTYP (*savalrm)(int);  /* For saving alarm handler */
2578static SIGTYP (*savint)(int);   /* For saving interrupt handler */
2579#else
2580static SIGTYP (*savalrm)();     /* For saving alarm handler */
2581static SIGTYP (*savint)();      /* For saving interrupt handler */
2582#endif /* CK_ANSIC */
2583
2584#ifndef MINIDIAL
2585#ifdef OLDTBCODE
2586int tbmodel = 0;                /* Telebit modem model */
2587
2588char *
2589gtbmodel() {                    /* Function to return name of Telebit model */
2590    if (tbmodel < 0 || tbmodel > TB__MAX) tbmodel = TB_UNK;
2591    return(tb_name[tbmodel]);
2592}
2593#endif /* OLDTBCODE */
2594
2595#ifdef COMMENT
2596static VOID
2597xcpy(to,from,len)               /* Copy the given number of bytes */
2598    register char *to, *from;
2599    register unsigned int len; {
2600        while (len--) *to++ = *from++;
2601}
2602#endif /* COMMENT */
2603#endif /* MINIDIAL */
2604
2605static SIGTYP
2606#ifdef CK_ANSIC
2607dialtime(int foo)                       /* Timer interrupt handler */
2608#else
2609dialtime(foo) int foo;                  /* Timer interrupt handler */
2610#endif /* CK_ANSIC */
2611/* dialtime */ {
2612
2613    fail_code = F_TIME;                 /* Failure reason = timeout */
2614    debug(F100,"dialtime caught SIGALRM","",0);
2615#ifdef BEBOX
2616    alarm_expired();
2617#endif /* BEBOX */
2618#ifdef OS2
2619    signal(SIGALRM, dialtime);
2620#endif /* OS2 */
2621#ifdef __EMX__
2622    signal(SIGALRM, SIG_ACK);           /* Needed for OS/2 */
2623#endif /* __EMX__ */
2624
2625#ifdef OSK                              /* OS-9 */
2626/*
2627  We are in an intercept routine but do not perform a F$RTE (done implicitly
2628  by RTS), so we have to decrement the sigmask as F$RTE does.  Warning:
2629  longjump only restores the CPU registers, NOT the FPU registers.  So, don't
2630  use FPU at all or at least don't use common FPU (double or float) register
2631  variables.
2632*/
2633    sigmask(-1);
2634#endif /* OSK */
2635
2636#ifdef NTSIG
2637    if (foo == SIGALRM)
2638      PostAlarmSigSem();
2639    else
2640      PostCtrlCSem();
2641#else /* NTSIG */
2642#ifdef NT
2643    cklongjmp(ckjaddr(sjbuf),1);
2644#else /* NT */
2645    cklongjmp(sjbuf,1);
2646#endif /* NT */
2647#endif /* NTSIG */
2648    /* NOTREACHED */
2649    SIGRETURN;
2650}
2651
2652static SIGTYP
2653#ifdef CK_ANSIC
2654dialint(int foo)                        /* Keyboard interrupt handler */
2655#else
2656dialint(foo) int foo;                   /* Keyboard interrupt handler */
2657#endif /* CK_ANSIC */
2658/* dialint */ {
2659    fail_code = F_INT;
2660    debug(F100,"dialint caught SIGINT","",0);
2661#ifdef OS2
2662    signal(SIGINT, dialint);
2663    debug(F100,"dialint() SIGINT caught -- dialint restored","",0) ;
2664#endif /* OS2 */
2665#ifdef __EMX__
2666    signal(SIGINT, SIG_ACK);            /* Needed for OS/2 */
2667#endif /* __EMX__ */
2668#ifdef OSK                              /* OS-9, see comment in dialtime() */
2669    sigmask(-1);
2670#endif /* OSK */
2671#ifdef NTSIG
2672    PostCtrlCSem() ;
2673#else /* NTSIG */
2674#ifdef NT
2675    cklongjmp(ckjaddr(sjbuf),1);
2676#else /* NT */
2677    cklongjmp(sjbuf,1);
2678#endif /* NT */
2679#endif /* NT */
2680    SIGRETURN;
2681}
2682
2683/*
2684  Routine to read a character from communication device, handling TELNET
2685  protocol negotiations in case we're connected to the modem through a
2686  TCP/IP TELNET modem server.
2687*/
2688static int
2689ddinc(n) int n; {
2690    int c;
2691
2692#ifdef TNCODE
2693    int done = 0;
2694    debug(F101,"ddinc entry n","",n);
2695    while (!done) {
2696        c = ttinc(n);
2697        debug(F000,"ddinc","",c);
2698        if (c < 0) return(c);
2699        if (c == IAC && network && ttnproto == NP_TELNET) {
2700            switch (tn_doop((CHAR)(c & 0xff),duplex,ttinc)) {
2701              case 2: duplex = 0; continue;
2702              case 1: duplex = 1;
2703              default: continue;
2704            }
2705        } else done = 1;
2706    }
2707    return(c & 0xff);
2708#else
2709    debug(F101,"ddinc entry n","",n);
2710    return(ttinc(n));
2711#endif /* TNCODE */
2712}
2713
2714static VOID
2715ttslow(s,millisec) char *s; int millisec; { /* Output s-l-o-w-l-y */
2716#ifdef TCPSOCKET
2717    extern int tn_nlm, tn_b_nlm, me_binary;
2718#endif /* TCPSOCKET */
2719    if (dialdpy && duplex)              /* Echo the command in case modem */
2720      printf("%s\n",s);                 /* isn't echoing commands. */
2721    for (; *s; s++) {
2722        ttoc(*s);
2723#ifdef TCPSOCKET
2724        if (*s == CR && network && ttnproto == NP_TELNET) {
2725       if (!me_binary && tn_nlm != TNL_CR)
2726          ttoc((char)((tn_nlm == TNL_CRLF) ? LF : NUL));
2727        else if (me_binary &&
2728            (tn_b_nlm == TNL_CRLF || tn_b_nlm == TNL_CRNUL))
2729          ttoc((char)((tn_b_nlm == TNL_CRLF) ? LF : NUL));
2730        }
2731#endif /* TCPSOCKET */
2732        msleep(millisec);
2733    }
2734}
2735
2736/*
2737 * Wait for a string of characters.
2738 *
2739 * The characters are waited for individually, and other characters may
2740 * be received "in between".  This merely guarantees that the characters
2741 * ARE received, and in the order specified.
2742 */
2743static VOID
2744waitfor(s) char *s; {
2745    CHAR c, x;
2746    while ( c = *s++ ) {                /* while more characters remain... */
2747        do {                            /* wait for the character */
2748            x = (CHAR) (ddinc(0) & 0177);
2749            debug(F000,"dial waitfor got","",x);
2750            if (dialdpy) {
2751                if (x != LF) conoc(x);
2752                if (x == CR) conoc(LF);
2753            }
2754        } while ( x != c);
2755    }
2756}
2757
2758static int
2759didweget(s,r) char *s, *r; {    /* Looks in string s for response r */
2760    int lr = (int)strlen(r);    /*  0 means not found, 1 means found it */
2761    int i;
2762    debug(F110,"didweget",r,0);
2763    debug(F110," in",s,0);
2764    for (i = (int)strlen(s)-lr; i >= 0; i--)
2765        if ( s[i] == r[0] ) if ( !strncmp(s+i,r,lr) ) return( 1 );
2766    return( 0 );
2767}
2768
2769
2770/* R E S E T -- Reset alarms, etc. on exit. */
2771
2772static VOID
2773dreset() {
2774    debug(F100,"dreset resetting alarm and signal handlers","",0);
2775    alarm(0);
2776    signal(SIGALRM,savalrm);            /* restore alarm handler */
2777    signal(SIGINT,savint);              /* restore interrupt handler */
2778    debug(F100,"dreset alarm and signal handlers reset","",0);
2779}
2780
2781/*
2782  Call this routine when the modem reports that it has connected at a certain
2783  speed, giving that speed as the argument.  If the connection speed is not
2784  the same as Kermit's current communication speed, AND the modem interface
2785  speed is not locked (i.e. DIAL SPEED-MATCHING is not ON), then change the
2786  device speed to the one given.
2787*/
2788static VOID
2789#ifdef CK_ANSIC
2790spdchg(long s)
2791#else
2792spdchg(s) long s;
2793#endif /* CK_ANSIC */
2794/* spdchg */ {
2795    int s2;
2796    if (!mdmspd)                        /* If modem interface speed locked, */
2797      return;                           /*  don't do this. */
2798    if (speed != s) {                   /* Speeds differ? */
2799        s2 = s / 10L;                   /* Convert to cps expressed as int */
2800        if (ttsspd(s2) < 0) {           /* Change speed. */
2801            printf(" WARNING - speed change to %ld failed.\r\n",s);
2802        } else {
2803            printf(" Speed changed to %ld.\r\n",s);
2804            speed = s;                  /* Update global speed variable */
2805        }
2806    }
2807}
2808
2809/*
2810  Display all characters received from modem dialer through this routine,
2811  for consistent handling of carriage returns and linefeeds.
2812*/
2813static VOID
2814#ifdef CK_ANSIC
2815dialoc(char c)
2816#else
2817dialoc(c) char c;
2818#endif /* CK_ANSIC */
2819{ /* dialoc */                          /* Dial Output Character */
2820    if (dialdpy) {
2821        if (c != LF) conoc(c);          /* Don't echo LF */
2822        if (c == CR) conoc(LF);         /* Echo CR as CRLF */
2823    }
2824}
2825
2826#ifndef MINIDIAL
2827#ifdef OLDTBCODE
2828/*
2829  tbati3() -- Routine to find out Telebit model when ATI reports "965"
2830  or "971". This routine sends another query, ATI3, to get further info
2831  to narrow down the model number.  Argument is ATI response as integer.
2832  Result: sets tbmodel variable to Telebit model.
2833*/
2834static VOID
2835tbati3(n) int n; {
2836    int status;
2837    ttflui();                           /* Flush input buffer */
2838    ttslow("ATI3\015",100);             /* Send ATI3<CR> */
2839    status = getok(5,0);                /* Get OK response, nonstrict */
2840    if (status < 1) {                   /* ERROR or timeout */
2841        tbmodel = TB_UNK;
2842        debug(F111,"tbati3 fails",rbuf,status);
2843        return;
2844    }
2845    debug(F110,"tbati3 rbuf",rbuf,0);
2846
2847/* Got a good response, check the model info */
2848
2849    if (n == 965) {                     /* "965" - various models. */
2850        if (didweget(rbuf,"T1600")) {
2851            tbmodel = TB_1600;                  /* T1600 */
2852        } else if (didweget(rbuf,"T3000")) {
2853            tbmodel = TB_3000;                  /* T3000 */
2854        } else if (didweget(rbuf,"World")) {
2855            tbmodel = TB_WBLA;                  /* WorldBlazer */
2856        } else if (didweget(rbuf,"Version B") || /* TrailBlazer-Plus models */
2857                   didweget(rbuf,"TBSA") ||
2858                   didweget(rbuf,"TBRM") ||
2859                   didweget(rbuf,"DC")) {       /* Ven-Tel EC18K */
2860            tbmodel = TB_PLUS;
2861        } else tbmodel = TB_UNK;                /* Others: Unknown */
2862
2863    } else if (n == 971) {              /* "971" could be T1500 or T1600. */
2864        if (didweget(rbuf,"T1500"))
2865          tbmodel = TB_1500;
2866        else tbmodel = TB_2500;
2867    }                                   /* Other, don't change tbmodel. */
2868}
2869#endif /* OLDTBCODE */
2870#endif /* MINIDIAL */
2871
2872VOID                            /* Get dialing defaults from environment */
2873getdialenv() {
2874    char *p = NULL;
2875
2876    makestr(&p,getenv("K_DIAL_DIRECTORY")); /* Dialing directories */
2877    if (p) {
2878        int i;
2879        xwords(p,(MAXDDIR - 2),dialdir,0);
2880        for (i = 0; i < (MAXDDIR - 1); i++) {
2881            if (!dialdir[i+1])
2882              break;
2883            else
2884              dialdir[i] = dialdir[i+1];
2885        }
2886        ndialdir = i;
2887    }
2888    makestr(&diallcc,getenv("K_COUNTRYCODE")); /* My country code */
2889    makestr(&dialixp,getenv("K_LD_PREFIX"));   /* My long-distance prefix */
2890    makestr(&dialldp,getenv("K_INTL_PREFIX")); /* My international prefix */
2891    makestr(&dialldp,getenv("K_TF_PREFIX"));   /* Ny Toll-free prefix */
2892
2893    p = NULL;
2894    makestr(&p,getenv("K_TF_AREACODE")); /* Toll-free areacodes */
2895    if (p) {
2896        int i;
2897        xwords(p,7,dialtfc,0);
2898        for (i = 0; i < 8; i++) {
2899            if (!dialtfc[i+1])
2900              break;
2901            else
2902              dialtfc[i] = dialtfc[i+1];
2903        }
2904        ntollfree = i;
2905    }
2906    if (diallcc) {                      /* Have country code */
2907        if (!strcmp(diallcc,"1")) {     /* If it's 1 */
2908            if (!dialldp)               /* Set these prefixes... */
2909              makestr(&dialldp,"1");
2910            if (!dialtfp)
2911              makestr(&dialtfp,"1");
2912            if (!dialixp)
2913              makestr(&dialixp,"011");
2914            if (ntollfree == 0) {       /* Toll-free area codes... */
2915                if (dialtfc[0] = malloc(4)) {
2916                    strcpy(dialtfc[0],"800");
2917                    ntollfree++;
2918                }
2919                if (dialtfc[1] = malloc(4)) {
2920                    strcpy(dialtfc[1],"888");
2921                    ntollfree++;
2922                }
2923            }
2924        } else if (!strcmp(diallcc,"358") &&
2925                   ((int) strcmp(zzndate(),"19961011") > 0)
2926                   ) {                  /* Finland */
2927            if (!dialldp)               /* Long-distance prefix */
2928              makestr(&dialldp,"9");
2929            if (!dialixp)               /* International dialing prefix */
2930              makestr(&dialixp,"990");
2931        } else {                        /* Not NANP or Finland */
2932            if (!dialldp)
2933              makestr(&dialldp,"0");
2934            if (!dialixp)
2935              makestr(&dialixp,"00");
2936        }
2937    }
2938    makestr(&diallac,getenv("K_AREACODE"));
2939    makestr(&dialpxo,getenv("K_PBX_XCH"));
2940    makestr(&dialpxi,getenv("K_PBX_ICP"));
2941    makestr(&dialpxx,getenv("K_PBX_OCP"));
2942}
2943
2944static int
2945dialfail(x) int x; {
2946    char * s;
2947
2948    fail_code = x;
2949    debug(F101,"ckudial dialfail","",x);
2950    dreset();                           /* Reset alarm and signal handlers */
2951
2952    printf("%s Failure: ", func_code == 0 ? "DIAL" : "ANSWER");
2953    if (dialdpy) {                      /* If showing progress */
2954       debug(F100,"dial display is on","",0);
2955        p = ck_time();                  /* get current time; */
2956        if (*p) printf("%s: ",p);
2957    }
2958    switch (fail_code) {                /* Type of failure */
2959      case F_TIME:                      /* Timeout */
2960        if (dial_what == DW_INIT)
2961          printf ("Timed out while trying to initialize modem.\n");
2962        else if (dial_what == DW_DIAL)
2963          printf ("%s interval expired.\n",
2964                  func_code == 0 ? "DIAL TIMEOUT" : "ANSWER timeout");
2965        else printf("Timeout.\n");
2966        if (mp->capas & CKD_AT)
2967          ttoc('\015');         /* Send CR to interrupt dialing */
2968        /* Some Hayes modems don't fail with BUSY on busy lines */
2969        dialsta = DIA_TIMO;
2970        debug(F110,"dial","timeout",0);
2971        break;
2972
2973      case F_INT:                       /* Dialing interrupted */
2974        printf ("Interrupted.\n");
2975        debug(F110,"dial","interrupted",0);
2976        if (mp->capas & CKD_AT)
2977          ttoc('\015');                 /* Send CR to interrupt dialing */
2978        dialsta = DIA_INTR;
2979        break;
2980
2981    case F_MODEM:                       /* Modem detected a failure */
2982         debug(F111,"dialfail()","lbuf",lbuf);
2983         if (lbuf && *lbuf) {
2984            printf(" \"");
2985            for (s = lbuf; *s; s++)
2986               if (isprint(*s))
2987                  putchar(*s);          /* Display printable reason */
2988            printf ("\"");
2989         } else printf(func_code == 0 ?
2990                        " Call not completed." :
2991                        " Call did not come in."
2992                        );
2993        printf("\n");
2994        debug(F110,"dial",lbuf?lbuf:"",0);
2995        if (dialsta < 0) dialsta = DIA_UNSP;
2996        break;
2997
2998      case F_MINIT:                     /* Failure to initialize modem */
2999        printf ("Error initializing modem.\n");
3000        debug(F110,"dial","modem init",0);
3001        dialsta = DIA_NOIN;
3002        break;
3003
3004    default:
3005        printf("unknown\n");
3006        debug(F110,"dial","unknown",0);
3007        if (mp->capas & CKD_AT)
3008          ttoc('\015');                 /* Send CR to interrupt dialing */
3009        dialsta = DIA_INTR;
3010    }
3011
3012#ifdef DYNAMIC
3013    if (lbuf) free(lbuf); lbuf = NULL;
3014    if (rbuf) free(rbuf); rbuf = NULL;
3015    if (fbuf) free(fbuf); fbuf = NULL;
3016#endif /* DYNAMIC */
3017
3018    if (dialsta < 0) dialsta = DIA_UERR; /* Set failure code */
3019    return(0);                          /* Return zero (important) */
3020}
3021
3022/*  C K D I A L  --  Dial up the remote system */
3023
3024/* Returns 1 if call completed, 0 otherwise */
3025
3026static int waitct, mdmwait, mdmstat = 0;
3027int mdmwaitd = 10 ;   /* difference between dialtmo and mdmwait */
3028static char c;
3029static char *telnbr;
3030
3031static SIGTYP
3032#ifdef CK_ANSIC
3033_dodial(void * threadinfo)
3034#else /* CK_ANSIC */
3035_dodial(threadinfo) VOID * threadinfo;
3036#endif /* CK_ANSIC */
3037/* _dodial */ {
3038    char c2;
3039    char *s, *ws;
3040    int x = 0, n = F_TIME;
3041
3042#ifdef NTSIG
3043    if (threadinfo) {                   /* Thread local storage... */
3044        TlsSetValue(TlsIndex,threadinfo);
3045    }
3046#endif /* NTSIG */
3047
3048    /* Hang up the modem (in case it wasn't "on hook") */
3049    /* But only if SET DIAL HANGUP ON... */
3050
3051    if (dialhup() < 0) {                /* Hangup first */
3052        debug(F100,"ckdial dialhup failed","",0);
3053#ifndef MINIDIAL
3054        if (mdmcapas & CKD_TB)          /* Telebits might need a BREAK */
3055          ttsndb();                     /*  first. */
3056#endif /* MINIDIAL */
3057        if (dialhng && dialsta != DIA_PART) { /* If hangup failed, */
3058            ttclos(0);                  /* close and reopen the device. */
3059            if (ttopen(ttname,&local,mymdmtyp,0) < 0) {
3060                printf("Sorry, Can't hang up communication device.\n");
3061                printf("Try 'set line %s' again.\n",ttname);
3062                dialsta = DIA_HANG;
3063#ifdef DYNAMIC
3064                if (lbuf) free(lbuf); lbuf = NULL;
3065                if (rbuf) free(rbuf); rbuf = NULL;
3066                if (fbuf) free(fbuf); fbuf = NULL;
3067#endif /* DYNAMIC */
3068                dreset();
3069#ifdef NTSIG
3070                ckThreadEnd(threadinfo);
3071#endif /* NTSIG */
3072                SIGRETURN;
3073            }
3074        }
3075    }
3076#ifndef MINIDIAL
3077    /* Don't start talking to Rolm too soon */
3078    if (mymdmtyp == n_ROLM && dialsta != DIA_PART)
3079      msleep(500);
3080#endif /* MINIDIAL */
3081
3082/* Send init-string */
3083
3084    if (dialsta != DIA_PART
3085#ifndef MINIDIAL
3086        && mymdmtyp != n_ATTUPC
3087#endif /* MINIDIAL */
3088        ) {
3089        fail_code = F_MINIT;            /* Default failure code */
3090        dial_what = DW_INIT;            /* What I'm Doing Now   */
3091        if (dialdpy) {                  /* If showing progress, */
3092            p = ck_time();              /* display timestamp.   */
3093            if (*p) printf(" Initializing: %s...\n",p);
3094        }
3095    }
3096
3097#ifndef MINIDIAL
3098#ifdef ATT7300
3099    if (mymdmtyp == n_ATTUPC) {
3100/*
3101  For ATT7300/Unix PC's with their special internal modem.  Whole dialing
3102  process is handled right here, an exception to the normal structure.
3103  Timeout and user interrupts are enabled during dialing.  attdial() is in
3104  file ckutio.c.  - jrd
3105*/
3106        _PROTOTYP( int attdial, (char *, long, char *) );
3107        fail_code = F_MODEM;            /* Default failure code */
3108        dial_what = DW_DIAL;
3109        if (dialdpy) {                  /* If showing progress */
3110            p = ck_time();              /* get current time; */
3111            if (*p) printf(" Dialing: %s...\n",p);
3112        }
3113        alarm(waitct);                  /* Do alarm properly */
3114        if (attdial(ttname,speed,telnbr)) { /* dial internal modem */
3115            dreset();                   /* reset alarms, etc. */
3116            printf(" Call failed.\r\n");
3117            dialhup();                  /* Hangup the call */
3118#ifdef DYNAMIC
3119            if (lbuf) free(lbuf); lbuf = NULL;
3120            if (rbuf) free(rbuf); rbuf = NULL;
3121            if (fbuf) free(fbuf); fbuf = NULL;
3122#endif /* DYNAMIC */
3123            dialsta = DIA_UERR;
3124#ifdef NTSIG
3125            ckThreadEnd(threadinfo);
3126#endif /* NTSIG */
3127            SIGRETURN;                  /* return failure */
3128        }
3129        dreset();                       /* reset alarms, etc. */
3130        ttpkt(speed,FLO_DIAX,parity);   /* cancel dialing ioctl */
3131        if (!quiet && !backgrd) {
3132            if (dialdpy) printf("\n");
3133            printf(" Call complete.\r\n");
3134        }
3135        dialsta = DIA_OK;
3136#ifdef DYNAMIC
3137        if (lbuf) free(lbuf); lbuf = NULL;
3138        if (rbuf) free(rbuf); rbuf = NULL;
3139        if (fbuf) free(fbuf); fbuf = NULL;
3140#endif /* DYNAMIC */
3141#ifdef NTSIG
3142        ckThreadEnd(threadinfo);
3143#endif /* NTSIG */
3144        SIGRETURN;      /* No conversation with modem to complete dialing */
3145    } else
3146#endif /* ATT7300 */
3147    if (mymdmtyp == n_TAPI) {           /* Windows dialer */
3148        printf("INSERT CALL TO WINDOWS TELEPHONY API HERE\n");
3149#ifdef NTSIG
3150        ckThreadEnd(threadinfo);
3151#endif /* NTSIG */
3152        SIGRETURN;
3153    } else
3154#endif /* MINIDIAL */
3155
3156/* Modems with AT command set... */
3157
3158      if ((mdmcapas & CKD_AT) && dialsta != DIA_PART) {
3159
3160          if (dialini)                  /* Get wakeup/init string */
3161            ws = dialini;
3162          else
3163            ws = mp->wake_str;
3164          if (!ws) ws = "\015";         /* If none, use CR */
3165
3166          for (tries = 4; tries > 0; tries--) { /* Send it */
3167              ttslow(ws,mp->wake_rate);
3168              mdmstat = getok(4,1);     /* Get response */
3169              if (mdmstat > 0) break;
3170              if (dialdpy && tries > 1)
3171                printf(" No response from modem, retrying%s...\n",
3172                       (tries < 4) ? " again" : "");
3173          }
3174          debug(F101,"ckdial wake_str mdmstat","",mdmstat);
3175
3176          if (mdmstat < 1) {            /* Initialized OK? */
3177              dialfail(F_MINIT); /* No, fail. */
3178#ifdef NTSIG
3179              ckThreadEnd(threadinfo);
3180#endif /* NTSIG */
3181              SIGRETURN;
3182          } else {                      /* Yes. */
3183              char hbuf[16];
3184
3185              if (mdmwait > 255)        /* If larger than maximum, */
3186                mdmwait = 255;          /* make it maximum. */
3187
3188              sprintf(hbuf,"ATS7=%d%c",mdmwait,13); /* S7 carrier wait time */
3189              ttslow(hbuf,mp->wake_rate); /* Set it. */
3190              mdmstat = getok(4,1);     /* Get response from modem */
3191              /* If it gets an error, go ahead anyway */
3192              debug(F101,"ckdial S7 mdmstat","",mdmstat);
3193          }
3194
3195#ifndef MINIDIAL
3196#ifdef OLDTBCODE
3197/*
3198  Telebit modems fall into two basic groups: old and new.  The functions and
3199  command sets are different between the two groups, and also vary by specific
3200  models within each group, and even by firmware ROM revision number.  Read
3201  ckcker.bwr for details.
3202
3203  Commands used by C-Kermit include:
3204
3205    Old       New            Meaning
3206    -------   --------       ----------------------------------------
3207    Q0        Q0             Enable result codes.
3208    X1        X1             Extended result codes.
3209    X1        X1             Extended result codes + BUSY, NO DIALTONE, etc.
3210    I         I              Model number inquiry.
3211    I3        I3             Additional model information inquiry.
3212    S12=50    S12=50         Escape sequence guard time (1 sec).
3213    S2=43     S2=43          Escape character is '+'.
3214    S7=xx     S7=xx          DIAL TIMEOUT, calculated or SET by user.
3215    S48=0     S48=0          7-bit data (Kermit's PARITY is not NONE).
3216    S48=1     S48=1          8-bit data (Kermit's PARITY is NONE).
3217    S50=0     S50=0          Automatic speed & protocol determination.
3218    S50=3     S50=3          2400/1200/300 bps.
3219    S50=6     S50=6          V.32 (9600 bps).
3220    S50=255   S50=255        PEP mode.
3221    S110=1    S190=1 S191=7  Allow compression in PEP mode.
3222    S51=?     S51=?          DTE interface speed (left alone by Kermit).
3223    S54=3     S61=0 S63=0    Pass BREAK signal (always).
3224    S58=2     S58=2          RTS/CTS flow control if Kermit's FLOW is RTS/CTS.
3225    S58=?     S58=?          S58 unchanged if Kermit's FLOW is not RTS/CTS.
3226    S68=255   S68=255        Use flow control specified by S58 (always).
3227    S95=0     S180=0         MNP disabled (SET DIAL MNP-ENABLE OFF)
3228    S95=2     S180=3         MNP, fallback to direct (also as V.42 fallback)
3229    S97=1     S180=2         Enable V.42 (LAPM) error correction
3230    S98=3                    Enable compression in both directions
3231    S106=1                   V.42bis compression enable
3232
3233For Kermit Spoof (same commands for all models that support it):
3234
3235    S111=0                   No Kermit spoofing
3236    S111=10                  Kermit with no parity
3237    S111=11                  Kermit with odd parity
3238    S111=12                  Kermit with even parity
3239    S111=13                  Kermit with mark parity
3240    S111=14                  Kermit with space parity
3241    S112=??                  Kermit's start-of-packet character (stchr).
3242*/
3243          if (mdmcapas & CKD_TB) { /* Telebits... */
3244
3245              int S111;                 /* Telebit Kermit spoof register */
3246              char tbcmdbuf[64];        /* Telebit modem command buffer */
3247              char *ecstr = "";         /* Pointer to EC-enable string */
3248              char *dprstr = "";        /* Pointer to dial protocol string */
3249/*
3250  If user defined a DIAL INIT-STRING, send that now, otherwise send built-in
3251  Telebit string.  Try up to 4 times to get OK or 0 response from modem.
3252  NOTE: The default init string *must* be independent of Telebit model.
3253*/
3254              ws = dialini ? dialini : TELEBIT.wake_str;
3255              debug(F110,"ckdial telebit init string",ws,0);
3256              for (tries = 4; tries > 0; tries--) {
3257                  ttsndb();             /* Begin by sending BREAK */
3258                  ttslow(ws,mp->wake_rate); /* Send wakeup string */
3259                  mdmstat = getok(5,0); /* Get modem's response */
3260                  if (mdmstat) break;   /* If response OK, done */
3261                  if (dialdpy && tries > 1)
3262                    printf(" No response from modem, retrying%s...\n",
3263                           (tries < 4) ? " again" : "");
3264                  msleep(300);          /* Otherwise, sleep 1/3 second */
3265                  dialhup();            /* Hang up */
3266                  ttflui();             /* Flush input buffer and try again */
3267              }
3268              if (mdmstat < 1) {        /* If we didn't get a response, */
3269                  dialfail(F_MINIT); /* fail. */
3270#ifdef NTSIG
3271                  ckThreadEnd(threadinfo);
3272#endif /* NTSIG */
3273                  SIGRETURN;
3274              }
3275              if (!dialini) {           /* If using built-in init strings... */
3276/*
3277  Try to get the model number.  It should be in the getok() response buffer,
3278  rbuf[], because the Telebit init string asks for it with the "I" command.
3279  If the model number is 965, we have to make another query to narrow it down.
3280*/
3281                  if (didweget(rbuf,"962") || /* Check model number */
3282                      didweget(rbuf,"961") ||
3283                      didweget(rbuf,"963")) {
3284                      tbmodel = TB_BLAZ; /* Trailblazer */
3285                  } else if (didweget(rbuf,"972")) {
3286                      tbmodel = TB_2500; /* T2500 */
3287                  } else if (didweget(rbuf,"968")) {
3288                      tbmodel = TB_1000;        /* T1000 */
3289                  } else if (didweget(rbuf,"966") ||
3290                             didweget(rbuf,"967") ||
3291                             didweget(rbuf,"964")) {
3292                      tbmodel = TB_PLUS; /* Trailblazer-Plus */
3293                  } else if (didweget(rbuf,"969")) {
3294                      tbmodel = TB_QBLA; /* Qblazer */
3295                  } else if (didweget(rbuf,"970")) {
3296                      tbmodel = TB_QBLA; /* Qblazer Plus */
3297                  } else if (didweget(rbuf,"965")) { /* Most new models */
3298                      tbati3(965);      /* Go find out */
3299                  } else if (didweget(rbuf,"971")) { /* T1500 or T2500 */
3300                      tbati3(971);      /* Go find out */
3301                  } else if (didweget(rbuf,"123") || didweget(rbuf,"960")) {
3302                      tbmodel = TB_UNK; /* Telebit in Hayes mode */
3303                  }
3304                  debug(F111,"Telebit model",tb_name[tbmodel],tbmodel);
3305                  if (dialdpy)
3306                    printf("Telebit model: %s\n",tb_name[tbmodel]);
3307                  ttflui();
3308/*
3309  Flow control.  If C-Kermit's FLOW-CONTROL is RTS/CTS, then we set this on
3310  the modem too.  Unfortunately, many versions of UNIX only allow RTS/CTS
3311  to be set outside of Kermit (e.g. by selecting a special device name).
3312  In that case, Kermit doesn't know that it should set RTS/CTS on the modem,
3313  in which case the user SET MODEM FLOW appropriately.
3314*/
3315                  if (flow == FLO_RTSC) { /* RTS/CTS active in Kermit */
3316                      sprintf(tbcmdbuf,
3317                              "ATS7=%d S48=%d S50=0 S58=2 S68=255\015",
3318                              mdmwait, parity ? 0 : 1);
3319                  } else
3320                    sprintf(tbcmdbuf,   /* Otherwise, don't touch modem's fc */
3321                            "ATS7=%d S48=%d S50=0 S68=255\015",
3322                            mdmwait, parity ? 0 : 1);
3323                  s = tbcmdbuf;
3324                  debug(F110,"ckdial Telebit init step 2",s,0);
3325                  for (tries = 4; tries > 0; tries--) {
3326                      ttslow(s,mp->wake_rate);
3327                      mdmstat = getok(5,1);
3328                      if (mdmstat) break;
3329                      if (dialdpy && tries > 1)
3330                        printf(" No response from modem, retrying%s...\n",
3331                               (tries < 4) ? " again" : "");
3332                      msleep(500);
3333                      ttflui();
3334                  }
3335                  if (mdmstat < 1) {
3336                      dialfail(F_MINIT);
3337#ifdef NTSIG
3338                      ckThreadEnd(threadinfo);
3339#endif /* NTSIG */
3340                      SIGRETURN;
3341                  }
3342/*
3343  Model-dependent items, but constant per model.
3344*/
3345                  switch (tbmodel) {
3346                    case TB_BLAZ:
3347                    case TB_PLUS:       /* TrailBlazer-Plus */
3348                    case TB_1000:       /* T1000 */
3349                    case TB_2000:       /* T2000 */
3350                    case TB_2500:       /* T2500 */
3351#ifdef COMMENT
3352/* Code from edit 183 told modem to follow RS-232 wrt CD and DTR */
3353                      /* DTR, CD, follow RS-232, pass BREAK */
3354                      sprintf(tbcmdbuf,"ATS52=1 S53=4 S54=3\015");
3355#else
3356/* But everybody agreed we should not touch modem's CD and DTR settings. */
3357                      /* Just pass BREAK */
3358                      sprintf(tbcmdbuf,"ATS54=3\015");
3359#endif /* COMMENT */
3360                      break;
3361                    case TB_1600:       /* T1600 */
3362                    case TB_3000:       /* T3000 */
3363                    case TB_WBLA:       /* WorldBlazer */
3364                    case TB_QBLA:       /* Qblazer */
3365#ifdef COMMENT
3366/* Code from edit 183 */
3367                      /* Follow RS-232, No CONNECT suffix, pass BREAK */
3368                      sprintf(tbcmdbuf,"AT&C1&D2&Q0 S59=0 S61=0 S63=0\015");
3369#else
3370/*
3371  Everybody agrees we should not touch modem's CD and DTR settings.
3372  Also no more &Q0, no more S59=0 (doesn't matter, so don't touch).
3373  So this section now deals only with treatment of BREAK.
3374  Here we also raise the result code from X1 to X2, which allows
3375  the T1600, T3000, and WB to supply NO DIALTONE, BUSY, RRING, and DIALING.
3376  X2 means something else on the other models.
3377*/
3378                      /* Transmit BREAK in sequence, raise result code. */
3379                      sprintf(tbcmdbuf,"ATX2 S61=0 S63=0\015");
3380#endif /* COMMENT */
3381                      break;
3382                    default:            /* Others, do nothing */
3383                      tbcmdbuf[0] = NUL;
3384                      break;
3385                  }
3386                  s = tbcmdbuf;
3387                  if (*s) {
3388                      debug(F110,"ckdial Telebit init step 3",s,0);
3389                      for (tries = 4; tries > 0; tries--) {
3390                          ttslow(s,mp->wake_rate);
3391                          mdmstat = getok(5,1);
3392                          if (mdmstat) break;
3393                          if (dialdpy && tries > 1)
3394                            printf(" No response from modem, retrying%s...\n",
3395                                   (tries < 4) ? " again" : "");
3396                          msleep(500);
3397                          ttflui();
3398                      }
3399                      if (mdmstat < 1)
3400                        dialfail(F_MINIT);
3401                  } else debug(F100,"ckdial Telebit init step 3 skipped","",0);
3402
3403/* Error correction, MNP or V.42 */
3404
3405                  if (dialec) {         /* User wants error correction */
3406                      switch (tbmodel) { /* which implies fallback to MNP. */
3407                        case TB_PLUS:   /* BC7.00 and up firmware */
3408                        case TB_2000:   /* now really the same as TB+ ? */
3409                        case TB_2500:   /* LAPM+compress->MNP->direct */
3410                          ecstr = "S50=0 S95=2 S97=1 S98=3 S106=1";
3411                          break;
3412                        case TB_1600:
3413                        case TB_3000:
3414                        case TB_WBLA:
3415                        case TB_QBLA:
3416#ifdef COMMENT
3417                          /* V.42, fallback = lock speed */
3418                          ecstr = "S180=2 S181=0";
3419#else
3420/* Better not to mess with S181, let it be used however user has it set. */
3421/* S180=2 allows fallback to MNP, S180=1 disallows fallback to MNP. */
3422                          ecstr = "S180=2";     /* V.42 */
3423#endif /* COMMENT */
3424                          break;
3425                        default:
3426                          if (dialdpy)
3427                            printf(
3428"V.42 not supported by this Telebit model\n");
3429                      }
3430                  } else {              /* Handle DIAL ERROR-CORRE.. setting */
3431                      switch (tbmodel) {
3432                        case TB_BLAZ:   /* TrailBlazer */
3433                        case TB_PLUS:   /* TrailBlazer-Plus */
3434                        case TB_1000:   /* T1000 */
3435                        case TB_2000:   /* T2000 */
3436                        case TB_2500:   /* T2500 */
3437                          ecstr = dialec ? "S95=2" : "S95=0"; /* ON, OFF */
3438                          break;
3439                        case TB_1600:   /* T1600 */
3440                        case TB_3000:   /* T3000 */
3441                        case TB_WBLA:   /* WorldBlazer */
3442                        case TB_QBLA:   /* Qblazer */
3443                          ecstr = dialec ? "S180=3" : "S180=0"; /* ON, OFF */
3444                          /* (Leave S181 fallback method alone) */
3445                          break;
3446                        default:
3447                          ecstr = "";
3448                      }
3449                  }
3450
3451/* Dialing protocol */
3452
3453                  dprstr = "";  /* Initialize dialing protocol string */
3454                  p = "";               /* and message string */
3455                  switch (mymdmtyp) {
3456                    case n_TELEBIT:     /* Start at highest and work down */
3457                      p = "standard";
3458                      switch (tbmodel) { /* First group starts with PEP */
3459                        case TB_BLAZ:   /* TrailBlazer */
3460                        case TB_PLUS:   /* TrailBlazer-Plus */
3461                        case TB_1000:   /* T1000 */
3462                        case TB_2000:   /* T2000 */
3463                        case TB_2500:   /* T2500 */
3464                          dprstr = "S50=0 S110=1"; /* PEP, compression. */
3465                          break;
3466                        case TB_WBLA:   /* WorldBlazer has PEP */
3467                          dprstr = "S50=0 S190=1 S191=7"; /* PEP, */
3468                          break;        /* compression allowed. */
3469                        case TB_1600:   /* T1600 doesn't have PEP */
3470                        case TB_3000:   /* T3000 doesn't */
3471                        case TB_QBLA:   /* Qblazer doesn't*/
3472                        default:
3473                          dprstr = "S50=0"; /* No PEP available */
3474                          break;
3475                      }
3476                      break;
3477
3478#ifdef COMMENT
3479/* Who needs it? */
3480                    case n_TBS:         /* Telebit up to 2400 Baud */
3481                      p = "300/1200/2400 Baud"; /* Leave S90 alone assuming */
3482                      dprstr = "S50=3"; /* already set for V.22 vs 212A */
3483                      break;
3484                    case n_TB3:         /* Telebit V.32 */
3485                      if (tbmodel == TB_3000 || tbmodel == TB_1600 ||
3486                          tbmodel == TB_2500 || tbmodel == TB_WBLA) {
3487                          p = "V.32";
3488                    /* Note: we don't touch S51 (interface speed) here. */
3489                    /* We're already talking to the modem, and the modem */
3490                    /* SHOULD be able to make a V.32 call no matter what */
3491                    /* its interface speed is.  (In practice, however, */
3492                    /* that is not always true.) */
3493                          dprstr = "S50=6";
3494                      } else if (dialdpy)
3495                        printf("V.32 not supported by this Telebit model.\n");
3496                      break;
3497
3498                    case n_TBPEP:       /* Force PEP Protocol */
3499                      /* Models that don't support PEP */
3500                      if (tbmodel != TB_1600 &&
3501                          tbmodel != TB_3000 &&
3502                          tbmodel != TB_QBLA) {
3503                          p = "PEP";
3504                          if (tbmodel == TB_WBLA) /* WorldBlazer */
3505                            dprstr = "S50=255 S190=1 S191=7";
3506                          else if (tbmodel != TB_1000)
3507                            dprstr = "S50=255 S110=1"; /* TrailBlazer, etc. */
3508                          else dprstr = "S50=255"; /* T1000, no compression */
3509                      } else if (dialdpy)
3510                        printf("PEP not supported by this Telebit model.\n");
3511                      break;
3512#endif /* COMMENT */
3513                  }
3514
3515                  /* Telebit Kermit Spoof */
3516
3517                  if (dialksp) {
3518                      p = "Kermit Spoof";
3519                      switch (parity) { /* S111 value depends on parity */
3520                        case 'e': S111 = 12; break;
3521                        case 'm': S111 = 13; break;
3522                        case 'o': S111 = 11; break;
3523                        case 's': S111 = 14; break;
3524                        case 0:
3525                        default:  S111 = 10; break;
3526                      }
3527                      if (tbmodel != TB_QBLA)
3528                        sprintf(tbcmdbuf,"AT%s %s S111=%d S112=%d\015",
3529                                ecstr,dprstr,S111,stchr);
3530                      else {            /* Qblazer has no Kermit spoof */
3531                          sprintf(tbcmdbuf,"AT%s %s\015", ecstr,dprstr);
3532                          p = "No Kermit Spoof";
3533                          if (dialdpy)
3534                            printf("Kermit Spoof not supported by Qblazer\n");
3535                      }
3536                  } else {              /* KERMIT-SPOOF OFF */
3537                      p = "No Kermit Spoof";
3538                      sprintf(tbcmdbuf,"AT%s %s %s\015",
3539                              ecstr, dprstr,
3540                              (tbmodel == TB_QBLA) ? "" : "S111=0");
3541                  }
3542                  s = tbcmdbuf;
3543                  debug(F111,"ckdial Telebit config",p,speed);
3544                  debug(F110,"ckdial Telebit init step 4",s,0);
3545                  if (*s) {
3546                      for (tries = 4; tries > 0; tries--) {
3547                          ttslow(s,mp->wake_rate);
3548                          mdmstat = getok(5,1);
3549                          if (mdmstat) break;
3550                          if (dialdpy && tries > 1)
3551                            printf(" No response from modem, retrying%s...\n",
3552                                   (tries < 4) ? " again" : "");
3553                          msleep(500);
3554                          ttflui();
3555                      }
3556                      debug(F101,"ckdial telebit init mdmstat","",mdmstat);
3557                      if (mdmstat < 1)
3558                        dialfail(F_MINIT);
3559                  }
3560              }
3561              /* Done with Telebit protocols, remove bits from modem type */
3562              /* Except nonverbal bit */
3563              debug(F101,"ckdial Telebit mymdmtyp","",mymdmtyp);
3564          }
3565#endif /* OLDTBCODE */
3566
3567    } else if (mymdmtyp == n_ATTDTDM && dialsta != DIA_PART) { /* AT&T ... */
3568        ttsndb();                       /* Send BREAK */
3569#endif /* MINIDIAL */
3570
3571    } else if ( dialsta != DIA_PART ) { /* All others */
3572
3573
3574
3575        /* Place modem into command mode */
3576
3577        ws = dialini ? dialini : mp->wake_str;
3578        if (ws && (int)strlen(ws) > 0) {
3579            debug(F111,"ckdial default, wake string", ws, mp->wake_rate);
3580            ttslow(ws, mp->wake_rate);
3581        } else debug(F100,"ckdial no wake_str","",0);
3582        if (mp->wake_prompt && (int)strlen(mp->wake_prompt) > 0) {
3583            debug(F110,"ckdial default, waiting for wake_prompt",
3584                  mp->wake_prompt,0);
3585            alarm(10);
3586            waitfor(mp->wake_prompt);
3587            alarm(0);
3588        } else debug(F100,"ckdial no wake_prompt","",0);
3589    }
3590    if (dialsta != DIA_PART) {
3591        alarm(0);                       /* Turn off alarm */
3592        debug(F100,"ckdial got wake prompt","",0);
3593        msleep(500);                    /* Allow settling time */
3594    }
3595/* Handle error correction, data compression, and flow control... */
3596
3597    if ( dialsta != DIA_PART
3598#ifndef MINIDIAL
3599#ifdef OLDTBCODE
3600        && !(mdmcapas & CKD_TB)         /* Telebits already done. */
3601#endif /* OLDTBCODE */
3602#endif /* MINIDIAL */
3603        ) {
3604
3605        /* Enable/disable error-correction */
3606
3607        x = 0;
3608        if (dialec) {                   /* DIAL ERROR-CORRECTION is ON */
3609            if (dialecon) {             /* SET DIAL STRING ERROR-CORRECTION */
3610                x = 1;
3611                ttslow(dialecon, mp->wake_rate);               
3612            } else if (mdmcapas & CKD_EC) {
3613                x = 1;
3614                ttslow(mp->ec_on_str, mp->wake_rate);
3615            } else printf(
3616                  "WARNING - I don't know how to turn on EC for this modem\n"
3617                     );
3618        } else {
3619            if (dialecoff) {            /* SET DIAL STRING */
3620                x = 1;
3621                ttslow(dialecoff, mp->wake_rate);               
3622            } else if (mdmcapas & CKD_EC) { /* Or built-in one... */
3623                x = 1;
3624                ttslow(mp->ec_off_str, mp->wake_rate);
3625            }
3626#ifdef COMMENT
3627            else printf(
3628                  "WARNING - I don't know how to turn off EC for this modem\n"
3629                     );
3630#endif /* COMMENT */
3631        }
3632        debug(F101,"ckudia xx_ok","",xx_ok);
3633        if (x && xx_ok) {                       /* Look for OK response */
3634            debug(F100,"ckudia calling xx_ok for EC","",0);
3635            x = (*xx_ok)(5,1);
3636            debug(F101,"ckudia xx_ok","",x);
3637            if (x < 0) {
3638                printf("WARNING - Trouble enabling error-correction.\n");
3639                printf(
3640" Likely cause: Your modem is an RPI model, which does not have built-in\n");
3641                printf(" error correction and data compression.");
3642            }
3643        }
3644
3645        /* Enable/disable data compression */
3646
3647        if (x > 0) x = 0;
3648        if (dialdc) {
3649            if (x < 0 || !dialec) {
3650                printf(
3651"WARNING - You can't have compression without error correction.\n");
3652            } else if (dialdcon) {      /* SET DIAL STRING ... */
3653                x = 1;
3654                ttslow(dialdcon, mp->wake_rate);               
3655            } else if (mdmcapas & CKD_DC) {
3656                x = 1;
3657                ttslow(mp->dc_on_str, mp->wake_rate);
3658            } else printf(
3659                  "WARNING - I don't know how to turn on DC for this modem\n"
3660                          );
3661        } else {
3662            if (dialdcoff) {            /* SET DIAL STRING */
3663                x = 1;
3664                ttslow(dialdcoff, mp->wake_rate);               
3665            } else if (mdmcapas & CKD_DC) { /* Or built-in one... */
3666                x = 1;
3667                ttslow(mp->dc_off_str, mp->wake_rate);
3668            }
3669#ifdef COMMENT
3670            else printf(
3671"WARNING - I don't know how to turn off compression for this modem\n"
3672                          );
3673#endif /* COMMENT */
3674        }
3675        if (x && xx_ok) {                       /* Look for OK response */
3676            x = (*xx_ok)(5,1);
3677            if (x < 0) printf("WARNING - Trouble enabling compression\n");
3678        }
3679
3680/* Flow control */
3681
3682        x = 0;                          /* User said SET DIAL FLOW RTS/CTS */
3683        if ( dialfc == FLO_RTSC ||      /* Even if Kermit's FLOW isn't...  */
3684            (dialfc == FLO_AUTO && flow == FLO_RTSC)) {
3685            if (dialhwfc) {             /* User-defined HWFC string */
3686                x = 1;
3687                ttslow(dialhwfc, mp->wake_rate);
3688            } else if (mdmcapas & CKD_HW) { /* or built-in one */
3689                x = 1;
3690                ttslow(mp->hwfc_str, mp->wake_rate);
3691            } else
3692              printf("WARNING - I don't know how to enable modem's HWFC.\n");
3693
3694        } else if ( dialfc == FLO_XONX || /* User said SET DIAL FLOW SOFT */
3695                   (dialfc == FLO_AUTO && flow == FLO_XONX)) {
3696            if (dialswfc) {
3697                x = 1;
3698                ttslow(dialswfc, mp->wake_rate);
3699            } else if (mdmcapas & CKD_SW) {
3700                x = 1;
3701                ttslow(mp->swfc_str, mp->wake_rate);
3702            }
3703
3704        } else if (dialfc == FLO_NONE) { /* User said SET DIAL FLOW NONE */
3705            if (dialnofc) {
3706                x = 1;
3707                ttslow(dialnofc, mp->wake_rate);
3708            } else if (mp->nofc_str && *(mp->nofc_str)) {
3709                x = 1;
3710                ttslow(mp->nofc_str, mp->wake_rate);
3711            }
3712        }
3713        if (x && xx_ok) {               /* Get modem's response */
3714            x = (*xx_ok)(5,1);
3715            if (x < 0)
3716             printf("WARNING - Trouble %sabling modem's local flow control\n",
3717                    (dialfc == FLO_NONE) ? "dis" : "en");
3718#ifdef CK_TTSETFLOW
3719#ifdef CK_RTSCTS
3720/*
3721  So far only ckutio.c has ttsetflow().
3722  We have just told the modem to turn on RTS/CTS flow control and the modem
3723  has said OK.  But we ourselves have not turned it on yet because of the
3724  disgusting ttpkt(...FLO_DIAL...) hack.  So now, if the computer does not
3725  happen to be asserting RTS, the modem will no longer send characters to it.
3726  So at EXACTLY THIS POINT, we must enable RTS/CTS in the device driver.
3727*/
3728            if (dialfc == FLO_RTSC ||
3729                (dialfc == FLO_AUTO && flow == FLO_RTSC))
3730              ttsetflow(FLO_RTSC);
3731#endif /* CK_RTSCTS */
3732#endif /* CK_TTSETFLOW */
3733        }
3734    }
3735
3736#ifndef MINIDIAL
3737    if (mdmcapas & CKD_KS && dialsta != DIA_PART) { /* Kermit spoof */
3738        int r;                          /* Register */
3739        char tbcmdbuf[20];              /* Command buffer */
3740        switch (mymdmtyp) {
3741 
3742          case n_MICROCOM:              /* Microcoms in SX mode */
3743            if (dialksp)
3744              sprintf(tbcmdbuf,"APM1;KMC%d\015",stchr);
3745            else
3746              sprintf(tbcmdbuf,"APM0\015");
3747            ttslow(tbcmdbuf, MICROCOM.wake_rate);
3748            alarm(3);
3749            waitfor(mp->wake_prompt);
3750            alarm(0);
3751            break;
3752
3753          case n_TELEBIT:               /* Old and new Telebits */
3754          case n_TBNEW:
3755            if (!dialksp) {
3756                sprintf(tbcmdbuf,"ATS111=0\015");
3757            } else {
3758                switch (parity) {       /* S111 value depends on parity */
3759                  case 'e': r = 12; break;
3760                  case 'm': r = 13; break;
3761                  case 'o': r = 11; break;
3762                  case 's': r = 14; break;
3763                  case 0:
3764                  default:  r = 10; break;
3765                }
3766                sprintf(tbcmdbuf,"ATS111=%d S112=%d\015",r,stchr);
3767            }
3768            ttslow(tbcmdbuf, mp->wake_rate);
3769
3770/* Not all Telebit models have the Kermit spoof, so ignore response. */
3771
3772            if (xx_ok) {                /* Get modem's response */
3773                x = (*xx_ok)(5,1);
3774#ifdef COMMENT
3775                if (x < 0)
3776                  printf("WARNING - Trouble %sabling Kermit spoof\n",
3777                         (dialksp == FLO_NONE) ? "dis" : "en");
3778#endif /* COMMENT */
3779            }
3780        }
3781    }
3782#endif /* MINIDIAL */
3783
3784    if (dialmth && dialsta != DIA_PART) { /* If dialing method specified... */
3785        char *s = "";                   /* Do it here... */
3786
3787        if (dialmth == XYDM_T)          /* Tone */
3788          s = dialtone ? dialtone : mp->tone;
3789        else if (dialmth == XYDM_P)     /* Pulse */
3790          s = dialpulse ? dialpulse : mp->pulse;
3791        if (s) if (*s) {
3792            ttslow(s, mp->dial_rate);
3793            if (xx_ok)          /* Get modem's response */
3794              (*xx_ok)(5,1);    /* (but ignore it...) */
3795        }
3796    }
3797    if (func_code == 1) {               /* ANSWER (not DIAL) */
3798        char *s;
3799        s = dialaaon ? dialaaon : mp->aa_on_str;
3800        if (!s) s = "";
3801        if (*s) {
3802            ttslow(s, mp->dial_rate);
3803            if (xx_ok)                  /* Get modem's response */
3804              (*xx_ok)(5,1);            /* (but ignore it...) */
3805        } else {
3806            printf(
3807"WARNING - I don't know how to enable autoanswer for this modem.\n"
3808                   );
3809        } /* And skip all the phone-number & dialing stuff... */
3810        alarm(waitct);                  /* This much time allowed. */
3811        debug(F101,"ckdial ANSWER waitct","",waitct);
3812
3813    } else {                            /* DIAL (not ANSWER) */
3814
3815        if (dialsta != DIA_PART) {      /* Last dial was not partial */
3816
3817            char *s = "";
3818#ifdef COMMENT
3819            s = dialaaoff ? dialaaoff : mp->aa_off_str;
3820#endif /* COMMENT */
3821            if (s) if (*s) {
3822                ttslow(s, mp->dial_rate);
3823                if (xx_ok)              /* Get modem's response */
3824                  (*xx_ok)(5,1);        /* (but ignore it...) */
3825            }
3826
3827            /* Put modem into dialing mode, if the modem requires it. */
3828
3829            if (mp->dmode_str && *(mp->dmode_str)) {
3830                ttslow(mp->dmode_str, mp->dial_rate);
3831                savalrm = signal(SIGALRM,dialtime);
3832                alarm(10);
3833                /* Wait for prompt, if any expected */
3834                if (mp->dmode_prompt && *(mp->dmode_prompt)) {
3835                    waitfor(mp->dmode_prompt);
3836                    msleep(300);
3837                }
3838                alarm(0);               /* Turn off alarm on dialing prompts */
3839                signal(SIGALRM,savalrm); /* Restore alarm */
3840                ttflui(); /* Clear out stuff from waking modem up */
3841            }
3842        }
3843
3844/* Allocate a buffer for the dialing string. */
3845
3846#ifdef DYNAMIC
3847        if (!lbuf) {                    /* If, for some reason, this is NULL */
3848            if (!(lbuf = malloc(LBUFL+1))) { /* allocate it... */
3849                dialsta = DIA_IE;
3850#ifdef NTSIG
3851                ckThreadEnd(threadinfo);
3852#endif /* NTSIG */
3853                SIGRETURN;
3854            }
3855        }
3856#endif /* DYNAMIC */
3857
3858        if (mdmcapas & CKD_AT && dialsta != DIA_PART) {
3859            sprintf(lbuf,"ATS2=%d\015", /* Set the escape character */
3860                    dialesc ? dialesc : mp->esc_char);
3861            ttslow(lbuf, mp->dial_rate);
3862            if (xx_ok)                  /* Get modem's response */
3863              x = (*xx_ok)(5,1);
3864            if (x < 0)
3865              printf(
3866                     "WARNING - Problem setting modem's escape character\n"
3867                     );
3868        }
3869        s = dialcmd ? dialcmd : mp->dial_str;
3870
3871        if ((int)strlen(s) + (int)strlen(telnbr) > LBUFL) {
3872            printf("DIAL command + phone number too long!\n");
3873            dreset();
3874#ifdef DYNAMIC
3875            if (lbuf) free(lbuf); lbuf = NULL;
3876            if (rbuf) free(rbuf); rbuf = NULL;
3877            if (fbuf) free(fbuf); fbuf = NULL;
3878#endif /* DYNAMIC */
3879#ifdef NTSIG
3880            ckThreadEnd(threadinfo);
3881#endif /* NTSIG */
3882            SIGRETURN;   /* No conversation with modem to complete dialing */
3883        }
3884
3885        sprintf(lbuf, s, telnbr);
3886
3887        debug(F110,"dialing",lbuf,0);
3888        ttslow(lbuf,mp->dial_rate);     /* Send the dialing string */
3889
3890        fail_code = F_MODEM;            /* New default failure code changes */
3891        dial_what = DW_DIAL;            /* and our state, too. */
3892        if (dialdpy) {                  /* If showing progress */
3893            p = ck_time();              /* get current time; */
3894            if (*p) printf(" Dialing: %s...\n",p);
3895        }
3896        alarm(waitct);                  /* This much time allowed. */
3897        debug(F101,"ckdial waitct","",waitct);
3898
3899#ifndef MINIDIAL
3900#ifdef OLDMODEMS
3901        switch (mymdmtyp) {
3902          case n_RACAL:                 /* Acknowledge dialing string */
3903            sleep(3);
3904            ttflui();
3905            ttoc('\015');
3906            break;
3907          case n_VENTEL:
3908            waitfor("\012\012");        /* Ignore the first two strings */
3909            break;
3910          default:
3911            break;
3912        }
3913#endif /* OLDMODEMS */
3914#endif /* MINIDIAL */
3915    }
3916
3917/* Check for connection */
3918
3919    mdmstat = 0;                        /* No status yet */
3920    strcpy(lbuf,"");                    /* Default reason for failure */
3921    debug(F101,"dial awaiting response, mymdmtyp","",mymdmtyp);
3922
3923#ifndef NOSPL
3924    modemmsg[0] = NUL;
3925#endif /* NOSPL */
3926    while (mdmstat == 0) {              /* Till we get a result or time out */
3927
3928        if ((mdmcapas & CKD_AT) && nonverbal) { /* AT command set */
3929            gethrn();                   /* In digit result mode */
3930            if (partial && dialsta == DIA_ERR) {
3931                /*
3932                   If we get an error here, the phone is still
3933                   off hook so we have to hang it up.
3934                */
3935                dialhup();
3936                dialsta = DIA_ERR;      /* (because dialhup() changes it) */
3937            }
3938            continue;
3939
3940        } else if (mymdmtyp == n_UNKNOWN) { /* Unknown modem type */
3941            int x, y = waitct;
3942            mdmstat = D_FAILED;         /* Assume failure. */
3943            while (y-- > -1) {
3944                x = ttchk();
3945                if (x > 0) {
3946                    if (x > LBUFL) x = LBUFL;
3947                    x = ttxin(x,(CHAR *)lbuf);
3948                    if ((x > 0) && dialdpy) conol(lbuf);
3949                } else if (network && x < 0) { /* Connection dropped */
3950#ifdef NTSIG
3951                    ckThreadEnd(threadinfo);
3952#endif /* NTSIG */
3953                    dialsta = DIA_IO;   /* Call it an I/O error */
3954#ifdef DYNAMIC
3955                    if (lbuf) free(lbuf); lbuf = NULL;
3956                    if (rbuf) free(rbuf); rbuf = NULL;
3957                    if (fbuf) free(fbuf); fbuf = NULL;
3958#endif /* DYNAMIC */
3959                    SIGRETURN;
3960                }
3961                x = ttgmdm();           /* Try to read modem signals */
3962                if (x < 0) break;       /* Can't, fail. */
3963                if (x & BM_DCD) {       /* Got signals OK.  Carrier present? */
3964                    mdmstat = CONNECTED; /* Yes, done. */
3965                    break;
3966                }                       /* No, keep waiting. */
3967                sleep(1);
3968            }
3969            continue;
3970        }
3971
3972        for (n = -1; n < LBUFL-1; ) {   /* Accumulate modem response */
3973            int xx;
3974            c2 = (char) (xx = ddinc(0)); /* Read a character, blocking */
3975            if (xx < 1)                 /* Ignore NULs and errors */
3976              continue;                 /* (Timeout will handle errors) */
3977            else                        /* Real character, keep it */
3978              lbuf[++n] = (char) (c2 & 0177);
3979            dialoc(lbuf[n]);            /* Maybe echo it  */
3980            if (mdmcapas & CKD_V25) {   /* V.25bis dialing... */
3981/*
3982  This assumes that V.25bis indications are all at least 3 characters long
3983  and are terminated by either CRLF or LFCR.
3984*/
3985                if (mymdmtyp == n_CCITT) {
3986                    if (n < 3) continue;
3987                    if ((lbuf[n] == CR) && (lbuf[n-1] == LF)) break;
3988                    if ((lbuf[n] == LF) && (lbuf[n-1] == CR)) break;
3989                }
3990#ifndef MINIDIAL
3991                else if (mymdmtyp == n_DIGITEL) {
3992                    if (((lbuf[n] == CR) && (lbuf[n-1] == LF)) ||
3993                        ((lbuf[n] == LF) && (lbuf[n-1] == CR)))
3994                      break;
3995                    else
3996                      continue;
3997                }
3998#endif /* MINIDIAL */
3999            } else {                    /* All others, break on CR or LF */
4000                if ( lbuf[n] == CR || lbuf[n] == LF ) break;
4001            }
4002        }
4003        lbuf[++n] = '\0';               /* Terminate response from modem */
4004        debug(F111,"ckdial modem response",lbuf,n);
4005#ifndef NOSPL
4006        strncpy(modemmsg,lbuf,79);      /* Call result message */
4007        {
4008            int x;                      /* Strip junk from end */
4009            x = (int)strlen(modemmsg) - 1;
4010            while ((modemmsg[x] < (char) 33) && (x > -1))
4011              modemmsg[x--] = NUL;
4012        }
4013#endif /* NOSPL */
4014        if (mdmcapas & CKD_AT) {        /* Hayes AT command set */
4015            gethrw();                   /* in word result mode */
4016            if (partial && dialsta == DIA_ERR) {
4017                dialhup();
4018                dialsta = DIA_ERR;      /* (because dialhup() changes it) */
4019            }
4020            continue;
4021        } else if (mdmcapas & CKD_V25) { /* CCITT command set */
4022            if (didweget(lbuf,"VAL")) { /* Dial command confirmation */
4023#ifndef MINIDIAL
4024                if (mymdmtyp == n_CCITT)
4025#endif /* MINIDIAL */
4026                  continue;             /* Go back and read more */
4027#ifndef MINIDIAL
4028/* Digitel doesn't give an explicit connect confirmation message */
4029                else {
4030                    int n;
4031                    for (n = -1; n < LBUFL-1; ) {
4032                        lbuf[++n] = c2 = (char) (ddinc(0) & 0177);
4033                        dialoc(lbuf[n]);
4034                        if (((lbuf[n] == CR) && (lbuf[n-1] == LF)) ||
4035                            ((lbuf[n] == LF) && (lbuf[n-1] == CR)))
4036                          break;
4037                    }
4038                    mdmstat = CONNECTED; /* Assume we're connected */
4039                    if (dialdpy && carrier != CAR_OFF) {
4040                        sleep(1);       /* Wait a second */
4041                        n = ttgmdm();   /* Try to read modem signals */
4042                        if ((n > -1) && ((n & BM_DCD) == 0))
4043                          printf("WARNING - no carrier\n");
4044                    }
4045                }
4046#endif /* MINIDIAL */
4047
4048                /* Standard V.25bis stuff */
4049
4050            } else if (didweget(lbuf,"CNX")) { /* Connected */
4051                mdmstat = CONNECTED;
4052            } else if (didweget(lbuf, "INV")) {
4053                mdmstat = D_FAILED;     /* Command error */
4054                dialsta = DIA_ERR;
4055                strcpy(lbuf,"INV");
4056
4057            } else if (didweget(lbuf,"CFI")) { /* Call Failure */
4058
4059                if (didweget(lbuf,"AB")) { /* Interpret reason code */
4060                    strcpy(lbuf,"AB: Timed out");
4061                    dialsta = DIA_TIMO;
4062                } else if (didweget(lbuf,"CB")) {
4063                    strcpy(lbuf,"CB: Local DCE Busy");
4064                    dialsta = DIA_NRDY;
4065                } else if (didweget(lbuf,"ET")) {
4066                    strcpy(lbuf,"ET: Busy");
4067                    dialsta = DIA_BUSY;
4068                } else if (didweget(lbuf, "NS")) {
4069                    strcpy(lbuf,"NS: Number not stored");
4070                    dialsta = DIA_ERR;
4071                } else if (didweget(lbuf,"NT")) {
4072                    strcpy(lbuf,"NT: No answer");
4073                    dialsta = DIA_NOAN;
4074                } else if (didweget(lbuf,"RT")) {
4075                    strcpy(lbuf,"RT: Ring tone");
4076                    dialsta = DIA_RING;
4077                } else if (didweget(lbuf,"PV")) {
4078                    strcpy(lbuf,"PV: Parameter value error");
4079                    dialsta = DIA_ERR;
4080                } else if (didweget(lbuf,"PS")) {
4081                    strcpy(lbuf,"PS: Parameter syntax error");
4082                    dialsta = DIA_ERR;
4083                } else if (didweget(lbuf,"MS")) {
4084                    strcpy(lbuf,"MS: Message syntax error");
4085                    dialsta = DIA_ERR;
4086                } else if (didweget(lbuf,"CU")) {
4087                    strcpy(lbuf,"CU: Command unknown");
4088                    dialsta = DIA_ERR;
4089                } else if (didweget(lbuf,"FC")) {
4090                    strcpy(lbuf,"FC: Forbidden call");
4091                    dialsta = DIA_NOAC;
4092                }
4093                mdmstat = D_FAILED;
4094            } else if (didweget(lbuf,"INC")) { /* Incoming Call */
4095                strcpy(lbuf,"INC: Incoming call");
4096                dialsta = DIA_RING;
4097                mdmstat = D_FAILED;
4098            } else if (didweget(lbuf,"DLC")) { /* Delayed Call */
4099                strcpy(lbuf,"DLC: Delayed call");
4100                dialsta = DIA_NOAN;
4101                mdmstat = D_FAILED;
4102            } else                      /* Response was probably an echo. */
4103#ifndef MINIDIAL
4104              if (mymdmtyp == n_CCITT)
4105#endif /* MINIDIAL */
4106                continue;
4107#ifndef MINIDIAL
4108              else                      /* Digitel: If no error, connect. */
4109                mdmstat = CONNECTED;
4110#endif /* MINIDIAL */
4111            break;
4112
4113        } else if (n) {                 /* Non-Hayes-compatibles... */
4114            switch (mymdmtyp) {
4115#ifndef MINIDIAL
4116              case n_ATTMODEM:
4117                /* Careful - "Connected" / "Not Connected" */
4118                if (didweget(lbuf,"Busy")) {
4119                    mdmstat = D_FAILED;
4120                    dialsta = DIA_BUSY;
4121                } else if (didweget(lbuf,"Not connected") ||
4122                           didweget(lbuf,"Not Connected")) {
4123                    mdmstat = D_FAILED;
4124                    dialsta = DIA_NOCA;
4125                } else if (didweget(lbuf,"No dial tone") ||
4126                           didweget(lbuf,"No Dial Tone")) {
4127                    mdmstat = D_FAILED;
4128                    dialsta = DIA_NODT;
4129                } else if (didweget(lbuf,"No answer") ||
4130                           didweget(lbuf,"No Answer")) {
4131                    mdmstat = D_FAILED;
4132                    dialsta = DIA_NOAN;
4133                } else if (didweget(lbuf,"Answered") ||
4134                           didweget(lbuf,"Connected")) {
4135                    mdmstat = CONNECTED;
4136                    dialsta = DIA_OK;
4137                }
4138                break;
4139
4140              case n_ATTISN:
4141                if (didweget(lbuf,"ANSWERED")) {
4142                    mdmstat = CONNECTED;
4143                    dialsta = DIA_OK;
4144                } else if (didweget(lbuf,"BUSY")) {
4145                    mdmstat = D_FAILED;
4146                    dialsta = DIA_BUSY;
4147                } else if (didweget(lbuf,"DISCONNECT")) {
4148                    mdmstat = D_FAILED;
4149                    dialsta = DIA_DISC;
4150                } else if (didweget(lbuf,"NO ANSWER")) {
4151                    mdmstat = D_FAILED;
4152                    dialsta = DIA_NOAN;
4153                } else if (didweget(lbuf,"WRONG ADDRESS")) {
4154                    mdmstat = D_FAILED;
4155                    dialsta = DIA_NOAC;
4156                }
4157                break;
4158
4159              case n_ATTDTDM:
4160                if (didweget(lbuf,"ANSWERED")) {
4161                    mdmstat = CONNECTED;
4162                } else if (didweget(lbuf,"BUSY")) {
4163                    mdmstat = D_FAILED;
4164                    dialsta = DIA_BUSY;
4165                } else if (didweget(lbuf,"CHECK OPTIONS")) {
4166                    mdmstat = D_FAILED;
4167                    dialsta = DIA_ERR;
4168                } else if (didweget(lbuf,"DISCONNECTED")) {
4169                    mdmstat = D_FAILED;
4170                    dialsta = DIA_DISC;
4171                } else if (didweget(lbuf,"DENIED")) {
4172                    mdmstat = D_FAILED;
4173                    dialsta = DIA_NOAC;
4174                }
4175#ifdef DEBUG
4176#ifdef ATT6300
4177                /* Horrible hack lost in history. */
4178                else if (deblog && didweget(lbuf,"~~"))
4179                  mdmstat = CONNECTED;
4180#endif /* ATT6300 */
4181#endif /* DEBUG */
4182                break;
4183               
4184#ifdef OLDMODEMS
4185              case n_CERMETEK:
4186                if (didweget(lbuf,"\016A")) {
4187                    mdmstat = CONNECTED;
4188                    ttslow("\016U 1\015",200); /* Make transparent*/
4189                }
4190                break;
4191
4192              case n_DF03:
4193                /* Because response lacks CR or NL . . . */
4194                c = (char) (ddinc(0) & 0177);
4195                dialoc(c);
4196                debug(F000,"dial df03 got","",c);
4197                if ( c == 'A' ) mdmstat = CONNECTED;
4198                if ( c == 'B' ) mdmstat = D_FAILED;
4199                break;
4200
4201              case n_DF100:          /* DF100 has short response codes */
4202                if (strcmp(lbuf,"A") == 0) {
4203                    mdmstat = CONNECTED; /* Attached */
4204                    dialsta = DIA_OK;
4205                } else if (strcmp(lbuf,"N") == 0) {
4206                    mdmstat = D_FAILED;
4207                    dialsta = DIA_NOAN; /* No answer or no dialtone */
4208                } else if (strcmp(lbuf,"E") == 0 || /* Error */
4209                           strcmp(lbuf,"R") == 0) { /* "Ready" (?) */
4210                    mdmstat = D_FAILED;
4211                    dialsta = DIA_ERR;  /* Command error */
4212                }
4213                /* otherwise fall thru... */
4214
4215              case n_DF200:
4216                if (didweget(lbuf,"Attached")) {
4217                    mdmstat = CONNECTED;
4218                    dialsta = DIA_OK;
4219                    /*
4220                     * The DF100 will respond with "Attached" even if DTR
4221                     * and/or carrier are not present.  Another reason to
4222                     * (also) wait for carrier?
4223                     */
4224                } else if (didweget(lbuf,"Busy")) {
4225                    mdmstat = D_FAILED;
4226                    dialsta = DIA_BUSY;
4227                } else if (didweget(lbuf,"Disconnected")) {
4228                    mdmstat = D_FAILED;
4229                    dialsta = DIA_DISC;
4230                } else if (didweget(lbuf,"Error")) {
4231                    mdmstat = D_FAILED;
4232                    dialsta = DIA_ERR;
4233                } else if (didweget(lbuf,"No answer")) {
4234                    mdmstat = D_FAILED;
4235                    dialsta = DIA_NOAN;
4236                } else if (didweget(lbuf,"No dial tone")) {
4237                    mdmstat = D_FAILED;
4238                    dialsta = DIA_NODT;
4239                } else if (didweget(lbuf,"Speed:)")) {
4240                    mdmstat = D_FAILED;
4241                    dialsta = DIA_ERR;
4242                }
4243                /*
4244                 * It appears that the "Speed:..." response comes after an
4245                 * "Attached" response, so this is never seen.  HOWEVER,
4246                 * it would be very handy to detect this and temporarily
4247                 * reset the speed, since it's a nuisance otherwise.
4248                 * If we wait for some more input from the modem, how do
4249                 * we know if it's from the remote host or the modem?
4250                 * Carrier reportedly doesn't get set until after the
4251                 * "Speed:..." response (if any) is sent.  Another reason
4252                 * to (also) wait for carrier.
4253                 */
4254                break;
4255
4256              case n_GDC:
4257                if (didweget(lbuf,"ON LINE"))
4258                  mdmstat = CONNECTED;
4259                else if (didweget(lbuf,"NO CONNECT"))
4260                  mdmstat = D_FAILED;
4261                break;
4262
4263              case n_PENRIL:
4264                if (didweget(lbuf,"OK")) {
4265                    mdmstat = CONNECTED;
4266                } else if (didweget(lbuf,"BUSY")) {
4267                    mdmstat = D_FAILED;
4268                    dialsta = DIA_BUSY;
4269                    } else if (didweget(lbuf,"NO RING")) {
4270                        mdmstat = D_FAILED;
4271                        dialsta = DIA_NOCA;
4272                    }
4273                break;
4274
4275              case n_RACAL:
4276                if (didweget(lbuf,"ON LINE"))
4277                  mdmstat = CONNECTED;
4278                else if (didweget(lbuf,"FAILED CALL"))
4279                  mdmstat = D_FAILED;
4280                break;
4281#endif /* OLDMODEMS */
4282
4283              case n_ROLM:
4284                if (didweget(lbuf,"CALLING"))
4285                  mdmstat = 0;
4286                else if (didweget(lbuf,"COMPLETE"))
4287                  mdmstat = CONNECTED;
4288                else if (didweget(lbuf,"FAILED") ||
4289                         didweget(lbuf,"ABANDONDED")) {
4290                    mdmstat = D_FAILED;
4291                    dialsta = DIA_NOCA;
4292                } else if (didweget(lbuf,"NOT AVAILABLE") ||
4293                           didweget(lbuf,"LACKS PERMISSION") ||
4294                           didweget(lbuf,"NOT A DATALINE") ||
4295                           didweget(lbuf,"INVALID DATA LINE NUMBER") ||
4296                           didweget(lbuf,"INVALID GROUP NAME")) {
4297                    mdmstat = D_FAILED;
4298                    dialsta = DIA_NOAC;
4299                } else if (didweget(lbuf,"BUSY")) {
4300                    mdmstat = D_FAILED;
4301                    dialsta = DIA_BUSY;
4302                } else if (didweget(lbuf,"DOES NOT ANSWER")) {
4303                    mdmstat = D_FAILED;
4304                    dialsta = DIA_NOAN;
4305                }
4306                break;
4307
4308#ifdef OLDMODEMS
4309              case n_VENTEL:
4310                if (didweget(lbuf,"ONLINE!") ||
4311                    didweget(lbuf,"Online!")) {
4312                    mdmstat = CONNECTED;
4313                } else if (didweget(lbuf,"BUSY") ||
4314                           didweget(lbuf,"Busy")) {
4315                    mdmstat = D_FAILED;
4316                    dialsta = DIA_BUSY;
4317                } else if (didweget(lbuf,"DEAD PHONE")) {
4318                    mdmstat = D_FAILED;
4319                    dialsta = DIA_DISC;
4320                }
4321                break;
4322
4323              case n_CONCORD:
4324                if (didweget(lbuf,"INITIATING"))
4325                  mdmstat = CONNECTED;
4326                else if (didweget(lbuf,"BUSY")) {
4327                    mdmstat = D_FAILED;                 
4328                    dialsta = DIA_BUSY;
4329                } else if (didweget(lbuf,"CALL FAILED")) {
4330                    mdmstat = D_FAILED;
4331                    dialsta = DIA_NOCA;
4332                }
4333                break;
4334#endif /* OLDMODEMS */
4335
4336              case n_MICROCOM:
4337                /* "RINGBACK" means phone line ringing, continue */
4338                if (didweget(lbuf,"NO CONNECT")) {
4339                    mdmstat = D_FAILED;
4340                    dialsta = DIA_NOCA;
4341                } else if (didweget(lbuf,"BUSY")) {
4342                    mdmstat = D_FAILED;
4343                    dialsta = DIA_BUSY;
4344                } else if (didweget(lbuf,"NO DIALTONE")) {
4345                    mdmstat = D_FAILED;
4346                    dialsta = DIA_NODT;
4347                } else if (didweget(lbuf,"COMMAND ERROR")) {
4348                    mdmstat = D_FAILED;
4349                    dialsta = DIA_ERR;
4350                } else if (didweget(lbuf,"IN USE")) {
4351                    mdmstat = D_FAILED;
4352                    dialsta = DIA_NOAC;
4353                } else if (didweget(lbuf,"CONNECT")) {
4354                    mdmstat = CONNECTED;
4355                    /* trailing speed ignored */
4356                }
4357                break;
4358
4359#endif /* MINIDIAL */
4360              default:
4361                printf(
4362                    "PROGRAM ERROR - No response handler for modem type %d\n",
4363                       mymdmtyp);
4364                mdmstat = D_FAILED;
4365                dialsta = DIA_ERR;
4366            }
4367        }
4368    } /* while (mdmstat == 0) */
4369
4370    debug(F101,"ckdial alarm off","",x);
4371    alarm(0);
4372    if (mdmstat == D_FAILED )   {       /* Failure detected by modem  */
4373        dialfail(F_MODEM);
4374#ifdef NTSIG
4375        ckThreadEnd(threadinfo);
4376#endif /* NTSIG */
4377        SIGRETURN;
4378    } else if (mdmstat == D_PARTIAL )   { /* Partial dial command OK */
4379        msleep(500);
4380        debug(F100,"dial partial","",0);
4381    } else {                            /* Call was completed */
4382        msleep(1000);                   /* In case DTR blinks  */
4383        debug(F100,"dial succeeded","",0);
4384        if (
4385#ifndef MINIDIAL
4386            mymdmtyp != n_ROLM          /* Rolm has weird modem signaling */
4387#else
4388            1
4389#endif /* MINIDIAL */
4390            ) {
4391            alarm(3);                   /* In case ttpkt() gets stuck... */
4392            ttpkt(speed,FLO_DIAX,parity); /* Cancel dialing state ioctl */
4393        }
4394    }
4395    dreset();                           /* Reset alarms and signals. */
4396    if (!quiet && !backgrd) {
4397        if (dialdpy && (p = ck_time())) { /* If DIAL DISPLAY ON, */
4398            printf(" %sall complete: %s.\n", /* include timestamp.  */
4399                   (mdmstat == D_PARTIAL) ?
4400                   "Partial c" :
4401                   "C",
4402                   p );
4403        } else {
4404            printf (" %sall complete.\n",
4405                    (mdmstat == D_PARTIAL) ?
4406                    "Partial c" :
4407                    "C"
4408                    );
4409        }
4410    }
4411
4412#ifdef DYNAMIC
4413    if (lbuf) free(lbuf); lbuf = NULL;
4414    if (rbuf) free(rbuf); rbuf = NULL;
4415    if (fbuf) free(fbuf); fbuf = NULL;
4416#endif /* DYNAMIC */
4417    dialsta = (mdmstat == D_PARTIAL) ? DIA_PART : DIA_OK;
4418#ifdef NTSIG
4419    ckThreadEnd(threadinfo);
4420#endif /* NTSIG */
4421    SIGRETURN;
4422}
4423
4424
4425static SIGTYP
4426#ifdef CK_ANSIC
4427faildial(void * threadinfo)
4428#else /* Not CK_ANSIC */
4429faildial(threadinfo) VOID * threadinfo;
4430#endif /* CK_ANSIC */
4431/* faildial */ {
4432    debug(F100,"longjmp returns to dial routine","",0);
4433    dialfail(fail_code);
4434    SIGRETURN;
4435}
4436
4437/*
4438  nbr = number to dial (string)
4439  x1  = Retry counter
4440  x2  = Number counter
4441  fc  = Function code:
4442        0 == DIAL
4443        1 == ANSWER
4444        2 == INIT/CONFIG
4445        3 == PARTIAL DIAL
4446*/
4447int
4448#ifdef OLD_DIAL
4449ckdial(nbr) char *nbr;
4450#else
4451ckdial(nbr, x1, x2, fc) char *nbr; int x1, x2, fc;
4452#endif /* OLD_DIAL */
4453/* ckdial */ {
4454#define ERMSGL 50
4455    char errmsg[ERMSGL], *erp;          /* For error messages */
4456    int n = F_TIME;
4457    char *s;
4458    long spdmax;
4459
4460    char *mmsg = "Sorry, DIAL memory buffer can't be allocated\n";
4461
4462    partial = 0;
4463    if (fc == 3) {                      /* Partial dial requested */
4464        partial = 1;                    /* Set flag */
4465        fc = 0;                         /* Treat like regular dialing */
4466    }
4467    func_code = fc;                     /* Make global to this module */
4468    telnbr = nbr;
4469    mymdmtyp = mdmtyp;
4470    if (mymdmtyp < 0) {                 /* Whoa, network dialing... */
4471        if (mdmsav > -1)
4472          mymdmtyp = mdmsav;
4473    }
4474    if (mymdmtyp < 0) {
4475        printf("Invalid modem type %d - internal error.\n",mymdmtyp);
4476        dialsta = DIA_NOMO;
4477        return 0;
4478    }
4479    dial_what = DW_NOTHING;             /* Doing nothing at first. */
4480    nonverbal = 0;
4481
4482/* These are ONLY for the purpose of interpreting numeric result codes. */
4483
4484    is_rockwell =
4485#ifdef MINIDIAL
4486      0
4487#else
4488      mymdmtyp == n_RWV32 || mymdmtyp == n_RWV32B || mymdmtyp == n_RWV34 ||
4489        mymdmtyp == n_BOCA || mymdmtyp == n_TELEPATH || mymdmtyp == n_CARDINAL
4490#endif /* MINIDIAL */
4491        ;
4492
4493    is_hayeshispd =
4494#ifdef MINIDIAL
4495      0
4496#else
4497      mymdmtyp == n_H_ULTRA || mymdmtyp == n_H_ACCURA || n_PPI
4498#endif /* MINIDIAL */
4499        ;
4500
4501#ifdef OLDTBCODE
4502#ifndef MINIDIAL
4503    tbmodel = TB_UNK;                   /* Initialize Telebit model */
4504#endif /* MINIDIAL */
4505#endif /* OLDTBCODE */
4506
4507    mp = modemp[mymdmtyp - 1];          /* Set pointer to modem info */
4508    if (!mp) {
4509        printf("Sorry, handler for this modem type not yet filled in.\n");
4510        dialsta = DIA_NOMO;
4511        return 0;
4512    }
4513    debug(F110,"dial number",telnbr,0);
4514#ifdef COMMENT
4515    debug(F110,"dial prefix",(dialnpr ? dialnpr : ""), 0);
4516#endif /* COMMENT */
4517
4518#ifdef DYNAMIC
4519    if (!(lbuf = malloc(LBUFL+1))) {    /* Allocate input line buffer */
4520        printf("%s", mmsg);
4521        dialsta = DIA_IE;
4522        return 0;
4523    }
4524    *lbuf = NUL;
4525    debug(F101,"DIAL lbuf malloc ok","",LBUFL+1);
4526
4527    if (!rbuf) {    /* This one might already have been allocated by getok() */
4528        if (!(rbuf = malloc(RBUFL+1))) {    /* Allocate input line buffer */
4529            printf("%s", mmsg);
4530            dialsta = DIA_IE;
4531            if (lbuf) free(lbuf); lbuf = NULL;
4532            return 0;
4533        } else
4534          debug(F101,"DIAL rbuf malloc ok","",RBUFL+1);
4535    }
4536    if (!(fbuf = malloc(FULLNUML+1))) {    /* Allocate input line buffer */
4537        printf("%s", mmsg);
4538        dialsta = DIA_IE;
4539        if (lbuf) free(lbuf); lbuf = NULL;
4540        if (rbuf) free(rbuf); rbuf = NULL;
4541        return 0;
4542    }
4543    debug(F101,"DIAL fbuf malloc ok","",FULLNUML+1);
4544#endif /* DYNAMIC */
4545
4546    /* NOTE: mdmtyp, not mymdmtyp */
4547
4548    if (ttopen(ttname,&local,mdmtyp,0) < 0) { /* Open, no carrier wait */
4549        erp = errmsg;
4550        if ((int)strlen(ttname) < (ERMSGL - 18))
4551          sprintf(erp,"Sorry, can't open %s",ttname);
4552        else
4553          sprintf(erp,"Sorry, can't open device");
4554        perror(errmsg);
4555        dialsta = DIA_OPEN;
4556#ifdef DYNAMIC
4557        if (lbuf) free(lbuf); lbuf = NULL;
4558        if (rbuf) free(rbuf); rbuf = NULL;
4559        if (fbuf) free(fbuf); fbuf = NULL;
4560#endif /* DYNAMIC */
4561        return 0;
4562    }
4563
4564/* Condition console terminal and communication line */
4565
4566    /* Place line into "clocal" dialing state, */
4567    /* important mainly for System V UNIX.     */
4568
4569    if (ttpkt(speed,FLO_DIAL,parity) < 0) {
4570        ttclos(0);                      /* If ttpkt fails do all this... */
4571        if (ttopen(ttname,&local,mymdmtyp,0) < 0) {
4572            erp = errmsg;
4573            if ((int)strlen(ttname) < (ERMSGL - 18))
4574              sprintf(erp,"Sorry, can't reopen %s",ttname);
4575            else
4576              sprintf(erp,"Sorry, can't reopen device");
4577            perror(errmsg);
4578            dialsta = DIA_OPEN;
4579#ifdef DYNAMIC
4580            if (lbuf) free(lbuf); lbuf = NULL;
4581            if (rbuf) free(rbuf); rbuf = NULL;
4582            if (fbuf) free(fbuf); fbuf = NULL;
4583#endif /* DYNAMIC */
4584            return 0;
4585        }                               /* And try again. */
4586        if ((ttpkt(speed,FLO_DIAL,parity) < 0)
4587#ifdef UNIX
4588        && (strcmp(ttname,"/dev/null"))
4589#else
4590#ifdef OSK
4591        && (strcmp(ttname,"/nil"))
4592#endif /* OSK */
4593#endif /* UNIX */
4594            ) {
4595            printf("Sorry, Can't condition communication line\n");
4596            printf("Try 'set line %s' again\n",ttname);
4597            dialsta = DIA_OPEN;
4598#ifdef DYNAMIC
4599            if (lbuf) free(lbuf); lbuf = NULL;
4600            if (rbuf) free(rbuf); rbuf = NULL;
4601            if (fbuf) free(fbuf); fbuf = NULL;
4602#endif /* DYNAMIC */
4603            return 0;
4604        }
4605    }
4606    /* Modem's escape sequence... */
4607
4608    c = (char) (dialesc ? dialesc : mp->esc_char);
4609    mdmcapas = dialcapas ? dialcapas : mp->capas;
4610
4611    xx_ok = mp->ok_fn;                  /* Pointer to response reader */
4612
4613    if (mdmcapas & CKD_AT) {            /* Hayes compatible */
4614        escbuf[0] = c;
4615        escbuf[1] = c;
4616        escbuf[2] = c;
4617        escbuf[3] = NUL;
4618        /* In case this modem type is user-defined */
4619        if (!xx_ok) xx_ok = getok;
4620    } else {                            /* Other */
4621        escbuf[0] = c;
4622        escbuf[1] = NUL;
4623        /* In case user-defined */
4624        if (mdmcapas & CKD_V25) if (!xx_ok) xx_ok = getok;
4625    }
4626
4627    /* Partial dialing */
4628
4629    if (mdmcapas & CKD_AT
4630#ifndef MINIDIAL
4631        || mymdmtyp == n_MICROCOM
4632#endif /* MINIDIAL */
4633        ) {
4634        int x;
4635        x = (int) strlen(telnbr);
4636        if (x > 0) {
4637            if (telnbr[x-1] == ';') {
4638                partial = 1;
4639            } else if (partial) {
4640                sprintf(fbuf,"%s;", telnbr); /* add one */
4641                telnbr = fbuf;
4642            }
4643        }
4644    }
4645    msleep(500);
4646
4647    /* Interdigit waits for tone dial */
4648
4649    if (fc == 1) {                      /* ANSWER */
4650        waitct = (dialatmo > -1) ? dialatmo : 0;
4651    } else {                            /* DIAL */
4652        if (dialtmo < 1) {              /* Automatic computation. */
4653            waitct = 1 * (int)strlen(telnbr) ; /* Worst case dial time */
4654            waitct += mp->dial_time;    /* dialtone + completion wait times */
4655            for (s = telnbr; *s; s++) { /* add in pause characters time */
4656                for (p = mp->pause_chars; *p; p++)
4657                  if (*s == *p) {
4658                      waitct += mp->pause_time;
4659                      break;
4660                  }
4661            }
4662#ifdef COMMENT
4663#ifndef MINIDIAL
4664#ifdef OLDTBCODE
4665        if (mymdmtyp == n_TBPEP)
4666          waitct += 30;                 /* Longer connect wait for PEP call */
4667#endif /* OLDTBCODE */
4668#endif /* MINIDIAL */
4669#endif /* COMMENT */
4670        } else waitct = dialtmo;        /* User-specified timeout */
4671    }
4672
4673/*
4674  waitct is our alarm() timer.
4675  mdmwait is how long we tell the modem to wait for carrier.
4676  We set mdmwait to be 5 seconds less than waitct, to increase the
4677  chance that we get a response from the modem before timing out.
4678*/
4679    if (waitct < 0) waitct = 0;
4680    if (fc == 0) {                      /* DIAL */
4681
4682#ifdef XWAITCT
4683        /* Addtl wait slop can be defined at compile time */   
4684        waitct += XWAITCT;
4685#endif /* XWAITCT */
4686        if (waitct < 25) waitct = 25;
4687        mdmwait = waitct - mdmwaitd;
4688    } else {                            /* ANSWER */
4689#ifdef COMMENT
4690/*
4691  This is wrong.  mdmwait is the value given to S7 in Hayeslike modems.
4692  When in autoanswer mode, this is the amount of time the modem waits for
4693  carrier once ringing starts.  Whereas waitct is the timeout given to the
4694  ANSWER command, which is an entirely different thing.  Since the default
4695  ANSWER timeout is 0 (meaning "wait forever"), the following statement sets
4696  S7 to 0, which, on some modems (like the USR Sportster) makes it hang up
4697  and report NO CARRIER the instant the phone rings.
4698*/     
4699        mdmwait = waitct;
4700#else
4701        mdmwait = 60;                   /* Always wait 60 seconds. */
4702#endif /* COMMENT */
4703
4704    }
4705    if (!quiet && !backgrd) {           /* Print information messages. */
4706        if (fc == 1)
4707          printf(" Waiting for phone call...\n");
4708        else
4709          printf(" %srying: %s...\n", x1 > 0 ? "Ret" : "T", telnbr);
4710        if (x1 == 0 && x2 == 0 && dialsta != DIA_PART) {
4711            if (network) {
4712                printf(" Via modem server: %s, modem: %s\n",
4713                       ttname, gmdmtyp() );
4714            } else {
4715                printf(" Device: %s, modem: %s",
4716                       ttname, gmdmtyp() );
4717                if (speed > -1L)
4718                  printf(", speed: %ld\n", speed);
4719                else
4720                  printf(", speed: (unknown)\n");
4721            }
4722            spdmax = dialmax > 0L ? dialmax : mp->max_speed;
4723
4724            if (!network &&  spdmax > 0L && speed > spdmax) {
4725                printf(
4726"\n  WARNING - interface speed %ld might be too high for this modem type.\n",
4727                       speed
4728                       );
4729                printf(
4730"  If dialing fails, SET SPEED to %ld or less and try again.\n\n",
4731                       spdmax
4732                       );
4733            }
4734            printf(" %s timeout: ", fc == 0 ? "Dial" : "Answer");
4735            if (waitct > 0)
4736              printf("%d seconds\n",waitct);
4737            else
4738              printf(" (none)\n");
4739            printf(
4740#ifdef MAC
4741               " Type Command-. to cancel.\n"
4742#else
4743#ifdef UNIX
4744               " To cancel: type your interrupt character (normally Ctrl-C).\n"
4745#else
4746               " To cancel: type Ctrl-C (hold down Ctrl, press C).\n"
4747#endif /* UNIX */
4748#endif /* MAC */
4749                   );
4750        }
4751    }
4752    debug(F111,"ckdial",ttname,(int) (speed / 10L));
4753    debug(F101,"ckdial timeout","",waitct);
4754
4755/* Set timer and interrupt handlers. */
4756    savint = signal( SIGINT, dialint ) ; /* And terminal interrupt handler. */
4757    cc_alrm_execute(ckjaddr(sjbuf), 0, dialtime, _dodial, faildial);
4758    signal(SIGINT, savint);
4759#ifdef OS2
4760    if (dialsta == DIA_OK)              /* Dialing is completed */
4761      DialerSend(OPT_KERMIT_CONNECT, 0);
4762#endif /* OS2 */
4763    if (dialsta == DIA_PART || dialsta == DIA_OK)
4764      return(1);                        /* Dial attempt succeeded */
4765    else
4766      return(0);                        /* Dial attempt failed */
4767} /* ckdial */
4768
4769/*
4770  getok() - wait up to n seconds for OK (0) or ERROR (4) response from modem.
4771  Use with Hayeslike or CCITT modems for reading the reply to a nondialing
4772  command.
4773
4774  Second argument says whether to be strict about numeric result codes, i.e.
4775  to require they be preceded by CR or else be the first character in the
4776  response, e.g. to prevent the ATH0<CR> echo from looking like a valid
4777  response.  Strict == 0 is needed for ATI on Telebit, which can return the
4778  model number concatenated with the numeric response code, e.g. "9620"
4779  ("962" is the model number, "0" is the response code).  getok() Returns:
4780
4781   0 if it timed out,
4782   1 if it succeeded,
4783  -1 on modem command, i/o, or other error.
4784*/
4785static ckjmpbuf okbuf;
4786
4787static SIGTYP
4788#ifdef CK_ANSIC
4789oktimo(int foo)                         /* Alarm handler for getok(). */
4790#else
4791oktimo(foo) int foo;                    /* Alarm handler for getok(). */
4792#endif /* CK_ANSIC */
4793/* oktimo */ {
4794
4795#ifdef OS2
4796    alarm(0);
4797    /* signal(SIGALRM,SIG_IGN); */
4798    debug(F100,"oktimo() SIGALRM caught -- SIG_IGN set","",0) ;
4799#endif /* OS2 */
4800   
4801#ifdef OSK                              /* OS-9, see comment in dialtime(). */
4802    sigmask(-1);
4803#endif /* OSK */
4804#ifdef NTSIG
4805    if ( foo == SIGALRM )
4806      PostAlarmSigSem();
4807    else
4808      PostCtrlCSem();
4809#else /* NTSIG */
4810#ifdef NT
4811    cklongjmp(ckjaddr(okbuf),1);
4812#else /* NT */
4813    cklongjmp(okbuf,1);
4814#endif /* NTSIG */
4815#endif /* NT */
4816    /* NOTREACHED */
4817    SIGRETURN;
4818}
4819
4820static int okstatus, okn, okstrict;
4821
4822static SIGTYP
4823#ifdef CK_ANSIC
4824dook(void * threadinfo)
4825#else /* CK_ANSIC */
4826dook(threadinfo) VOID * threadinfo ;
4827#endif /* CK_ANSIC */
4828/* dook */ {
4829    CHAR c;
4830    int i, x;
4831
4832#ifdef NTSIG
4833    if (threadinfo) {                   /* Thread local storage... */
4834        TlsSetValue(TlsIndex,threadinfo);
4835    }
4836#endif /* NTSIG */
4837
4838    if (mdmcapas & CKD_V25) {           /* CCITT, easy... */
4839        waitfor("VAL");
4840        okstatus = 1 ;
4841#ifdef NTSIG
4842        ckThreadEnd(threadinfo);
4843#endif /* NTSIG */
4844        SIGRETURN;
4845#ifndef MINIDIAL
4846    } else if (mymdmtyp == n_MICROCOM) { /* Microcom in SX mode, also easy */
4847        waitfor(MICROCOM.wake_prompt);  /* (I think...) */
4848        okstatus = 1 ;
4849#ifdef NTSIG
4850        ckThreadEnd(threadinfo);
4851#endif /* NTSIG */
4852        SIGRETURN;
4853#endif /* MINIDIAL */
4854    } else {                            /* Hayes & friends, start here... */
4855        okstatus = 0;                   /* No status yet. */
4856        for (x = 0; x < RBUFL; x++)     /* Initialize response buffer */
4857          rbuf[x] = SP;                 /*  to all spaces */
4858        rbuf[RBUFL] = NUL;              /* and terminate with NUL. */
4859        debug(F100,"getok rbuf init ok","",0);
4860        while (okstatus == 0) {         /* While no status... */
4861            x = ddinc(okn);             /* Read a character */
4862            if (x < 0) {                /* I/O error */
4863                okstatus = -1 ;
4864#ifdef NTSIG
4865                ckThreadEnd(threadinfo);
4866#endif /* NTSIG */
4867                SIGRETURN;
4868            }
4869            debug(F101,"getok ddinc","",x); /* Got a character. */
4870            c = (char) (x & 0x7f);      /* Get low order 7 bits */
4871            if (!c)                     /* Don't deposit NULs */
4872              continue;                 /* or else didweget() won't work */
4873            if (dialdpy) conoc((char)c); /* Echo it if requested */
4874            for (i = 0; i < RBUFL-1; i++) /* Rotate buffer */
4875              rbuf[i] = rbuf[i+1];
4876            rbuf[RBUFL-1] = c;          /* Deposit character at end */
4877            debug(F000,"getok:",rbuf,(int) c); /* Log it */
4878            switch (c) {                /* Interpret it. */
4879              case CR:                  /* Got a carriage return. */
4880                switch(rbuf[RBUFL-2]) { /* Look at character before it. */
4881                  case '0':             /* 0 = OK numeric response */
4882                    if (!okstrict ||
4883                        rbuf[RBUFL-3] == CR || rbuf[RBUFL-3] == SP) {
4884                        nonverbal = 1;
4885                        okstatus = 1;   /* Good response */
4886                    }
4887                    break;
4888                  case '4':             /* 4 = ERROR numeric response */
4889#ifndef MINIDIAL
4890                    /* Or Telebit model number 964! */
4891                    if (mymdmtyp == n_TELEBIT &&
4892                        isdigit(rbuf[RBUFL-3]) &&
4893                        isdigit(rbuf[RBUFL-4]))
4894                      break;
4895                    else
4896#endif /* MINIDIAL */
4897                      if (!okstrict ||
4898                        rbuf[RBUFL-3] == CR || rbuf[RBUFL-3] == SP) {
4899                        nonverbal = 1;
4900                        okstatus = -1;  /* Bad command */
4901                    }
4902                    break;
4903                }
4904                if (dialdpy && nonverbal) /* If numeric results, */
4905                  conoc(LF);              /* echo a linefeed too. */
4906                break;
4907              case LF:                  /* Got a linefeed. */
4908                /*
4909                  Note use of explicit octal codes in the string for
4910                  CR and LF.  We want real CR and LF here, not whatever
4911                  the compiler happens to replace \r and \n with...
4912                */
4913                if (!strcmp(rbuf+RBUFL-4,"OK\015\012")) /* Good response */
4914                  okstatus = 1;
4915                else if (!strcmp(rbuf+RBUFL-7,"ERROR\015\012")) /* Error */
4916                  okstatus = -1;
4917                break;
4918              /* Check whether modem echoes its commands... */
4919              case 't':                 /* Got little t */
4920                if (!strcmp(rbuf+RBUFL-3,"\015at") || /* See if it's "at" */
4921                    !strcmp(rbuf+RBUFL-3," at"))
4922                    mdmecho = 1;
4923                debug(F111,"MDMECHO-t",rbuf+RBUFL-2,mdmecho);
4924                break;
4925              case 'T':                 /* Got Big T */
4926                if (!strcmp(rbuf+RBUFL-3,"\015AT") ||   /* See if it's "AT" */
4927                    !strcmp(rbuf+RBUFL-3," AT"))
4928                    mdmecho = 1;
4929                debug(F111,"MDMECHO-T",rbuf+RBUFL-3,mdmecho);
4930                break;
4931              default:                  /* Other characters, accumulate. */
4932                okstatus = 0;
4933                break;
4934            }
4935        }
4936    }
4937    debug(F101,"getok returns","",okstatus); /* <-- It's a lie */
4938#ifdef NTSIG
4939    ckThreadEnd(threadinfo);
4940#endif /* NTSIG */
4941    SIGRETURN;
4942}
4943
4944static SIGTYP
4945#ifdef CK_ANSIC
4946failok(void * threadinfo)
4947#else /* CK_ANSIC */
4948failok(threadinfo) VOID * threadinfo;
4949#endif /* CK_ANSIC */
4950/* failok */ {
4951    debug(F100,"longjmp returned to getok()","",0);
4952    debug(F100,"getok timeout","",0);
4953    SIGRETURN;
4954}
4955
4956static int
4957getok(n, strict) int n, strict; {
4958    debug(F101,"getok entry n","",n);
4959    okstatus = 0;
4960    okn = n;
4961    okstrict = strict;
4962
4963#ifdef DYNAMIC
4964    if (!rbuf) {
4965        if (!(rbuf = malloc(RBUFL+1))) { /* Allocate input line buffer */
4966            dialsta = DIA_IE;
4967            return(-1);
4968        }
4969        debug(F101,"GETOK rbuf malloc ok","",RBUFL+1);
4970    }
4971#endif /* DYNAMIC */
4972
4973    mdmecho = 0;                        /* Assume no echoing of commands */
4974
4975    debug(F100,"about to alrm_execute dook()","",0);
4976    alrm_execute( ckjaddr(okbuf), n, oktimo, dook, failok ) ;
4977    debug(F100,"returning from alrm_execute dook()","",0);
4978
4979    ttflui();                           /* Flush input buffer */
4980    return(okstatus);                   /* Return status */
4981}
4982
4983/*  G E T H R N  --  Get Hayes Result Numeric  */
4984
4985static VOID
4986gethrn() {
4987    char c;
4988    int x;
4989/*
4990  Hayes numeric result codes (Hayes 1200 and higher):
4991     0 = OK
4992     1 = CONNECT at 300 bps (or 1200 bps on Hayes 1200 with basic code set)
4993     2 = RING
4994     3 = NO CARRIER
4995     4 = ERROR (in command line)
4996     5 = CONNECT 1200 (extended code set)
4997  Hayes 2400 and higher:
4998     6 = NO DIALTONE
4999     7 = BUSY
5000     8 = NO ANSWER
5001     9 = (there is no 9)
5002    10 = CONNECT 2400
5003  Reportedly, the codes for Hayes V.32 modems are:
5004    1x = CONNECT <suffix>
5005    5x = CONNECT 1200 <suffix>
5006    9x = CONNECT 2400 <suffix>
5007   11x = CONNECT 4800 <suffix>
5008   12x = CONNECT 9600 <suffix>
5009  Where:
5010    x:   suffix:
5011    R  = RELIABLE
5012    RC = RELIABLE COMPRESSED
5013    L  = LAPM
5014    LC = LAPM COMPRESSED
5015  And for Telebits, all the above, except no suffix in numeric mode, plus:
5016    11 = CONNECT 4800
5017    12 = CONNECT 9600
5018    13 = CONNECT 14400
5019    14 = CONNECT 19200
5020    15 = CONNECT 38400
5021    16 = CONNECT 57600
5022    20 = CONNECT 300/REL  (= MNP)
5023    22 = CONNECT 1200/REL (= MNP)
5024    23 = CONNECT 2400/REL (= MNP)
5025    46 = CONNECT 7512  (i.e. 75/1200)
5026    47 = CONNECT 1275  (i.e. 1200/75)
5027    48 = CONNECT 7200
5028    49 = CONNECT 12000
5029    50 = CONNECT FAST (not on T1600/3000)
5030    52 = RRING
5031    53 = DIALING
5032    54 = NO PROMPTTONE
5033    61 = CONNECT FAST/KERM (Kermit spoof)
5034    70 = CONNECT FAST/COMP (PEP + compression)
5035    71 = CONNECT FAST/KERM/COMP (PEP + compression + Kermit spoof)
5036
5037  And for others, lots of special cases below...
5038*/
5039#define NBUFL 8
5040    char nbuf[NBUFL+1];                 /* Response buffer */
5041    int i = 0, j = 0;                   /* Buffer pointers */
5042
5043    debug(F101,"RESPONSE mdmecho","",mdmecho);
5044    if (mdmecho) {                      /* Sponge up dialing string echo. */
5045        while (1) {
5046            c = (char) (ddinc(0) & 0x7f);
5047            debug(F000,"SPONGE","",c);
5048            dialoc(c);
5049            if (c == CR) break;
5050        }
5051    }
5052    while (mdmstat == 0) {              /* Read response */
5053        for (i = 0; i < NBUFL; i++)     /* Clear the buffer */
5054          nbuf[i] = '\0';
5055        i = 0;                          /* Reset the buffer pointer. */
5056        c = (char) (ddinc(0) & 0177);   /* Get first digit of response. */
5057                                        /* using an untimed, blocking read. */
5058        debug(F000,"RESPONSE-A","",c);
5059        dialoc(c);                      /* Echo it if requested. */
5060        if (!isdigit(c))                /* If not a digit, keep looking. */
5061          continue;
5062        nbuf[i++] = c;                  /* Got first digit, save it. */
5063        while (c != CR && i < 8) {      /* Read chars up to CR */
5064            x = ddinc(0) & 0177;        /* Get a character. */
5065            c = (char) x;               /* Got it OK. */
5066            debug(F000,"RESPONSE-C","",c);
5067            if (c != CR)                /* If it's not a carriage return, */
5068              nbuf[i++] = c;            /*  save it. */
5069            dialoc(c);                  /* Echo it. */
5070        }
5071        nbuf[i] = '\0';                 /* Done, terminate the buffer. */
5072        debug(F110,"dial hayesnv lbuf",lbuf,0);
5073        debug(F111,"dial hayesnv got",nbuf,i);
5074        /*
5075           Separate any non-numeric suffix from the numeric
5076           result code with a null.
5077        */
5078        for (j = i-1; (j > -1) && !isdigit(nbuf[j]); j--)
5079          nbuf[j+1] = nbuf[j];
5080        j++;
5081        nbuf[j++] = '\0';
5082        debug(F110,"dial hayesnv numeric",nbuf,0);
5083        debug(F111,"dial hayesnv suffix ",nbuf+j,j);
5084        /* Probably phone number echoing. */
5085        if ((int)strlen(nbuf) > 3)
5086          continue;
5087
5088        /* Now read and interpret the results... */
5089
5090        i = atoi(nbuf); /* Convert to integer */
5091        switch (i) {
5092          case 0:
5093            mdmstat = D_PARTIAL;        /* OK response */
5094            break;
5095          case 1:                       /* CONNECT */
5096            mdmstat = CONNECTED;        /* Could be any speed */
5097            break;
5098          case 2:                       /* RING */
5099            if (dialdpy)
5100              printf("\r\n Local phone is ringing!\r\n");
5101            mdmstat = D_FAILED;
5102            dialsta = DIA_RING;
5103            break;
5104          case 3:                       /* NO CARRIER */
5105            if (dialdpy) printf("\r\n No Carrier.\r\n");
5106            mdmstat = D_FAILED;
5107            dialsta = DIA_NOCA;
5108            break;
5109          case 4:                       /* ERROR */
5110            if (dialdpy)
5111              printf("\r\n Modem Command Error.\r\n");
5112            mdmstat = D_FAILED;
5113            dialsta = DIA_ERR;
5114            break;
5115          case 5:                       /* CONNECT 1200 */
5116            spdchg(1200L); /* Change speed if necessary. */
5117            mdmstat = CONNECTED;
5118            break;
5119          case 6:                       /* NO DIALTONE */
5120#ifndef MINIDIAL
5121            if (mymdmtyp == n_MICROLINK && atoi(diallcc) == 49 && dialdpy)
5122              printf("\r\n Dial Locked.\r\n"); /* Germany */
5123            else
5124#endif /* MINIDIAL */
5125              if (dialdpy)
5126                printf("\r\n No Dialtone.\r\n");
5127            mdmstat = D_FAILED;
5128            dialsta = DIA_NODT;
5129            break;
5130          case 7:                       /* BUSY */
5131            if (dialdpy) printf("\r\n Busy.\r\n");
5132            mdmstat = D_FAILED;
5133            dialsta = DIA_BUSY;
5134            break;
5135          case 8:                       /* NO ANSWER */
5136#ifndef MINIDIAL
5137            if (mymdmtyp == n_MICROLINK && atoi(diallcc) == 41 && dialdpy)
5138              printf("\r\n Dial Locked.\r\n"); /* Switzerland */
5139            else
5140#endif /* MINIDIAL */
5141              if (dialdpy)
5142                printf("\r\n No Answer.\r\n");
5143            mdmstat = D_FAILED;
5144            dialsta = DIA_NOAN;
5145            break;
5146          case 9:                       /* CONNECT 2400 */
5147          case 10:
5148            spdchg(2400L); /* Change speed if necessary. */
5149            mdmstat = CONNECTED;
5150            break;
5151
5152#ifndef MINIDIAL
5153
5154/* Starting here, we get different meanings from different manufacturers */
5155
5156          case 11:
5157            if (mymdmtyp == n_USR) {
5158                if (dialdpy) printf(" Ringing...\r\n");         
5159            } else {
5160                spdchg(4800L);          /* CONNECT 4800 */
5161                mdmstat = CONNECTED;
5162            }
5163            break;
5164          case 12:
5165            if (mymdmtyp == n_USR) {
5166                if (dialdpy)
5167                  printf("\r\n Answered by voice.\r\n");
5168                mdmstat = D_FAILED;
5169                dialsta = DIA_VOIC;
5170            } else {
5171                spdchg(9600L);
5172                mdmstat = CONNECTED;
5173            }
5174            break;
5175          case 13:
5176            if (mymdmtyp == n_USR)
5177              spdchg(9600L);
5178            if (is_rockwell || mymdmtyp == n_ZOLTRIX)
5179              spdchg(7200L);
5180            else if (mymdmtyp != n_MICROLINK) /* 12000 */
5181              spdchg(14400L);
5182            mdmstat = CONNECTED;
5183            break;
5184          case 14:
5185            if (is_rockwell)
5186              spdchg(12000L);
5187            else if (mymdmtyp == n_DATAPORT || mymdmtyp == n_MICROLINK)
5188              spdchg(14400L);
5189            else if (mymdmtyp != n_USR && mymdmtyp != n_ZOLTRIX)
5190              spdchg(19200L);
5191            mdmstat = CONNECTED;
5192            break;
5193          case 15:
5194            if (is_rockwell || mymdmtyp == n_ZOLTRIX)
5195              spdchg(14400L);
5196            else if (mymdmtyp == n_ZYXEL || mymdmtyp == n_INTEL)
5197              spdchg(7200L);
5198            else if (mymdmtyp == n_DATAPORT)
5199              spdchg(19200L);
5200            else
5201              spdchg(38400L);
5202            mdmstat = CONNECTED;
5203            break;
5204          case 16:
5205            if (is_rockwell || mymdmtyp == n_ZOLTRIX)
5206              spdchg(19200L);
5207            else if (mymdmtyp == n_DATAPORT)
5208              spdchg(7200L);
5209            else if (mymdmtyp != n_ZYXEL && mymdmtyp != n_INTEL) /* 12000 */
5210              spdchg(57600L);
5211            mdmstat = CONNECTED;
5212            break;
5213          case 17:
5214            if (mymdmtyp != n_DATAPORT) /* 16800 */
5215              spdchg(38400L);
5216            else if (mymdmtyp == n_ZYXEL || mymdmtyp == n_INTEL)
5217              spdchg(14400L);
5218            mdmstat = CONNECTED;
5219            break;
5220          case 18:
5221            if (is_rockwell || mymdmtyp == n_ZOLTRIX)
5222              spdchg(57600L);
5223            else if (mymdmtyp == n_INTEL)
5224              spdchg(19200L);
5225            else if (mymdmtyp == n_USR)
5226              spdchg(4800L);
5227            mdmstat = CONNECTED;
5228            break;
5229          case 19:
5230            if (mymdmtyp == n_DATAPORT)
5231              spdchg(300L);
5232            else if (mymdmtyp == n_ZYXEL || mymdmtyp == n_INTEL)
5233              spdchg(38400L);
5234            else
5235              spdchg(115200L);
5236            mdmstat = CONNECTED;
5237            break;
5238          case 20:
5239            if (mymdmtyp == n_USR)
5240              spdchg(7200L);
5241            else if (mymdmtyp == n_DATAPORT)
5242              spdchg(2400L);
5243            else if (mymdmtyp == n_ZYXEL || mymdmtyp == n_INTEL)
5244              spdchg(57600L);
5245            else
5246              spdchg(300L);
5247            mdmstat = CONNECTED;
5248            break;
5249          case 21:
5250            if (mymdmtyp == n_DATAPORT)
5251              spdchg(4800L);
5252            mdmstat = CONNECTED;
5253            break;
5254          case 22:
5255            if (is_rockwell)
5256              spdchg(8880L);
5257            else if (mymdmtyp == n_DATAPORT)
5258              spdchg(9600L);
5259            else if (!is_hayeshispd)
5260              spdchg(1200L);
5261            mdmstat = CONNECTED;
5262            break;
5263          case 23:
5264            if (is_hayeshispd || mymdmtyp == n_MULTI)
5265              spdchg(8880L);
5266            else if (mymdmtyp != n_DATAPORT && !is_rockwell) /* 12000 */
5267              spdchg(2400L);
5268            mdmstat = CONNECTED;
5269            break;
5270          case 24:
5271            if (is_rockwell) {
5272                mdmstat = D_FAILED;
5273                dialsta = DIA_DELA;     /* Delayed */
5274                break;
5275            } else if (is_hayeshispd)
5276              spdchg(7200L);
5277            else if (mymdmtyp == n_DATAPORT)
5278              spdchg(14400L);
5279            else if (mymdmtyp == n_INTEL)
5280              spdchg(1200L);
5281            mdmstat = CONNECTED;
5282            break;
5283          case 25:
5284            if (mymdmtyp == n_MOTOROLA)
5285              spdchg(9600L);
5286            else if (mymdmtyp == n_INTEL)
5287              spdchg(2400L);
5288            mdmstat = CONNECTED;
5289            break;
5290          case 26:
5291            if (mymdmtyp == n_DATAPORT)
5292              spdchg(19200L);
5293            else if (mymdmtyp == n_INTEL)
5294              spdchg(4800L);
5295            mdmstat = CONNECTED;
5296            break;
5297          case 27:
5298            if (mymdmtyp == n_DATAPORT)
5299              spdchg(38400L);
5300            else if (mymdmtyp == n_INTEL)
5301              spdchg(7200L);
5302            mdmstat = CONNECTED;
5303            break;
5304          case 28:
5305            if (mymdmtyp == n_DATAPORT)
5306              spdchg(7200L);
5307            else if (mymdmtyp == n_INTEL)
5308              spdchg(9600L);
5309            mdmstat = CONNECTED;
5310            break;
5311          case 29:
5312            if (mymdmtyp == n_MOTOROLA)
5313              spdchg(4800L);
5314            else if (mymdmtyp == n_DATAPORT)
5315              spdchg(19200L);
5316            mdmstat = CONNECTED;
5317            break;
5318          case 30:
5319            if (mymdmtyp == n_INTEL) {
5320                spdchg(14400L);
5321                mdmstat = CONNECTED;
5322            } /* fall thru on purpose... */
5323          case 31:
5324            if (mymdmtyp == n_UCOM_AT || mymdmtyp == n_MICROLINK) {
5325                spdchg(4800L);
5326                mdmstat = CONNECTED;
5327            } else if (mymdmtyp == n_MOTOROLA) {
5328                spdchg(57600L);
5329                mdmstat = CONNECTED;
5330            }
5331            break;
5332          case 32:
5333            if (is_rockwell) {
5334                mdmstat = D_FAILED;
5335                dialsta = DIA_BLCK;     /* Blacklisted */
5336            } else if (mymdmtyp == n_UCOM_AT || mymdmtyp == n_MICROLINK) {
5337                spdchg(9600L);
5338                mdmstat = CONNECTED;
5339            } else if (mymdmtyp == n_INTEL) {
5340                spdchg(2400L);
5341                mdmstat = CONNECTED;
5342            }
5343            break;
5344          case 33:                      /* FAX connection */
5345            if (is_rockwell || mymdmtyp == n_ZOLTRIX) {
5346                mdmstat = D_FAILED;
5347                dialsta = DIA_FAX;
5348            } else if (mymdmtyp == n_UCOM_AT ||
5349                       mymdmtyp == n_MOTOROLA ||
5350                       mymdmtyp == n_MICROLINK
5351                       ) {
5352                spdchg(9600L);
5353                mdmstat = CONNECTED;
5354            }
5355            break;
5356          case 34:
5357            if (mymdmtyp == n_INTEL) {
5358                spdchg(1200L);
5359                mdmstat = CONNECTED;
5360            } else if (mymdmtyp == n_MICROLINK) {
5361                spdchg(7200L);
5362                mdmstat = CONNECTED;
5363            }
5364            break;
5365          case 35:
5366            if (is_rockwell) {
5367                spdchg(300L);
5368                dialsta = CONNECTED;
5369            } else if (mymdmtyp == n_MOTOROLA) {
5370                spdchg(14400L);
5371                mdmstat = CONNECTED;
5372            } else if (mymdmtyp == n_INTEL) {
5373                spdchg(2400L);
5374                mdmstat = CONNECTED;
5375            } else if (mymdmtyp == n_MICROLINK) {
5376                spdchg(7200L);
5377                mdmstat = CONNECTED;
5378            } else if (mymdmtyp == n_ZOLTRIX) /* "DATA" */
5379              mdmstat = CONNECTED;
5380            break;
5381          case 36:
5382            if (mymdmtyp == n_UCOM_AT) {
5383                spdchg(19200L);
5384                mdmstat = CONNECTED;
5385            } else if (mymdmtyp == n_MOTOROLA) {
5386                spdchg(1200L);
5387                mdmstat = CONNECTED;
5388            } else if (mymdmtyp == n_INTEL) {
5389                spdchg(4800L);
5390                mdmstat = CONNECTED;
5391            }
5392            break;
5393          case 37:
5394            if (mymdmtyp == n_UCOM_AT) {
5395                spdchg(19200L);
5396                mdmstat = CONNECTED;
5397            } else if (mymdmtyp == n_MOTOROLA) {
5398                spdchg(2400L);
5399                mdmstat = CONNECTED;
5400            } else if (mymdmtyp == n_INTEL) {
5401                spdchg(7200L);
5402                mdmstat = CONNECTED;
5403            }
5404            break;
5405          case 38:
5406            if (mymdmtyp == n_MOTOROLA) {
5407                spdchg(4800L);
5408                mdmstat = CONNECTED;
5409            } else if (mymdmtyp == n_INTEL) {
5410                spdchg(9600L);
5411                mdmstat = CONNECTED;
5412            } /* fall thru on purpose... */
5413          case 39:
5414            if (mymdmtyp == n_UCOM_AT) {
5415                spdchg(38400L);
5416                mdmstat = CONNECTED;
5417            } else if (mymdmtyp == n_MOTOROLA) {
5418                spdchg(9600L);
5419                mdmstat = CONNECTED;
5420            } else if (mymdmtyp == n_MICROLINK) {
5421                spdchg(14400L);
5422                mdmstat = CONNECTED;
5423            }
5424            break;
5425          case 40:
5426            if (mymdmtyp == n_UCOM_AT) {
5427                mdmstat = D_FAILED;
5428                dialsta = DIA_NOCA;
5429            } else if (mymdmtyp == n_MOTOROLA || mymdmtyp == n_INTEL) {
5430                spdchg(14400L);
5431                mdmstat = CONNECTED;
5432            }
5433            break;
5434          case 41:
5435            if (mymdmtyp == n_MOTOROLA) {
5436                spdchg(19200L);
5437                mdmstat = CONNECTED;
5438            }
5439            break;
5440          case 42:
5441            if (mymdmtyp == n_MOTOROLA) {
5442                spdchg(38400L);
5443                mdmstat = CONNECTED;
5444            } /* fall thru on purpose... */
5445          case 43:
5446            if (mymdmtyp == n_UCOM_AT) {
5447                spdchg(57600L);
5448                mdmstat = CONNECTED;
5449            }
5450            break;
5451          case 44:
5452            if (is_rockwell) {
5453                spdchg(8800L);
5454                dialsta = CONNECTED;
5455            } else if (mymdmtyp == n_MOTOROLA) {
5456                spdchg(7200L);
5457                mdmstat = CONNECTED;
5458            } else if (mymdmtyp == n_INTEL) {
5459                spdchg(1200L);
5460                mdmstat = CONNECTED;
5461            }
5462            break;
5463          case 45:
5464            if (mymdmtyp == n_MOTOROLA) {
5465                spdchg(57600L);
5466                mdmstat = CONNECTED;
5467            } else if (mymdmtyp == n_INTEL) {
5468                spdchg(2400L);
5469                mdmstat = CONNECTED;
5470            }
5471            break;
5472          case 46:
5473            if (is_rockwell)
5474              spdchg(1200L);
5475            else if (mymdmtyp == n_INTEL)
5476              spdchg(4800L);
5477            else
5478              spdchg(8880L);            /* 75/1200 split speed */
5479            mdmstat = CONNECTED;
5480            break;
5481          case 47:
5482            if (is_rockwell)
5483              spdchg(2400L);
5484            else if (mymdmtyp == n_INTEL)
5485              spdchg(7200L);
5486            else
5487              printf("CONNECT 1200/75 - Not supported by C-Kermit\r\n");
5488            mdmstat = CONNECTED;
5489            break;
5490          case 48:
5491            if (is_rockwell)
5492              spdchg(4800L);
5493            else if (mymdmtyp == n_INTEL)
5494              spdchg(9600L);
5495            else
5496              spdchg(7200L);
5497            mdmstat = CONNECTED;
5498            break;
5499          case 49:
5500            if (is_rockwell)
5501              spdchg(7200L);
5502            mdmstat = CONNECTED;
5503            break;
5504          case 50:                      /* CONNECT FAST */
5505            if (is_rockwell)
5506              spdchg(9600L);
5507            else if (mymdmtyp == n_INTEL)
5508              spdchg(14400L);
5509            mdmstat = CONNECTED;
5510            break;
5511          case 51:
5512            if (mymdmtyp == n_UCOM_AT) {
5513                mdmstat = D_FAILED;
5514                dialsta = DIA_NODT;
5515            }
5516            break;
5517          case 52:                      /* RRING */
5518            if (mymdmtyp == n_TELEBIT)
5519              if (dialdpy) printf(" Ringing...\r\n");
5520            break;
5521          case 53:                      /* DIALING */
5522            if (mymdmtyp == n_TELEBIT)
5523              if (dialdpy) printf(" Dialing...\r\n");
5524            break;
5525          case 54:
5526            if (is_rockwell) {
5527                spdchg(19200L);
5528                mdmstat = CONNECTED;
5529            } else if (mymdmtyp == n_INTEL) {
5530                spdchg(1200L);
5531                mdmstat = CONNECTED;
5532            } else if (mymdmtyp == n_TELEBIT) {
5533                if (dialdpy) printf("\r\n No Prompttone.\r\n");
5534                mdmstat = D_FAILED;
5535                dialsta = DIA_NODT;
5536            }
5537            break;
5538          case 55:
5539            if (mymdmtyp == n_INTEL) {
5540                spdchg(2400L);
5541                mdmstat = CONNECTED;
5542            }
5543            break;
5544          case 56:
5545            if (mymdmtyp == n_INTEL) {
5546                spdchg(4800L);
5547                mdmstat = CONNECTED;
5548            }
5549            break;
5550          case 57:
5551            if (mymdmtyp == n_INTEL) {
5552                spdchg(7200L);
5553                mdmstat = CONNECTED;
5554            }
5555            break;
5556          case 58:
5557            if (mymdmtyp == n_INTEL) {
5558                spdchg(9600L);
5559                mdmstat = CONNECTED;
5560            }
5561            break;
5562          case 59:
5563            if (mymdmtyp == n_INTEL)    /* 12000 */
5564              mdmstat = CONNECTED;
5565            break;
5566          case 60:
5567            if (mymdmtyp == n_INTEL) {
5568                spdchg(14400L);
5569                mdmstat = CONNECTED;
5570            }
5571            break;
5572          case 64:
5573            if (mymdmtyp == n_INTEL) {
5574                spdchg(1200L);
5575                mdmstat = CONNECTED;
5576            }
5577            break;
5578          case 65:
5579            if (mymdmtyp == n_INTEL) {
5580                spdchg(2400L);
5581                mdmstat = CONNECTED;
5582            }
5583            break;
5584          case 66:
5585            if (mymdmtyp == n_INTEL) {
5586                spdchg(4800L);
5587                mdmstat = CONNECTED;
5588            }
5589            break;
5590          case 67:
5591            if (mymdmtyp == n_INTEL) {
5592                spdchg(7200L);
5593                mdmstat = CONNECTED;
5594            }
5595            break;
5596          case 68:
5597            if (mymdmtyp == n_INTEL) {
5598                spdchg(9600L);
5599                mdmstat = CONNECTED;
5600            }
5601            break;
5602          case 69:
5603            if (mymdmtyp == n_INTEL)    /* 12000 */
5604              mdmstat = CONNECTED;
5605            break;
5606          case 70:
5607            if (mymdmtyp == n_INTEL) {
5608                spdchg(14400L);
5609                mdmstat = CONNECTED;
5610            }
5611            break;
5612          case 73:
5613            if (mymdmtyp == n_UCOM_AT) {
5614                spdchg(115200L);
5615                mdmstat = CONNECTED;
5616                break;
5617            } /* else fall thru */
5618            if (mymdmtyp == n_TELEBIT)  /* Early models only */
5619              mdmstat = CONNECTED;
5620            break;
5621          case 85:
5622            if (mymdmtyp == n_USR)
5623              spdchg(19200L);
5624            mdmstat = CONNECTED;
5625            break;
5626#endif /* MINIDIAL */
5627          default:
5628#ifndef MINIDIAL
5629            if (mymdmtyp == n_USR || is_hayeshispd || is_rockwell)
5630#endif /* MINIDIAL */
5631              if (i > 12)               /* There are hundreds of them... */
5632                mdmstat = CONNECTED;
5633            break;
5634        }
5635    }
5636    if (mdmstat == CONNECTED && nbuf[j] != '\0') {
5637        if (dialdpy) {
5638            printf("\r\n");
5639            if (nbuf[j] == 'R') printf(" RELIABLE");
5640            if (nbuf[j] == 'L') printf(" LAPM");
5641            if (nbuf[j+1] == 'C') printf(" COMPRESSED");
5642            printf("\r\n");
5643        }
5644        strcpy(lbuf,nbuf);              /* (for messages...) */
5645    }
5646}
5647
5648static VOID                             /* Get Hayes Result in Word mode */
5649gethrw() {
5650    char *cptr, *s;
5651    long conspd;
5652
5653    if (mdmspd && !network) {
5654        s = lbuf;
5655        while (*s != '\0' && *s != 'C') s++;
5656        cptr = (*s == 'C') ? s : NULL;
5657        conspd = 0L;
5658        if ((cptr != NULL) && !strncmp(cptr,"CONNECT ",8)) {
5659            if ((int)strlen(cptr) < 9)   /* Just CONNECT, */
5660              conspd = 300L;             /* use 300 bps */
5661            else if (isdigit(*(cptr+8))) /* not CONNECT FAST */
5662              conspd = atol(cptr + 8);   /* CONNECT nnnn */
5663            if (conspd != speed) {
5664                if ((conspd / 10L) > 0) {
5665                    if (ttsspd((int) (conspd / 10L)) < 0) {
5666                        printf(" Can't change speed to %ld\r\n",
5667                               conspd);
5668                    } else {
5669                        speed = conspd;
5670                        mdmstat = CONNECTED;
5671                        if ( !quiet && !backgrd )
5672                          printf(" Speed changed to %ld\r\n",
5673                                 conspd);
5674                    }
5675                }
5676            } /* Expanded to handle any conceivable speed */
5677        }
5678    }
5679#ifndef MINIDIAL
5680    if (mymdmtyp == n_TELEBIT) {
5681        if (didweget(lbuf,"CONNECT FAST/KERM")) {
5682            mdmstat = CONNECTED;
5683            if (dialdpy) printf("FAST/KERM ");
5684            return;
5685        }
5686    }
5687#endif /* MINIDIAL */
5688    if (didweget(lbuf,"RRING") ||
5689        didweget(lbuf,"RINGING") ||
5690        didweget(lbuf,"DIALING")) {
5691        mdmstat = 0;
5692    } else if (didweget(lbuf,"CONNECT")) {
5693        mdmstat = CONNECTED;
5694    } else if (didweget(lbuf,"OK")) {
5695        mdmstat = D_PARTIAL;
5696    } else if (didweget(lbuf,"NO CARRIER")) {
5697        mdmstat = D_FAILED;
5698        dialsta = DIA_NOCA;
5699    } else if (didweget(lbuf,"NO DIALTONE")) {
5700        mdmstat = D_FAILED;
5701        dialsta = DIA_NODT;
5702    } else if (didweget(lbuf,"NO DIAL TONE")) {
5703        mdmstat = D_FAILED;
5704        dialsta = DIA_NODT;
5705    } else if (didweget(lbuf,"BUSY")) {
5706        mdmstat = D_FAILED;
5707        dialsta = DIA_BUSY;
5708    } else if (didweget(lbuf,"NO ANSWER")) {
5709        mdmstat = D_FAILED;
5710        dialsta = DIA_NOAN;
5711    } else if (didweget(lbuf,"VOICE")) {
5712        mdmstat = D_FAILED;
5713        dialsta = DIA_VOIC;
5714    } else if (didweget(lbuf,"NO PROMPT TONE")) {
5715        mdmstat = D_FAILED;
5716        dialsta = DIA_NODT;
5717    } else if (didweget(lbuf,"REMOTE ACCESS FAILED")) {
5718        mdmstat = D_FAILED;
5719        dialsta = DIA_NOCA;
5720    } else if (didweget(lbuf,"FAX")) {
5721        mdmstat = D_FAILED;
5722        dialsta = DIA_FAX;
5723    } else if (didweget(lbuf,"DELAYED")) {
5724        mdmstat = D_FAILED;
5725        dialsta = DIA_DELA;
5726    } else if (didweget(lbuf,"BLACKLISTED")) {
5727        mdmstat = D_FAILED;
5728        dialsta = DIA_BLCK;
5729    } else if (didweget(lbuf,"DIAL LOCKED")) { /* Germany, Austria, Schweiz */
5730        mdmstat = D_FAILED;
5731        dialsta = DIA_BLCK;
5732    } else if (didweget(lbuf,"RING")) {
5733        mdmstat = (func_code == 0) ? D_FAILED : 0;
5734        dialsta = DIA_RING;                     
5735    } else if (didweget(lbuf,"ERROR")) {
5736        mdmstat = D_FAILED;
5737        dialsta = DIA_ERR;
5738    } else if (didweget(lbuf,"CARRIER")) { /* Boca */
5739        mdmstat = CONNECTED;
5740    } else if (didweget(lbuf,"DATA")) { /* Boca */
5741        mdmstat = CONNECTED;
5742    }
5743}
5744
5745/* Maybe hang up the phone, depending on various SET DIAL parameters. */
5746
5747int
5748dialhup() {
5749    int x = 0;
5750    if (dialhng && dialsta != DIA_PART) { /* DIAL HANGUP ON? */
5751        x = mdmhup();                   /* Try modem-specific method first */
5752        debug(F101,"dialhup mdmhup","",x);
5753        if (x > 0) {                    /* If it worked, */
5754            dialsta = DIA_HUP;
5755            if (dialdpy)
5756              printf(" Modem hangup OK\r\n"); /* fine. */
5757        } else if (network) {           /* If we're telnetted to */
5758            dialsta = DIA_HANG;
5759            if (dialdpy)                /* a modem server, just print a msg */
5760              printf(" WARNING - modem hangup failed\r\n"); /* don't hangup! */
5761            return(0);
5762        } else {                        /* Otherwise */
5763            x = tthang();               /* Tell the OS to turn off DTR. */
5764            if (x > 0) {                /* Yes, tell results from tthang() */
5765                dialsta = DIA_HUP;
5766                if (dialdpy) printf(" Hangup OK\r\n");
5767            } else if (x == 0) {
5768                if (dialdpy) printf(" Hangup skipped\r\n");
5769            } else {
5770                dialsta = DIA_HANG;
5771                if (dialdpy) perror(" Hangup error");
5772            }
5773        }
5774    } else if (dialdpy) printf(" Hangup skipped\r\n"); /* DIAL HANGUP OFF */
5775    return(x);
5776}
5777
5778/*
5779  M D M H U P  --
5780
5781  Sends escape sequence to modem, then sends its hangup command.  Returns:
5782   0: If modem type is 0 (direct serial connection),
5783      or if modem type is < 0 (network connection),
5784      or if no action taken because DIAL MODEM-HANGUP is OFF)
5785        or because no hangup string for current modem type,
5786      or C-Kermit is in remote mode,
5787      or if action taken but there was no positive response from modem;
5788   1: Success: modem is in command state and acknowledged the hangup command;
5789  -1: On modem command error.
5790*/
5791int
5792mdmhup() {
5793#ifdef MDMHUP
5794    int m, x = 0;
5795    int xparity;
5796    char *s, *p;
5797    MDMINF * mp = NULL;
5798
5799    if (dialmhu == 0 || local == 0)     /* If DIAL MODEM-HANGUP is OFF, */
5800      return(0);                        /*  or not in local mode, fail. */
5801
5802#ifdef OS2
5803/*
5804  In OS/2, if CARRIER is OFF, and there is indeed no carrier signal, any
5805  attempt to do i/o at this point can hang the program.  This might be true
5806  for other operating systems too.
5807*/
5808    if (!network) {                     /* Not a network connection */
5809        m = ttgmdm();                   /* Get modem signals */
5810        if ((m > -1) && (m & BM_DCD == 0)) /* Check for carrier */
5811          return(0);                    /* No carrier, skip the rest */
5812    }
5813#endif /* OS2 */
5814   
5815    if (mymdmtyp < 0)
5816      return(0);
5817    if (mymdmtyp > 0) mp = modemp[mymdmtyp - 1];
5818    if (!mp) return(0);
5819
5820    s = dialhcmd ? dialhcmd : mp->hup_str;
5821    if (!s) return(0);
5822    if (!*s) return(0);
5823
5824    debug(F110,"mdmhup hup_str",s,0);
5825    xparity = parity;                   /* Set PARITY to NONE temporarily */
5826
5827    if (escbuf[0]) {                    /* Have escape sequence? */
5828        debug(F110,"mdmhup escbuf",escbuf,0);
5829        debug(F101,"mdmhup esc_time",0,mp->esc_time);
5830        parity = 0;
5831        if (ttpkt(speed,FLO_DIAL,parity) < 0) { /* Condition line */
5832            parity = xparity;
5833            return(-1);                 /*  for dialing. */
5834        }
5835        if (mp->esc_time)               /* If we have a guard time */
5836          msleep(mp->esc_time);         /* Pause for guard time */
5837        debug(F100,"mdmhup pause 1 OK","",0);
5838
5839#ifdef NETCONN                          /* Send modem's escape sequence */
5840        if (network) {                  /* Must catch errors here. */
5841            if (ttol((CHAR *)escbuf,(int)strlen((char *)escbuf)) < 0) {
5842                parity = xparity;
5843                return(-1);
5844            }
5845        } else {
5846#endif /* NETCONN */
5847            ttslow((char *)escbuf,mp->wake_rate); /* Send escape sequence */
5848            debug(F110,"mdmhup net ttslow ok",escbuf,0);
5849#ifdef NETCONN
5850        }
5851#endif /* NETCONN */
5852
5853        if (mp->esc_time)               /* Pause for guard time again */
5854          msleep(mp->esc_time);
5855        else
5856          msleep(500);                  /* Wait half a sec for echoes. */
5857        debug(F100,"mdmhup pause 1 OK","",0);
5858#ifdef COMMENT 
5859        ttflui();                       /* Flush response or echo, if any */
5860        debug(F100,"mdmhup ttflui OK","",0);
5861#endif /* COMMENT */
5862        ttslow(s,mp->wake_rate);        /* Now Send hangup string */
5863        debug(F110,"mdmhup ttslow ok",s,0);
5864/*
5865  This is not exactly right, but it works.
5866  If we are online:
5867    the modem says OK when it gets the escape sequence,
5868    and it says NO CARRIER when it gets the hangup command.   
5869  If we are offline:
5870    the modem does NOT say OK (or anything else) when it gets the esc sequence,
5871    but it DOES say OK (and not NO CARRIER) when it gets the hangup command.
5872  So the following function should read the OK in both cases.
5873  Of course, this is somewhat Hayes-specific...
5874*/
5875        if (xx_ok) {                    /* Look for OK response */
5876            debug(F100,"mdmhup calling response function","",0);
5877            x = (*xx_ok)(3,1);          /* Give it 3 seconds, be strict. */
5878            debug(F101,"mdmhup hangup response","",x);
5879            msleep(500);                /* Wait half a sec */
5880            ttflui();                   /* Get rid of NO CARRIER, if any */
5881        } else {                        /* No OK function, */
5882            x = 1;                      /* so assume it worked */
5883            debug(F101,"mdmhup no ok_fn","",x);
5884        }
5885    }
5886    parity = xparity;                   /* Restore prevailing parity */
5887    return(x);                          /* Return OK function's return code. */
5888
5889#else  /* MDMHUP not defined. */
5890
5891    return(0);                          /* Always fail. */
5892#endif /* MDMHUP */
5893}
5894
5895#else /* NODIAL */
5896
5897char *dialv = "Dial Command Disabled";
5898
5899int                                     /* To allow NODIAL versions to */
5900mdmhup() {                              /* call mdmhup(), so calls to  */
5901    return(0);                          /* mdmhup() need not be within */
5902}                                       /* #ifndef NODIAL conditionals */
5903
5904#endif /* NOICP */
5905#endif /* NODIAL */
5906#endif /* NOLOCAL */
Note: See TracBrowser for help on using the repository browser.