ecu.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631
  1. /*+-----------------------------------------------------------------------
  2. ecu.c - Extended Calling Unit/Call Utility/Call UNIX/whatever
  3. wht@wht.net
  4. Defined functions:
  5. main(argc, argv)
  6. xmtr()
  7. "Now tell me, old man, what's your name?"
  8. "Holloway, sir. Charles William Holloway."
  9. "Oh yes, the town's librarian."
  10. "I have the honor, sir, and have had for many years."
  11. "I believe all that time spent living through other men's lives,
  12. other men's dreams, what a waste."
  13. "Sometimes, a man can learn more from other men's dreams than he
  14. can from his own. Come visit me sir, if you wish to improve your
  15. education and I may improve yours." -- Something Wicked This Way Comes
  16. ------------------------------------------------------------------------*/
  17. /*+:EDITS:*/
  18. /*:04-26-2000-11:15-wht@bob-RELEASE 4.42 */
  19. /*:12-19-1997-21:45-wht@kepler-add -k */
  20. /*:12-18-1997-05:06-wht@sidonia-AIX port: sbrk and getpgrp */
  21. /*:05-10-1997-13:53-wht@gyro-strncpy not strcpy to shm->ttyname */
  22. /*:01-24-1997-02:36-wht@yuriatin-SOURCE RELEASE 4.00 */
  23. /*:10-24-1996-03:11-wht@yuriatin-T switch now incremental sw for proc_trace */
  24. /*:09-11-1996-19:59-wht@yuriatin-3.48-major telnet,curses,structural overhaul */
  25. /*:08-21-1996-16:57-wht@fep-add -C switch for show_config */
  26. /*:08-20-1996-12:39-wht@kepler-locale/ctype fixes from ache@nagual.ru */
  27. /*:12-12-1995-14:22-wht@kepler-notify [no line attached] on keystroke */
  28. /*:12-06-1995-13:30-wht@n4hgf-termecu w/errno -1 consideration */
  29. /*:12-03-1995-19:57-wht@gyro-use Setuid */
  30. /*:11-23-1995-11:20-wht@kepler-source control 3.37 for tsx-11 */
  31. /*:11-14-1995-10:23-wht@kepler-3.37.80-source control point: SOCKETS */
  32. /*:11-13-1995-12:07-wht@kepler-xmtr() can live with no line open */
  33. /*:11-12-1995-01:11-wht@gyro-add switch -n to turn off rcvr_ansi_filter */
  34. /*:11-12-1995-00:18-wht@gyro-show_telnet_traffic now in shm */
  35. /*:11-10-1995-18:32-wht@gyro-add switch -z for show_telnet_traffic */
  36. /*:11-04-1995-21:03-root@wwtp1-move windows rattle for quirk earlier in run */
  37. /*:10-14-1995-16:17-wht@kepler-call build_valid_baud_string */
  38. /*:09-17-1995-16:28-wht@kepler-remove obsolete #if 0 code */
  39. /*:06-14-1995-19:08-wht@n4hgf-do not use setuid if root is real user */
  40. /*:06-12-1995-15:03-wht@n4hgf-if ecu has uucp euid, make use of it */
  41. /*:06-12-1995-14:13-wht@n4hgf-no more root euid nice code */
  42. /*:01-12-1995-15:19-wht@n4hgf-apply Andrew Chernov 8-bit clean+FreeBSD patch */
  43. /*:05-04-1994-04:38-wht@n4hgf-ECU release 3.30 */
  44. /*:08-16-1993-17:19-wht@n4hgf-aid share debug with report_initial_line() */
  45. /*:08-07-1993-20:38-wht@n4hgf-add xmtr_wfp_debug_hack */
  46. /*:12-20-1992-12:08-wht@n4hgf-continue -l=Devices support work */
  47. /*:12-04-1992-20:57-wht@n4hgf-add -l=Devices support */
  48. /*:09-10-1992-13:58-wht@n4hgf-ECU release 3.20 */
  49. /*:08-22-1992-15:38-wht@n4hgf-ECU release 3.20 BETA */
  50. /*:08-16-1992-03:43-wht@n4hgf-add -F funckeytype */
  51. /*:08-16-1992-03:08-wht@n4hgf-head off another POSIX plot */
  52. /*:04-30-1992-00:49-wht@n4hgf-remove obsolete -c */
  53. /*:04-24-1992-21:59-wht@n4hgf-more SCO tty name normalizing */
  54. /*:04-17-1992-18:19-wht@n4hgf-"default" keyset read if present */
  55. /*:02-16-1992-02:39-wht@n4hgf-add -P phonedir switch for rll@sco */
  56. /*:02-16-1992-01:41-wht@n4hgf-turn off xterm_title */
  57. /*:08-11-1991-19:56-wht@n4hgf-soup up -l for ISC vs. SCO */
  58. /*:08-06-1991-13:02-wht@n4hgf-jpm@logixwi fix: HZ getenv test wrong sense */
  59. /*:07-29-1991-17:57-wht@n4hgf-add memstat */
  60. /*:07-25-1991-12:55-wht@n4hgf-ECU release 3.10 */
  61. /*:07-17-1991-07:04-wht@n4hgf-avoid SCO UNIX nap bug */
  62. /*:04-27-1991-01:52-wht@n4hgf-overhaul revision numbers */
  63. /*:03-17-1991-13:44-wht@n4hgf-nice and uid revision */
  64. /*:01-09-1991-22:31-wht@n4hgf-ISC port */
  65. /*:11-30-1990-19:04-wht@n4hgf-new ttyinit parameter - see TTYINIT_... */
  66. /*:11-28-1990-15:58-wht@n4hgf-add non-ansi terminal support */
  67. /*:08-14-1990-20:39-wht@n4hgf-ecu3.00-flush old edit history */
  68. #ifdef __FreeBSD__
  69. #include <locale.h>
  70. #endif
  71. #include "ecu.h"
  72. #include "dvent.h"
  73. #include "esd.h"
  74. #include "procedure.h"
  75. #include "ecukey.h"
  76. #include "ecuxkey.h"
  77. #include "termecu.h"
  78. #include "ecu_pwd.h"
  79. char *getenv();
  80. void xmtr_SIGINT_handler();
  81. extern char *makedate; /* temporary make date */
  82. extern char *revstr; /* ecunumrev.c */
  83. extern char *revision_modifier; /* ecunumrev.c */
  84. extern ESD *icmd_prompt;
  85. extern char kbdeof; /* current input EOF */
  86. extern char kbdeol2; /* current secondary input EOL */
  87. extern char kbdeol; /* current input EOL */
  88. extern char kbderase; /* current input ERASE */
  89. extern char kbdintr; /* current input INTR */
  90. extern char kbdkill; /* current input KILL */
  91. extern char kbdquit; /* current input QUIT */
  92. extern UINT tcap_LINES;
  93. extern UINT tcap_COLS;
  94. extern UINT32 colors_current;
  95. extern int there_is_hdb_on_this_machine;
  96. extern char phonedir_name[PHONEDIR_NAME_SIZE];
  97. char *eculibdir = CFG_EcuLibDir;
  98. char *dash_f_funckeytype;
  99. char hello_str[128]; /* msg printed upon BOJ */
  100. char errmsg[128];
  101. char initial_procedure[128] = "";
  102. char *default_tty = CFG_DefaultTty; /* configurable default tty name */
  103. int init_proc_argc = 0;
  104. char *init_proc_argv[MAX_PARGV];
  105. CFG_PidType xmtr_pid = 0;
  106. int quit_on_init_proc_fail = 0;
  107. int quit_on_init_proc_done = 0;
  108. int rc_ep_has_run = 0;
  109. struct TIMEB starting_timeb;
  110. extern int hertz; /* HZ from environ or sys/param.h */
  111. extern UINT32 hzmsec; /* clock period in msec rounded up */
  112. #ifdef CFG_Malloc3X
  113. char *startbrk;
  114. char *startsp;
  115. #endif
  116. char *_rc = "_rc"; /* _rc.ep */
  117. /*+-----------------------------------------------------------------------
  118. xmtr() -- copy stdin to comm line
  119. THE INITIAL PROCESS EXECUTES THIS PROCESS UNTIL PROGRAM TERMINATION
  120. ------------------------------------------------------------------------*/
  121. void
  122. xmtr()
  123. {
  124. UINT xmtr_char;
  125. char nlchar = NL;
  126. char tmpc;
  127. xmtr_wfp_debug_hack(); /* don't ask */
  128. ttymode(1);
  129. xmtr_signals();
  130. while (1)
  131. {
  132. xmtr_char = ttygetc(1);
  133. if (xmtr_char & 0x100)
  134. {
  135. kbd_escape(xmtr_char);
  136. continue;
  137. }
  138. if (shm->Liofd <= 0)
  139. {
  140. UINT32 colors_at_entry = colors_current;
  141. setcolor(colors_notify);
  142. fputs("[no line attached]", se);
  143. setcolor(colors_at_entry);
  144. ff(se, "\r\n");
  145. continue;
  146. }
  147. lputc(xmtr_char);
  148. if (!shm->Lfull_duplex)
  149. { /* echo character if asked */
  150. tmpc = xmtr_char;
  151. write(TTYERR, &tmpc, 1);
  152. }
  153. if (xmtr_char == CRET)
  154. {
  155. #if defined(CFG_TelnetOption)
  156. if (shm->Ltelnet && !shm->Ltelnet_raw)
  157. lputc(0);
  158. #endif
  159. if (shm->Ladd_nl_outgoing)
  160. lputc('\n');
  161. if (!shm->Lfull_duplex)
  162. write(TTYERR, &nlchar, 1);
  163. }
  164. }
  165. /* NOTREACHED */
  166. } /* end of xmtr */
  167. /*+-------------------------------------------------------------------------
  168. keyboard_test_only() - diagnose keyboard problems
  169. --------------------------------------------------------------------------*/
  170. void
  171. keyboard_test_only()
  172. {
  173. ttyinit(TTYUSE_NORMAL);
  174. if (tty_not_char_special)
  175. {
  176. ff(se, "Cannot test keyboard unless it is stanmdard input\n");
  177. exit(1);
  178. }
  179. ttymode(1); /* put user console in `raw' mode */
  180. kbd_test(); /* in ecutty.c */
  181. ttymode(0); /* restore keyboard */
  182. termecu(0);
  183. } /* end of keyboard_test_only */
  184. /*+-------------------------------------------------------------------------
  185. main(argc,argv)
  186. main() program forks to create rcvr process; then main()
  187. becomes the xmtr process
  188. ------------------------------------------------------------------------*/
  189. int
  190. main(argc, argv)
  191. int argc;
  192. char **argv;
  193. {
  194. int swchar;
  195. int itmp;
  196. UINT32 colors_save;
  197. struct passwd *pw;
  198. char *get_ttyname();
  199. extern char *optarg;
  200. extern int optind;
  201. #ifdef CFG_Malloc3X
  202. /*
  203. * absolutely must be first on the list
  204. */
  205. startbrk = sbrk(0); /* initial break */
  206. startsp = (char *)&swchar; /* initial sp */
  207. (void)mallopt(M_MXFAST, 256);
  208. (void)mallopt(M_NLBLKS, 64);
  209. (void)mallopt(M_GRAIN, 64);
  210. #endif
  211. #ifdef __FreeBSD__
  212. setlocale(LC_ALL, "");
  213. #endif
  214. setbuf(stderr, NULL); /* rarely necessary */
  215. build_valid_baud_string();
  216. Ftime(&starting_timeb); /* get startup time */
  217. xmtr_signals(); /* catch xmtr signals */
  218. xmtr_pid = (CFG_PidType) getpid();
  219. /*
  220. * get this off quick, cause we'll be busy for a little while on 286
  221. */
  222. build_revision_string();
  223. sprintf(hello_str, "ecu %s", revstr);
  224. #ifdef M_I286
  225. ff(se, "%s\n", hello_str);
  226. #endif
  227. /*
  228. * initialize 'hertz'/'hzmsec' and Nap() implimentation
  229. */
  230. init_Nap();
  231. /*
  232. * init uucp euid processing
  233. */
  234. uid = getuid();
  235. euid = geteuid();
  236. if (pw = getpwnam("uucp"))
  237. uid_uucp = pw->pw_uid;
  238. endpwent();
  239. /*
  240. * if we are not root, nor uucp (unlikely) and we are euid uucp, then
  241. * use Setuid() to access uucp owned lines
  242. */
  243. setuid_uucp = (uid) && (uid_uucp) && (uid != euid) && (euid == uid_uucp);
  244. if ((uid != euid) && Setuid(uid))
  245. {
  246. ff(se, "\r\n");
  247. perror("Setuid(uid) failed");
  248. ff(se, "\r\n");
  249. exit(-1);
  250. }
  251. /*
  252. * Initialize shared memory segment. This must be done before any uses
  253. * are made of the Lermio variable see ecushm.c and ecu.h.
  254. */
  255. shm_init();
  256. /*
  257. * ecu has its own keyboard handler ... blessing and curse since it
  258. * depends on little outside help but can be tedious to configure for
  259. * a new host or even instance
  260. */
  261. keyset_init(); /* intialize keyset */
  262. keyset_read("default");
  263. /*
  264. * make ~/.ecu if necessary ... but chmod 700 the directory even if it
  265. * already existed (needs to be very early before lots of init)
  266. */
  267. make_ecu_subdir();
  268. get_curr_dir(curr_dir, sizeof(curr_dir));
  269. cd_array_init(); /* read %cd directory list */
  270. hdb_init();
  271. var_init(); /* initialize procedure variables */
  272. poutput_init(); /* initialize procedure output */
  273. icmd_prompt = esdalloc(64);
  274. set_default_escape_prompt();
  275. /*
  276. * init line variables
  277. */
  278. memset(shm->Lline, 0, sizeof(shm->Lline));
  279. shm->Liofd = -1; /* no line open now */
  280. shm->Lbitrate = CFG_DefaultBitRate; /* from config.c run */
  281. shm->Lparity = CFG_DefaultParity; /* from config.c run */
  282. if (shm->Lparity == 'n')
  283. shm->Lparity = 0;
  284. shm->Ltelno[0] = 0; /* no telephone number for remote yet */
  285. shm->Llogical[0] = 0; /* no logical name for remote yet */
  286. shm->Lrname[0] = 0; /* no logical name for remote yet */
  287. shm->Ldescr[0] = 0; /* no description for remote yet */
  288. shm->Lconnected = 0; /* not connected */
  289. shm->Ladd_nl_incoming = 0; /* dont add nl to incoming cr */
  290. shm->Ladd_nl_outgoing = 0; /* dont add nl to outgoing cr */
  291. shm->Lfull_duplex = 1; /* assume full duplex */
  292. shm->Lmodem_already_init = 0; /* modem has not been initialized */
  293. shm->Lxonxoff = IXON | IXOFF; /* default to xon/xoff protocol */
  294. shm->xmtr_pid = (CFG_PidType) getpid();
  295. shm->xmtr_ppid = (CFG_PidType) getppid();
  296. #if defined(CFG_GetpgrpVoidArg)
  297. shm->xmtr_pgrp = (CFG_PidType) getpgrp();
  298. #else
  299. shm->xmtr_pgrp = (CFG_PidType) getpgrp(0);
  300. #endif
  301. strncpy(shm->tty_name, get_ttyname(), sizeof(shm->tty_name));
  302. shm->tty_name[sizeof(shm->tty_name) - 1] = 0;
  303. shm->shm_revision = SHM_REV;
  304. shm->ttyuse = TTYUSE_NORMAL;
  305. shm->terminating = 0;
  306. while ((swchar = getopt(argc, argv, "kCDF:HNP:Tb:defhl:no:p:tz")) != -1)
  307. {
  308. switch (swchar)
  309. {
  310. case 'k':
  311. keyboard_test_only();
  312. /* NOTREACHED */
  313. case 'b':
  314. if (valid_baud(shm->Lbitrate = atoi(optarg)) == -1)
  315. {
  316. ff(se, "invalid bit rate %u\n", shm->Lbitrate);
  317. usage();
  318. }
  319. break;
  320. case 'l':
  321. shm->Lline[0] = 0;
  322. if ((*optarg != '=') && (*optarg != '/'))
  323. strcpy(shm->Lline, "/dev/");
  324. strncat(shm->Lline, optarg,
  325. sizeof(shm->Lline) - strlen(shm->Lline) -
  326. strlen(optarg) - 1);
  327. shm->Lline[sizeof(shm->Lline) - 1] = 0;
  328. break;
  329. case 'p':
  330. strncpy(initial_procedure, optarg, sizeof(initial_procedure));
  331. initial_procedure[sizeof(initial_procedure) - 1] = 0;
  332. break;
  333. case 'h':
  334. shm->Lfull_duplex = 0;
  335. break;
  336. case 'f':
  337. shm->Lfull_duplex = 1;
  338. break;
  339. case 'd':
  340. quit_on_init_proc_fail = 1;
  341. break;
  342. case 'D':
  343. quit_on_init_proc_done = 1;
  344. break;
  345. case 't':
  346. shm->Ladd_nl_incoming = 1;
  347. shm->Ladd_nl_outgoing = 1;
  348. break;
  349. case 'e':
  350. shm->Lparity = 'e';
  351. break;
  352. case 'o':
  353. shm->Lparity = 'o';
  354. break;
  355. case 'N':
  356. shm->ttyuse = TTYUSE_FORCE_SIMPLE;
  357. break;
  358. case 'T':
  359. proc_trace++;
  360. break;
  361. #if defined(CFG_TelnetOption)
  362. case 'R':
  363. shm->Ltelnet_raw = 1;
  364. break;
  365. #endif
  366. case 'P':
  367. strncpy(phonedir_name, optarg, PHONEDIR_NAME_SIZE);
  368. phonedir_name[PHONEDIR_NAME_SIZE - 1] = 0;
  369. break;
  370. case 'C':
  371. show_config();
  372. termecu(0);
  373. break;
  374. case 'F':
  375. dash_f_funckeytype = optarg;
  376. break;
  377. case 'n':
  378. shm->rcvr_ansi_filter = 0;
  379. break;
  380. case 'z':
  381. shm->show_telnet_traffic = 1;
  382. break;
  383. case '?':
  384. usage();
  385. }
  386. }
  387. /*
  388. * check a few options for validity
  389. */
  390. if (!initial_procedure[0] &&
  391. (quit_on_init_proc_done || quit_on_init_proc_fail))
  392. {
  393. ff(se, "no -D/-d without -p\n");
  394. usage();
  395. }
  396. ttyinit(shm->ttyuse); /* init console tty mode handler */
  397. ttymode(3); /* put user console in `raw' mode but SIGINT
  398. * terms prog */
  399. if (tty_not_char_special)
  400. quit_on_init_proc_done = 1;
  401. else
  402. {
  403. /*
  404. * rattle curses once - fixes quirk/bug I can't find
  405. */
  406. windows_start();
  407. windows_end(0);
  408. fflush(so);
  409. tcap_clear_screen();
  410. }
  411. #if defined(WHT2) || defined(XTERM_FRIEND)
  412. /*
  413. * if xterm, put notice in title bar but this really should be done in
  414. * _rc.ep
  415. */
  416. xterm_title("ECU", 0);
  417. #endif
  418. /*
  419. * do the _rc.ep execution
  420. */
  421. if (find_procedure(_rc))
  422. {
  423. if (do_proc(1, &_rc))
  424. {
  425. if (quit_on_init_proc_fail || quit_on_init_proc_done)
  426. termecu(TERMECU_INIT_PROC_ERROR);
  427. }
  428. }
  429. rc_ep_has_run = 1;
  430. /*
  431. * check out line
  432. */
  433. if (!shm->Lline[0])
  434. {
  435. if (!there_is_hdb_on_this_machine)
  436. strcpy(shm->Lline, default_tty);
  437. else
  438. {
  439. DVE *tdve;
  440. if (tdve = hdb_choose_Any(shm->Lbitrate))
  441. sprintf(shm->Lline, "/dev/%s", tdve->line);
  442. else
  443. strcpy(shm->Lline, default_tty);
  444. }
  445. }
  446. else if (shm->Lline[0] == '=') /* Devices lookup */
  447. {
  448. DVE *tdve = 0;
  449. char acutype[128];
  450. if (!there_is_hdb_on_this_machine)
  451. {
  452. ff(se, "\r\n\n");
  453. tcap_stand_out();
  454. fputs("[cannot use -l=Devices ... HDB not available]", se);
  455. tcap_stand_end();
  456. ff(se, "\r\n");
  457. usage();
  458. }
  459. strncpy(acutype, shm->Lline + 1, sizeof(acutype));
  460. acutype[sizeof(acutype) - 1] = 0;
  461. if (!(tdve = getdvtype(shm->Lline + 1)))
  462. {
  463. ff(se, "\r\n\n");
  464. tcap_stand_out();
  465. fprintf(se, "[no Devices line of type '%s']", acutype);
  466. tcap_stand_end();
  467. ff(se, "\r\n");
  468. errno = -1;
  469. termecu(TERMECU_SVC_NOT_AVAIL);
  470. }
  471. shm->Lline[0] = 0;
  472. shm->Lbitrate = tdve->high_baud;
  473. setdvent(); /* rewind for assured passthru/enddvent by
  474. * hdb_choose */
  475. if (!(tdve = hdb_choose_Device(acutype, shm->Lbitrate)))
  476. {
  477. ff(se, "\r\n\n");
  478. tcap_stand_out();
  479. fprintf(se, "[no idle Devices line of type '%s' at %u baud]",
  480. acutype, shm->Lbitrate);
  481. tcap_stand_end();
  482. ff(se, "\r\n");
  483. errno = -1;
  484. termecu(TERMECU_SVC_NOT_AVAIL);
  485. }
  486. strcpy(shm->Lline, "/dev/");
  487. strncat(shm->Lline, tdve->line, sizeof(shm->Lline) - strlen(shm->Lline));
  488. shm->Lline[sizeof(shm->Lline) - 1] = 0;
  489. }
  490. report_initial_line(); /* in #ifdef'ed debug event logging context */
  491. /*
  492. * either present startup screen or run initial procedure or both
  493. */
  494. if (initial_procedure[0])
  495. {
  496. init_proc_argv[0] = initial_procedure;
  497. init_proc_argc = 1;
  498. for (itmp = optind; itmp < argc; itmp++)
  499. {
  500. if (*argv[itmp] != '-')
  501. {
  502. if (init_proc_argc == MAX_PARGV)
  503. {
  504. ff(se, "too many arguments to initial procedure\r\n");
  505. errno = -1;
  506. termecu(TERMECU_USAGE);
  507. }
  508. init_proc_argv[init_proc_argc++] = argv[itmp];
  509. }
  510. }
  511. if (do_proc(init_proc_argc, init_proc_argv))
  512. {
  513. if (quit_on_init_proc_fail || quit_on_init_proc_done)
  514. termecu(TERMECU_INIT_PROC_ERROR);
  515. }
  516. proc_file_reset();
  517. colors_save = colors_current;
  518. setcolor(colors_notify);
  519. pputs("[procedure finished]");
  520. setcolor(colors_save);
  521. pputs("\n");
  522. if (quit_on_init_proc_done)
  523. {
  524. errno = -1;
  525. termecu(TERMECU_OK);
  526. }
  527. if (shm->Liofd < 0)
  528. {
  529. ff(se, "\r\n\n");
  530. tcap_stand_out();
  531. fputs("[no line attached by initial procedure]", se);
  532. tcap_stand_end();
  533. ff(se, "\r\n");
  534. if (quit_on_init_proc_fail)
  535. termecu(TERMECU_INIT_PROC_ERROR);
  536. tcap_stand_out();
  537. fputs("[press ESC to exit or SPACE for setup menu]", se);
  538. tcap_stand_end();
  539. itmp = ttygetc(0);
  540. ff(se, "\r\n");
  541. if (itmp == ESC)
  542. termecu(TERMECU_OK);
  543. shm->Llogical[0] = 0;
  544. shm->Ltelno[0] = 0;
  545. shm->Ldescr[0] = 0;
  546. setup_screen((char *)0);
  547. }
  548. else
  549. start_rcvr_process(0);
  550. }
  551. else
  552. /* no initial procedure */
  553. {
  554. if (!tty_not_char_special)
  555. setup_screen((optind < argc) ? argv[optind] : (char *)0);
  556. else
  557. {
  558. errno = -1;
  559. pprintf("Cannot run ecu from non-tty without initial procedure.\n");
  560. termecu(TERMECU_UNRECOVERABLE);
  561. }
  562. }
  563. /* enter xmtr operation */
  564. xmtr();
  565. termecu(TERMECU_OK);
  566. return (0); /* never get here, but keep gcc optim from
  567. * complaining */
  568. /* NOTREACHED */
  569. } /* end of main */
  570. /* end of ecu.c */
  571. /* vi: set tabstop=4 shiftwidth=4: */