ecupde.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643
  1. /*+-------------------------------------------------------------------------
  2. ecupde.c - various PDE-related functions
  3. wht@wht.net
  4. Defined functions:
  5. call_logical_telno(logical)
  6. choose_tty_for_pde(tpde)
  7. copy_pde_to_Lvariables(tpde, trial)
  8. logical_telno_to_pde(logical)
  9. pde_dial(tpde)
  10. pdetty_to_devtty(pdetty, devtty)
  11. --------------------------------------------------------------------------*/
  12. /*+:EDITS:*/
  13. /*:04-26-2000-11:15-wht@bob-RELEASE 4.42 */
  14. /*:01-24-1997-02:37-wht@yuriatin-SOURCE RELEASE 4.00 */
  15. /*:09-16-1996-05:21-wht@yuriatin-move phdir_list_read to ecuphdir.c */
  16. /*:09-11-1996-20:00-wht@yuriatin-3.48-major telnet,curses,structural overhaul */
  17. /*:09-09-1996-20:51-wht@yuriatin-pde_dial handles telnet */
  18. /*:08-20-1996-12:39-wht@kepler-locale/ctype fixes from ache@nagual.ru */
  19. /*:08-11-1996-03:22-wht@kepler-use vlogevent */
  20. /*:12-12-1995-14:40-wht@kepler-preserve trailing period in logical telno */
  21. /*:11-23-1995-11:20-wht@kepler-source control 3.37 for tsx-11 */
  22. /*:11-14-1995-10:23-wht@kepler-3.37.80-source control point: SOCKETS */
  23. /*:11-03-1995-16:53-wht@wwtp1-use CFG_TelnetOption */
  24. /*:09-17-1995-16:43-wht@kepler-ECU on Linux does not support dcdw==1 */
  25. /*:08-27-1995-06:53-wht@n4hgf-handle shm->Lrtsctsval and pde->rtscts_val */
  26. /*:06-15-1995-07:41-wht@kepler-ensure new tty exists before lclose other */
  27. /*:05-04-1994-04:38-wht@n4hgf-ECU release 3.30 */
  28. /*:05-29-1993-21:47-wht@n4hgf-better debug */
  29. /*:05-29-1993-20:21-wht@n4hgf-change linst_err_text to LINST_text */
  30. /*:03-27-1993-17:45-wht@n4hgf-SVR4 cc complained about strlen <= constant */
  31. /*:09-10-1992-13:58-wht@n4hgf-ECU release 3.20 */
  32. /*:09-05-1992-14:17-wht@n4hgf-was starting rcvr process too early on connect */
  33. /*:08-22-1992-15:38-wht@n4hgf-ECU release 3.20 BETA */
  34. /*:05-13-1992-13:27-wht@n4hgf-active_pde use */
  35. /*:04-24-1992-21:59-wht@n4hgf-more SCO tty name normalizing */
  36. /*:12-02-1991-20:58-wht@n4hgf-breakout into separate module */
  37. #include "ecu.h"
  38. #include "esd.h"
  39. #include "var.h"
  40. #include "ecupde.h"
  41. #include "dvent.h"
  42. #include "termecu.h"
  43. #include "ecuerror.h"
  44. #include "utmpstatus.h"
  45. DVE *hdb_choose_Any();
  46. DVE *hdb_choose_Device();
  47. PDE *phdir_list_search();
  48. char *LINST_text();
  49. extern char errmsg[];
  50. extern char *default_tty;
  51. extern int windows_active;
  52. char phonedir_name[PHONEDIR_NAME_SIZE];
  53. char *phonedir_trigger = "#ECUPHONE\n";
  54. /*+-------------------------------------------------------------------------
  55. pde_dial(tpde) - dial using a pde (using procedure if configured)
  56. If the tpde->logical points to a valid procedure, use it,
  57. otherwise call DCE_dial()
  58. returns proc error code
  59. $i0 value ($s0 is also set, BTW)
  60. assumes rcvr process dead (shm->rcvr_pid == -1)
  61. --------------------------------------------------------------------------*/
  62. int
  63. pde_dial(tpde)
  64. PDE *tpde;
  65. {
  66. int status = 0;
  67. int restart_rcvr = need_rcvr_restart();
  68. char *cp;
  69. extern int dcdwatch_set; /* see ldcdwatch() in eculine.c */
  70. dcdwatch_set = 0; /* this is a rat-faced kludge */
  71. kill_rcvr_process(SIGUSR1);
  72. if (proc_level || !find_procedure(tpde->logical))
  73. {
  74. #ifdef CFG_TelnetOption
  75. if (!strcmp(tpde->tty, "telnet"))
  76. {
  77. enum linst linst;
  78. shm->Lbitrate = tpde->baud;
  79. strcpy(shm->Llogical, tpde->logical);
  80. strcpy(shm->Ldescr, tpde->descr);
  81. strcpy(shm->Ltelno, tpde->telno);
  82. if (!proc_level)
  83. restart_rcvr = 1;
  84. linst = telnet_open();
  85. if (linst)
  86. {
  87. UINT32 colors_at_entry = colors_current;
  88. setcolor(colors_error);
  89. pprintf("CONNECT FAILED");
  90. setcolor(colors_at_entry);
  91. pprintf("\n");
  92. }
  93. if (restart_rcvr)
  94. start_rcvr_process(1);
  95. return ((!linst) ? 0 : eFATAL_ALREADY);
  96. }
  97. #endif /* CFG_TelnetOption */
  98. if (copy_pde_to_Lvariables(tpde, 0))
  99. {
  100. pprintf("%s: %s\n", tpde->logical, errmsg);
  101. pprintf("Current line is %s (%s)\n",
  102. shm->Lline, (shm->Liofd < 0) ? "closed" : "open");
  103. status = eFATAL_ALREADY;
  104. }
  105. else
  106. status = DCE_dial();
  107. }
  108. else
  109. {
  110. char *pargv[2];
  111. pargv[0] = tpde->logical;
  112. pargv[1] = "!MENU";
  113. iv[0] = 0;
  114. if (do_proc(2, pargv))
  115. status = eFATAL_ALREADY;
  116. else
  117. status = (iv[0]) ? eConnectFailed : 0;
  118. #ifdef CFG_TelnetOption
  119. if (shm->Ltelnet && (shm->Liofd > -1))
  120. start_rcvr_process(1);
  121. #endif /* CFG_TelnetOption */
  122. }
  123. /*
  124. * if we connected and a procedure did not change the DCD watcher,
  125. * then use the dialing directory choice
  126. */
  127. if (!status && !dcdwatch_set)
  128. {
  129. cp = (char *)0;
  130. switch (tpde->dcdwatch)
  131. {
  132. case '0':
  133. ldcdwatch(DCDW_OFF);
  134. cp = "OFF (ignore DCD loss)";
  135. break;
  136. #ifndef linux
  137. case '1':
  138. ldcdwatch(DCDW_ON);
  139. cp = "ON (detect DCD loss)";
  140. break;
  141. #endif
  142. case 't':
  143. ldcdwatch(DCDW_TERMINATE);
  144. cp = "TERMINATE (terminate ecu on DCD loss)";
  145. break;
  146. case 'n':
  147. default:
  148. break;
  149. }
  150. if (cp)
  151. {
  152. UINT32 colors_save;
  153. colors_save = colors_current;
  154. setcolor(colors_notify);
  155. pprintf("[DCD watcher set to %s]", cp);
  156. setcolor(colors_save);
  157. fputs("\r\n", se);
  158. pputs("\n");
  159. }
  160. }
  161. if (restart_rcvr)
  162. start_rcvr_process(1);
  163. return (status);
  164. } /* end of pde_dial */
  165. /*+-------------------------------------------------------------------------
  166. pdetty_to_devtty(pdetty,devtty) -> pde tty field to complete pathname
  167. --------------------------------------------------------------------------*/
  168. void
  169. pdetty_to_devtty(pdetty, devtty)
  170. char *pdetty;
  171. char *devtty;
  172. {
  173. strcpy(devtty, "/dev/");
  174. strcat(devtty, pdetty);
  175. } /* end of pdetty_to_devtty */
  176. /*+-------------------------------------------------------------------------
  177. choose_tty_for_pde(tpde) - new pde might mandate switching line
  178. Returns 1 if new line open needed
  179. 0 if no new line open needed
  180. -1 if request cannot be satisfied
  181. --------------------------------------------------------------------------*/
  182. int
  183. choose_tty_for_pde(tpde)
  184. PDE *tpde;
  185. {
  186. int itmp = 0;
  187. int rtn = 0;
  188. DVE *tdve;
  189. struct stat st;
  190. char newtty[64];
  191. #ifdef CHOOSE_DEBUG
  192. vlogevent(xmtr_pid, "CHOOSE_TTY_FOR_PDE '%s' %u baud",
  193. tpde->tty, tpde->baud);
  194. errmsg[0] = 0;
  195. #endif
  196. #ifdef CFG_TelnetOption
  197. if (shm->Ltelnet)
  198. goto FUNC_RETURN;
  199. #endif
  200. /*
  201. * if desired line is Devices type
  202. */
  203. if ((tpde->tty[0] == '=') || (tpde->tty[0] == '/')) /* Devices or device */
  204. {
  205. if (!(tdve = hdb_choose_Device(tpde->tty, tpde->baud)))
  206. {
  207. sprintf(errmsg, "no idle line matches type '%s' at %u baud",
  208. *tpde->tty ? tpde->tty : "Any", tpde->baud);
  209. rtn = -1;
  210. goto FUNC_RETURN;
  211. }
  212. sprintf(newtty, "/dev/%s", tdve->line);
  213. if (stat(newtty, &st))
  214. {
  215. sprintf(errmsg, "%s: %s", newtty, strerror(errno));
  216. rtn = -1;
  217. goto FUNC_RETURN;
  218. }
  219. if ((itmp = reserve_line(newtty)) && (itmp != LINST_WEGOTIT))
  220. {
  221. sprintf(errmsg, "%s: %s", newtty, LINST_text(itmp));
  222. rtn = -1;
  223. goto FUNC_RETURN;
  224. }
  225. if ((itmp = lock_tty(newtty)) && (itmp != LINST_WEGOTIT))
  226. {
  227. sprintf(errmsg, "%s (%s): %s",
  228. tpde->tty, tdve->line, LINST_text(itmp));
  229. rtn = -1;
  230. goto FUNC_RETURN;
  231. }
  232. }
  233. /*
  234. * if desired line is a specific tty
  235. */
  236. else if (tpde->tty[0])
  237. {
  238. pdetty_to_devtty(tpde->tty, newtty);
  239. if ((shm->Liofd > 0) && !strcmp(newtty, shm->Lline))
  240. {
  241. rtn = 0; /* requesting line we already have */
  242. goto FUNC_RETURN;
  243. }
  244. if (stat(newtty, &st))
  245. {
  246. sprintf(errmsg, "%s: %s", newtty, strerror(errno));
  247. rtn = -1;
  248. goto FUNC_RETURN;
  249. }
  250. if ((itmp = reserve_line(newtty)) && (itmp != LINST_WEGOTIT))
  251. {
  252. sprintf(errmsg, "%s: %s", newtty, LINST_text(itmp));
  253. rtn = -1;
  254. goto FUNC_RETURN;
  255. }
  256. if ((itmp = lock_tty(newtty)) && (itmp != LINST_WEGOTIT))
  257. {
  258. sprintf(errmsg, "%s: %s", newtty, LINST_text(itmp));
  259. rtn = -1;
  260. goto FUNC_RETURN;
  261. }
  262. }
  263. /*
  264. * if desired line is "Any" (any Devices type beginning with ACU)
  265. */
  266. else
  267. /* "Any" */
  268. {
  269. tdve = hdb_choose_Any(tpde->baud);
  270. if (!tdve)
  271. {
  272. sprintf(errmsg, "no idle ACU line at %u baud", tpde->baud);
  273. rtn = -1;
  274. goto FUNC_RETURN;
  275. }
  276. sprintf(newtty, "/dev/%s", tdve->line);
  277. if ((itmp = lock_tty(newtty)) && (itmp != LINST_WEGOTIT))
  278. {
  279. sprintf(errmsg, "%s: %s", newtty, LINST_text(itmp));
  280. rtn = -1;
  281. goto FUNC_RETURN;
  282. }
  283. if ((itmp = reserve_line(newtty)) && (itmp != LINST_WEGOTIT))
  284. {
  285. sprintf(errmsg, "%s: %s", newtty, LINST_text(itmp));
  286. rtn = -1;
  287. goto FUNC_RETURN;
  288. }
  289. }
  290. rtn = !(!strcmp(newtty, shm->Lline) && (shm->Liofd != -1));
  291. if (rtn)
  292. {
  293. lclose();
  294. strcpy(shm->Lline, newtty);
  295. }
  296. FUNC_RETURN:
  297. #ifdef CHOOSE_DEBUG
  298. vlogevent(xmtr_pid, "CHOOSE_TTY_FOR_PDE rtn=%d line='%s' errmsg='%s' itmp=%d",
  299. rtn, shm->Lline, errmsg, itmp);
  300. #endif
  301. return (rtn);
  302. } /* end of choose_tty_for_pde */
  303. /*+-------------------------------------------------------------------------
  304. copy_pde_to_Lvariables(tpde,trial)
  305. 'trial' controls whether this is a dry run (setup) or a live
  306. request; if changing line, close old line and open new one; if
  307. cannot change line, return -1, else 0
  308. --------------------------------------------------------------------------*/
  309. int
  310. copy_pde_to_Lvariables(tpde, trial)
  311. PDE *tpde;
  312. int trial;
  313. {
  314. int reopen = 0;
  315. int lerr;
  316. DVE *tdve;
  317. #ifdef CHOOSE_DEBUG
  318. vlogevent(xmtr_pid, "COPY_PDE1 trial=%d Lline='%s' pdetty='%s'",
  319. trial, shm->Lline, tpde->tty);
  320. #endif
  321. #ifdef CFG_TelnetOption
  322. if ((!strcmp(tpde->tty, "telnet")) || strchr(tpde->telno, '.'))
  323. {
  324. int itmp;
  325. strcpy(shm->Lline, "/dev/telnet");
  326. shm->Ltelnet = 1;
  327. shm->Lfull_duplex = 1;
  328. shm->Lbitrate = tpde->baud;
  329. shm->Lparity = 0;
  330. shm->Ladd_nl_incoming = 0;
  331. shm->Ladd_nl_outgoing = 0;
  332. strcpy(shm->Llogical, tpde->logical);
  333. strcpy(shm->Ldescr, tpde->descr);
  334. strcpy(shm->Ltelno, tpde->telno);
  335. if ((itmp = strlen(shm->Ltelno)) && (shm->Ltelno[itmp - 1] == '.'))
  336. shm->Ltelno[itmp - 1] = 0;
  337. if (!shm->Ldescr[0])
  338. strcpy(shm->Ldescr, shm->Llogical);
  339. return (0);
  340. }
  341. shm->Ltelnet = 0;
  342. #endif
  343. enddvent(); /* krock safety */
  344. if (!trial)
  345. {
  346. if ((reopen = choose_tty_for_pde(tpde)) < 0)
  347. return (-1); /* errmsg[] updated */
  348. }
  349. else if ((!tpde->tty[0]) || (!strcmp(tpde->tty, "Any")))
  350. {
  351. if (!(tdve = hdb_choose_Any(tpde->baud)))
  352. {
  353. strcpy(errmsg, "no idle line matches type 'Any'");
  354. return (-1);
  355. }
  356. strcpy(shm->Lline, "/dev/");
  357. strncat(shm->Lline, tdve->line, sizeof(shm->Lline) - 5);
  358. shm->Lline[sizeof(shm->Lline) - 1] = 0;
  359. }
  360. else if ((tpde->tty[0] == '/') || (tpde->tty[0] == '='))
  361. {
  362. if (!(tdve = hdb_choose_Device(tpde->tty, tpde->baud)))
  363. {
  364. sprintf(errmsg, "no idle line matches type '%s' at %u baud",
  365. *tpde->tty ? tpde->tty : "Any", tpde->baud);
  366. return (-1);
  367. }
  368. strcpy(shm->Lline, "/dev/");
  369. strncat(shm->Lline, tdve->line, sizeof(shm->Lline) - 5);
  370. shm->Lline[sizeof(shm->Lline) - 1] = 0;
  371. }
  372. else
  373. pdetty_to_devtty(tpde->tty, shm->Lline);
  374. #ifdef CHOOSE_DEBUG
  375. vlogevent(xmtr_pid, "COPY_PDE2 Lline='%s' reopen=%d", shm->Lline, reopen);
  376. #endif
  377. shm->Lbitrate = tpde->baud;
  378. strcpy(shm->Llogical, tpde->logical);
  379. strcpy(shm->Ldescr, tpde->descr);
  380. strcpy(shm->Ltelno, tpde->telno);
  381. if (!shm->Ldescr[0])
  382. strcpy(shm->Ldescr, shm->Llogical);
  383. shm->Lparity = tpde->parity;
  384. if (shm->Lbitrate != tpde->baud)
  385. shm->Lmodem_already_init = 0;
  386. Ldial_debug_level = tpde->debug_level;
  387. if (isdigit(tpde->rtscts_val)) /* 'n' n means leave alone */
  388. {
  389. char s2[2];
  390. s2[0] = tpde->rtscts_val;
  391. s2[1] = 0;
  392. shm->Lrtscts_val = atoi(s2);
  393. }
  394. /* tpde->dcdwatch is explicitly unused here; must defer until connect */
  395. if (!trial)
  396. {
  397. if (reopen)
  398. {
  399. if (lerr = lopen())
  400. {
  401. tcap_curbotleft();
  402. pprintf("%s: %s\n", shm->Lline, LINST_text(lerr));
  403. lopen_error_reset(); /* clear static error area */
  404. termecu(TERMECU_LINE_OPEN_ERROR);
  405. }
  406. }
  407. else
  408. {
  409. lset_baud(1);
  410. lset_parity(1);
  411. }
  412. }
  413. return (0);
  414. } /* end of copy_pde_to_Lvariables */
  415. /*+-----------------------------------------------------------------------
  416. logical_telno_to_pde() - logical dial string to dialing info (PDE)
  417. NOT USED BY THE CURSES DIRECTORY MANAGER
  418. A logical telephone number is one of:
  419. 1. null,
  420. 2. a symbolic identifer, or
  421. 3. an actual telephone number.
  422. A symbolic identifer is a string whose initial character is a
  423. letter. An actual telephone number begins with a numeral.
  424. This function converts a logical telephone number to a dialing
  425. entry (PDE) from the directory or a constructed static one. It
  426. is called by command line processing when 'ecu logical-name' is
  427. specified or in response to a %dial logical-name.
  428. The function returns one of the following:
  429. directory or static PDE if no error occurs
  430. (PDE *)0 if not numeric phone number
  431. and logical string not found in directory;
  432. global char[] errmsg has been plugged with
  433. error message
  434. ------------------------------------------------------------------------*/
  435. PDE *
  436. logical_telno_to_pde(logical)
  437. char *logical;
  438. {
  439. static PDE literal_number_pde;
  440. PDE *tpde = 0;
  441. extern int phdir_list_quan;
  442. /*
  443. * if hostname, get funky-delic
  444. */
  445. #ifdef CFG_TelnetOption
  446. if (strchr(logical, '.'))
  447. {
  448. int itmp;
  449. tpde = &literal_number_pde;
  450. memset((char *)tpde, 0, sizeof(PDE));
  451. tpde->baud = 115200; /* a guess */
  452. tpde->parity = 0;
  453. strncpy(tpde->logical, logical, LOGICAL_LEN);
  454. tpde->logical[LOGICAL_LEN] = 0;
  455. strcpy(tpde->tty, "telnet");
  456. strcpy(tpde->telno, tpde->logical);
  457. strcpy(tpde->descr, "<telnet connect>");
  458. if ((itmp = strlen(tpde->telno)) && (tpde->telno[itmp - 1] == '.'))
  459. tpde->telno[itmp - 1] = 0;
  460. tpde->dcdwatch = 'n';
  461. tpde->rtscts_val = 'n';
  462. strcpy(shm->Lline, "/dev/telnet");
  463. shm->Ltelnet = 1;
  464. shm->Ladd_nl_incoming = 0;
  465. shm->Ladd_nl_outgoing = 0;
  466. shm->Lfull_duplex = 1;
  467. goto FUNC_RETURN;
  468. }
  469. shm->Ltelnet = 0;
  470. #endif
  471. /*
  472. * if literal phone number, return homemade, static "PDE" with most
  473. * stuff dummied up with the status quo
  474. */
  475. if (isdigit((uchar) * logical))
  476. {
  477. tpde = &literal_number_pde;
  478. memset((char *)tpde, 0, sizeof(PDE));
  479. tpde->baud = shm->Lbitrate;
  480. tpde->parity = shm->Lparity;
  481. strncpy(tpde->logical, logical, LOGICAL_LEN);
  482. tpde->logical[LOGICAL_LEN] = 0;
  483. strncpy(tpde->telno, logical, DESTREF_LEN);
  484. tpde->telno[DESTREF_LEN] = 0;
  485. strncpy(tpde->tty, shm->Lline + 5, PDE_TTY_LEN);
  486. tpde->tty[PDE_TTY_LEN] = 0;
  487. if ((unsigned)(strlen(logical) + 8) <= (unsigned)PDE_DESCR_LEN)
  488. sprintf(tpde->descr, "<telno %s>", logical);
  489. else
  490. strcpy(tpde->descr, "<telno>");
  491. tpde->dcdwatch = 'n';
  492. tpde->rtscts_val = 'n';
  493. goto FUNC_RETURN;
  494. }
  495. /*
  496. * if empty phone number, return homemade, static "PDE" with most
  497. * stuff dummied up with the status quo
  498. */
  499. if (!*logical)
  500. {
  501. tpde = &literal_number_pde;
  502. memset((char *)tpde, 0, sizeof(PDE));
  503. tpde->baud = shm->Lbitrate;
  504. tpde->parity = shm->Lparity;
  505. strcpy(tpde->tty, shm->Lline + 5);
  506. if (!tpde->tty[0])
  507. strcpy(tpde->tty, default_tty + 5);
  508. strcpy(tpde->descr, "<direct connect>");
  509. tpde->dcdwatch = 'n';
  510. tpde->rtscts_val = 'n';
  511. goto FUNC_RETURN;
  512. }
  513. /*
  514. * read directory if necessary
  515. */
  516. if (!phdir_list_quan)
  517. {
  518. if (phdir_list_read() && !phdir_list_quan)
  519. { /* if still no good, ... */
  520. strcpy(errmsg, "phone directory empty");
  521. tpde = 0;
  522. goto FUNC_RETURN;
  523. }
  524. }
  525. /*
  526. * now, look up the entry
  527. */
  528. if (tpde = phdir_list_search(logical, 0))
  529. goto FUNC_RETURN;
  530. /*
  531. * whoops ... not found
  532. */
  533. shm->Lrname[0] = 0;
  534. shm->Ltelno[0] = 0;
  535. shm->Ldescr[0] = 0;
  536. strcpy(errmsg, "entry not found in directory");
  537. tpde = 0;
  538. FUNC_RETURN:
  539. #ifdef CHOOSE_DEBUG
  540. vlogevent(xmtr_pid, "LOGICAL->PDE %s=%s chosen tty=%s",
  541. (tpde == &literal_number_pde) ? "TELNO" : "LOGICAL",
  542. logical, (tpde && tpde->tty[0]) ? tpde->tty : "<none>");
  543. #endif
  544. return (tpde);
  545. } /* end of logical_telno_to_pde */
  546. /*+-------------------------------------------------------------------------
  547. call_logical_telno(logical) - call a logical or literal telephone number
  548. -1 if no such entry or pde_dial() status
  549. --------------------------------------------------------------------------*/
  550. int
  551. call_logical_telno(logical)
  552. char *logical;
  553. {
  554. int ret;
  555. PDE *tpde;
  556. if (tpde = logical_telno_to_pde(logical))
  557. ret = pde_dial(tpde);
  558. else
  559. {
  560. pprintf("%s: %s\n", logical, errmsg);
  561. ret = eFATAL_ALREADY;
  562. }
  563. return (ret);
  564. } /* end of call_logical_telno */
  565. /* vi: set tabstop=4 shiftwidth=4: */
  566. /* end of ecupde.c */