home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / misc / volume42 / ecu / part08 < prev    next >
Encoding:
Internet Message Format  |  1994-05-23  |  64.5 KB

  1. From: wht@n4hgf.atl.ga.us (Warren Tucker)
  2. Newsgroups: comp.sources.misc
  3. Subject: v42i106:  ecu - ECU Asynchronous Communications v3.30, Part08/37
  4. Date: 23 May 1994 14:22:39 -0500
  5. Organization: Sterling Software
  6. Sender: kent@sparky.sterling.com
  7. Approved: kent@sparky.sterling.com
  8. Message-ID: <2rqvpv$dl7@sparky.sterling.com>
  9. X-Md4-Signature: f5fe7d980b50fd39c9b672a7a41112cf
  10.  
  11. Submitted-by: wht@n4hgf.atl.ga.us (Warren Tucker)
  12. Posting-number: Volume 42, Issue 106
  13. Archive-name: ecu/part08
  14. Environment: SCO,SCOXENIX,MOTOROLA,HP-UX,LINUX,NetBSD,SUNOS,SYSVR4,SOLARIS2
  15. Supersedes: ecu: Volume 32, Issue 36-75
  16.  
  17. #! /bin/sh
  18. # This is a shell archive.  Remove anything before this line, then feed it
  19. # into a shell via "sh file" or similar.  To overwrite existing files,
  20. # type "sh file -c".
  21. # Contents:  ecu330/ecurcvr.c ecu330/ecusighdl.c
  22. # Wrapped by kent@sparky on Mon May 23 13:40:48 1994
  23. PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin:$PATH ; export PATH
  24. echo If this archive is complete, you will see the following message:
  25. echo '          "shar: End of archive 8 (of 37)."'
  26. if test -f 'ecu330/ecurcvr.c' -a "${1}" != "-c" ; then 
  27.   echo shar: Will not clobber existing file \"'ecu330/ecurcvr.c'\"
  28. else
  29.   echo shar: Extracting \"'ecu330/ecurcvr.c'\" \(42110 characters\)
  30.   sed "s/^X//" >'ecu330/ecurcvr.c' <<'END_OF_FILE'
  31. X/* #define DEFENSIVE */
  32. X /* #define ANSI_DEBUG *//* debug ansi */
  33. X /* #define ANSI_DEBUG_2 *//* debug ansi intensive output */
  34. X /* #define ANSI_DEBUG_3 *//* debug ansi selected output */
  35. X /* #define ANSI_DEBUG_NOBUF *//* unbufferred logging */
  36. X/* #define ANSI_DEBUG_LOGFILE    "/dev/tty2h" */
  37. X/* #define CURSOR_DEBUG */
  38. X
  39. X#ifndef LIMIT_BELL
  40. X#define LIMIT_BELL
  41. X#endif
  42. X
  43. X#if defined(WHT) && defined(WHT_CONFUSED)
  44. X#define ANSI_DEBUG
  45. X#define ANSI_DEBUG_2
  46. X#define ANSI_DEBUG_3
  47. X#define ANSI_DEBUG_NOBUF
  48. X#define ANSI_DEBUG_LOGFILE    "./ansi.log"
  49. X#endif
  50. X
  51. X/*+-------------------------------------------------------------------------
  52. X    ecurcvr.c - rcvr process + ANSI filter + non-ANSI<->ANSI hoop jumping
  53. X    wht@n4hgf.atl.ga.us
  54. X
  55. X  Defined functions:
  56. X    accumulate_ansi_sequence(rchar)
  57. X    ansi_CNL()
  58. X    ansi_CPL()
  59. X    ansi_CUB()
  60. X    ansi_CUD()
  61. X    ansi_CUF()
  62. X    ansi_CUP()
  63. X    ansi_CUU()
  64. X    ansi_DCH()
  65. X    ansi_DL()
  66. X    ansi_DSR()
  67. X    ansi_ECH()
  68. X    ansi_ED()
  69. X    ansi_EL()
  70. X    ansi_HPA()
  71. X    ansi_ICH()
  72. X    ansi_IL()
  73. X    ansi_SD()
  74. X    ansi_SGR()
  75. X    ansi_SU()
  76. X    ansi_VPA()
  77. X    is_ansi_terminator(rchar)
  78. X    lgetc_rcvr()
  79. X    process_ansi_sequence()
  80. X    process_rcvd_char(rchar)
  81. X    rcvd_ESC()
  82. X    rcvr()
  83. X    rcvr_log_open()
  84. X    rcvrdisp(buf,buflen)
  85. X    rcvrdisp_actual()
  86. X    rcvrdisp_actual2()
  87. X    redisplay_rcvr_screen()
  88. X    saved_cursor_restore_cursor()
  89. X    saved_cursor_save_cursor()
  90. X    spaces(buf,buflen)
  91. X    spaces_trap(code,buf,buflen)
  92. X
  93. X    Any perceptible delay will eventually get on your nerves. --Bob Hyers
  94. X
  95. X--------------------------------------------------------------------------*/
  96. X/*+:EDITS:*/
  97. X/*:05-04-1994-04:39-wht@n4hgf-ECU release 3.30 */
  98. X/*:10-03-1993-20:09-wht@n4hgf-document read errors w/fd on screen */
  99. X/*:08-18-1993-05:49-wht@n4hgf-rcvr seems ready for release */
  100. X/*:08-07-1993-20:38-wht@n4hgf-add xmtr_wfp_debug_hack */
  101. X/*:07-23-1993-15:42-wht@n4hgf-detect/ignore ESC = or ESC > VT100 keypad */
  102. X/*:07-17-1993-12:36-wht@n4hgf-no more rcvrdisp_actual2_xmtr_buffer junk */
  103. X/*:12-31-1992-15:34-wht@n4hgf-handle VT100 save/restore cursor */
  104. X/*:12-03-1992-14:24-wht@n4hgf-differentiate between type 5 and other DSR */
  105. X/*:09-10-1992-13:58-wht@n4hgf-ECU release 3.20 */
  106. X/*:09-06-1992-13:29-wht@n4hgf-add receiver process buffered screen write */
  107. X/*:08-22-1992-15:38-wht@n4hgf-ECU release 3.20 BETA */
  108. X/*:05-29-1992-13:28-wht@n4hgf-no banner - phone numbers are security risk */
  109. X/*:11-11-1991-14:25-wht@n4hgf-lzero_length_read_detected code */
  110. X/*:11-11-1991-12:45-wht@n4hgf-add LIMIT_BELL code */
  111. X/*:08-26-1991-16:39-wht@n4hgf2-SD was still hopelessly manic */
  112. X/*:07-25-1991-12:56-wht@n4hgf-ECU release 3.10 */
  113. X/*:07-05-1991-06:13-wht@n4hgf-SD was in baaaaadd shape */
  114. X/*:01-09-1991-22:31-wht@n4hgf-ISC port */
  115. X/*:12-26-1990-14:32-wht@n4hgf-use memset in spaces() */
  116. X/*:12-21-1990-21:06-wht@n4hgf-CUF and CUB set non-ansi cursor incorrectly */
  117. X/*:12-20-1990-16:27-wht@n4hgf-had SU and SD swapped */
  118. X/*:11-30-1990-18:39-wht@n4hgf-non-ansi console rcvr appears to be working */
  119. X/*:11-28-1990-14:13-wht@n4hgf-start non-ansi console support */
  120. X/*:08-14-1990-20:40-wht@n4hgf-ecu3.00-flush old edit history */
  121. X
  122. X#include "ecu.h"
  123. X#include "ecukey.h"
  124. X
  125. X#ifdef CFG_SemWithShm
  126. X#include <sys/ipc.h>
  127. X#include <sys/sem.h>
  128. X#endif /* CVRDISP_PV */
  129. X
  130. Xextern int errno;
  131. Xextern char rcvr_log_file[]; /* if rcvr_log!= 0,log filename */
  132. Xextern int rcvr_log;         /* rcvr log active if != 0 */
  133. Xextern FILE *rcvr_log_fp;     /* rcvr log file */
  134. Xextern int rcvr_log_raw;     /* if true, log all, else filter ctl chrs */
  135. Xextern int rcvr_log_append;     /* if true, append, else scratch */
  136. Xextern int rcvr_log_flusheach;    /* if true, flush log on each char */
  137. Xextern int rcvr_log_gen_title;
  138. X
  139. Xextern uint tcap_LINES;         /* terminal line quantity - see ecutcap.c */
  140. Xextern uint tcap_COLS;         /* terminal column quantity - see ecutcap.c */
  141. Xextern uint LINESxCOLS;
  142. X
  143. Xstatic char esc = ESC;
  144. X
  145. X#define MAX_ANSI_LEN    30     /* generous */
  146. Xchar ansibuf[MAX_ANSI_LEN];
  147. Xchar *ansi;
  148. Xint ansilen = 0;
  149. Xint in_ansi_accumulation = 0;
  150. X
  151. Xint saved_cursor_y;
  152. Xint saved_cursor_x;
  153. X
  154. X#define RCVR_RDQUAN        250
  155. Xchar lgetc_buf[RCVR_RDQUAN];
  156. Xchar *lgetc_ptr;
  157. Xextern int lgetc_count;
  158. X
  159. Xuchar autorz_frame[] =
  160. X{SUB, 'B', '0', '0'};
  161. X
  162. X#ifdef ANSI_DEBUG
  163. XFILE *wfp = (FILE *) 0;
  164. X
  165. X#endif
  166. X
  167. Xuchar non_multiscreen_hi_map[128] =
  168. X{
  169. X    /* 80 */ 'c', 'u', 'e', 'a', 'a', 'a', 'a', 'c',    /* the main purpose of
  170. X                                                         * this ... */
  171. X    /* 88 */ 'e', 'e', 'e', 'i', 'i', 'i', 'a', 'a',    /* ... is to map ruling
  172. X                                                         * ... */
  173. X    /* 90 */ 'e', 'e', 'a', 'a', 'a', 'o', 'u', 'u',    /* ... characters, but
  174. X                                                         * as ... */
  175. X    /* 98 */ 'y', 'o', 'u', 'X', '#', 'Y', 'P', 'f',    /* ... a side effect,
  176. X                                                         * also map ... */
  177. X    /* A0 */ 'a', 'i', 'o', 'u', 'n', 'n', 'a', 'o',    /* ... others to
  178. X                                                         * reasonable, ... */
  179. X    /* A8 */ '?', '-', '-', '%', '%', '|', '<', '>',    /* ... near, amusing, or
  180. X                                                         * random ... */
  181. X    /* B0 */ '#', '#', '#', '|', '+', '+', '+', '.',    /* ... printing
  182. X                                                         * characters as well */
  183. X    /* B8 */ '.', '+', '|', '.', '\'', '\'', '\'', '.',
  184. X    /* C0 */ '`', '+', '+', '+', '-', '+', '+', '+',
  185. X    /* C8 */ '`', '.', '+', '+', '+', '=', '+', '+',
  186. X    /* D0 */ '+', '+', '+', '`', '`', '.', '.', '+',
  187. X    /* D8 */ '+', '\'', '.', '#', '_', '|', '|', '-',
  188. X    /* E0 */ 'a', 'b', 'F', 'T', 'E', 'o', 'u', 't',
  189. X    /* E8 */ 'I', '0', 'O', 'o', 'o', 'o', 'e', 'n',
  190. X    /* F0 */ '=', '+', '>', '<', 'f', 'j', '%', '=',
  191. X    /* F8 */ 'o', '.', '.', 'V', 'n', '2', '*', ' '
  192. X};
  193. X
  194. X/*+-------------------------------------------------------------------------
  195. X    rcvrdisp_p() - lock rcvrdisp mechanism
  196. X--------------------------------------------------------------------------*/
  197. X#ifdef CFG_SemWithShm
  198. Xvoid
  199. Xrcvrdisp_p()
  200. X{
  201. X    register int retn;
  202. X    struct sembuf sembuf;
  203. X
  204. X    sembuf.sem_num = 0;
  205. X    sembuf.sem_op = -1;
  206. X    sembuf.sem_flg = 0;
  207. X
  208. X    while (1)
  209. X    {
  210. X        if (((retn = semop(shm->rcvrdisp_semid, &sembuf, 1)) >= 0) ||
  211. X            (errno != EINTR))
  212. X        {
  213. X            break;
  214. X        }
  215. X    }
  216. X
  217. X    if ((retn < 0) && (errno != EINVAL))
  218. X    {
  219. X        strcpy(lopen_err_str, "rcvrdisp_p failed: SysV IPC error");
  220. X        termecu(TERMECU_IPC_ERROR);
  221. X    }
  222. X
  223. X}                             /* end of rcvrdisp_p */
  224. X#endif /* CFG_SemWithShm */
  225. X
  226. X/*+-------------------------------------------------------------------------
  227. X    rcvrdisp_v() - unlock rcvrdisp mechanism
  228. X--------------------------------------------------------------------------*/
  229. X#ifdef CFG_SemWithShm
  230. Xvoid
  231. Xrcvrdisp_v()
  232. X{
  233. X    register int retn;
  234. X    struct sembuf sembuf;
  235. X
  236. X    sembuf.sem_num = 0;
  237. X    sembuf.sem_op = 1;
  238. X    sembuf.sem_flg = 0;
  239. X
  240. X    while (1)
  241. X    {
  242. X        if (((retn = semop(shm->rcvrdisp_semid, &sembuf, 1)) >= 0) ||
  243. X            (errno != EINTR))
  244. X        {
  245. X            break;
  246. X        }
  247. X    }
  248. X
  249. X    if ((retn < 0) && (errno != EINVAL))
  250. X    {
  251. X        strcpy(lopen_err_str, "rcvrdisp_v failed: SysV IPC error");
  252. X        termecu(TERMECU_IPC_ERROR);
  253. X    }
  254. X}                             /* end of rcvrdisp_v */
  255. X#endif /* CFG_SemWithShm */
  256. X
  257. X/*+-------------------------------------------------------------------------
  258. X    rcvrdisp_actual() - actual write to screen
  259. X--------------------------------------------------------------------------*/
  260. Xvoid
  261. Xrcvrdisp_actual()
  262. X{
  263. X#ifdef CFG_SemWithShm
  264. X    rcvrdisp_p();
  265. X#endif /* CFG_SemWithShm */
  266. X    if (shm->rcvrdisp_count)
  267. X        write(TTYOUT, shm->rcvrdisp_buffer, shm->rcvrdisp_count);
  268. X    shm->rcvrdisp_ptr = shm->rcvrdisp_buffer;
  269. X    shm->rcvrdisp_count = 0;
  270. X#ifdef CFG_SemWithShm
  271. X    rcvrdisp_v();
  272. X#endif /* CFG_SemWithShm */
  273. X
  274. X}                             /* end of rcvrdisp_actual */
  275. X
  276. X/*+-------------------------------------------------------------------------
  277. X    rcvrdisp_actual2() - for tcap, flush only if not receiver
  278. X--------------------------------------------------------------------------*/
  279. Xvoid
  280. Xrcvrdisp_actual2()
  281. X{
  282. X    if (getpid() == rcvr_pid)
  283. X        return;
  284. X#ifdef CFG_SemWithShm
  285. X    rcvrdisp_p();
  286. X#endif /* CFG_SemWithShm */
  287. X    if (shm->rcvrdisp_count)
  288. X        write(TTYOUT, shm->rcvrdisp_buffer, shm->rcvrdisp_count);
  289. X    shm->rcvrdisp_ptr = shm->rcvrdisp_buffer;
  290. X    shm->rcvrdisp_count = 0;
  291. X#ifdef CFG_SemWithShm
  292. X    rcvrdisp_v();
  293. X#endif /* CFG_SemWithShm */
  294. X
  295. X}                             /* end of rcvrdisp_actual2 */
  296. X
  297. X/*+-------------------------------------------------------------------------
  298. X    rcvrdisp(buf,buflen) - logical write to screen
  299. X--------------------------------------------------------------------------*/
  300. Xvoid
  301. Xrcvrdisp(buf, buflen)
  302. Xchar *buf;
  303. Xint buflen;
  304. X{
  305. X
  306. X    if ((buflen + shm->rcvrdisp_count) > sizeof(shm->rcvrdisp_buffer))
  307. X        rcvrdisp_actual();
  308. X    if ((buflen + shm->rcvrdisp_count) > sizeof(shm->rcvrdisp_buffer))
  309. X    {
  310. X        write(TTYOUT, buf, buflen);
  311. X        return;
  312. X    }
  313. X#ifdef CFG_SemWithShm
  314. X    rcvrdisp_p();
  315. X#endif /* CFG_SemWithShm */
  316. X    memcpy(shm->rcvrdisp_ptr, buf, buflen);
  317. X    shm->rcvrdisp_ptr += buflen;
  318. X    shm->rcvrdisp_count += buflen;
  319. X#ifdef CFG_SemWithShm
  320. X    rcvrdisp_v();
  321. X#endif /* CFG_SemWithShm */
  322. X
  323. X}                             /* end of rcvrdisp */
  324. X
  325. X/*+-------------------------------------------------------------------------
  326. X    redisplay_rcvr_screen() - redisplay logical receiver screen
  327. XAs of writing, this function is called only by the XMTR process
  328. X--------------------------------------------------------------------------*/
  329. Xvoid
  330. Xredisplay_rcvr_screen()
  331. X{
  332. X    register uint y;
  333. X    extern int tty_not_char_special;
  334. X
  335. X    if (tty_not_char_special)
  336. X        return;
  337. X
  338. X    setcolor(colors_current);
  339. X    tcap_stand_end();
  340. X    for (y = 0; y < tcap_LINES; y++)
  341. X    {
  342. X        tcap_cursor(y, 0);
  343. X        fwrite(&shm->screen[y][0],
  344. X            ((y != tcap_LINES - 1) ? tcap_COLS : tcap_COLS - 1), 1, se);
  345. X    }
  346. X    tcap_eeol();
  347. X    tcap_cursor(shm->cursor_y, shm->cursor_x);
  348. X
  349. X}                             /* end of redisplay_rcvr_screen */
  350. X
  351. X/*+-------------------------------------------------------------------------
  352. X    spaces_trap(code,buf,buflen)
  353. X--------------------------------------------------------------------------*/
  354. X#ifdef DEBUG_CURSOR
  355. Xvoid
  356. Xspaces_trap(code, buf, buflen)
  357. Xint code;
  358. Xregister uchar *buf;
  359. Xregister uint buflen;
  360. X{
  361. X    char *xyz = (char *)0x90000000;
  362. X
  363. X    ff(se, "rcvr 'spaces trap' code %d: cursor x,y=%d,%d\r\n",
  364. X        code, shm->cursor_y, shm->cursor_x);
  365. X    ff(se, "buf=%08lx len=%08lx offs=%08lx\r\n", buf, buflen,
  366. X        (ulong) buf - (ulong) shm->screen);
  367. X    *xyz = 0;
  368. X    abort();
  369. X}                             /* end of spaces_trap */
  370. X#endif
  371. X
  372. X/*+-------------------------------------------------------------------------
  373. X    spaces(buf,buflen) - fill with spaces
  374. X--------------------------------------------------------------------------*/
  375. Xvoid
  376. Xspaces(buf, buflen)
  377. Xregister uchar *buf;
  378. Xuint buflen;
  379. X{
  380. X#ifdef DEBUG_CURSOR
  381. X    if ((ulong) buf > (((ulong) shm->screen) + LINESxCOLS))
  382. X        spaces_trap(1, buf, buflen);
  383. X    if ((ulong) buf < (ulong) shm->screen)
  384. X        spaces_trap(2, buf, buflen);
  385. X    if ((ulong) (buf + buflen) > (((ulong) shm->screen) + LINESxCOLS))
  386. X        spaces_trap(3, buf, buflen);
  387. X    if ((ulong) (buf + buflen) < (ulong) shm->screen)
  388. X        spaces_trap(4, buf, buflen);
  389. X#endif
  390. X
  391. X    if (!buflen)
  392. X        return;
  393. X
  394. X#ifdef DEFENSIVE
  395. X    if ((ulong) buf < (ulong) shm->screen)
  396. X        return;
  397. X    if ((ulong) (buf + buflen) > (((ulong) shm->screen) + LINESxCOLS))
  398. X        return;
  399. X#endif
  400. X
  401. X    memset(buf, SPACE, buflen);
  402. X
  403. X}                             /* end of spaces */
  404. X
  405. X/*+-------------------------------------------------------------------------
  406. X    lgetc_rcvr() - rcvr version of get char from line
  407. X--------------------------------------------------------------------------*/
  408. Xint
  409. Xlgetc_rcvr()
  410. X{
  411. X    extern int errno;
  412. X
  413. X    if (!lgetc_count)
  414. X    {
  415. X        rcvrdisp_actual();
  416. X        while (lgetc_count <= 0)
  417. X        {
  418. X            errno = 0;
  419. X            if ((lgetc_count =
  420. X                    read(shm->Liofd, lgetc_buf, RCVR_RDQUAN)) < 0)
  421. X            {
  422. X                if (errno == EINTR)    /* if signal interrupted, ... */
  423. X                    continue;/* ... read again */
  424. X                ff(se, "lgetc read error fd=%d\r\n", shm->Liofd);
  425. X                termecu(TERMECU_LINE_READ_ERROR);
  426. X            }
  427. X            if (!lgetc_count)
  428. X            {
  429. X                lzero_length_read_detected();    /* maybe terminate program
  430. X                                                 * ... */
  431. X                continue;     /* ... but if not, read again */
  432. X            }
  433. X        }
  434. X        shm->rcvd_chars += lgetc_count;
  435. X        shm->rcvd_chars_this_connect += lgetc_count;
  436. X        lgetc_ptr = lgetc_buf;
  437. X    }
  438. X
  439. X    lgetc_count--;
  440. X
  441. X    if (shm->Lparity)
  442. X        return (*lgetc_ptr++ & 0x7F);
  443. X    else
  444. X        return (*lgetc_ptr++);
  445. X
  446. X}                             /* end of lgetc_rcvr */
  447. X
  448. X/*+-------------------------------------------------------------------------
  449. X    ansi_SGR() - Set Graphics Rendition
  450. X
  451. XThe DOS ANSI world expects to be able to be able to chain 0,1 and
  452. X3x,4x params together with semicolons.
  453. X
  454. X  Supported modifiers for non-ansi terminals
  455. X  0       normal
  456. X  1       bold
  457. X  4       underscore
  458. X  5       blink
  459. X  7       reverse video
  460. X--------------------------------------------------------------------------*/
  461. Xvoid
  462. Xansi_SGR()
  463. X{
  464. X    register itmp;
  465. X    register char *cptr;
  466. X    char SGRstr[MAX_ANSI_LEN];
  467. X    char *token;
  468. X    char *str_token();
  469. X
  470. X    if (!tty_is_multiscreen)
  471. X    {
  472. X        ansibuf[ansilen - 1] = 0;    /* get rid of 'm' */
  473. X        cptr = ansibuf + 1;     /* get rid of '[' */
  474. X        if (!strlen(cptr))
  475. X            goto SGR_0;
  476. X        while (token = str_token(cptr, ";"))
  477. X        {
  478. X            cptr = (char *)0;/* further calls to str_token need NULL */
  479. X            switch (atoi(token))
  480. X            {
  481. X                default:
  482. X                case 0:     /* normal */
  483. X                  SGR_0:
  484. X                    tcap_stand_end();
  485. X                    tcap_blink_off();
  486. X                    tcap_underscore_off();
  487. X                    tcap_bold_off();
  488. X                    break;
  489. X                case 1:     /* bold */
  490. X                    tcap_bold_on();
  491. X                    break;
  492. X                case 4:     /* underscore */
  493. X                    tcap_underscore_on();
  494. X                    break;
  495. X                case 5:     /* blink */
  496. X                    tcap_blink_on();
  497. X                    break;
  498. X                case 7:     /* reverse video */
  499. X                    tcap_stand_out();
  500. X                    break;
  501. X            }
  502. X        }
  503. X        return;
  504. X    }
  505. X
  506. X    if (ansilen <= 3)         /* 'ESC[<0-9>m' and 'ESC[m' - quickly handled */
  507. X    {
  508. X        rcvrdisp(&esc, 1);
  509. X        rcvrdisp(ansibuf, ansilen);
  510. X        return;
  511. X    }
  512. X
  513. X/* check XENIX 'ESC[<2,3,7>m' extensions */
  514. X    switch (itmp = atoi(ansibuf + 1))
  515. X    {
  516. X        case 7:             /* XENIX 'ESC[7;<0-15>;<0-15>m' set
  517. X                              * fore/background color */
  518. X            itmp = atoi(ansibuf + 3);    /* second parameter */
  519. X            if (itmp > 15)     /* not XENIX extension */
  520. X                break;
  521. X            /* fall through */
  522. X        case 2:             /* XENIX 'ESC[2;<0-15>;<0-15>m' set
  523. X                              * fore/background color */
  524. X        case 3:             /* XENIX 'ESC[3;<0-1>m' color only set/clear
  525. X                              * blink */
  526. X            rcvrdisp(&esc, 1);
  527. X            rcvrdisp(ansibuf, ansilen);
  528. X            return;
  529. X        default:
  530. X            break;
  531. X    }
  532. X
  533. X/* not XENIX extension */
  534. X    ansibuf[ansilen - 1] = 0;/* get rid of 'm' */
  535. X    cptr = ansibuf + 1;         /* get rid of '[' */
  536. X
  537. X    while (token = str_token(cptr, ";"))
  538. X    {
  539. X        cptr = (char *)0;     /* further calls to str_token need NULL */
  540. X        sprintf(SGRstr, "\033[%sm", token);
  541. X        rcvrdisp(SGRstr, strlen(SGRstr));
  542. X    }
  543. X
  544. X}                             /* end of ansi_SGR */
  545. X
  546. X/*+-------------------------------------------------------------------------
  547. X    ansi_CUP() - cursor position (also HVP horiz/vertical position)
  548. X--------------------------------------------------------------------------*/
  549. Xvoid
  550. Xansi_CUP()
  551. X{
  552. X    register uint param_count = 0;
  553. X    char ansicopy[MAX_ANSI_LEN];
  554. X    register char *cptr = ansicopy;
  555. X    register char *token;
  556. X    char *str_token();
  557. X
  558. X    strcpy(cptr, ansibuf + 1);
  559. X    *(cptr + ansilen - 2) = 0;
  560. X
  561. X    while (token = str_token(cptr, ";"))
  562. X    {
  563. X        cptr = (char *)0;     /* further calls to str_token need NULL */
  564. X        switch (++param_count)
  565. X        {
  566. X            case 1:
  567. X                shm->cursor_y = atoi(token) - 1;
  568. X                break;
  569. X            case 2:
  570. X                shm->cursor_x = atoi(token) - 1;
  571. X                break;
  572. X        }
  573. X    }
  574. X    switch (param_count)
  575. X    {
  576. X        case 0:
  577. X            shm->cursor_y = 0;
  578. X        case 1:
  579. X            shm->cursor_x = 0;
  580. X    }
  581. X    if (shm->cursor_x >= tcap_COLS)
  582. X        shm->cursor_x = tcap_COLS - 1;
  583. X    if (shm->cursor_y >= tcap_LINES)
  584. X        shm->cursor_y = tcap_LINES - 1;
  585. X
  586. X    if (!tty_is_multiscreen)
  587. X        tcap_cursor(shm->cursor_y, shm->cursor_x);
  588. X
  589. X}                             /* end of ansi_CUP */
  590. X
  591. X/*+-------------------------------------------------------------------------
  592. X    ansi_CUU() - cursor up
  593. X--------------------------------------------------------------------------*/
  594. Xvoid
  595. Xansi_CUU()
  596. X{
  597. X    register uint count;
  598. X    register uint y;
  599. X
  600. X    if (ansilen == 2)         /* no param */
  601. X        count = 1;
  602. X    else
  603. X        count = atoi(ansibuf + 1);
  604. X
  605. X    y = shm->cursor_y - count;
  606. X    if (y >= tcap_LINES)     /* unsigned comparison */
  607. X        y = 0;
  608. X
  609. X    if (y != shm->cursor_y)
  610. X    {
  611. X        shm->cursor_y = y;
  612. X        if (!tty_is_multiscreen)
  613. X            tcap_cursor(shm->cursor_y, shm->cursor_x);
  614. X    }
  615. X
  616. X}                             /* end of ansi_CUU */
  617. X
  618. X/*+-------------------------------------------------------------------------
  619. X    ansi_CUD() - cursor down (also VPR vertical position relative)
  620. X--------------------------------------------------------------------------*/
  621. Xvoid
  622. Xansi_CUD()
  623. X{
  624. X    register uint count;
  625. X    register uint y;
  626. X
  627. X    if (ansilen == 2)         /* no param */
  628. X        count = 1;
  629. X    else
  630. X        count = atoi(ansibuf + 1);
  631. X
  632. X    y = shm->cursor_y + count;
  633. X    if (y >= tcap_LINES)
  634. X        y = tcap_LINES - 1;
  635. X
  636. X    if (y != shm->cursor_y)
  637. X    {
  638. X        shm->cursor_y = y;
  639. X        if (!tty_is_multiscreen)
  640. X            tcap_cursor(shm->cursor_y, shm->cursor_x);
  641. X    }
  642. X
  643. X}                             /* end of ansi_CUD */
  644. X
  645. X/*+-------------------------------------------------------------------------
  646. X    ansi_CUF() - cursor forward (also HPR horizontal position relative)
  647. X--------------------------------------------------------------------------*/
  648. Xvoid
  649. Xansi_CUF()
  650. X{
  651. X    register uint count;
  652. X    register uint x;
  653. X
  654. X    if (ansilen == 2)         /* no param */
  655. X        count = 1;
  656. X    else
  657. X        count = atoi(ansibuf + 1);
  658. X
  659. X    x = shm->cursor_x + count;
  660. X    if (x >= tcap_COLS)
  661. X        x = tcap_COLS - 1;
  662. X
  663. X    if (x != shm->cursor_x)
  664. X    {
  665. X        shm->cursor_x = x;
  666. X        if (!tty_is_multiscreen)
  667. X            tcap_cursor(shm->cursor_y, shm->cursor_x);
  668. X    }
  669. X
  670. X}                             /* end of ansi_CUF */
  671. X
  672. X/*+-------------------------------------------------------------------------
  673. X    ansi_CUB() - cursor forward
  674. X--------------------------------------------------------------------------*/
  675. Xvoid
  676. Xansi_CUB()
  677. X{
  678. X    register uint count;
  679. X    register uint x;
  680. X
  681. X    if (ansilen == 2)         /* no param */
  682. X        count = 1;
  683. X    else
  684. X        count = atoi(ansibuf + 1);
  685. X
  686. X    x = shm->cursor_x - count;
  687. X    if (x >= tcap_COLS)         /* unsigned comparison */
  688. X        x = 0;
  689. X
  690. X    if (x != shm->cursor_x)
  691. X    {
  692. X        shm->cursor_x = x;
  693. X        if (!tty_is_multiscreen)
  694. X            tcap_cursor(shm->cursor_y, shm->cursor_x);
  695. X    }
  696. X
  697. X}                             /* end of ansi_CUB */
  698. X
  699. X/*+-------------------------------------------------------------------------
  700. X    ansi_DSR() - device status report
  701. X
  702. X  ESC [ Ps n  - Device Status Report (DSR)           ECU Response
  703. X        Ps = 5 -> Status Report                      ESC [ 0 n
  704. X        Ps = 6 -> Report Cursor Position (CPR)       ESC [ r ; c R
  705. X
  706. X--------------------------------------------------------------------------*/
  707. Xvoid
  708. Xansi_DSR()
  709. X{
  710. X    register uint param;
  711. X    char response_buf[MAX_ANSI_LEN];
  712. X    char *response = 0;
  713. X
  714. X    if (ansilen < 2)         /* no param */
  715. X        param = 0;
  716. X    else
  717. X        param = atoi(ansibuf + 1);
  718. X
  719. X#ifdef ANSI_DEBUG_3
  720. X    if (wfp)
  721. X    {
  722. X        ff(wfp, "DSR: param=%u y,x=%d,%d", param,
  723. X            shm->cursor_y, shm->cursor_x);
  724. X        if (!param && (ansilen == 3))
  725. X            ff(wfp, ": ignoring \"ESC 0 ] n\"");
  726. X        ff(wfp, "\n");
  727. X    }
  728. X#endif
  729. X
  730. X    switch (param)
  731. X    {
  732. X        case 0:             /* sanity */
  733. X        case 5:             /* sanity */
  734. X            response = "\033[0n";
  735. X            break;
  736. X
  737. X        case 6:             /* report cursor position */
  738. X            sprintf(response_buf, "\033[%d;%dR",
  739. X                shm->cursor_y + 1, shm->cursor_x + 1);
  740. X            response = response_buf;
  741. X            break;
  742. X    }
  743. X
  744. X    if (response)
  745. X    {
  746. X        Nap(300L);
  747. X        write(shm->Liofd, response, strlen(response));
  748. X    }
  749. X
  750. X#ifdef ANSI_DEBUG_3
  751. X    if (response)
  752. X    {
  753. X        char s80[80];
  754. X
  755. X        sprintf(s80, "strlen(DSR response) = %d", strlen(response));
  756. X        hex_dump_fp(wfp, response, strlen(response), s80, 0);
  757. X    }
  758. X#endif
  759. X
  760. X}                             /* end of ansi_DSR */
  761. X
  762. X/*+-------------------------------------------------------------------------
  763. X    ansi_ED() - erase in display
  764. X--------------------------------------------------------------------------*/
  765. Xvoid
  766. Xansi_ED()
  767. X{
  768. X    register uint param;
  769. X    int y;
  770. X
  771. X    if (ansilen == 2)         /* no param */
  772. X        param = 0;
  773. X    else
  774. X        param = atoi(ansibuf + 1);
  775. X
  776. X    switch (param)
  777. X    {
  778. X        case 0:             /* erase to end of display */
  779. X            spaces(&shm->screen[shm->cursor_y][shm->cursor_x],
  780. X                LINESxCOLS - ((shm->cursor_y * tcap_COLS) + shm->cursor_x));
  781. X            if (!tty_is_multiscreen)
  782. X                tcap_eeod();
  783. X            break;
  784. X        case 1:             /* erase from beginning of display */
  785. X            spaces((char *)shm->screen, (shm->cursor_y * tcap_COLS) +
  786. X                shm->cursor_x);
  787. X            if (!tty_is_multiscreen)
  788. X            {
  789. X                for (y = 0; y < shm->cursor_y - 1; y++)
  790. X                {
  791. X                    tcap_cursor(y, 0);
  792. X                    tcap_eeol();
  793. X                }
  794. X                if (shm->cursor_x)
  795. X                {
  796. X                    tcap_cursor(shm->cursor_y, 0);
  797. X                    tcap_clear_area_char(shm->cursor_x, ' ');
  798. X                }
  799. X                else
  800. X                    tcap_cursor(shm->cursor_y, shm->cursor_x);
  801. X            }
  802. X            break;
  803. X        case 2:             /* clear display */
  804. X            shm->cursor_y = 0;
  805. X            shm->cursor_x = 0;
  806. X            spaces((char *)shm->screen, LINESxCOLS);
  807. X            if (!tty_is_multiscreen)
  808. X            {
  809. X                tcap_clear_screen();
  810. X                tcap_cursor(shm->cursor_y, shm->cursor_x);
  811. X            }
  812. X            break;
  813. X    }
  814. X
  815. X}                             /* end of ansi_ED */
  816. X
  817. X/*+-------------------------------------------------------------------------
  818. X    ansi_EL() - erase in line
  819. X--------------------------------------------------------------------------*/
  820. Xvoid
  821. Xansi_EL()
  822. X{
  823. X    register uint param;
  824. X    char cr = CRET;
  825. X
  826. X    if (ansilen == 2)         /* no param */
  827. X        param = 0;
  828. X    else
  829. X        param = atoi(ansibuf + 1);
  830. X
  831. X    switch (param)
  832. X    {
  833. X        case 2:             /* clear line */
  834. X            shm->cursor_x = 0;
  835. X            if (!tty_is_multiscreen)
  836. X                rcvrdisp(&cr, 1);
  837. X            /* fall thru */
  838. X        case 0:             /* erase to end of line */
  839. X            spaces(&shm->screen[shm->cursor_y][shm->cursor_x],
  840. X                tcap_COLS - shm->cursor_x);
  841. X            if (!tty_is_multiscreen)
  842. X                tcap_eeol();
  843. X            break;
  844. X        case 1:             /* erase from beginning of line */
  845. X            spaces(&shm->screen[shm->cursor_y][0], shm->cursor_x);
  846. X            if (!tty_is_multiscreen && shm->cursor_x)
  847. X            {
  848. X                rcvrdisp(&cr, 1);
  849. X                tcap_clear_area_char(shm->cursor_x, ' ');
  850. X            }
  851. X            break;
  852. X    }
  853. X
  854. X}                             /* end of ansi_EL */
  855. X
  856. X/*+-------------------------------------------------------------------------
  857. X    ansi_ECH() - erase characters
  858. X--------------------------------------------------------------------------*/
  859. Xvoid
  860. Xansi_ECH()
  861. X{
  862. X    register uint param;
  863. X    register uint screen_pos;
  864. X
  865. X    if (ansilen == 2)         /* no param */
  866. X        param = 1;
  867. X    else
  868. X        param = atoi(ansibuf + 1);
  869. X
  870. X    if ((shm->cursor_x + param) >= tcap_COLS)
  871. X        return;
  872. X
  873. X    screen_pos = (shm->cursor_y * tcap_COLS) + shm->cursor_x;
  874. X    mem_cpy((char *)shm->screen + screen_pos,
  875. X        (char *)shm->screen + screen_pos + param, param);
  876. X    spaces((char *)shm->screen + ((shm->cursor_y + 1) * tcap_COLS) -
  877. X        param, param);
  878. X
  879. X    if (!tty_is_multiscreen)
  880. X        tcap_delete_chars(param);
  881. X
  882. X}                             /* end of ansi_ECH */
  883. X
  884. X/*+-------------------------------------------------------------------------
  885. X    ansi_SU() - scroll up (new blank lines at the bottom)
  886. X--------------------------------------------------------------------------*/
  887. Xvoid
  888. Xansi_SU()
  889. X{
  890. X    register uint param;
  891. X    register uint count;
  892. X
  893. X    if (ansilen == 2)         /* no param */
  894. X        param = 1;
  895. X    else
  896. X        param = atoi(ansibuf + 1);
  897. X
  898. X    if (param > tcap_LINES)
  899. X        param = tcap_LINES;
  900. X    if (!param)
  901. X        return;
  902. X
  903. X#ifdef ANSI_DEBUG_3
  904. X    if (wfp)
  905. X        fprintf(wfp, "SU: param=%u y,x=%d,%d\n", param,
  906. X            shm->cursor_y, shm->cursor_x);
  907. X#endif
  908. X
  909. X    count = tcap_COLS * param;
  910. X    mem_cpy((char *)shm->screen, (char *)shm->screen + count,
  911. X        LINESxCOLS - count);
  912. X    spaces((char *)shm->screen + LINESxCOLS - count, count);
  913. X
  914. X    if (!tty_is_multiscreen)
  915. X    {
  916. X        tcap_cursor(tcap_LINES - 1, 0);
  917. X        while (param--)
  918. X            ff(se, "\r\n");
  919. X        tcap_cursor(shm->cursor_y, shm->cursor_x);
  920. X    }
  921. X
  922. X}                             /* end of ansi_SU */
  923. X
  924. X/*+-------------------------------------------------------------------------
  925. X    ansi_SD() - scroll down (new blank lines at the top)
  926. X--------------------------------------------------------------------------*/
  927. Xvoid
  928. Xansi_SD()
  929. X{
  930. X    register uint param;
  931. X    register uint count;
  932. X
  933. X    if (ansilen == 2)         /* no param */
  934. X        param = 1;
  935. X    else
  936. X        param = atoi(ansibuf + 1);
  937. X
  938. X    if (param > tcap_LINES)
  939. X        param = tcap_LINES;
  940. X    if (!param)
  941. X        return;
  942. X
  943. X#ifdef ANSI_DEBUG_3
  944. X    if (wfp)
  945. X        fprintf(wfp, "SD: param=%u y,x=%d,%d\n", param,
  946. X            shm->cursor_y, shm->cursor_x);
  947. X#endif
  948. X
  949. X    count = tcap_COLS * param;
  950. X    mem_cpy((char *)shm->screen, (char *)shm->screen + count,
  951. X        LINESxCOLS - count);
  952. X    spaces((char *)shm->screen + LINESxCOLS - count, count);
  953. X
  954. X    if (!tty_is_multiscreen)
  955. X    {
  956. X        tcap_cursor(0, 0);
  957. X        tcap_insert_lines(param);
  958. X        tcap_cursor(shm->cursor_y, shm->cursor_x);
  959. X    }
  960. X
  961. X}                             /* end of ansi_SD */
  962. X
  963. X/*+-------------------------------------------------------------------------
  964. X    ansi_HPA() - horizontal position absolute
  965. X--------------------------------------------------------------------------*/
  966. Xvoid
  967. Xansi_HPA()
  968. X{
  969. X    register uint param;
  970. X
  971. X    if (ansilen == 2)         /* no param */
  972. X        param = 1;
  973. X    else
  974. X        param = atoi(ansibuf + 1);
  975. X
  976. X    if (param >= tcap_LINES)
  977. X        return;
  978. X
  979. X    if ((unsigned)(shm->cursor_x = param) >= (unsigned)tcap_COLS)
  980. X        shm->cursor_x = tcap_COLS - 1;
  981. X
  982. X    if (!tty_is_multiscreen)
  983. X        tcap_cursor(shm->cursor_y, shm->cursor_x);
  984. X
  985. X}                             /* end of ansi_HPA */
  986. X
  987. X/*+-------------------------------------------------------------------------
  988. X    ansi_VPA() - vertical position absolute
  989. X--------------------------------------------------------------------------*/
  990. Xvoid
  991. Xansi_VPA()
  992. X{
  993. X    register uint param;
  994. X
  995. X    if (ansilen == 2)         /* no param */
  996. X        param = 1;
  997. X    else
  998. X        param = atoi(ansibuf + 1);
  999. X
  1000. X    if (param >= tcap_COLS)
  1001. X        return;
  1002. X
  1003. X    if ((unsigned)(shm->cursor_y = param) >= (unsigned)tcap_LINES)
  1004. X        shm->cursor_y = tcap_LINES - 1;
  1005. X
  1006. X    if (!tty_is_multiscreen)
  1007. X        tcap_cursor(shm->cursor_y, shm->cursor_x);
  1008. X
  1009. X}                             /* end of ansi_VPA */
  1010. X
  1011. X/*+-------------------------------------------------------------------------
  1012. X    ansi_IL() - insert lines
  1013. X--------------------------------------------------------------------------*/
  1014. Xvoid
  1015. Xansi_IL()
  1016. X{
  1017. X    register uint param;
  1018. X    register uint count;
  1019. X    register uint screen_pos;
  1020. X
  1021. X    if (ansilen == 2)         /* no param */
  1022. X        param = 1;
  1023. X    else
  1024. X        param = atoi(ansibuf + 1);
  1025. X
  1026. X    if ((shm->cursor_y + param) >= tcap_LINES)
  1027. X        return;
  1028. X
  1029. X    count = tcap_COLS * param;
  1030. X    screen_pos = shm->cursor_y * tcap_COLS;
  1031. X    mem_cpy((char *)shm->screen + screen_pos + count,
  1032. X        (char *)shm->screen + screen_pos,
  1033. X        LINESxCOLS - screen_pos - count);
  1034. X    spaces((char *)shm->screen + screen_pos, count);
  1035. X
  1036. X    if (!tty_is_multiscreen)
  1037. X        tcap_insert_lines(param);
  1038. X
  1039. X}                             /* end of ansi_IL */
  1040. X
  1041. X/*+-------------------------------------------------------------------------
  1042. X    ansi_ICH() - insert characters
  1043. X--------------------------------------------------------------------------*/
  1044. Xvoid
  1045. Xansi_ICH()
  1046. X{
  1047. X    register uint param;
  1048. X    register uint count;
  1049. X    register uint screen_pos;
  1050. X
  1051. X    if (ansilen == 2)         /* no param */
  1052. X        param = 1;
  1053. X    else
  1054. X        param = atoi(ansibuf + 1);
  1055. X
  1056. X    if (param > tcap_COLS - shm->cursor_x)
  1057. X        param = tcap_COLS - shm->cursor_x;
  1058. X
  1059. X    if (!param)
  1060. X        return;
  1061. X
  1062. X    screen_pos = (shm->cursor_y * tcap_COLS) + shm->cursor_x;
  1063. X    count = tcap_COLS - shm->cursor_x - param;
  1064. X    mem_cpy((char *)shm->screen + screen_pos + param,
  1065. X        (char *)shm->screen + screen_pos, count);
  1066. X    spaces((char *)shm->screen + screen_pos, param);
  1067. X
  1068. X    if (!tty_is_multiscreen)
  1069. X        tcap_insert_chars(param);
  1070. X
  1071. X}                             /* end of ansi_ICH */
  1072. X
  1073. X/*+-------------------------------------------------------------------------
  1074. X    ansi_DL() - delete lines
  1075. X--------------------------------------------------------------------------*/
  1076. Xvoid
  1077. Xansi_DL()
  1078. X{
  1079. X    register uint param;
  1080. X    register uint count;
  1081. X    register uint screen_pos;
  1082. X
  1083. X    if (ansilen == 2)         /* no param */
  1084. X        param = 1;
  1085. X    else
  1086. X        param = atoi(ansibuf + 1);
  1087. X
  1088. X    if (param > (tcap_LINES - shm->cursor_y))
  1089. X        param = tcap_LINES - shm->cursor_y;
  1090. X
  1091. X    if (!param)
  1092. X        return;
  1093. X
  1094. X    count = tcap_COLS * param;
  1095. X    screen_pos = shm->cursor_y * tcap_COLS;
  1096. X    mem_cpy((char *)shm->screen + screen_pos,
  1097. X        (char *)shm->screen + screen_pos + count,
  1098. X        LINESxCOLS - screen_pos - count);
  1099. X    spaces((char *)shm->screen + LINESxCOLS - count, count);
  1100. X
  1101. X    if (!tty_is_multiscreen)
  1102. X        tcap_delete_lines(param);
  1103. X
  1104. X}                             /* end of ansi_DL */
  1105. X
  1106. X/*+-------------------------------------------------------------------------
  1107. X    ansi_DCH() - delete characters
  1108. X--------------------------------------------------------------------------*/
  1109. Xvoid
  1110. Xansi_DCH()
  1111. X{
  1112. X    register uint param;
  1113. X    register uint count;
  1114. X    register uint screen_pos;
  1115. X
  1116. X    if (ansilen == 2)         /* no param */
  1117. X        param = 1;
  1118. X    else
  1119. X        param = atoi(ansibuf + 1);
  1120. X
  1121. X    if (ansilen == 2)         /* no param */
  1122. X        param = 1;
  1123. X    else
  1124. X        param = atoi(ansibuf + 1);
  1125. X
  1126. X    if (param > tcap_COLS - shm->cursor_x)
  1127. X        param = tcap_COLS - shm->cursor_x;
  1128. X
  1129. X    if (!param)
  1130. X        return;
  1131. X
  1132. X    screen_pos = (shm->cursor_y * tcap_COLS) + shm->cursor_x;
  1133. X    count = tcap_COLS - shm->cursor_x - param;
  1134. X    mem_cpy((char *)shm->screen + screen_pos,
  1135. X        (char *)shm->screen + screen_pos + param, count);
  1136. X    screen_pos = ((shm->cursor_y + 1) * tcap_COLS) - param;
  1137. X    spaces((char *)shm->screen + screen_pos, param);
  1138. X
  1139. X    if (!tty_is_multiscreen)
  1140. X        tcap_delete_chars(param);
  1141. X
  1142. X}                             /* end of ansi_DCH */
  1143. X
  1144. X/*+-------------------------------------------------------------------------
  1145. X    ansi_CPL() - cursor to previous line
  1146. X--------------------------------------------------------------------------*/
  1147. Xvoid
  1148. Xansi_CPL()
  1149. X{
  1150. X    register uint param;
  1151. X
  1152. X    if (ansilen == 2)         /* no param */
  1153. X        param = 1;
  1154. X    else
  1155. X        param = atoi(ansibuf + 1);
  1156. X
  1157. X    if ((shm->cursor_y -= param) >= tcap_LINES)    /* unsigned comparison */
  1158. X        shm->cursor_y = 0;
  1159. X    shm->cursor_x = 0;
  1160. X
  1161. X    if (!tty_is_multiscreen)
  1162. X        tcap_cursor(shm->cursor_y, shm->cursor_x);
  1163. X
  1164. X}                             /* end of ansi_CPL */
  1165. X
  1166. X/*+-------------------------------------------------------------------------
  1167. X    ansi_CNL() - cursor to next line
  1168. X--------------------------------------------------------------------------*/
  1169. Xvoid
  1170. Xansi_CNL()
  1171. X{
  1172. X    register uint param;
  1173. X
  1174. X    if (ansilen == 2)         /* no param */
  1175. X        param = 1;
  1176. X    else
  1177. X        param = atoi(ansibuf + 1);
  1178. X
  1179. X    if ((shm->cursor_y += param) >= tcap_LINES)
  1180. X        shm->cursor_y = tcap_LINES - 1;
  1181. X    shm->cursor_x = 0;
  1182. X
  1183. X    if (!tty_is_multiscreen)
  1184. X        tcap_cursor(shm->cursor_y, shm->cursor_x);
  1185. X
  1186. X}                             /* end of ansi_CNL */
  1187. X
  1188. X/*+-------------------------------------------------------------------------
  1189. X    saved_cursor_save_cursor() - nice but unfortunate IBM extension
  1190. X
  1191. XI can't find this used anywhere but in the DOS world.  Supporting this
  1192. Xpair of sequences is what started this whole complex mess.
  1193. X--------------------------------------------------------------------------*/
  1194. Xvoid
  1195. Xsaved_cursor_save_cursor()
  1196. X{
  1197. X    saved_cursor_y = shm->cursor_y;
  1198. X    saved_cursor_x = shm->cursor_x;
  1199. X}                             /* end of saved_cursor_save_cursor */
  1200. X
  1201. X/*+-------------------------------------------------------------------------
  1202. X    saved_cursor_restore_cursor() - nice but unfortunate IBM extension
  1203. X
  1204. XI can't find this used anywhere but in the DOS world.  Supporting this
  1205. Xpair of sequences is what started this whole complex mess.
  1206. X--------------------------------------------------------------------------*/
  1207. Xvoid
  1208. Xsaved_cursor_restore_cursor()
  1209. X{
  1210. X    shm->cursor_y = saved_cursor_y;
  1211. X    shm->cursor_x = saved_cursor_x;
  1212. X    tcap_cursor(shm->cursor_y, shm->cursor_x);
  1213. X}                             /* end of saved_cursor_restore_cursor */
  1214. X
  1215. X/*+-------------------------------------------------------------------------
  1216. X    rcvd_ESC() - ESC seen-prepare to accumulate ansi sequence
  1217. X--------------------------------------------------------------------------*/
  1218. Xvoid
  1219. Xrcvd_ESC()
  1220. X{
  1221. X#ifdef ANSI_DEBUG
  1222. X    if (wfp)
  1223. X        fprintf(wfp, "ESC ");
  1224. X#endif
  1225. X
  1226. X    ansi = ansibuf;
  1227. X    ansilen = 0;
  1228. X    in_ansi_accumulation = 1;
  1229. X
  1230. X}                             /* end of rcvd_ESC */
  1231. X
  1232. X/*+-------------------------------------------------------------------------
  1233. X    is_ansi_terminator(rchar) - is character terminator for ansi sequence?
  1234. X--------------------------------------------------------------------------*/
  1235. Xint
  1236. Xis_ansi_terminator(rchar)
  1237. Xregister uint rchar;
  1238. X{
  1239. X    return (isalpha(rchar) || strchr("@>=", rchar));
  1240. X}                             /* end of is_ansi_terminator */
  1241. X
  1242. X/*+-------------------------------------------------------------------------
  1243. X    accumulate_ansi_sequence(rchar)
  1244. X--------------------------------------------------------------------------*/
  1245. Xvoid
  1246. Xaccumulate_ansi_sequence(rchar)
  1247. Xuint rchar;
  1248. X{
  1249. X    if (ansilen == (MAX_ANSI_LEN - 2))
  1250. X    {
  1251. X        in_ansi_accumulation = 0;
  1252. X        return;
  1253. X    }
  1254. X
  1255. X#ifdef ANSI_DEBUG_2
  1256. X    if (wfp)
  1257. X    {
  1258. X        fprintf(wfp, "\naas: %02x %c ansilen=%d",
  1259. X            rchar, (rchar & 0x7F < SPACE) ? '.' : (rchar & 0x7F), ansilen);
  1260. X    }
  1261. X#endif
  1262. X
  1263. X    *ansi++ = (uchar) rchar;
  1264. X    *ansi = 0;
  1265. X    ansilen++;
  1266. X
  1267. X}                             /* end of accumulate_ansi_sequence */
  1268. X
  1269. X/*+-------------------------------------------------------------------------
  1270. X    process_ansi_sequence() - a full ansi sequence is to be decoded
  1271. X--------------------------------------------------------------------------*/
  1272. Xvoid
  1273. Xprocess_ansi_sequence()
  1274. X{
  1275. X    register itmp;
  1276. X
  1277. X#ifdef ANSI_DEBUG
  1278. X    if (wfp)
  1279. X    {
  1280. X        fprintf(wfp, "\npas: inansi=%d len=%d '%s' y,x=%d,%d\n",
  1281. X            in_ansi_accumulation, ansilen, ansibuf,
  1282. X            shm->cursor_y, shm->cursor_x);
  1283. X    }
  1284. X#endif
  1285. X
  1286. X    if (!in_ansi_accumulation)
  1287. X        return;
  1288. X    in_ansi_accumulation = 0;
  1289. X
  1290. X    itmp = 1;                 /* assume write needed */
  1291. X    if ((ansilen > 1) && (ansibuf[1] == '='))
  1292. X        ;
  1293. X    else
  1294. X        switch (ansibuf[ansilen - 1])
  1295. X        {
  1296. X            case '@':
  1297. X                ansi_ICH();
  1298. X                break;
  1299. X            case '=':
  1300. X                break;         /* VT-100 application keypad */
  1301. X            case '>':
  1302. X                break;         /* VT-100 numeric keypad */
  1303. X            case 'A':
  1304. X                ansi_CUU();
  1305. X                break;
  1306. X            case 'B':
  1307. X                ansi_CUD();
  1308. X                break;
  1309. X            case 'C':
  1310. X                ansi_CUF();
  1311. X                break;
  1312. X            case 'D':
  1313. X                ansi_CUB();
  1314. X                break;
  1315. X            case 'E':
  1316. X                ansi_CNL();
  1317. X                break;
  1318. X            case 'F':
  1319. X                ansi_CPL();
  1320. X                break;
  1321. X            case 'H':
  1322. X                ansi_CUP();
  1323. X                break;
  1324. X            case 'J':
  1325. X                ansi_ED();
  1326. X                break;
  1327. X            case 'K':
  1328. X                ansi_EL();
  1329. X                break;
  1330. X            case 'L':
  1331. X                ansi_IL();
  1332. X                break;
  1333. X            case 'M':
  1334. X                ansi_DL();
  1335. X                break;
  1336. X            case 'P':
  1337. X                ansi_DCH();
  1338. X                break;
  1339. X            case 'S':
  1340. X                ansi_SU();
  1341. X                break;
  1342. X            case 'T':
  1343. X                ansi_SD();
  1344. X                break;
  1345. X            case 'X':
  1346. X                ansi_ECH();
  1347. X                break;
  1348. X            case '`':
  1349. X                ansi_HPA();
  1350. X                break;
  1351. X            case 'a':
  1352. X                ansi_CUF();
  1353. X                break;         /* HPR */
  1354. X            case 'd':
  1355. X                ansi_VPA();
  1356. X                break;
  1357. X            case 'e':
  1358. X                ansi_CUD();
  1359. X                break;         /* VPR */
  1360. X            case 'f':
  1361. X                ansi_CUP();
  1362. X                break;         /* HVP */
  1363. X            case 'm':
  1364. X                ansi_SGR();
  1365. X                itmp = 0;
  1366. X                break;
  1367. X            case 'n':
  1368. X                ansi_DSR();
  1369. X                itmp = 0;
  1370. X                break;
  1371. X            case 's':
  1372. X                saved_cursor_save_cursor();
  1373. X                itmp = 0;
  1374. X                break;
  1375. X            case 'u':
  1376. X                saved_cursor_restore_cursor();
  1377. X                itmp = 0;
  1378. X                break;
  1379. X#ifdef FUTURES
  1380. X            case 'h':
  1381. X                ansi_SM();
  1382. X                break;         /* Set Mode: SCO: lock keyboard MSDOS: host
  1383. X                              * of shit */
  1384. X            case 'i':
  1385. X                ansi_MC();
  1386. X                break;         /* Media Copy: send screen to line */
  1387. X            case 'l':
  1388. X                ansi_RM();
  1389. X                break;         /* Reset Mode: SCO: unlock keyboard MSDOS:
  1390. X                              * host of shit */
  1391. X#endif /* FUTURES */
  1392. X            default:
  1393. X                break;
  1394. X        }
  1395. X
  1396. X/* if proper ansi console and indicated, write the buffer to the screen */
  1397. X    if (tty_is_multiscreen && itmp)
  1398. X    {
  1399. X        rcvrdisp(&esc, 1);
  1400. X        rcvrdisp(ansibuf, ansilen);
  1401. X    }
  1402. X
  1403. X#ifdef ANSI_DEBUG
  1404. X    if (wfp)
  1405. X        fprintf(wfp, "pas: new cursor y,x=%d,%d\n", shm->cursor_y, shm->cursor_x);
  1406. X#endif
  1407. X}                             /* end of process_ansi_sequence */
  1408. X
  1409. X/*+-------------------------------------------------------------------------
  1410. X    rcvr_log_open()
  1411. X--------------------------------------------------------------------------*/
  1412. Xvoid
  1413. Xrcvr_log_open()
  1414. X{
  1415. X
  1416. X    if (rcvr_log)             /* if xmtr set us up for logging */
  1417. X    {
  1418. X        rcvr_log_fp = fopen(rcvr_log_file, rcvr_log_append ? "a" : "w");
  1419. X        rcvr_log_append = 1; /* until next %log -s */
  1420. X        if (!rcvr_log_fp)
  1421. X        {
  1422. X            ff(se, "ecu RCVR: Could not open log file: %s\r\n", rcvr_log_file);
  1423. X            ff(se, "recording aborted.\r\n");
  1424. X            rcvr_log = 0;
  1425. X        }
  1426. X        else if (!rcvr_log_raw && rcvr_log_gen_title)
  1427. X        {
  1428. X#if 0                         /* decommitted - security risk */
  1429. X            char tstr[80];
  1430. X
  1431. X            get_tod(2, tstr);
  1432. X            fprintf(rcvr_log_fp, "\n====> %s (%s, %s, %s) %s\n\n",
  1433. X                shm->Lrname, shm->Llogical,
  1434. X                shm->Ldescr, (shm->Ltelno[0]) ? shm->Ltelno : "NONE", tstr);
  1435. X#endif
  1436. X        }
  1437. X        rcvr_log_gen_title = 0;
  1438. X    }
  1439. X}                             /* end of rcvr_log_open */
  1440. X
  1441. X/*+-------------------------------------------------------------------------
  1442. X    process_rcvd_char(rchar) - process a received character
  1443. X
  1444. XReturn 0 if char should be written to console, 1 otherwise
  1445. X--------------------------------------------------------------------------*/
  1446. Xint
  1447. Xprocess_rcvd_char(rchar)
  1448. Xregister uint rchar;
  1449. X{
  1450. X    register itmp;
  1451. X
  1452. X#ifdef LIMIT_BELL
  1453. X    long now;
  1454. X    static long last_bell_time = -1L;
  1455. X
  1456. X#endif
  1457. X
  1458. X    /*
  1459. X     * automatic ZMODEM frame detection (expensive CPU burners for lazy
  1460. X     * folks)
  1461. X     */
  1462. X    if (shm->autorz)
  1463. X    {
  1464. X        if ((uchar) rchar == autorz_frame[shm->autorz_pos])
  1465. X        {
  1466. X            itmp = shm->autorz_pos;    /* copy to register trying to be quick */
  1467. X            if (++itmp == sizeof(autorz_frame))
  1468. X            {
  1469. X                if (lgetc_count)
  1470. X                {
  1471. X                    rcvrdisp(lgetc_ptr, lgetc_count);
  1472. X                    lgetc_count = 0;
  1473. X                }
  1474. X                shmr_notify_zmodem_frame();
  1475. X                pause();     /* wait for death */
  1476. X                itmp = 0;     /* in case something starts us up */
  1477. X            }
  1478. X            shm->autorz_pos = itmp;
  1479. X            return (!itmp);     /* don't try to print ^X */
  1480. X        }
  1481. X        else
  1482. X            shm->autorz_pos = 0;
  1483. X    }
  1484. X
  1485. X    /*
  1486. X     * BEL and alarm-on-incoming-data processing
  1487. X     */
  1488. X    if (shm->bell_notify_state == 2)
  1489. X    {
  1490. X        shm->bell_notify_state = 1;
  1491. X        bell_notify(XBELL_3T);
  1492. X    }
  1493. X    else if (rchar == BEL)
  1494. X    {
  1495. X#ifdef LIMIT_BELL
  1496. X        time(&now);
  1497. X        if ((now - last_bell_time) < 2L)
  1498. X            return (1);
  1499. X        last_bell_time = now;
  1500. X#endif
  1501. X        bell_notify(XBELL_ATTENTION);
  1502. X        return (0);
  1503. X    }
  1504. X
  1505. X#if !defined(NO_ANSI_EMULATION)
  1506. X
  1507. X    /*
  1508. X     * video control sequences
  1509. X     */
  1510. X    if (rchar == ESC)
  1511. X    {
  1512. X        rcvd_ESC();
  1513. X        return (1);
  1514. X    }
  1515. X    else if (in_ansi_accumulation)
  1516. X    {
  1517. X
  1518. X        /*
  1519. X         * we handle some VT-100 two character sequences (ESC + one
  1520. X         * character)
  1521. X         */
  1522. X        int consumed = 0;
  1523. X
  1524. X        if (!ansilen)
  1525. X        {
  1526. X            switch (rchar & 0x7F)
  1527. X            {
  1528. X                case '7':     /* VT100 save cursor position */
  1529. X                    consumed = 1;
  1530. X                    saved_cursor_save_cursor();
  1531. X                    break;
  1532. X                case '8':     /* VT100 save cursor position */
  1533. X                    consumed = 1;
  1534. X                    saved_cursor_restore_cursor();
  1535. X                    break;
  1536. X            }
  1537. X            if (consumed)
  1538. X            {
  1539. X#ifdef ANSI_DEBUG
  1540. X                if (wfp)
  1541. X                    fprintf(wfp, "single: '%c'\n", rchar);
  1542. X#endif
  1543. X                in_ansi_accumulation = 0;
  1544. X                return (1);
  1545. X            }
  1546. X        }
  1547. X
  1548. X        /*
  1549. X         * other sequences go through the ANSI decode path
  1550. X         */
  1551. X        accumulate_ansi_sequence(rchar);
  1552. X        if (is_ansi_terminator(rchar))
  1553. X            process_ansi_sequence();
  1554. X        return (1);
  1555. X    }
  1556. X#endif /* !NO_ANSI_EMULATION */
  1557. X
  1558. X    /*
  1559. X     * the bread and butter of the receiver: print printable characters
  1560. X     * and obey formatting characters
  1561. X     */
  1562. X    if (rchar < SPACE)
  1563. X    {
  1564. X        switch (rchar)
  1565. X        {
  1566. X            case CTL_L:
  1567. X                spaces((char *)shm->screen, LINESxCOLS);
  1568. X                shm->cursor_y = 0;
  1569. X                shm->cursor_x = 0;
  1570. X                break;
  1571. X
  1572. X            case BS:
  1573. X                if (shm->cursor_x)
  1574. X                    shm->cursor_x--;
  1575. X                break;
  1576. X
  1577. X            case NL:
  1578. X                if (shm->cursor_y != tcap_LINES - 1)
  1579. X                    shm->cursor_y++;
  1580. X                else
  1581. X                {
  1582. X                    mem_cpy((char *)shm->screen, (char *)shm->screen + tcap_COLS,
  1583. X                        LINESxCOLS - tcap_COLS);
  1584. X                    spaces(&shm->screen[shm->cursor_y][0], tcap_COLS);
  1585. X                }
  1586. X                break;
  1587. X
  1588. X            case CRET:
  1589. X                shm->cursor_x = 0;
  1590. X                break;
  1591. X
  1592. X            case TAB:
  1593. X                itmp = 8 - (shm->cursor_x % 8);
  1594. X                shm->cursor_x += itmp;
  1595. X                if (shm->cursor_x >= tcap_COLS)
  1596. X                {
  1597. X                    shm->cursor_x = 0;
  1598. X                    if (++shm->cursor_y >= tcap_LINES)
  1599. X                        shm->cursor_y = tcap_LINES - 1;
  1600. X                }
  1601. X                spaces(&shm->screen[shm->cursor_y][shm->cursor_x], itmp);
  1602. X                break;
  1603. X
  1604. X#ifdef TANDEM_ENQ_ACK         /* for my friend John Dashner at Tandem */
  1605. X            case ENQ:
  1606. X                lputc(ACK);
  1607. X                return (0);
  1608. X#endif
  1609. X
  1610. X        }
  1611. X    }
  1612. X    else
  1613. X    {
  1614. X        shm->screen[shm->cursor_y][shm->cursor_x++] = (uchar) rchar;
  1615. X        if (shm->cursor_x >= tcap_COLS)
  1616. X        {
  1617. X            shm->cursor_x = 0;
  1618. X            if (shm->cursor_y != tcap_LINES - 1)
  1619. X                shm->cursor_y++;
  1620. X            else
  1621. X            {
  1622. X                mem_cpy((char *)shm->screen, (char *)shm->screen + tcap_COLS,
  1623. X                    LINESxCOLS - tcap_COLS);
  1624. X                spaces(&shm->screen[shm->cursor_y][shm->cursor_x], tcap_COLS);
  1625. X            }
  1626. X        }
  1627. X    }
  1628. X
  1629. X#ifdef ANSI_DEBUG_2
  1630. X    if (wfp)
  1631. X    {
  1632. X        if ((rchar & 0x7F) == NL)
  1633. X            fputs("\n", wfp);
  1634. X        else
  1635. X            fputc(((rchar & 0x7F) < SPACE) ? '.' : (rchar & 0x7F), wfp);
  1636. X    }
  1637. X#endif
  1638. X
  1639. X    /*
  1640. X     * receiver logging
  1641. X     */
  1642. X    if (rcvr_log && rcvr_log_fp)
  1643. X    {
  1644. X        /* if raw mode or character not excluded from "cooked" logging */
  1645. X        if (rcvr_log_raw || ((rchar >= SPACE) && (rchar <= '~')) ||
  1646. X            (rchar == NL) || (rchar == TAB))
  1647. X        {
  1648. X            LOGPUTC(rchar, rcvr_log_fp);
  1649. X        }
  1650. X        /* back if log file if not raw and char is backspace */
  1651. X        else if (!rcvr_log_raw && (rchar == BS))
  1652. X        {
  1653. X            long logpos = 0;
  1654. X
  1655. X            if (logpos = ftell(rcvr_log_fp))
  1656. X                fseek(rcvr_log_fp, logpos - 1, 0);
  1657. X        }
  1658. X
  1659. X        if (rcvr_log_flusheach)
  1660. X            fflush(rcvr_log_fp);
  1661. X    }
  1662. X    return (0);
  1663. X
  1664. X}                             /* end of process_rcvd_char */
  1665. X
  1666. X/*+-----------------------------------------------------------------------
  1667. X    rcvr() - copy characters from remote line to screen
  1668. X------------------------------------------------------------------------*/
  1669. Xvoid
  1670. Xrcvr()
  1671. X{
  1672. X    uchar rchar;
  1673. X    uchar nlchar = NL;
  1674. X
  1675. X#if defined(ANSI_DEBUG) || defined(RCVR_DEBUG)
  1676. X    char s80[80];
  1677. X
  1678. X#endif /* ANSI_DEBUG */
  1679. X
  1680. X#ifdef ANSI_DEBUG
  1681. X    wfp = fopen(ANSI_DEBUG_LOGFILE, "a");
  1682. X    if (ulindex(ANSI_DEBUG_LOGFILE, "/dev/tty") != -1)
  1683. X    {
  1684. X        sprintf(s80, "stty opost ocrnl < %s", ANSI_DEBUG_LOGFILE);
  1685. X        system(s80);
  1686. X    }
  1687. X#ifdef ANSI_DEBUG_NOBUF
  1688. X    setbuf(wfp, NULL);
  1689. X#endif /* ANSI_DEBUG_NOBUF */
  1690. X    fprintf(wfp, "***************\n");
  1691. X#endif /* ANSI_DEBUG */
  1692. X
  1693. X    rcvr_pid = getpid();
  1694. X    shm->autorz_pos = 0;
  1695. X    lgetc_count = 0;
  1696. X    in_ansi_accumulation = 0;
  1697. X    ansi = ansibuf;
  1698. X    ansilen = 0;
  1699. X    shm->rcvrdisp_ptr = shm->rcvrdisp_buffer;
  1700. X    shm->rcvrdisp_count = 0;
  1701. X
  1702. X#ifdef RCVR_DEBUG
  1703. X    sprintf(s80, "RSANE01 shm=%x", shm);
  1704. X    ecu_log_event(getppid(), s80);
  1705. X#endif /* RCVR_DEBUG */
  1706. X
  1707. X    /*
  1708. X     * yetch - magic number gretching for lines and columns
  1709. X     */
  1710. X    if (!tcap_LINES || !tcap_COLS)
  1711. X    {
  1712. X        tcap_LINES = 25;
  1713. X        tcap_COLS = 80;
  1714. X    }
  1715. X    if (tcap_LINES > SCREEN_LINES_MAX)
  1716. X        tcap_LINES = SCREEN_LINES_MAX;
  1717. X    if (tcap_COLS > SCREEN_COLS_MAX)
  1718. X        tcap_COLS = SCREEN_COLS_MAX;
  1719. X    LINESxCOLS = tcap_LINES * tcap_COLS;
  1720. X
  1721. X    rcvr_signals();
  1722. X    rcvr_log_open();
  1723. X
  1724. X    saved_cursor_y = shm->cursor_y;
  1725. X    saved_cursor_x = shm->cursor_x;
  1726. X
  1727. X    /*
  1728. X     * receive loop - keep tight as possible!
  1729. X     */
  1730. X
  1731. X#ifdef RCVR_DEBUG
  1732. X    sprintf(s80, "RSANE02 tty_is_multiscreen=%d", tty_is_multiscreen);
  1733. X    ecu_log_event(getppid(), s80);
  1734. X#endif /* RCVR_DEBUG */
  1735. X
  1736. X    if (tty_is_multiscreen)
  1737. X    {
  1738. X        while (1)
  1739. X        {
  1740. X            rchar = lgetc_rcvr();
  1741. X
  1742. X            if (process_rcvd_char(rchar))
  1743. X                continue;
  1744. X
  1745. X            rcvrdisp((char *)&rchar, 1);
  1746. X
  1747. X            if (shm->Ladd_nl_incoming && (rchar == CRET))
  1748. X                rcvrdisp((char *)&nlchar, 1);
  1749. X        }
  1750. X    }
  1751. X    else
  1752. X    {
  1753. X        while (1)
  1754. X        {
  1755. X            rchar = lgetc_rcvr();
  1756. X
  1757. X            if (rchar >= 0x80)
  1758. X                rchar = non_multiscreen_hi_map[rchar - 0x80];
  1759. X
  1760. X            if (process_rcvd_char(rchar))
  1761. X                continue;
  1762. X
  1763. X            rcvrdisp((char *)&rchar, 1);
  1764. X
  1765. X            if (shm->Ladd_nl_incoming && (rchar == CRET))
  1766. X                rcvrdisp((char *)&nlchar, 1);
  1767. X        }
  1768. X    }
  1769. X
  1770. X    /* NOTREACHED */
  1771. X
  1772. X}                             /* end of rcvr */
  1773. X
  1774. X/*+-------------------------------------------------------------------------
  1775. X    xmtr_wfp_debug_hack() - keep xmtr use of rcvr code from bombing
  1776. X
  1777. XThis function is called once by xmtr() before it does much else.
  1778. XThis is a horrible hack only necessary when the chips are down.
  1779. XIf ANSI_DEBUG has wfp open in rcvr, this opens it in the xmtr too.
  1780. XThe function has scope in the production binary only so ecu.c
  1781. Xhas no need to know the ANSI debug status.  This is the kind of
  1782. Xhack you never find out about in binary programs you buy :->.
  1783. X
  1784. X--------------------------------------------------------------------------*/
  1785. Xvoid
  1786. Xxmtr_wfp_debug_hack()
  1787. X{
  1788. X#ifdef ANSI_DEBUG
  1789. X    wfp = fopen("/dev/null", "w");
  1790. X#endif
  1791. X}                             /* end of xmtr_wfp_debug_hack */
  1792. X
  1793. X/* end of ecurcvr.c */
  1794. X/* vi: set tabstop=4 shiftwidth=4: */
  1795. END_OF_FILE
  1796.   if test 42110 -ne `wc -c <'ecu330/ecurcvr.c'`; then
  1797.     echo shar: \"'ecu330/ecurcvr.c'\" unpacked with wrong size!
  1798.   fi
  1799.   # end of 'ecu330/ecurcvr.c'
  1800. fi
  1801. if test -f 'ecu330/ecusighdl.c' -a "${1}" != "-c" ; then 
  1802.   echo shar: Will not clobber existing file \"'ecu330/ecusighdl.c'\"
  1803. else
  1804.   echo shar: Extracting \"'ecu330/ecusighdl.c'\" \(19004 characters\)
  1805.   sed "s/^X//" >'ecu330/ecusighdl.c' <<'END_OF_FILE'
  1806. X/* #define TRICKY_SEGV */
  1807. X/*+-----------------------------------------------------------------------
  1808. X    ecusighdl.c - xmtr/rcvr individual process signal handlers
  1809. X    wht@n4hgf.atl.ga.us
  1810. X
  1811. X  Defined functions:
  1812. X    _start_rcvr_process(notify_flag)
  1813. X    _start_rcvr_process(notify_flag,fname,fline)
  1814. X    child_signals()
  1815. X    kill_rcvr_process(sig)
  1816. X    rcvr_SIGUSR2_handler()
  1817. X    rcvr_common_signal_handler()
  1818. X    rcvr_death_handler(sig)
  1819. X    rcvr_signals()
  1820. X    termecu(code)
  1821. X    termecu_code_text(code)
  1822. X    xmtr_SIGCLD_handler()
  1823. X    xmtr_SIGHUP_handler(sig)
  1824. X    xmtr_SIGINT_handler()
  1825. X    xmtr_SIGTERM_handler(sig)
  1826. X    xmtr_SIGUSR2_handler()
  1827. X    xmtr_death_handler(sig)
  1828. X    xmtr_signals()
  1829. X
  1830. X------------------------------------------------------------------------*/
  1831. X/*+:EDITS:*/
  1832. X/*:05-04-1994-04:39-wht@n4hgf-ECU release 3.30 */
  1833. X/*:11-25-1993-14:47-wht@n4hgf-call shm_done AFTER restore_initial_colors */
  1834. X/*:10-04-1993-03:57-wht@n4hgf-simplify rcvr signal service + better reporting */
  1835. X/*:10-04-1993-01:58-wht@n4hgf-spice up term diags + report sigs for 1st time */
  1836. X/*:08-30-1993-12:39-wht@n4hgf-revert WHT to catch SEGV */
  1837. X/*:08-07-1993-20:25-wht@n4hgf-if WHT, do not catch SEGV, etc. */
  1838. X/*:06-26-1993-16:33-wht@n4hgf-check for rcvr active in rcvr death test */
  1839. X/*:10-18-1992-14:11-wht@n4hgf-FAS 2.10 users getting SIGUSR1 on xmtr */
  1840. X/*:09-16-1992-13:29-wht@n4hgf-add TERMECU_UNRECOVERABLE text */
  1841. X/*:09-10-1992-13:59-wht@n4hgf-ECU release 3.20 */
  1842. X/*:08-22-1992-15:38-wht@n4hgf-ECU release 3.20 BETA */
  1843. X/*:08-17-1992-04:55-wht@n4hgf-keep rcvr pid in shm for friend code */
  1844. X/*:08-16-1992-03:08-wht@n4hgf-head off another POSIX plot */
  1845. X/*:08-16-1992-01:54-wht@n4hgf-job control signals get SIG_IGN */
  1846. X/*:04-29-1992-19:04-wht@n4hgf-make a pass at handling job control signals */
  1847. X/*:04-29-1992-13:46-wht@n4hgf-ignore SIGQUIT */
  1848. X/*:04-23-1992-16:20-wht@n4hgf-disable mysterious rcvr SIGCLD events */
  1849. X/*:02-16-1992-01:42-wht@n4hgf-turn off xterm_title + add _terminate.ep */
  1850. X/*:08-25-1991-23:56-wht@n4hgf2-handle xmtr core dump gracefully */
  1851. X/*:07-25-1991-12:56-wht@n4hgf-ECU release 3.10 */
  1852. X/*:07-17-1991-07:04-wht@n4hgf-avoid SCO UNIX nap bug */
  1853. X/*:06-29-1991-15:42-wht@n4hgf-if WHT and xterm, play with title bar */
  1854. X/*:01-29-1991-12:57-wht@n4hgf-on exit, restore setcolor colors if possible */
  1855. X/*:12-18-1990-20:02-wht@n4hgf-add rcvr_death_handler */
  1856. X/*:09-19-1990-19:36-wht@n4hgf-ecu_log_event now gets pid for log from caller */
  1857. X/*:08-14-1990-20:40-wht@n4hgf-ecu3.00-flush old edit history */
  1858. X
  1859. X#include "ecu.h"
  1860. X#include "ecufork.h"
  1861. X
  1862. Xextern int windows_active;
  1863. Xextern int current_ttymode;
  1864. Xextern int ttymode_termecu_on_sigint;
  1865. Xextern int rcvr_log;
  1866. Xextern FILE *rcvr_log_fp;
  1867. Xextern char rcvr_log_file[]; /* if rcvr_log!= 0,log filename */
  1868. Xextern int rcvr_log_append;
  1869. X
  1870. Xint sigint = 0;                 /* interrupt indicator */
  1871. Xint proc_interrupt = 0;         /* procedure interrupt indicator */
  1872. Xint last_child_wait_status;
  1873. Xint last_child_wait_pid;
  1874. Xint xmtr_killed_rcvr;
  1875. X
  1876. Xchar *signal_name_text();
  1877. X
  1878. Xvoid xmtr_signals();
  1879. Xvoid rcvr_signals();
  1880. Xvoid child_signals();
  1881. X
  1882. XSIGTYPE kill_rcvr_process();
  1883. X
  1884. XSIGTYPE rcvr_SIGUSR2_handler();
  1885. XSIGTYPE xmtr_SIGINT_handler();
  1886. XSIGTYPE xmtr_SIGHUP_handler();
  1887. XSIGTYPE xmtr_SIGTERM_handler();
  1888. XSIGTYPE xmtr_SIGCLD_handler();
  1889. XSIGTYPE xmtr_death_handler();
  1890. XSIGTYPE rcvr_common_signal_handler();
  1891. XSIGTYPE rcvr_death_handler();
  1892. X
  1893. X/*
  1894. X * macros for wait() status ... in case they aren't defined
  1895. X */
  1896. X#undef WIFEXITED             /* in case they were */
  1897. X#undef WEXITSTATUS
  1898. X#undef WIFSIGNALED
  1899. X#undef WTERMSIG
  1900. X#undef WIFSTOPPED
  1901. X#undef WSTOPSIG
  1902. X
  1903. X#define WIFEXITED(status)    ((status & 0xFF) == 0)
  1904. X#define WEXITSTATUS(status)    ((status >> 8) & 0xFF)
  1905. X#define WIFSIGNALED(status)    ((status) && ((status & 0x00FF) == 0xFF))
  1906. X#define WTERMSIG(status)    (status & 0x7F)
  1907. X#define WIFSTOPPED(status)    ((status & 0xFF) == 0xFF)
  1908. X#define WSTOPSIG(status)    ((status >> 8) & 0xFF)
  1909. X
  1910. X/*+-------------------------------------------------------------------------
  1911. X    termecu_code_text(code)
  1912. X--------------------------------------------------------------------------*/
  1913. Xchar *
  1914. Xtermecu_code_text(code)
  1915. Xint code;
  1916. X{
  1917. X    static char errant[16];
  1918. X    char *signal_name_text();
  1919. X
  1920. X    if ((code >= TERMECU_SIG1) && (code <= TERMECU_SIGN))
  1921. X        return (signal_name_text(code));
  1922. X
  1923. X    switch (code)
  1924. X    {
  1925. X        case TERMECU_BSD4_IOCTL:
  1926. X            return ("BSD4 ioctl error");
  1927. X        case TERMECU_CONFIG_ERROR:
  1928. X            return ("configuration error");
  1929. X        case TERMECU_CURSES_ERROR:
  1930. X            return ("error in curses use");
  1931. X        case TERMECU_GEOMETRY:
  1932. X            return ("unsupported screen geometry");
  1933. X        case TERMECU_INIT_PROC_ERROR:
  1934. X            return ("error during initial procedure");
  1935. X        case TERMECU_IPC_ERROR:
  1936. X            return ("IPC (shm/sem) init failed");
  1937. X        case TERMECU_LINE_OPEN_ERROR:
  1938. X            return ("line open error");
  1939. X        case TERMECU_LINE_READ_ERROR:
  1940. X            return ("line read error");
  1941. X        case TERMECU_LOGIC_ERROR:
  1942. X            return ("internal logic error");
  1943. X        case TERMECU_MALLOC:
  1944. X            return ("critical memory allocation failure");
  1945. X        case TERMECU_NO_FORK_FOR_RCVR:
  1946. X            return ("can't fork for RCVR");
  1947. X        case TERMECU_PWENT_ERROR:
  1948. X            return ("password entry error");
  1949. X        case TERMECU_RCVR_FATAL_ERROR:
  1950. X            return ("detected RCVR FATAL ERROR");
  1951. X        case TERMECU_SHM_ABL:
  1952. X            return ("SHM ABL error");
  1953. X        case TERMECU_SHM_RTL:
  1954. X            return ("SHM RTL error");
  1955. X        case TERMECU_SVC_NOT_AVAIL:
  1956. X            return ("service not available");
  1957. X        case TERMECU_TTYIN_READ_ERROR:
  1958. X            return ("keyboard read error");
  1959. X        case TERMECU_UNRECOVERABLE:
  1960. X            return ("unrecoverable error");
  1961. X        case TERMECU_USAGE:
  1962. X            return ("usage");
  1963. X        case TERMECU_XMTR_FATAL_ERROR:
  1964. X            return ("detected XMTR FATAL ERROR");
  1965. X        default:
  1966. X            sprintf(errant, "code %u?", code);
  1967. X            return (errant);
  1968. X    }
  1969. X
  1970. X}                             /* end of termecu_code_text */
  1971. X
  1972. X/*+-----------------------------------------------------------------------
  1973. X    termecu(code) -- terminate program (with cleanup)
  1974. X
  1975. X  see termecu.h for a list of codes
  1976. X
  1977. X  Separate processing for rcvr and xmtr processes;  rcvr entry
  1978. X  is only upon some kind of serious error and it more less just dies,
  1979. X  causing xmtr process to wake up with SIGCLD and come in here.
  1980. X
  1981. X  Upon entry by xmtr process:
  1982. X    close comm line
  1983. X    run any _terminate.ep procedure
  1984. X    return any ungetty'd line
  1985. X    return user's console to normal status
  1986. X    remove shm segment
  1987. X    terminate program
  1988. X
  1989. X------------------------------------------------------------------------*/
  1990. XSIGTYPE
  1991. Xtermecu(code)
  1992. Xint code;
  1993. X{
  1994. X    static int already_in_termecu = 0;    /* one per fork */
  1995. X    int isig;
  1996. X    int save_errno = errno;
  1997. X    char s256[256];
  1998. X    extern char initial_procedure[];
  1999. X    char *signal_name_text();
  2000. X
  2001. X    if (already_in_termecu)
  2002. X    {
  2003. X        pprintf("\n\n\n%s REENTERED TERMECU ... CANNOT RECOVER\n",
  2004. X            (getpid() == xmtr_pid) ? "XMTR" : "RCVR");
  2005. X        exit(255);
  2006. X    }
  2007. X    already_in_termecu = 1;
  2008. X
  2009. X    if (shm)                 /* tell friends goodbye */
  2010. X        shm->terminating = 1;
  2011. X
  2012. X    if (xmtr_pid == getpid())/* if we are xmtr */
  2013. X    {
  2014. X        for (isig = 1; isig < NSIG; isig++)
  2015. X            signal(isig, SIG_IGN);
  2016. X        kill_rcvr_process(SIGUSR1);
  2017. X        if (windows_active)
  2018. X            windows_end_signal();
  2019. X        tcap_curbotleft();
  2020. X        tcap_eeod();
  2021. X        if (shm && shm->Lconnected)
  2022. X            DCE_hangup();
  2023. X        if (find_procedure("_terminate"))
  2024. X        {
  2025. X            char code_str[16];
  2026. X            char *_doproc_args[2];
  2027. X
  2028. X            _doproc_args[0] = "_terminate";    /* _terminate.ep */
  2029. X            sprintf(code_str, "%d", code);
  2030. X            _doproc_args[1] = code_str;
  2031. X            (void)do_proc(2, _doproc_args);
  2032. X        }
  2033. X
  2034. X        if (shm && (shm->Liofd != -1))
  2035. X            lclose();
  2036. X
  2037. X        /*
  2038. X         * make SURE we release any line(s) acquired from getty
  2039. X         */
  2040. X        ungetty_return_line((char *)0, "terminating");
  2041. X
  2042. X        ttymode(0);             /* normal tty status */
  2043. X        if (!code)
  2044. X            ;
  2045. X        else if (code <= TERMECU_SIGN)
  2046. X        {
  2047. X            pprintf("## XMTR caught signal %d (%s)\n",
  2048. X                code, signal_name_text(code));
  2049. X        }
  2050. X        else
  2051. X        {
  2052. X            setcolor(colors_error);
  2053. X            if (code == TERMECU_INIT_PROC_ERROR)
  2054. X                pprintf("initial procedure '%s' failed\n", initial_procedure);
  2055. X            else if ((code > TERMECU_INIT_PROC_ERROR) &&
  2056. X                (code <= TERMECU_INIT_PROC_ERROR + 32))
  2057. X            {
  2058. X                pprintf("procedure command: exit %d\n",
  2059. X                    code - TERMECU_INIT_PROC_ERROR);
  2060. X            }
  2061. X            else
  2062. X            {
  2063. X                sprintf(s256, "## XMTR %s, errno = %d", termecu_code_text(code),
  2064. X                    save_errno);
  2065. X                pputs(s256);
  2066. X                pputs("\n");
  2067. X                if (lopen_err_str[0])
  2068. X                {
  2069. X                    pputs(lopen_err_str);
  2070. X                    pputs("\n");
  2071. X                }
  2072. X                ecu_log_event(getpid(), s256);
  2073. X                errno = save_errno;
  2074. X                if (errno)
  2075. X                    pperror("errno may not apply, but");
  2076. X            }
  2077. X        }
  2078. X        restore_initial_colors();
  2079. X        shm_done();
  2080. X    }
  2081. X    else
  2082. X        /* we are rcvr */
  2083. X    {
  2084. X        if (code <= TERMECU_SIGN)
  2085. X        {
  2086. X            pprintf("## RCVR caught signal %d (%s)\n",
  2087. X                code, signal_name_text(code));
  2088. X        }
  2089. X        else
  2090. X        {
  2091. X            sprintf(s256, "## RCVR %s, errno = %d", termecu_code_text(code),
  2092. X                save_errno);
  2093. X            setcolor(colors_error);
  2094. X            pputs(s256);
  2095. X            pputs("\n");
  2096. X            ecu_log_event(getpid(), s256);
  2097. X            errno = save_errno;
  2098. X            if (errno)
  2099. X                pperror("errno may not apply, but");
  2100. X        }
  2101. X        restore_initial_colors();
  2102. X        kill(xmtr_pid, SIGHUP);
  2103. X    }
  2104. X    exit(code);
  2105. X    /* NOTREACHED */
  2106. X
  2107. X}                             /* end of termecu */
  2108. X
  2109. X/*+-----------------------------------------------------------------------
  2110. X    start_rcvr_process(notify_flag) - start RCVR process if not extant
  2111. X------------------------------------------------------------------------*/
  2112. Xvoid
  2113. Xstart_rcvr_process(notify_flag)
  2114. Xint notify_flag;
  2115. X{
  2116. X    extern ulong colors_current;
  2117. X    ulong colors_at_entry = colors_current;
  2118. X
  2119. X#if defined(FORK_DEBUG)
  2120. X    char s128[128];
  2121. X
  2122. X#endif
  2123. X
  2124. X    fflush(so);
  2125. X    fflush(se);
  2126. X
  2127. X    if (rcvr_pid > 0)         /* if process already active,just ... */
  2128. X        return;
  2129. X
  2130. X    if (rcvr_log && rcvr_log_file[0] && rcvr_log_fp)
  2131. X    {
  2132. X        fclose(rcvr_log_fp);
  2133. X        rcvr_log_fp = (FILE *) 0;
  2134. X    }
  2135. X
  2136. X    xmtr_killed_rcvr = 0;
  2137. X    shm->rcvr_pid = rcvr_pid = smart_fork();
  2138. X    if (rcvr_pid == 0)         /* if we are the (spawned) rcvr process */
  2139. X    {
  2140. X        if (notify_flag)
  2141. X        {
  2142. X            setcolor(colors_notify);
  2143. X            fputs("[interactive mode]", se);
  2144. X            setcolor(colors_at_entry);
  2145. X            fputs("\r\n", se);
  2146. X        }
  2147. X
  2148. X#if defined(FORK_DEBUG)
  2149. X        sprintf(s128, "RCVR-START pid %d", getpid());
  2150. X        ecu_log_event(getppid(), s128);    /* rcvr */
  2151. X#endif
  2152. X        rcvr();                 /* run until killed */
  2153. X        /* NOTREACHED */
  2154. X    }
  2155. X    else if (rcvr_pid > 0)     /* we are the father (xmtr) process */
  2156. X    {
  2157. X#if defined(FORK_DEBUG)
  2158. X        sleep(2);
  2159. X#endif
  2160. X        if (rcvr_log)
  2161. X            rcvr_log_append = 1;    /* until next %log -s */
  2162. X        xmtr_signals();
  2163. X        return;
  2164. X    }
  2165. X
  2166. X    shm->rcvr_pid = rcvr_pid = -1;    /* no receiver active */
  2167. X
  2168. X    pprintf("\n\nECU could not fork for receive process\n");
  2169. X    termecu(TERMECU_NO_FORK_FOR_RCVR);
  2170. X    /* NOTREACHED */
  2171. X
  2172. X}                             /* end of _start_rcvr_process */
  2173. X
  2174. X/*+-----------------------------------------------------------------------
  2175. X    kill_rcvr_process(sig) -- kill rcvr process with signal 'sig'
  2176. X------------------------------------------------------------------------*/
  2177. XSIGTYPE
  2178. Xkill_rcvr_process(sig)
  2179. Xint sig;
  2180. X{
  2181. X    int wait_count = 70;
  2182. X
  2183. X    if (rcvr_pid > 0)         /* if we have forked a rcvr process */
  2184. X    {
  2185. X        xmtr_killed_rcvr = 1;
  2186. X        rcvr_log_fp = (FILE *) 0;
  2187. X        xmtr_signals();
  2188. X        kill(rcvr_pid, sig);
  2189. X        if (sig != SIGUSR2)     /* rcvr does not die on SIGUSR2 */
  2190. X        {
  2191. X            errno = 0;
  2192. X            while (wait_count)
  2193. X            {
  2194. X                if (kill(rcvr_pid, 0) && (errno == ESRCH))
  2195. X                    break;
  2196. X                errno = 0;
  2197. X                Nap(40L);
  2198. X                wait_count--;
  2199. X            }
  2200. X            if (!wait_count)
  2201. X            {
  2202. X                while (!kill(rcvr_pid, SIGKILL))
  2203. X                {
  2204. X                    wait((int *)0);
  2205. X                    Nap(40L);
  2206. X                }
  2207. X            }
  2208. X            shm->rcvr_pid = rcvr_pid = -1;    /* no receiver active */
  2209. X            if (rcvr_log && rcvr_log_file[0])
  2210. X                rcvr_log_fp = fopen(rcvr_log_file, "a");
  2211. X
  2212. X            rcvrdisp_actual();    /* write any buffered screen data */
  2213. X        }
  2214. X    }
  2215. X
  2216. X}                             /* end of kill_rcvr_process */
  2217. X
  2218. X/*+-------------------------------------------------------------------------
  2219. X    rcvr_common_signal_handler(sig)
  2220. X--------------------------------------------------------------------------*/
  2221. XSIGTYPE
  2222. Xrcvr_common_signal_handler(sig)
  2223. Xint sig;
  2224. X{
  2225. X    extern int rcvr_log;
  2226. X    extern int rcvr_log_raw;
  2227. X    extern FILE *rcvr_log_fp;
  2228. X
  2229. X    if (rcvr_log)
  2230. X    {
  2231. X        if (!rcvr_log_raw)
  2232. X            fputs("\n", rcvr_log_fp);
  2233. X        fclose(rcvr_log_fp);
  2234. X    }
  2235. X
  2236. X    if (sig == SIGUSR1)
  2237. X        _exit(0);
  2238. X
  2239. X    termecu(sig);
  2240. X
  2241. X}                             /* end of rcvr_common_signal_handler */
  2242. X
  2243. X/*+-------------------------------------------------------------------------
  2244. X    rcvr_SIGUSR2_handler(sig)
  2245. X--------------------------------------------------------------------------*/
  2246. XSIGTYPE
  2247. Xrcvr_SIGUSR2_handler(sig)
  2248. Xint sig;
  2249. X{
  2250. X    signal(SIGUSR2, rcvr_SIGUSR2_handler);
  2251. X    shmr_process_rcvr_SIGUSR2(sig);
  2252. X}                             /* end of rcvr_SIGUSR2_handler */
  2253. X
  2254. X/*+-------------------------------------------------------------------------
  2255. X    rcvr_death_handler(sig) - unexpected signal; try to dump core
  2256. X--------------------------------------------------------------------------*/
  2257. XSIGTYPE
  2258. Xrcvr_death_handler(sig)
  2259. Xint sig;
  2260. X{
  2261. X    int itmp;
  2262. X
  2263. X#ifdef TRICKY_SEGV             /* SCO/i386 */
  2264. X    int *open_elevator_shaft = (int *)0xb0000000;
  2265. X
  2266. X#endif
  2267. X
  2268. X    ttymode(0);
  2269. X    pprintf("\nreceiver process caught signal %d (%s)\n",
  2270. X        sig, signal_name_text(sig));
  2271. X    pprintf("screen cursor (y,x) = (%u,%u)\n", shm->cursor_y, shm->cursor_x);
  2272. X    for (itmp = 1; itmp < NSIG; itmp++)
  2273. X        signal(itmp, SIG_DFL);
  2274. X#ifdef TRICKY_SEGV
  2275. X    signal(SIGSEGV, SIG_DFL);
  2276. X    printf("Roes=%08lx\n", open_elevator_shaft);
  2277. X    *open_elevator_shaft = itmp;
  2278. X#else
  2279. X    rcvr_common_signal_handler(sig);
  2280. X#endif
  2281. X    _exit(-1);
  2282. X
  2283. X}                             /* end of rcvr_death_handler */
  2284. X
  2285. X/*+-------------------------------------------------------------------------
  2286. X    xmtr_SIGINT_handler()
  2287. X--------------------------------------------------------------------------*/
  2288. XSIGTYPE
  2289. Xxmtr_SIGINT_handler()
  2290. X{
  2291. X    if (ttymode_termecu_on_sigint)
  2292. X        termecu(SIGINT);
  2293. X
  2294. X    signal(SIGINT, xmtr_SIGINT_handler);
  2295. X    sigint = 1;
  2296. X    proc_interrupt = 1;
  2297. X}                             /* end of xmtr_SIGINT_handler */
  2298. X
  2299. X/*+-------------------------------------------------------------------------
  2300. X    xmtr_SIGHUP_handler(sig)
  2301. X--------------------------------------------------------------------------*/
  2302. XSIGTYPE
  2303. Xxmtr_SIGHUP_handler(sig)
  2304. Xint sig;
  2305. X{
  2306. X    termecu(sig);
  2307. X}                             /* end of xmtr_SIGHUP_handler */
  2308. X
  2309. X/*+-------------------------------------------------------------------------
  2310. X    xmtr_SIGTERM_handler(sig)
  2311. X--------------------------------------------------------------------------*/
  2312. XSIGTYPE
  2313. Xxmtr_SIGTERM_handler(sig)
  2314. Xint sig;
  2315. X{
  2316. X    termecu(sig);
  2317. X}                             /* end of xmtr_SIGTERM_handler */
  2318. X
  2319. X/*+-------------------------------------------------------------------------
  2320. X    xmtr_SIGUSR2_handler()
  2321. X--------------------------------------------------------------------------*/
  2322. XSIGTYPE
  2323. Xxmtr_SIGUSR2_handler(sig)
  2324. Xint sig;
  2325. X{
  2326. X    SIGTYPE xmtr_SIGUSR2_handler();
  2327. X
  2328. X    signal(sig, xmtr_SIGUSR2_handler);
  2329. X    shmx_process_xmtr_SIGUSR2();
  2330. X
  2331. X}                             /* end of xmtr_SIGUSR2_handler */
  2332. X
  2333. X/*+-------------------------------------------------------------------------
  2334. X    xmtr_death_handler(sig) - unexpected signal; try to dump core
  2335. X--------------------------------------------------------------------------*/
  2336. XSIGTYPE
  2337. Xxmtr_death_handler(sig)
  2338. Xint sig;
  2339. X{
  2340. X    int itmp;
  2341. X
  2342. X#ifdef TRICKY_SEGV
  2343. X    int *open_elevator_shaft = (int *)0xb0000000;
  2344. X
  2345. X#endif
  2346. X
  2347. X    ttymode(0);
  2348. X    pprintf("\ntransmitter process caught signal %d (%s)\n",
  2349. X        sig, signal_name_text(sig));
  2350. X    kill_rcvr_process(SIGUSR1);
  2351. X    for (itmp = 1; itmp < NSIG; itmp++)
  2352. X        signal(itmp, SIG_DFL);
  2353. X#ifdef TRICKY_SEGV
  2354. X    signal(SIGSEGV, SIG_DFL);
  2355. X    printf("Xoes=%08lx\n", open_elevator_shaft);
  2356. X    fflush(stdout);
  2357. X    *open_elevator_shaft = itmp;
  2358. X#else
  2359. X    kill((PID_T) getpid(), SIGIOT);
  2360. X#endif
  2361. X    termecu(sig);
  2362. X}                             /* end of xmtr_death_handler */
  2363. X
  2364. X/*+-------------------------------------------------------------------------
  2365. X    xmtr_SIGCLD_handler()
  2366. X--------------------------------------------------------------------------*/
  2367. XSIGTYPE
  2368. Xxmtr_SIGCLD_handler()
  2369. X{
  2370. X    int itmp;
  2371. X
  2372. X#if defined(FORK_DEBUG)
  2373. X    char s512[512];
  2374. X
  2375. X#endif
  2376. X
  2377. X  WAIT:
  2378. X    errno = 0;
  2379. X    if ((last_child_wait_pid = wait(&last_child_wait_status)) < 0)
  2380. X    {
  2381. X        if (errno == EINTR)
  2382. X            goto WAIT;
  2383. X    }
  2384. X
  2385. X#if defined(FORK_DEBUG)
  2386. X    sprintf(s512, "XMTR SIGCLD pid %d (%s) s=%04x ",
  2387. X        last_child_wait_pid,
  2388. X        (last_child_wait_pid == rcvr_pid) ? "RCVR!" : "AUXOP",
  2389. X        last_child_wait_status);
  2390. X    if (WIFEXITED(last_child_wait_status))
  2391. X    {
  2392. X        sprintf(s512 + strlen(s512), "exit status=%d ",
  2393. X            WEXITSTATUS(last_child_wait_status));
  2394. X    }
  2395. X    if (WIFSIGNALED(last_child_wait_status))
  2396. X    {
  2397. X        sprintf(s512 + strlen(s512), "signal=%d ",
  2398. X            WTERMSIG(last_child_wait_status));
  2399. X    }
  2400. X    ecu_log_event(getpid(), s512);    /* xmtr_SIGCLD_handler() */
  2401. X#endif
  2402. X
  2403. X    if ((last_child_wait_pid == rcvr_pid) && (rcvr_pid > 0) &&
  2404. X        !xmtr_killed_rcvr)
  2405. X    {
  2406. X        pprintf("\nECU receiver (pid %d died) unexpectedly: s=0x%04x\n",
  2407. X            last_child_wait_pid, last_child_wait_status);
  2408. X        itmp = 0;
  2409. X        if (WIFEXITED(last_child_wait_status))
  2410. X        {
  2411. X            itmp = 1;
  2412. X            pprintf("exit status=%d ", WEXITSTATUS(last_child_wait_status));
  2413. X        }
  2414. X        if (WIFSIGNALED(last_child_wait_status))
  2415. X        {
  2416. X            itmp = 1;
  2417. X            pprintf("signal=%d ", WTERMSIG(last_child_wait_status));
  2418. X        }
  2419. X        if (itmp)
  2420. X            pputs("\n");
  2421. X        termecu(TERMECU_RCVR_FATAL_ERROR);
  2422. X    }
  2423. X    signal(SIGCLD, xmtr_SIGCLD_handler);
  2424. X
  2425. X}                             /* end of xmtr_SIGCLD_handler */
  2426. X
  2427. X/*+-------------------------------------------------------------------------
  2428. X    child_signals() - signal() calls for children processes
  2429. X--------------------------------------------------------------------------*/
  2430. Xvoid
  2431. Xchild_signals()
  2432. X{
  2433. X    int isig;
  2434. X
  2435. X    for (isig = 0; isig < NSIG; isig++)
  2436. X        signal(isig, SIG_DFL);
  2437. X
  2438. X}                             /* end of child_signals */
  2439. X
  2440. X/*+-------------------------------------------------------------------------
  2441. X    xmtr_signals()
  2442. X--------------------------------------------------------------------------*/
  2443. Xvoid
  2444. Xxmtr_signals()
  2445. X{
  2446. X    int sig;
  2447. X
  2448. X    for (sig = 1; sig < NSIG; sig++)
  2449. X    {
  2450. X        switch (sig)
  2451. X        {
  2452. X
  2453. X            case SIGHUP:
  2454. X                signal(sig, xmtr_SIGHUP_handler);
  2455. X                break;
  2456. X
  2457. X#if    defined(SIGSTOP)
  2458. X
  2459. X                /*
  2460. X                 * call Roto-Rooter on POSIX plots
  2461. X                 */
  2462. X            case SIGSTOP:
  2463. X            case SIGTSTP:
  2464. X            case SIGCONT:
  2465. X            case SIGTTIN:
  2466. X            case SIGTTOU:
  2467. X                signal(sig, SIG_IGN);
  2468. X                break;
  2469. X#endif
  2470. X
  2471. X#ifdef SIGWINCH
  2472. X            case SIGWINCH:
  2473. X                signal(sig, SIG_DFL);
  2474. X                break;
  2475. X#endif
  2476. X            case SIGQUIT:
  2477. X                signal(sig, SIG_IGN);
  2478. X                break;
  2479. X            case SIGINT:
  2480. X                signal(sig, xmtr_SIGINT_handler);
  2481. X                break;
  2482. X            case SIGTERM:
  2483. X                signal(sig, xmtr_SIGTERM_handler);
  2484. X                break;
  2485. X            case SIGCLD:
  2486. X                signal(sig, xmtr_SIGCLD_handler);
  2487. X                break;
  2488. X            case SIGUSR1:
  2489. X                signal(sig, SIG_IGN);
  2490. X                break;
  2491. X            case SIGUSR2:
  2492. X                signal(sig, xmtr_SIGUSR2_handler);
  2493. X                break;
  2494. X            default:
  2495. X#ifndef WHT                     /* I want the bloody crash */
  2496. X                signal(sig, xmtr_death_handler);
  2497. X#endif
  2498. X                break;
  2499. X        }
  2500. X    }
  2501. X
  2502. X}                             /* end of xmtr_signals */
  2503. X
  2504. X/*+-------------------------------------------------------------------------
  2505. X    rcvr_signals()
  2506. X--------------------------------------------------------------------------*/
  2507. Xvoid
  2508. Xrcvr_signals()
  2509. X{
  2510. X    int sig;
  2511. X
  2512. X    for (sig = 1; sig < NSIG; sig++)
  2513. X    {
  2514. X        switch (sig)
  2515. X        {
  2516. X
  2517. X#if    defined(SIGSTOP)
  2518. X            case SIGSTOP:
  2519. X            case SIGTSTP:
  2520. X            case SIGCONT:
  2521. X            case SIGTTIN:
  2522. X            case SIGTTOU:
  2523. X                signal(sig, SIG_IGN);
  2524. X                break;
  2525. X#endif
  2526. X
  2527. X#ifdef SIGWINCH
  2528. X            case SIGWINCH:
  2529. X#endif
  2530. X            case SIGCLD:
  2531. X                signal(sig, SIG_DFL);
  2532. X                break;
  2533. X            case SIGQUIT:
  2534. X                signal(sig, SIG_IGN);
  2535. X                break;
  2536. X            case SIGHUP:
  2537. X            case SIGINT:
  2538. X            case SIGTERM:
  2539. X            case SIGUSR1:
  2540. X                signal(sig, rcvr_common_signal_handler);
  2541. X                break;
  2542. X            case SIGUSR2:
  2543. X                signal(sig, rcvr_SIGUSR2_handler);
  2544. X                break;
  2545. X            default:
  2546. X#ifndef WHT                     /* I want the bloody crash */
  2547. X                signal(sig, rcvr_death_handler);
  2548. X#endif
  2549. X                break;
  2550. X        }
  2551. X    }
  2552. X}                             /* end of rcvr_signals */
  2553. X
  2554. X/* vi: set tabstop=4 shiftwidth=4: */
  2555. END_OF_FILE
  2556.   if test 19004 -ne `wc -c <'ecu330/ecusighdl.c'`; then
  2557.     echo shar: \"'ecu330/ecusighdl.c'\" unpacked with wrong size!
  2558.   fi
  2559.   # end of 'ecu330/ecusighdl.c'
  2560. fi
  2561. echo shar: End of archive 8 \(of 37\).
  2562. cp /dev/null ark8isdone
  2563. MISSING=""
  2564. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 ; do
  2565.     if test ! -f ark${I}isdone ; then
  2566.     MISSING="${MISSING} ${I}"
  2567.     fi
  2568. done
  2569. if test "${MISSING}" = "" ; then
  2570.     echo You have unpacked all 37 archives.
  2571.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  2572. else
  2573.     echo You still must unpack the following archives:
  2574.     echo "        " ${MISSING}
  2575. fi
  2576. exit 0
  2577. exit 0 # Just in case...
  2578.