ecuDCE.c 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173
  1. /* #define USE_S7 */
  2. /*+-------------------------------------------------------------------------
  3. ecuDCE.c - ECU DCE dialing and management
  4. wht@wht.net
  5. Defined functions:
  6. DCE_autoanswer()
  7. DCE_dial()
  8. DCE_get_result(msec_to_wait)
  9. DCE_get_sreg_value(regnum)
  10. DCE_hangup()
  11. DCE_modem_init()
  12. DCE_now_on_hook()
  13. DCE_read_modem_init()
  14. DCE_redial(arg, argc)
  15. DCE_report_iv_set(varnum)
  16. DCE_send_cmd(cmd)
  17. DCE_set_sreg(regnum, value)
  18. check_queued_sigint()
  19. is_extant_dialproc(device)
  20. process_modem_init(str)
  21. show_modem_init_error(erc, iesd)
  22. Lothar Hirschbiegel <emory!tmcsys.uucp!lothar> added the ability to
  23. specify a modem acknowledgement string other than "OK".
  24. Example use:
  25. #+-----------------------------------------------------------------
  26. # tty1a.mi - Microcom QX/V.32c
  27. #------------------------------------------------------------------
  28. init_default:sceon
  29. dial_default:dp
  30. ok_string:!
  31. connect_string:CONNECT
  32. --------------------------------------------------------------------------*/
  33. /*+:EDITS:*/
  34. /*:04-26-2000-11:15-wht@bob-RELEASE 4.42 */
  35. /*:02-09-1997-20:13-wht@yuriatin-add dialer procedures */
  36. /*:01-24-1997-02:37-wht@yuriatin-SOURCE RELEASE 4.00 */
  37. /*:09-11-1996-19:59-wht@yuriatin-3.48-major telnet,curses,structural overhaul */
  38. /*:08-20-1996-12:39-wht@kepler-locale/ctype fixes from ache@nagual.ru */
  39. /*:08-11-1996-02:10-wht@kepler-rename ecu_log_event to logevent */
  40. /*:08-10-1996-13:52-wht@kepler-Ltelnet hangup no longer kills ecu */
  41. /*:07-31-1996-17:00-dgy@rtd.com-built-in dialer fixes */
  42. /*:12-06-1995-13:30-wht@n4hgf-termecu w/errno -1 consideration */
  43. /*:11-23-1995-11:20-wht@kepler-source control 3.37 for tsx-11 */
  44. /*:11-20-1995-12:15-wht@n4hgf-"Type INT to abort" only if tty char special */
  45. /*:11-14-1995-10:23-wht@kepler-3.37.80-source control point: SOCKETS */
  46. /*:11-03-1995-16:53-wht@wwtp1-use CFG_TelnetOption */
  47. /*:05-11-1995-15:55-wht@n4hgf-ck_sigint fools optimizing compilers */
  48. /*:01-12-1995-15:19-wht@n4hgf-apply Andrew Chernov 8-bit clean+FreeBSD patch */
  49. /*:05-04-1994-04:38-wht@n4hgf-ECU release 3.30 */
  50. /*:02-11-1994-16:03-wht@n4hgf-add connect string */
  51. /*:01-04-1994-05:45-wht@n4hgf-add CFG_DialTimeout */
  52. /*:04-06-1993-11:51-wht@n4hgf-need to kill rcvr to use built-in dialer */
  53. /*:09-10-1992-13:58-wht@n4hgf-ECU release 3.20 */
  54. /*:09-05-1992-14:17-wht@n4hgf-was starting rcvr process too early on connect */
  55. /*:08-22-1992-15:38-wht@n4hgf-ECU release 3.20 BETA */
  56. /*:04-19-1992-03:21-jhpb@sarto.budd-lake.nj.us-3.18.37 has ESIX SVR4 */
  57. /*:02-16-1992-01:41-wht@n4hgf-turn off xterm_title */
  58. /*:02-04-1992-04:49-wht@n4hgf-fix bug in kill_rcvr_process logic */
  59. /*:01-17-1992-15:32-wht@n4hgf-.credit open to public */
  60. /*:11-07-1991-16:54-tmcsys!lothar-alternate OK string for built-in dialer */
  61. /*:08-28-1991-14:07-wht@n4hgf2-SVR4 cleanup by aega84!lh */
  62. /*:07-25-1991-12:55-wht@n4hgf-ECU release 3.10 */
  63. /*:07-17-1991-07:04-wht@n4hgf-avoid SCO UNIX nap bug */
  64. /*:06-29-1991-15:42-wht@n4hgf-if WHT and xterm, play with title bar */
  65. /*:06-16-1991-23:24-wht@n4hgf-ensure hangup since proc could fail connected */
  66. /*:06-07-1991-04:09-wht@n4hgf-remove unnecessary naps after kill_rcvr_process */
  67. /*:05-20-1991-00:56-wht@n4hgf-fix/upgrade auto fkey load */
  68. /*:01-09-1991-22:31-wht@n4hgf-ISC port */
  69. /*:01-09-1991-21:23-wht@n4hgf-fix statement not reached */
  70. /*:09-19-1990-19:36-wht@n4hgf-logevent now gets pid for log from caller */
  71. /*:08-14-1990-20:40-wht@n4hgf-ecu3.00-flush old edit history */
  72. #include "ecu.h"
  73. #include "ecukey.h"
  74. #include "esd.h"
  75. #include "var.h"
  76. #include "ecupde.h"
  77. #include "ecuerror.h"
  78. #include "relop.h"
  79. char *elapsed_time_text();
  80. void DCE_hangup();
  81. extern UINT32 colors_current;
  82. extern char kbdintr;
  83. int mi_line;
  84. char mi_name[64];
  85. char last_dial_result[64];
  86. #define MI_MAX_LEN 65
  87. char Lmodem_init[MI_MAX_LEN] = ""; /* modem init string w/o trailing CR */
  88. char Lmodem_dial[MI_MAX_LEN] = ""; /* modem dialing prefix */
  89. char Lmodem_autoans[MI_MAX_LEN] = ""; /* modem autoanswer */
  90. char Lmodem_okstring[MI_MAX_LEN] = ""; /* modem ok_answer */
  91. char Lmodem_connstring[MI_MAX_LEN] = ""; /* modem ok_answer */
  92. char *interrupted_string = "!Interrupted";
  93. UINT ttygetc();
  94. /*+-------------------------------------------------------------------------
  95. check_queued_sigint()
  96. --------------------------------------------------------------------------*/
  97. int
  98. check_queued_sigint()
  99. {
  100. while (ttyrdchk())
  101. {
  102. if (ttygetc(1) == (uchar) kbdintr)
  103. {
  104. sigint = 1;
  105. return (1);
  106. }
  107. }
  108. return (0);
  109. } /* end of check_queued_sigint */
  110. /*+-------------------------------------------------------------------------
  111. show_modem_init_error(erc,iesd)
  112. --------------------------------------------------------------------------*/
  113. void
  114. show_modem_init_error(erc, iesd)
  115. int erc;
  116. ESD *iesd;
  117. {
  118. int itmp;
  119. pputs(mi_name);
  120. pprintf(" line %d: ", mi_line);
  121. proc_error(erc);
  122. pputs(iesd->pb);
  123. pputc(NL);
  124. itmp = iesd->old_index;
  125. while (itmp--)
  126. pputc(' ');
  127. pputs("^\n\n");
  128. } /* end of show_modem_init_error */
  129. /*+-----------------------------------------------------------------------
  130. process_modem_init(str)
  131. sample /usr/lib/ecu/tty??.mi lines:
  132. init_9600:ATS11=47X4S0=0S7=30\Q0\X0\N0
  133. init_>2400:ATS11=47X4S0=0S7=30\Q0\X0\N0
  134. init_<=2400:ATS11=47X4S0=0S7=30\Q1\X1\N3
  135. ATDT
  136. return 0 if entire list read, else 1 if error (error msg in errmsg)
  137. ------------------------------------------------------------------------*/
  138. void
  139. process_modem_init(str)
  140. char *str;
  141. {
  142. #define MI_INIT 1
  143. #define MI_DIAL 2
  144. #define MI_AUTOANS 3
  145. #define MI_OKSTRING 4
  146. #define MI_CONNSTR 5
  147. int erc;
  148. ESD sesd;
  149. char typestr[32];
  150. int relop;
  151. int truth = 0;
  152. int type;
  153. long test_baud;
  154. sesd.pb = str;
  155. sesd.cb = strlen(str);
  156. sesd.maxcb = strlen(str);
  157. sesd.index = 0;
  158. sesd.old_index = 0;
  159. if (get_alpha_zstr(&sesd, typestr, sizeof(typestr)))
  160. {
  161. erc = eSyntaxError;
  162. goto SHOW_ERROR;
  163. }
  164. if (ulindex(typestr, "init_") == 0)
  165. type = MI_INIT;
  166. else if (ulindex(typestr, "dial_") == 0)
  167. type = MI_DIAL;
  168. /* DGY 07/25/96 allow "connect_string_" to be conditioned by baud */
  169. else if (ulindex(typestr, "connect_string_") == 0)
  170. type = MI_CONNSTR;
  171. else if (!strcmpi(typestr, "autoanswer"))
  172. type = MI_AUTOANS;
  173. else if (!strcmpi(typestr, "ok_string"))
  174. type = MI_OKSTRING;
  175. else
  176. {
  177. erc = eSyntaxError;
  178. goto SHOW_ERROR;
  179. }
  180. /* test for default ... if none, check bit rate */
  181. if ((type == MI_AUTOANS) || (type == MI_OKSTRING))
  182. truth = 1;
  183. else if (ulindex(typestr, "_default") > 0)
  184. {
  185. truth = !(((type == MI_INIT) && Lmodem_init[0]) ||
  186. ((type == MI_CONNSTR) && Lmodem_connstring[0]) ||
  187. ((type == MI_DIAL) && Lmodem_dial[0]));
  188. }
  189. else
  190. {
  191. /* get optional operator */
  192. if (get_relop(&sesd, &relop))
  193. relop = OP_EQ;
  194. if (erc = gint_constant(&sesd, &test_baud))
  195. goto SHOW_ERROR;
  196. truth = test_truth_int((long)shm->Lbitrate, relop, test_baud);
  197. }
  198. /* if no match, skip this one */
  199. if (!truth)
  200. return;
  201. /* skip over colon */
  202. if (erc = skip_colon(&sesd))
  203. goto SHOW_ERROR;
  204. /* make sure init connect or dial string not empty or too long */
  205. if ((erc = skip_cmd_break(&sesd)) &&
  206. !((type == MI_AUTOANS) || (type == MI_OKSTRING)))
  207. goto SHOW_ERROR;
  208. if ((sesd.cb - sesd.index) > (MI_MAX_LEN - 1))
  209. {
  210. erc = eBufferTooSmall;
  211. goto SHOW_ERROR;
  212. }
  213. erc = eDuplicateMatch; /* in case of show error in switch */
  214. switch (type)
  215. {
  216. case MI_INIT:
  217. if (Lmodem_init[0])
  218. goto SHOW_ERROR;
  219. strcpy(Lmodem_init, sesd.pb + sesd.index);
  220. break;
  221. case MI_DIAL:
  222. if (Lmodem_dial[0])
  223. goto SHOW_ERROR;
  224. strcpy(Lmodem_dial, sesd.pb + sesd.index);
  225. break;
  226. case MI_AUTOANS:
  227. if (Lmodem_autoans[0])
  228. goto SHOW_ERROR;
  229. if (!sesd.cb)
  230. strcpy(Lmodem_autoans, "!null!");
  231. else
  232. strcpy(Lmodem_autoans, sesd.pb + sesd.index);
  233. break;
  234. case MI_OKSTRING:
  235. if (Lmodem_okstring[0])
  236. goto SHOW_ERROR;
  237. strcpy(Lmodem_okstring, sesd.pb + sesd.index);
  238. break;
  239. case MI_CONNSTR:
  240. if (Lmodem_connstring[0])
  241. goto SHOW_ERROR;
  242. strcpy(Lmodem_connstring, sesd.pb + sesd.index);
  243. break;
  244. }
  245. return; /* <<<<====== done */
  246. SHOW_ERROR:
  247. show_modem_init_error(erc, &sesd);
  248. } /* end of process_modem_init */
  249. /*+-----------------------------------------------------------------------
  250. DCE_read_modem_init()
  251. 0123456789
  252. /dev/ttyxx
  253. ------------------------------------------------------------------------*/
  254. void
  255. DCE_read_modem_init()
  256. {
  257. char *cp;
  258. FILE *fp_modem;
  259. char *skip_ld_break();
  260. char buffer[128];
  261. /* zap init information */
  262. Lmodem_init[0] = 0;
  263. Lmodem_dial[0] = 0;
  264. /* build filename */
  265. sprintf(mi_name, "%s/%s.mi", CFG_EcuLibDir, shm->Lline + 5);
  266. /* read modem initialization */
  267. if (!(fp_modem = fopen(mi_name, "r")))
  268. pperror(mi_name);
  269. else
  270. {
  271. mi_line = 0;
  272. while ((!Lmodem_init[0] || !Lmodem_dial[0] || !Lmodem_okstring[0] ||
  273. !Lmodem_connstring[0]) &&
  274. fgets(buffer, sizeof(buffer), fp_modem))
  275. {
  276. mi_line++;
  277. buffer[strlen(buffer) - 1] = 0;
  278. cp = skip_ld_break(buffer);
  279. /* skip comments and null lines */
  280. if (!strlen(cp) || (*cp == '#'))
  281. continue;
  282. process_modem_init(cp);
  283. }
  284. fclose(fp_modem);
  285. }
  286. /* default */
  287. if (!Lmodem_init[0])
  288. {
  289. strcpy(Lmodem_init, "ATE1Q0V1");
  290. pputs("modem init string not found (using default '");
  291. pputs(Lmodem_init);
  292. pputs("')\n");
  293. }
  294. if (!Lmodem_dial[0])
  295. {
  296. strcpy(Lmodem_dial, "ATDT");
  297. pputs("modem dial string not found (using default '");
  298. pputs(Lmodem_dial);
  299. pputs("')\n");
  300. }
  301. if (!Lmodem_autoans[0])
  302. strcpy(Lmodem_autoans, "ATQ1S0=1");
  303. if (!Lmodem_okstring[0])
  304. strcpy(Lmodem_okstring, "OK");
  305. if (!Lmodem_connstring[0])
  306. strcpy(Lmodem_connstring, "CONNECT");
  307. if (!strcmp(Lmodem_autoans, "!null!"))
  308. Lmodem_autoans[0] = 0;
  309. if (proc_trace > 1)
  310. {
  311. pprintf("init: '%s'\n", Lmodem_init);
  312. pprintf("dial: '%s'\n", Lmodem_dial);
  313. pprintf("autoanswer: '%s'\n", Lmodem_autoans);
  314. pprintf("ok str: '%s'\n", Lmodem_okstring);
  315. pprintf("conn str: '%s'\n", Lmodem_connstring);
  316. }
  317. } /* end of DCE_read_modem_init */
  318. /*+-------------------------------------------------------------------------
  319. DCE_get_result(msec_to_wait)
  320. return pointer to static buf containing result code
  321. --------------------------------------------------------------------------*/
  322. char *
  323. DCE_get_result(msec_to_wait)
  324. long msec_to_wait;
  325. {
  326. static char s32[32];
  327. LRWT lr;
  328. if (ck_sigint())
  329. return ("!Interrupted");
  330. s32[0] = 0;
  331. lr.to1 = msec_to_wait;
  332. lr.to2 = 200L;
  333. lr.raw_flag = 0x80; /* allow interrupts */
  334. lr.buffer = s32;
  335. lr.bufsize = sizeof(s32);
  336. lr.delim = (char *)0;
  337. lr.echo_flag = 0;
  338. lgets_timeout(&lr);
  339. if (ck_sigint())
  340. return ("!Interrupted");
  341. return (lr.buffer);
  342. } /* end of DCE_get_result */
  343. /*+-------------------------------------------------------------------------
  344. DCE_modem_init()
  345. --------------------------------------------------------------------------*/
  346. DCE_modem_init()
  347. {
  348. int itmp;
  349. int retries = 0;
  350. char *cmd;
  351. char *cp;
  352. int old_ttymode = get_ttymode();
  353. if (shm->Lmodem_already_init)
  354. return (0);
  355. DCE_read_modem_init();
  356. ttymode(2);
  357. lputs_paced(0, "\b\b\b\b\b\b\b\b\b");
  358. (void)Nap(200L);
  359. lflush(0);
  360. while (!shm->Lmodem_already_init)
  361. {
  362. INIT_LOOP:
  363. if (retries > 3)
  364. goto ERROR_RETURN;
  365. if (ck_sigint())
  366. goto ERROR_RETURN;
  367. if (retries)
  368. {
  369. lflash_dtr();
  370. lputs_paced(0, "AT\r");
  371. (void)Nap(200L);
  372. lputs_paced(0, "ATQ0V1E1\r");
  373. (void)Nap(200L);
  374. }
  375. lflush(0);
  376. cmd = Lmodem_init;
  377. itmp = 0;
  378. #ifdef NEUROTIC
  379. while (*cmd)
  380. {
  381. lputc_paced(0, *cmd++);
  382. if (++itmp < 2)
  383. (void)Nap(40L);
  384. if ((itmp = lgetc_timeout(500L)) < 0)
  385. {
  386. if (ck_sigint())
  387. goto ERROR_RETURN;
  388. retries++;
  389. goto INIT_LOOP;
  390. }
  391. pputc(itmp);
  392. }
  393. #else
  394. lputs(cmd);
  395. pputs(cmd);
  396. #endif
  397. pputc(NL);
  398. lputc_paced(0, CRET);
  399. itmp = 0;
  400. while (itmp != CRET)
  401. {
  402. if ((itmp = lgetc_timeout(500L)) < 0)
  403. {
  404. if (ck_sigint())
  405. goto ERROR_RETURN;
  406. pputs("missed expected carriage return\n");
  407. if (itmp < 0)
  408. pprintf("got nothing\n");
  409. else
  410. pprintf("got: %x\n", itmp);
  411. retries++;
  412. goto INIT_LOOP;
  413. }
  414. }
  415. if (strcmp(cp = DCE_get_result(1200L), Lmodem_okstring))
  416. {
  417. if (!strcmp(cp, interrupted_string))
  418. {
  419. sigint = 1;
  420. goto ERROR_RETURN;
  421. }
  422. pprintf("unexpected result: '%s'\n", cp);
  423. retries++;
  424. continue;
  425. }
  426. shm->Lmodem_already_init = 1;
  427. }
  428. ttymode(old_ttymode);
  429. return (0);
  430. ERROR_RETURN:
  431. ttymode(old_ttymode);
  432. return (-1);
  433. } /* end of DCE_modem_init */
  434. /*+-------------------------------------------------------------------------
  435. DCE_send_cmd(cmd)
  436. --------------------------------------------------------------------------*/
  437. int
  438. DCE_send_cmd(cmd)
  439. char *cmd;
  440. {
  441. int itmp;
  442. DCE_modem_init();
  443. (void)Nap(600L);
  444. lflush(0);
  445. #ifdef NEUROTIC
  446. while (*cmd)
  447. {
  448. lputc_paced(20, *cmd++);
  449. if (++char_count < 2)
  450. (void)Nap(40L);
  451. if ((itmp = lgetc_timeout(500L)) < 0)
  452. return (-1);
  453. pputc(itmp);
  454. }
  455. #else
  456. lputs(cmd);
  457. pputs(cmd);
  458. #endif
  459. pputc(NL);
  460. lputc_paced(20, CRET);
  461. itmp = 0;
  462. if (ck_sigint() || check_queued_sigint())
  463. return (-1);
  464. while (itmp != CRET)
  465. {
  466. if ((itmp = lgetc_timeout(1000L)) < 0)
  467. {
  468. pputs("missed expected carriage return\n");
  469. return (-1);
  470. }
  471. if (ck_sigint() || check_queued_sigint())
  472. return (-1);
  473. }
  474. return (0);
  475. } /* end of DCE_send_cmd */
  476. /*+-------------------------------------------------------------------------
  477. DCE_report_iv_set(varnum)
  478. --------------------------------------------------------------------------*/
  479. void
  480. DCE_report_iv_set(varnum)
  481. int varnum;
  482. {
  483. if (proc_trace)
  484. pprintf("Dialer set $i%02d = %ld\n", varnum, iv[varnum]);
  485. } /* end of DCE_report_iv_set */
  486. /*+-------------------------------------------------------------------------
  487. is_extant_dialproc(device) - find dialer procedure for device
  488. --------------------------------------------------------------------------*/
  489. char *
  490. is_extant_dialproc(device)
  491. char *device;
  492. {
  493. char *devbase = base_name(device);
  494. char dpnm[ECU_MAXPN];
  495. strcpy(dpnm, "dialproc/");
  496. strcat(dpnm, devbase);
  497. return ((find_procedure(dpnm)) ? dpnm : 0);
  498. } /* end of is_extant_dialproc */
  499. /*+-----------------------------------------------------------------------
  500. DCE_dial() - dial a remote or connect
  501. All shm->L... variables have been set up and are used to
  502. drive the dialing sequence
  503. returns 0 on success (CONNECT),
  504. eConnectFailed if failure
  505. eCONINT on interrupt
  506. sets #I0 to 0==connect,
  507. 1==failed to connect,
  508. 2==interrupted
  509. 3==modem error
  510. sets #S0 to modem result code or uucp status code string
  511. This function has become quite NASTY and needs rewriting!
  512. ------------------------------------------------------------------------*/
  513. int
  514. DCE_dial()
  515. {
  516. char s128[128];
  517. char *_proc_args[10];
  518. int itmp;
  519. int erc = -1; /* assume error unless chg'd */
  520. int s7;
  521. char *result = "";
  522. int restart_rcvr = need_rcvr_restart();
  523. UINT32 colors_at_entry = colors_current;
  524. char s64[64];
  525. FILE *fp;
  526. char *cp;
  527. char credit_file[128];
  528. extern int tty_not_char_special;
  529. kill_rcvr_process(SIGUSR1);
  530. lclear_xmtr_xoff();
  531. if (shm->Ldescr[0])
  532. {
  533. setcolor(colors_success);
  534. timeofday_text(1, s64);
  535. pprintf("%s %s\n",
  536. (shm->Ltelno[0]) ? "Dialing" : "Connecting to", shm->Ldescr);
  537. pprintf("on %s at %u baud (%s)\n", shm->Lline, shm->Lbitrate, s64);
  538. }
  539. if (shm->Liofd > 0)
  540. DCE_hangup();
  541. last_dial_result[0] = 0;
  542. setcolor(colors_alert);
  543. if (!shm->Ltelno[0]) /* if no phone number, direct connect */
  544. {
  545. sprintf(s64, "CONNECT %u", shm->Lbitrate);
  546. result = s64;
  547. iv[0] = 0;
  548. erc = 0;
  549. shm->Lconnected = 1;
  550. Ldial_debug_level = 0;
  551. goto CONNECTED;
  552. }
  553. else
  554. {
  555. char *dialproc = is_extant_dialproc(shm->Lline);
  556. /*
  557. * if there is a dialer procedure, invoke it else call the
  558. * traditional dialer
  559. */
  560. if (!dialproc)
  561. {
  562. itmp = hdb_dial(&result);
  563. lreset_ksr(); /* dialer may have changed termio */
  564. }
  565. else
  566. {
  567. char dialproc_buf[ECU_MAXPN];
  568. /*
  569. * copy static result
  570. */
  571. strcpy(dialproc_buf,dialproc);
  572. /*
  573. * call procedure
  574. */
  575. pprintf("Using dialer procedure %s\n",
  576. find_procedure(dialproc_buf));
  577. _proc_args[0] = dialproc_buf;
  578. _proc_args[1] = shm->Ltelno;
  579. if (do_proc(2, _proc_args)) /* if procedure executes well */
  580. {
  581. erc = eConnectFailed;
  582. goto START_RCVR_PROCESS;
  583. }
  584. /*
  585. * dialproc responsible for plugging $i0 and $s0
  586. */
  587. itmp = iv[0]; /* dial result code 0-n returned in $i0 */
  588. result = sv[0]->pb;
  589. }
  590. /*
  591. * check status of dialing operation
  592. */
  593. switch (itmp)
  594. {
  595. case 0: /* success */
  596. goto CONNECTED;
  597. case 1: /* failure -- iv[0] set by hdb_dial */
  598. DCE_report_iv_set(0);
  599. erc = eConnectFailed;
  600. goto START_RCVR_PROCESS;
  601. case 2: /* interrupted -- iv[0] set by hdb_dial */
  602. erc = eCONINT;
  603. DCE_report_iv_set(0);
  604. goto START_RCVR_PROCESS;
  605. case 3: /* modem error */
  606. DCE_report_iv_set(0);
  607. setcolor(colors_error);
  608. pprintf("%s\n", result);
  609. goto CANNOT_TALK_TO_MODEM;
  610. case 4: /* try built-in dialer */
  611. break;
  612. default:
  613. DCE_report_iv_set(0);
  614. setcolor(colors_error);
  615. pprintf("Undefined dialer result %d\n", itmp);
  616. erc = eConnectFailed;
  617. goto START_RCVR_PROCESS;
  618. }
  619. /*
  620. * brain-damaged "built-in dialer"
  621. */
  622. pputs("\nTrying ecu dialer\n");
  623. kill_rcvr_process(SIGUSR1);
  624. DCE_modem_init();
  625. #if defined(USE_S7)
  626. if ((s7 = DCE_get_sreg_value(7)) < 0)
  627. s7 = CFG_DialTimeout;
  628. #else
  629. s7 = CFG_DialTimeout;
  630. #endif
  631. /*
  632. * build dial command
  633. */
  634. strcpy(s128, Lmodem_dial);
  635. strcat(s128, shm->Ltelno);
  636. /*
  637. * if trailing '$', read and append ~/.ecu/.credit
  638. */
  639. if (*(cp = s128 + strlen(s128) - 1) == '$')
  640. {
  641. *cp = 0;
  642. get_home_dir(credit_file);
  643. strcat(credit_file, "/.ecu/.credit");
  644. if (fp = fopen(credit_file, "r"))
  645. {
  646. fgets(cp, 30, fp);
  647. fclose(fp);
  648. }
  649. if (!fp || !(*cp))
  650. {
  651. result = "!CREDIT CARD ERROR";
  652. goto CONNECT_FAILED;
  653. }
  654. if (*(cp + strlen(cp) - 1) == 0x0A)
  655. *(cp + strlen(cp) - 1) = 0; /* kill NL */
  656. }
  657. if (ck_sigint() || check_queued_sigint())
  658. goto SEND_CMD_ERROR;
  659. if (DCE_send_cmd(s128))
  660. goto SEND_CMD_ERROR;
  661. /*
  662. * some modems (ahem, the Hayes 2400) do not accurately honor S7
  663. * so our timer is twice sreg 7
  664. */
  665. if (!tty_not_char_special)
  666. {
  667. pprintf("Type %s to abort ... ", (kbdintr == DEL) ? "DEL" :
  668. graphic_char_text(kbdintr, 0));
  669. }
  670. setcolor(colors_normal);
  671. lflush(0);
  672. strcpy(s64, DCE_get_result(s7 * 2 * 1000L));
  673. result = s64;
  674. if (ck_sigint() || !strcmp(result, interrupted_string))
  675. {
  676. setcolor(colors_error);
  677. pprintf("%s\n", result);
  678. sigint = 0;
  679. lputc(0); /* send char in case DTR ignored */
  680. lflash_dtr(); /* force on hook */
  681. (void)DCE_get_result(2000L); /* wait for any result code */
  682. erc = eCONINT;
  683. iv[0] = 2;
  684. DCE_report_iv_set(0);
  685. goto START_RCVR_PROCESS;
  686. }
  687. if (!strncmp(result, Lmodem_connstring, strlen(Lmodem_connstring)))
  688. {
  689. if (strlen(result) > 7)
  690. {
  691. UINT speed = atoi(result + strlen(Lmodem_connstring));
  692. if (speed && (shm->Lbitrate != speed))
  693. {
  694. setcolor(colors_alert);
  695. pprintf("%s (warning: unexpected rate)\n", result);
  696. }
  697. }
  698. CONNECTED:
  699. #if defined(WHT2) && defined(XTERM_FRIEND)
  700. /*
  701. * if xterm, put connection in title bar but this really
  702. * should be done in _connect.ep
  703. */
  704. sprintf(s128, "connected to %s", shm->Llogical);
  705. xterm_title(s128, 1);
  706. #endif
  707. setcolor(colors_success);
  708. pprintf("%s\n", result);
  709. sprintf(s128, "CONNECT %s (%s) %u baud",
  710. shm->Llogical, shm->Ltelno, shm->Lbitrate);
  711. strcpy(shm->Lrname, shm->Llogical);
  712. logevent(getpid(), s128);
  713. if (isalpha(shm->Llogical[0]))
  714. {
  715. if (!keyset_read(shm->Llogical))
  716. pprintf("[autoloaded fkeys for %s]\n", shm->Llogical);
  717. }
  718. shm->rcvd_chars_this_connect = 0;
  719. shm->xmit_chars_this_connect = 0;
  720. shm->Loff_hook_time = time((long *)0);
  721. iv[0] = 0;
  722. DCE_report_iv_set(0);
  723. erc = 0;
  724. shm->Lconnected = 1;
  725. lCLOCAL(!shm->Ldcdwatch); /* set CLOCAL per DCD watcher */
  726. goto START_RCVR_PROCESS;
  727. }
  728. CONNECT_FAILED:
  729. setcolor(colors_error);
  730. pprintf("%s\n", result);
  731. iv[0] = 1;
  732. DCE_report_iv_set(0);
  733. erc = eConnectFailed;
  734. goto START_RCVR_PROCESS;
  735. }
  736. SEND_CMD_ERROR:
  737. if (ck_sigint())
  738. {
  739. sigint = 0;
  740. result = interrupted_string;
  741. iv[0] = 2;
  742. DCE_report_iv_set(0);
  743. erc = eCONINT;
  744. }
  745. else
  746. {
  747. CANNOT_TALK_TO_MODEM:
  748. setcolor(colors_error);
  749. pprintf("Cannot talk to modem\n");
  750. result = "!Modem Error";
  751. iv[0] = 3;
  752. DCE_report_iv_set(0);
  753. erc = eConnectFailed;
  754. }
  755. START_RCVR_PROCESS:
  756. setcolor(colors_at_entry);
  757. strcpy(sv[0]->pb, result);
  758. sv[0]->cb = strlen(result);
  759. strcpy(last_dial_result, result);
  760. /*
  761. * do the _connect.ep or _connfail.ep execution
  762. */
  763. if (!iv[0])
  764. {
  765. if (find_procedure("_connect"))
  766. {
  767. int erc2;
  768. _proc_args[0] = "_connect"; /* _connect.ep */
  769. _proc_args[1] = result; /* "CONNECT XXXX" */
  770. if (erc2 = do_proc(2, _proc_args))
  771. {
  772. DCE_hangup();
  773. if (erc2 < 256)
  774. {
  775. sprintf(s64, "!CONNECT PROCEDURE RETURNED %d", erc2);
  776. result = s64;
  777. }
  778. else
  779. result = "!CONNECT PROCEDURE ABNORMAL TERMINATION";
  780. strcpy(sv[0]->pb, result);
  781. sv[0]->cb = strlen(result);
  782. setcolor(colors_error);
  783. pprintf("%s\n", result);
  784. iv[0] = 1;
  785. DCE_report_iv_set(0);
  786. erc = eConnectFailed;
  787. }
  788. }
  789. }
  790. else if (find_procedure("_connfail"))
  791. {
  792. _proc_args[0] = "_connfail"; /* _connfail.ep */
  793. _proc_args[1] = shm->Llogical;
  794. _proc_args[2] = result;
  795. (void)do_proc(3, _proc_args);
  796. }
  797. rcvr_conditional_restart(restart_rcvr, 1);
  798. return (erc);
  799. } /* end of DCE_dial */
  800. /*+-------------------------------------------------------------------------
  801. DCE_redial(arg,argc)
  802. --------------------------------------------------------------------------*/
  803. DCE_redial(arg, argc)
  804. char **arg;
  805. int argc;
  806. {
  807. int erc = 0;
  808. int delay = 60;
  809. int retries = 10;
  810. long nap_msec;
  811. char ans;
  812. if (shm->Ltelno[0] == 0)
  813. {
  814. pprintf(" no previous number\n");
  815. return (-1);
  816. }
  817. if ((argc > 1) && ((retries = atoi(arg[1])) == 0))
  818. {
  819. pprintf(" invalid retry count\n");
  820. return (-1);
  821. }
  822. if ((argc > 2) && ((delay = atoi(arg[2])) == 0))
  823. {
  824. pprintf(" invalid delay\n");
  825. return (-1);
  826. }
  827. if (delay < 0) /* try to be nice to telcos */
  828. delay = 0; /* (they are our friends :-) */
  829. pprintf(" for %d retries, pause between: %d secs\n",
  830. retries, delay);
  831. kill_rcvr_process(SIGUSR1); /* kill rcvr process */
  832. DCE_hangup();
  833. while (retries--)
  834. {
  835. if (!isdigit((uchar) shm->Llogical[0]) &&
  836. find_procedure(shm->Llogical))
  837. {
  838. char *_proc_args[2];
  839. UINT32 colors_at_entry = colors_current;
  840. _proc_args[0] = shm->Llogical;
  841. _proc_args[1] = "!REDIAL;";
  842. sigint = 0;
  843. ttymode(2);
  844. erc = do_proc(2, _proc_args);
  845. proc_file_reset();
  846. ttymode(1);
  847. setcolor(colors_notify);
  848. ff(se, "[procedure finished]");
  849. setcolor(colors_at_entry);
  850. ff(se, "\r\n");
  851. if (!erc)
  852. {
  853. start_rcvr_process(0);
  854. return (0);
  855. }
  856. lflash_dtr();
  857. sigint = 0;
  858. }
  859. else if (!(erc = DCE_dial()))
  860. {
  861. start_rcvr_process(1);
  862. return (0);
  863. }
  864. if (ck_sigint() || !strcmp(last_dial_result, interrupted_string))
  865. goto ABORT_CYCLE;
  866. if ((retries == 0) || (erc >= e_FATAL))
  867. break;
  868. pprintf("%d %s left ... ",
  869. retries, (retries == 1) ? "retry" : "retries");
  870. nap_msec = delay * 1000L;
  871. ff(se, "waiting %d seconds ... 'c' to cycle, %s to abort\r\n",
  872. delay, (kbdintr == DEL) ? "DEL" : graphic_char_text(kbdintr, 0));
  873. while (nap_msec > 0)
  874. {
  875. nap_msec -= Nap(100L);
  876. while (ttyrdchk())
  877. {
  878. ans = to_lower(ttygetc(1));
  879. if (ans == 'c')
  880. goto CONTINUE_CYCLE;
  881. else if (ans == (char)kbdintr)
  882. goto ABORT_CYCLE;
  883. else
  884. ring_bell();
  885. }
  886. if (ck_sigint())
  887. goto ABORT_CYCLE;
  888. }
  889. CONTINUE_CYCLE:
  890. DCE_hangup();
  891. }
  892. ERROR_RETURN:
  893. DCE_hangup();
  894. start_rcvr_process(1);
  895. return (-1);
  896. ABORT_CYCLE:
  897. DCE_hangup();
  898. ff(se, "redial ABORTED\r\n");
  899. sigint = 0;
  900. goto ERROR_RETURN;
  901. } /* end of DCE_redial */
  902. /*+-------------------------------------------------------------------------
  903. DCE_now_on_hook() - DCE no longer in connection
  904. This may be called, however, when no connection is active
  905. --------------------------------------------------------------------------*/
  906. void
  907. DCE_now_on_hook()
  908. {
  909. char s128[128];
  910. long connect_secs;
  911. lCLOCAL(1); /* turn on CLOCAL */
  912. if (shm->Lconnected)
  913. {
  914. connect_secs = time((long *)0) - shm->Loff_hook_time;
  915. sprintf(s128, "DISCONNECT %s (%s) %ld %s",
  916. shm->Llogical, shm->Ltelno, connect_secs,
  917. elapsed_time_text(connect_secs));
  918. logevent(getpid(), s128);
  919. #if defined(WHT2) || defined(XTERM_FRIEND)
  920. /*
  921. * if xterm, put disconnected status in title bar but this really
  922. * should be done in _hangup.ep
  923. */
  924. xterm_title("disconnected", 1);
  925. #endif
  926. /*
  927. * do the _hangup.ep execution
  928. */
  929. if (find_procedure("_hangup"))
  930. {
  931. char *_hangup_args[2];
  932. sprintf(s128, "%ld", connect_secs);
  933. _hangup_args[0] = "_hangup";
  934. _hangup_args[1] = s128;
  935. (void)do_proc(2, _hangup_args);
  936. }
  937. shm->Lconnected = 0;
  938. }
  939. shm->Lrname[0] = 0;
  940. set_default_escape_prompt();
  941. #ifdef CFG_TelnetOption
  942. if (shm->Ltelnet)
  943. {
  944. lclose();
  945. shm->Ltelnet = 0;
  946. }
  947. #endif
  948. } /* end of DCE_now_on_hook */
  949. /*+-------------------------------------------------------------------------
  950. DCE_hangup() - terminate any active connection
  951. --------------------------------------------------------------------------*/
  952. void
  953. DCE_hangup()
  954. {
  955. int restart_rcvr = need_rcvr_restart();
  956. if (restart_rcvr)
  957. kill_rcvr_process(SIGUSR1);
  958. lflash_dtr();
  959. DCE_now_on_hook();
  960. if (restart_rcvr)
  961. start_rcvr_process(0);
  962. } /* end of DCE_hangup */
  963. /*+-------------------------------------------------------------------------
  964. DCE_get_sreg_value(regnum)
  965. assumes rcvr process has been killed
  966. --------------------------------------------------------------------------*/
  967. int
  968. DCE_get_sreg_value(regnum)
  969. int regnum;
  970. {
  971. char s128[128];
  972. LRWT lr;
  973. sprintf(s128, "ATS%d?", regnum);
  974. DCE_send_cmd(s128);
  975. lflush(0);
  976. lr.to1 = 2000L;
  977. lr.to2 = 140L;
  978. lr.raw_flag = 0;
  979. lr.buffer = s128;
  980. lr.bufsize = sizeof(s128);
  981. lr.delim = (char *)0;
  982. lr.echo_flag = 0;
  983. lgets_timeout(&lr);
  984. if (lr.count != 3)
  985. return (-1);
  986. return (atoi(s128));
  987. } /* end of DCE_get_sreg_value */
  988. /*+-------------------------------------------------------------------------
  989. DCE_set_sreg(regnum,value)
  990. assumes rcvr process has been killed
  991. returns 0 if no error (reads back value set),
  992. else -1 and error message has been printed
  993. --------------------------------------------------------------------------*/
  994. int
  995. DCE_set_sreg(regnum, value)
  996. int regnum;
  997. int value;
  998. {
  999. char s128[128];
  1000. int value2;
  1001. LRWT lr;
  1002. sprintf(s128, "ATS%d=%d", regnum, value);
  1003. DCE_send_cmd(s128);
  1004. lflush(0);
  1005. lr.to1 = 2000L;
  1006. lr.to2 = 140L;
  1007. lr.raw_flag = 0;
  1008. lr.buffer = s128;
  1009. lr.bufsize = sizeof(s128);
  1010. lr.delim = (char *)0;
  1011. lr.echo_flag = 0;
  1012. lgets_timeout(&lr);
  1013. value2 = DCE_get_sreg_value(regnum);
  1014. if (value2 < 0)
  1015. pprintf("PROBLEM setting modem S%d=%d; cannot talk to modem\n",
  1016. regnum, value);
  1017. else if (value != value2)
  1018. pprintf("PROBLEM setting modem S%d=%d; got %d back\n",
  1019. regnum, value, value2);
  1020. return ((value != value2) ? -1 : 0);
  1021. } /* end of DCE_set_sreg */
  1022. /*+-------------------------------------------------------------------------
  1023. DCE_autoanswer()
  1024. --------------------------------------------------------------------------*/
  1025. void
  1026. DCE_autoanswer()
  1027. {
  1028. if (!Lmodem_autoans[0])
  1029. return;
  1030. (void)Nap(200L);
  1031. lputs_paced(20, "AT\r");
  1032. (void)Nap(100L);
  1033. lputs_paced(20, Lmodem_autoans); /* quiet modem */
  1034. lputs_paced(20, "\r");
  1035. (void)Nap(200L);
  1036. lputs_paced(20, Lmodem_autoans); /* quiet modem */
  1037. lputs_paced(20, "\r");
  1038. (void)Nap(200L);
  1039. lflush(0);
  1040. } /* end of DCE_autoanswer */
  1041. /* end of ecuDCE.c */
  1042. /* vi: set tabstop=4 shiftwidth=4: */