home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / misc / volume32 / ecu / part11 < prev    next >
Encoding:
Text File  |  1992-09-13  |  56.9 KB  |  2,310 lines

  1. Newsgroups: comp.sources.misc
  2. From: wht@n4hgf.Mt-Park.GA.US (Warren Tucker)
  3. Subject:  v32i046:  ecu - ECU Asynchronous Communications v3.20, Part11/40
  4. Message-ID: <1992Sep13.153342.5205@sparky.imd.sterling.com>
  5. X-Md4-Signature: abdf55d55ae00d07c4efded06efca8e5
  6. Date: Sun, 13 Sep 1992 15:33:42 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: wht@n4hgf.Mt-Park.GA.US (Warren Tucker)
  10. Posting-number: Volume 32, Issue 46
  11. Archive-name: ecu/part11
  12. Environment: SCO,XENIX,ISC,SUNOS,SYSVR4,HDB,Curses
  13. Supersedes: ecu: Volume 21, Issue 53-89
  14.  
  15. ---- Cut Here and feed the following to sh ----
  16. #!/bin/sh
  17. # this is ecu320.11 (part 11 of ecu320)
  18. # do not concatenate these parts, unpack them in order with /bin/sh
  19. # file ecuphrase.c continued
  20. #
  21. if test ! -r _shar_seq_.tmp; then
  22.     echo 'Please unpack part 1 first!'
  23.     exit 1
  24. fi
  25. (read Scheck
  26.  if test "$Scheck" != 11; then
  27.     echo Please unpack part "$Scheck" next!
  28.     exit 1
  29.  else
  30.     exit 0
  31.  fi
  32. ) < _shar_seq_.tmp || exit 1
  33. if test ! -f _shar_wnt_.tmp; then
  34.     echo 'x - still skipping ecuphrase.c'
  35. else
  36. echo 'x - continuing file ecuphrase.c'
  37. sed 's/^X//' << 'SHAR_EOF' >> 'ecuphrase.c' &&
  38. Xchar *phrases_label[P_N_QUAN];
  39. Xint phrases_count = 0;
  40. Xint phrases_resident = 0;
  41. X
  42. X/*+-----------------------------------------------------------------------
  43. X    read_phrases()
  44. X------------------------------------------------------------------------*/
  45. Xvoid
  46. Xread_phrases()
  47. X{
  48. Xregister char *phrases_str;
  49. Xchar phrases_buf[256];
  50. Xchar phrases_buf_copy[256];
  51. Xchar *phrases_lbl;
  52. XFILE *fd_phrase;
  53. X
  54. X    if(phrases_resident)
  55. X    {
  56. X        while(phrases_count)
  57. X            free(phrases_string[--phrases_count]);
  58. X        phrases_resident = 0;
  59. X    }
  60. X
  61. X    get_home_dir(phrases_buf);
  62. X    strcat(phrases_buf,"/.ecu/phrases");
  63. X
  64. X    if(!(fd_phrase = fopen(phrases_buf,"r")))
  65. X    {
  66. X        ff(se,"\r\n");
  67. X        perror(phrases_buf);
  68. X        ff(se,"\r\n");
  69. X        ff(se,"... no phrases resident\r\n");
  70. X        return;
  71. X    }
  72. X
  73. X/* we have an open .ecu/phrase file */
  74. X    phrases_count = 0;
  75. X    while(fgets(phrases_buf,sizeof(phrases_buf),fd_phrase))
  76. X    {
  77. X        phrases_buf[strlen(phrases_buf) - 1] = 0;
  78. X        if(strlen(phrases_buf) == 0)
  79. X            continue;
  80. X
  81. X        if(phrases_count == P_N_QUAN)
  82. X        {
  83. X            ff(se,"\r\nMaximum number of phrases %d exceeded\r\n",P_N_QUAN);
  84. X            ff(se,"rest of file ignored, starting with the following:\r\n");
  85. X            ff(se,"--> %s\r\n\r\n",phrases_buf);
  86. X            phrases_resident = 1;
  87. X            fclose(fd_phrase);
  88. X            return;
  89. X        }
  90. X        strcpy(phrases_buf_copy,phrases_buf);
  91. X        phrases_lbl = phrases_buf_copy;
  92. X        for(phrases_str = phrases_buf_copy; *phrases_str; phrases_str++)
  93. X        {
  94. X            if(*phrases_str == ':')
  95. X            {
  96. X                *phrases_str++ = 0;
  97. X                break;
  98. X            }
  99. X            if(*phrases_str == 0)
  100. X            {
  101. X                ff(se,"invalid entry `%s'\n",phrases_buf);
  102. X                continue;
  103. X            }
  104. X        }
  105. X
  106. X        if(!(phrases_string[phrases_count] = malloc(strlen(phrases_str)+2)) ||
  107. X           !(phrases_label[phrases_count] = malloc(strlen(phrases_lbl)+2)))
  108. X        {
  109. X            ff(se,"\r\nNo more memory for phrases\r\n");
  110. X            ff(se,"rest of file ignored, starting with the following:\r\n");
  111. X            ff(se,"--> %s\r\n\r\n",phrases_buf);
  112. X            phrases_resident = 1;
  113. X            fclose(fd_phrase);
  114. X            if(phrases_string[phrases_count])
  115. X                free(phrases_string[phrases_count]);
  116. X            return;
  117. X        }
  118. X        strcpy(phrases_string[phrases_count],phrases_str);
  119. X        strcpy(phrases_label[phrases_count],phrases_lbl);
  120. X        phrases_count++;
  121. X    }            /* while records left to read */
  122. X
  123. X    fclose(fd_phrase);
  124. X    phrases_resident = 1;
  125. X}    /* end of read_phrases */
  126. X
  127. X/*+-------------------------------------------------------------------------
  128. X    phrases(nargc,nargv)
  129. X--------------------------------------------------------------------------*/
  130. Xphrases(nargc,nargv)
  131. Xint nargc;
  132. Xchar **nargv;
  133. X{
  134. Xregister itmp;
  135. Xregister ichar;
  136. Xregister char *cptr;
  137. Xint old_ttymode = get_ttymode();
  138. Xextern char *phrases_string[]; 
  139. Xextern int phrases_count;
  140. Xextern int phrases_resident;
  141. Xextern int icmd_prompt_len;
  142. X
  143. X    for(itmp = icmd_prompt_len + strlen(nargv[0]); itmp; itmp--)
  144. X        fputs("\b \b",se);
  145. X
  146. X    itmp = atoi(nargv[0]);
  147. X
  148. X    if(itmp == 0)
  149. X    {
  150. X        ff(se,"\r\n");
  151. X        read_phrases();
  152. X        if(!phrases_count)
  153. X            return(0);
  154. X        tcap_stand_out();
  155. X        ff(se,
  156. X" # |  mnemonic    |     phrase                                              ");
  157. X        tcap_stand_end();
  158. X        ff(se,"\r\n");
  159. X        for(itmp = 0; itmp < phrases_count; itmp++)
  160. X            ff(se,"%2d | %12s |  %s\r\n",itmp + 1,phrases_label[itmp],
  161. X                        phrases_string[itmp]);
  162. X        return(0);
  163. X    }
  164. X    else
  165. X        if(phrases_resident == 0)
  166. X            read_phrases();
  167. X
  168. X    if(itmp > phrases_count)
  169. X    {
  170. X        ff(se,"  unknown: %d\r\n",itmp);
  171. X        return(-1);
  172. X    }
  173. X    else
  174. X    {
  175. X        cptr = phrases_string[itmp - 1];
  176. X        ttymode(2);
  177. X        while(*cptr)
  178. X        {
  179. X            if(sigint)
  180. X                break;
  181. X
  182. X            switch(ichar = *cptr++)
  183. X            {
  184. X                case '^':
  185. X                    ichar = *cptr++;
  186. X                    if((ichar >= '@') && (ichar <= '_'))
  187. X                        lputc_paced(0,ichar & 0x1F);
  188. X                    else if(ichar == '?')
  189. X                        lputc_paced(0,0x7F);
  190. X                    else
  191. X                    {
  192. X                        switch(ichar)
  193. X                        {
  194. X                            case 0:
  195. X                                goto NUL_FOUND;
  196. X                            case 'r':
  197. X                                lputc_paced(0,'\r');
  198. X                                break;
  199. X                            case 'n':
  200. X                                lputc_paced(0,'\n');
  201. X                                break;
  202. X                            case 't':
  203. X                                lputc_paced(0,'\t');
  204. X                                break;
  205. X                            case '^':
  206. X                                lputc_paced(0,'^'); 
  207. X                                break;
  208. X                            case 'p': 
  209. X                                itmp = atoi(cptr);
  210. X                                while((*cptr >= '0') && (*cptr <= '9'))
  211. X                                    cptr++;
  212. X                                if(*cptr == '.')
  213. X                                    cptr++;
  214. X                                if(!itmp)
  215. X                                    itmp = 1;
  216. X                                Nap((long)itmp * 100L);
  217. X                                break;
  218. X                            case 'a':
  219. X                                itmp = atoi(cptr);
  220. X                                while((*cptr >= '0') && (*cptr <= '9'))
  221. X                                    cptr++;
  222. X                                if(*cptr == '.')
  223. X                                    cptr++;
  224. X                                if(itmp < nargc)
  225. X                                {
  226. X                                    lputs_paced(0,nargv[itmp]);
  227. X                                    itmp = strlen(nargv[itmp]);
  228. X                                }
  229. X                                break;
  230. X                        }
  231. X                    }
  232. X                    break;
  233. X                default:
  234. X                    lputc_paced(0,ichar);
  235. X            }
  236. X        }
  237. X
  238. XNUL_FOUND:
  239. X        if(sigint)
  240. X        {
  241. X            sigint = 0;
  242. X            ff(se,"\r\n--> interrupted\r\n");
  243. X        }
  244. X
  245. X    }
  246. X
  247. X    ttymode(old_ttymode);
  248. X    return(0);
  249. X
  250. X}    /* end of phrases */
  251. X
  252. X
  253. X/*+-------------------------------------------------------------------------
  254. X    phrase_help()
  255. X--------------------------------------------------------------------------*/
  256. Xvoid
  257. Xphrase_help()
  258. X{
  259. X    ff(se,"^r == \\r    ^n == \\n   ^t == \\t  ^^ == '^'\r\n");
  260. X    ff(se,"^p#.  pause # secs\r\n");
  261. X    ff(se,"^a#.  arg number # of %%# invocation\r\n");
  262. X}    /* end of phrase_help */
  263. X/* vi: set tabstop=4 shiftwidth=4: */
  264. SHAR_EOF
  265. echo 'File ecuphrase.c is complete' &&
  266. chmod 0644 ecuphrase.c ||
  267. echo 'restore of ecuphrase.c failed'
  268. Wc_c="`wc -c < 'ecuphrase.c'`"
  269. test 5683 -eq "$Wc_c" ||
  270.     echo 'ecuphrase.c: original size 5683, current size' "$Wc_c"
  271. rm -f _shar_wnt_.tmp
  272. fi
  273. # ============= ecurcvr.c ==============
  274. if test -f 'ecurcvr.c' -a X"$1" != X"-c"; then
  275.     echo 'x - skipping ecurcvr.c (File already exists)'
  276.     rm -f _shar_wnt_.tmp
  277. else
  278. > _shar_wnt_.tmp
  279. echo 'x - extracting ecurcvr.c (Text)'
  280. sed 's/^X//' << 'SHAR_EOF' > 'ecurcvr.c' &&
  281. X/* #define DEFENSIVE */
  282. X/* #define ANSI_DEBUG */        /* debug ansi */
  283. X/* #define ANSI_DEBUG_2 */        /* debug ansi intensive output */
  284. X/* #define ANSI_DEBUG_3 */        /* debug ansi selected output */
  285. X/* #define ANSI_DEBUG_NOBUF */    /* unbufferred logging */
  286. X/* #define ANSI_DEBUG_LOGFILE    "/dev/tty2h" */
  287. X/* #define DEBUG_CURSOR */
  288. X#ifndef LIMIT_BELL
  289. X#define LIMIT_BELL
  290. X#endif
  291. X/*+-------------------------------------------------------------------------
  292. X    ecurcvr.c - rcvr process + ANSI filter + non-ANSI<->ANSI hoop jumping
  293. X    wht@n4hgf.Mt-Park.GA.US
  294. X
  295. X  Defined functions:
  296. X    accumulate_ansi_sequence(rchar)
  297. X    ansi_CNL()
  298. X    ansi_CPL()
  299. X    ansi_CUB()
  300. X    ansi_CUD()
  301. X    ansi_CUF()
  302. X    ansi_CUP()
  303. X    ansi_CUU()
  304. X    ansi_DCH()
  305. X    ansi_DL()
  306. X    ansi_DSR()
  307. X    ansi_ECH()
  308. X    ansi_ED()
  309. X    ansi_EL()
  310. X    ansi_HPA()
  311. X    ansi_ICH()
  312. X    ansi_IL()
  313. X    ansi_SD()
  314. X    ansi_SGR()
  315. X    ansi_SU()
  316. X    ansi_VPA()
  317. X    is_ansi_terminator(rchar)
  318. X    lgetc_rcvr()
  319. X    process_ansi_sequence()
  320. X    process_rcvd_char(rchar)
  321. X    rcvd_ESC()
  322. X    rcvr()
  323. X    rcvr_log_open()
  324. X    rcvrdisp(buf,buflen)
  325. X    rcvrdisp_actual()
  326. X    rcvrdisp_actual2()
  327. X    redisplay_rcvr_screen()
  328. X    saved_cursor_restore_cursor()
  329. X    saved_cursor_save_cursor()
  330. X    spaces(buf,buflen)
  331. X    spaces_trap(code,buf,buflen)
  332. X
  333. X--------------------------------------------------------------------------*/
  334. X/*+:EDITS:*/
  335. X/*:09-10-1992-13:58-wht@n4hgf-ECU release 3.20 */
  336. X/*:09-06-1992-13:29-wht@n4hgf-add receiver process buffered screen write */
  337. X/*:08-22-1992-15:38-wht@n4hgf-ECU release 3.20 BETA */
  338. X/*:05-29-1992-13:28-wht@n4hgf-no banner - phone numbers are security risk */
  339. X/*:11-11-1991-14:25-wht@n4hgf-lzero_length_read_detected code */
  340. X/*:11-11-1991-12:45-wht@n4hgf-add LIMIT_BELL code */
  341. X/*:08-26-1991-16:39-wht@n4hgf2-SD was still hopelessly manic */
  342. X/*:07-25-1991-12:56-wht@n4hgf-ECU release 3.10 */
  343. X/*:07-05-1991-06:13-wht@n4hgf-SD was in baaaaadd shape */
  344. X/*:01-09-1991-22:31-wht@n4hgf-ISC port */
  345. X/*:12-26-1990-14:32-wht@n4hgf-use memset in spaces() */
  346. X/*:12-21-1990-21:06-wht@n4hgf-CUF and CUB set non-ansi cursor incorrectly */
  347. X/*:12-20-1990-16:27-wht@n4hgf-had SU and SD swapped */
  348. X/*:11-30-1990-18:39-wht@n4hgf-non-ansi console rcvr appears to be working */
  349. X/*:11-28-1990-14:13-wht@n4hgf-start non-ansi console support */
  350. X/*:08-14-1990-20:40-wht@n4hgf-ecu3.00-flush old edit history */
  351. X
  352. X#include "ecu.h"
  353. X#include "ecukey.h"
  354. X#include <sys/ipc.h>
  355. X#include <sys/sem.h>
  356. X
  357. Xextern int errno;
  358. Xextern char rcvr_log_file[];    /* if rcvr_log!= 0,log filename */
  359. Xextern int rcvr_log;            /* rcvr log active if != 0 */
  360. Xextern FILE *rcvr_log_fp;        /* rcvr log file */
  361. Xextern int rcvr_log_raw;        /* if true, log all, else filter ctl chrs */
  362. Xextern int rcvr_log_append;        /* if true, append, else scratch */
  363. Xextern int rcvr_log_flusheach;    /* if true, flush log on each char */
  364. Xextern int rcvr_log_gen_title;
  365. X
  366. Xextern uint tcap_LINES;    /* terminal line quantity - see ecutcap.c */
  367. Xextern uint tcap_COLS;    /* terminal column quantity - see ecutcap.c */
  368. Xextern uint LINESxCOLS;
  369. X
  370. Xstatic char esc = ESC;
  371. X#define MAX_ANSI_LEN    30    /* generous */
  372. Xchar ansibuf[MAX_ANSI_LEN];
  373. Xchar *ansi;
  374. Xint ansilen = 0;
  375. Xint in_ansi_accumulation = 0;
  376. X
  377. Xint saved_cursor_y;
  378. Xint saved_cursor_x;
  379. X
  380. X#define RCVR_RDQUAN        250
  381. Xchar lgetc_buf[RCVR_RDQUAN];
  382. Xchar *lgetc_ptr;
  383. Xextern int lgetc_count;
  384. X
  385. Xuchar autorz_frame[] = { SUB, 'B', '0', '0' };
  386. X
  387. X#ifdef ANSI_DEBUG
  388. XFILE *wfp = (FILE *)0;
  389. X#endif
  390. X
  391. Xuchar non_multiscreen_hi_map[128] = {
  392. X/*80*/    'c','u','e','a','a','a','a','c', /* the main purpose of this ... */
  393. X/*88*/    'e','e','e','i','i','i','a','a', /* ... is to map ruling ... */
  394. X/*90*/    'e','e','a','a','a','o','u','u', /* ... characters, but as ...*/
  395. X/*98*/    'y','o','u','X','#','Y','P','f', /* ... a side effect, also map ... */
  396. X/*A0*/    'a','i','o','u','n','n','a','o', /* ... others to reasonable, ... */
  397. X/*A8*/    '?','-','-','%','%','|','<','>', /* ... near, amusing, or random ... */
  398. X/*B0*/    '#','#','#','|','+','+','+','.', /* ... printing characters as well */
  399. X/*B8*/    '.','+','|','.','\'','\'','\'','.',
  400. X/*C0*/    '`','+','+','+','-','+','+','+',
  401. X/*C8*/    '`','.','+','+','+','=','+','+',
  402. X/*D0*/    '+','+','+','`','`','.','.','+',
  403. X/*D8*/    '+','\'','.','#','_','|','|','-',
  404. X/*E0*/    'a','b','F','T','E','o','u','t',
  405. X/*E8*/    'I','0','O','o','o','o','e','n',
  406. X/*F0*/    '=','+','>','<','f','j','%','=',
  407. X/*F8*/    'o','.','.','V','n','2','*',' '
  408. X};
  409. X
  410. X/*
  411. X * if != 0, allow xmtr use of rcvrdisp_actual2() function to buffer,
  412. X * if 0, flush buffer whenever the function is called
  413. X */
  414. Xint rcvrdisp_actual2_xmtr_buffer = 0;
  415. X
  416. X/*+-------------------------------------------------------------------------
  417. X    rcvrdisp_p() - lock rcvrdisp mechanism
  418. X--------------------------------------------------------------------------*/
  419. X#ifdef RCVRDISP_PV
  420. Xvoid
  421. Xrcvrdisp_p()
  422. X{
  423. X    register int retn;
  424. X    struct sembuf sembuf;
  425. X
  426. X    sembuf.sem_num = 0;
  427. X    sembuf.sem_op = -1;
  428. X    sembuf.sem_flg = 0;
  429. X
  430. X    while(1)
  431. X    {
  432. X        if(((retn = semop(shm->rcvrdisp_semid,&sembuf,1)) >= 0) ||
  433. X            (errno != EINTR))
  434. X        {
  435. X            break;
  436. X        }
  437. X    }
  438. X
  439. X    if((retn < 0) && (errno != EINVAL))
  440. X    {
  441. X        extern char lopen_err_str[];
  442. X        strcpy(lopen_err_str,"rcvrdisp_p failed: SysV IPC error");
  443. X        termecu(TERMECU_IPC_ERROR);
  444. X    }
  445. X
  446. X}    /* end of rcvrdisp_p */
  447. X#endif /*  RCVRDISP_PV */
  448. X
  449. X/*+-------------------------------------------------------------------------
  450. X    rcvrdisp_v() - unlock rcvrdisp mechanism
  451. X--------------------------------------------------------------------------*/
  452. X#ifdef RCVRDISP_PV
  453. Xvoid
  454. Xrcvrdisp_v()
  455. X{
  456. X    register int retn;
  457. X    struct sembuf sembuf;
  458. X
  459. X    sembuf.sem_num = 0;
  460. X    sembuf.sem_op = 1;
  461. X    sembuf.sem_flg = 0;
  462. X
  463. X    while(1)
  464. X    {
  465. X        if(((retn = semop(shm->rcvrdisp_semid,&sembuf,1)) >= 0) ||
  466. X            (errno != EINTR))
  467. X        {
  468. X            break;
  469. X        }
  470. X    }
  471. X
  472. X    if((retn < 0) && (errno != EINVAL))
  473. X    {
  474. X        extern char lopen_err_str[];
  475. X        strcpy(lopen_err_str,"rcvrdisp_v failed: SysV IPC error");
  476. X        termecu(TERMECU_IPC_ERROR);
  477. X    }
  478. X}    /* end of rcvrdisp_v */
  479. X#endif /*  RCVRDISP_PV */
  480. X
  481. X/*+-------------------------------------------------------------------------
  482. X    rcvrdisp_actual() - actual write to screen
  483. X--------------------------------------------------------------------------*/
  484. Xvoid
  485. Xrcvrdisp_actual()
  486. X{
  487. X#ifdef RCVRDISP_PV
  488. X    rcvrdisp_p();
  489. X#endif /*  RCVRDISP_PV */
  490. X    if(shm->rcvrdisp_count)
  491. X        write(TTYOUT,shm->rcvrdisp_buffer,shm->rcvrdisp_count);
  492. X    shm->rcvrdisp_ptr = shm->rcvrdisp_buffer;
  493. X    shm->rcvrdisp_count = 0;
  494. X#ifdef RCVRDISP_PV
  495. X    rcvrdisp_v();
  496. X#endif /*  RCVRDISP_PV */
  497. X
  498. X}    /* end of rcvrdisp_actual */
  499. X
  500. X/*+-------------------------------------------------------------------------
  501. X    rcvrdisp_actual2() - for tcap, flush only if not receiver
  502. X--------------------------------------------------------------------------*/
  503. Xvoid
  504. Xrcvrdisp_actual2()
  505. X{
  506. X    if(rcvrdisp_actual2_xmtr_buffer || (getpid() == rcvr_pid))
  507. X        return;
  508. X#ifdef RCVRDISP_PV
  509. X    rcvrdisp_p();
  510. X#endif /*  RCVRDISP_PV */
  511. X    if(shm->rcvrdisp_count)
  512. X        write(TTYOUT,shm->rcvrdisp_buffer,shm->rcvrdisp_count);
  513. X    shm->rcvrdisp_ptr = shm->rcvrdisp_buffer;
  514. X    shm->rcvrdisp_count = 0;
  515. X#ifdef RCVRDISP_PV
  516. X    rcvrdisp_v();
  517. X#endif /*  RCVRDISP_PV */
  518. X
  519. X}    /* end of rcvrdisp_actual2 */
  520. X
  521. X/*+-------------------------------------------------------------------------
  522. X    rcvrdisp(buf,buflen) - logical write to screen
  523. X--------------------------------------------------------------------------*/
  524. Xvoid
  525. Xrcvrdisp(buf,buflen)
  526. Xchar *buf;
  527. Xint buflen;
  528. X{
  529. X
  530. X    if((buflen + shm->rcvrdisp_count) > sizeof(shm->rcvrdisp_buffer))
  531. X        rcvrdisp_actual();
  532. X    if((buflen + shm->rcvrdisp_count) > sizeof(shm->rcvrdisp_buffer))
  533. X    {
  534. X        write(TTYOUT,buf,buflen);
  535. X        return;
  536. X    }
  537. X#ifdef RCVRDISP_PV
  538. X    rcvrdisp_p();
  539. X#endif /*  RCVRDISP_PV */
  540. X    memcpy(shm->rcvrdisp_ptr,buf,buflen);
  541. X    shm->rcvrdisp_ptr += buflen;
  542. X    shm->rcvrdisp_count += buflen;
  543. X#ifdef RCVRDISP_PV
  544. X    rcvrdisp_v();
  545. X#endif /*  RCVRDISP_PV */
  546. X
  547. X}    /* end of rcvrdisp */
  548. X
  549. X/*+-------------------------------------------------------------------------
  550. X    redisplay_rcvr_screen() - redisplay logical receiver screen
  551. XAs of writing, this function is called only by the XMTR process
  552. X--------------------------------------------------------------------------*/
  553. Xvoid
  554. Xredisplay_rcvr_screen()
  555. X{
  556. X    register uint y;
  557. X    extern int tty_not_char_special;
  558. X
  559. X
  560. X    if(tty_not_char_special)
  561. X        return;
  562. X
  563. X    setcolor(colors_current);
  564. X    tcap_stand_end();
  565. X    for(y = 0; y < tcap_LINES; y++)
  566. X    {
  567. X        tcap_cursor(y,0);
  568. X        fwrite(&shm->screen[y][0],
  569. X            ((y != tcap_LINES - 1) ? tcap_COLS : tcap_COLS - 1),1,se);
  570. X    }
  571. X    tcap_eeol();
  572. X    tcap_cursor(shm->cursor_y,shm->cursor_x);
  573. X
  574. X}    /* end of redisplay_rcvr_screen */
  575. X
  576. X#ifdef DEBUG_CURSOR
  577. Xvoid
  578. Xspaces_trap(code,buf,buflen)
  579. Xint code;
  580. Xregister uchar *buf;
  581. Xregister uint buflen;
  582. X{
  583. X    char *xyz = (char *)0x90000000;
  584. X    ff(se,"rcvr 'spaces trap' code %d: cursor x,y=%d,%d\r\n",
  585. X        code,
  586. X        shm->cursor_y,shm->cursor_x);
  587. X    ff(se,"buf=%08lx len=%08lx offs=%08lx\r\n",buf,buflen,
  588. X        (ulong)buf - (ulong)shm->screen);
  589. X    *xyz = 0;
  590. X    abort();
  591. X}
  592. X#endif
  593. X
  594. X/*+-------------------------------------------------------------------------
  595. X    spaces(buf,buflen) - fill with spaces
  596. X--------------------------------------------------------------------------*/
  597. Xvoid
  598. Xspaces(buf,buflen)
  599. Xregister uchar *buf;
  600. Xuint buflen;
  601. X{
  602. X#ifdef DEBUG_CURSOR
  603. X    if((ulong)buf > (((ulong)shm->screen) + LINESxCOLS))
  604. X        spaces_trap(1,buf,buflen);
  605. X    if((ulong)buf < (ulong)shm->screen)
  606. X        spaces_trap(2,buf,buflen);
  607. X    if((ulong)(buf + buflen) > (((ulong)shm->screen) + LINESxCOLS))
  608. X        spaces_trap(3,buf,buflen);
  609. X    if((ulong)(buf + buflen) < (ulong)shm->screen)
  610. X        spaces_trap(4,buf,buflen);
  611. X#endif
  612. X
  613. X    if(!buflen)
  614. X        return;
  615. X
  616. X#ifdef DEFENSIVE
  617. X    if((ulong)buf < (ulong)shm->screen)
  618. X        return;
  619. X    if((ulong)(buf + buflen) > (((ulong)shm->screen) + LINESxCOLS))
  620. X        return;
  621. X#endif
  622. X
  623. X    memset(buf,SPACE,buflen);
  624. X
  625. X}    /* end of spaces */
  626. X
  627. X/*+-------------------------------------------------------------------------
  628. X    lgetc_rcvr() - rcvr version of get char from line
  629. X--------------------------------------------------------------------------*/
  630. Xint
  631. Xlgetc_rcvr()
  632. X{
  633. X    extern int errno;
  634. X
  635. X    if(!lgetc_count)
  636. X    {
  637. X        rcvrdisp_actual();
  638. X        while(lgetc_count <= 0)
  639. X        {
  640. X            errno = 0;
  641. X            if((lgetc_count =
  642. X                read(shm->Liofd,lgetc_buf,RCVR_RDQUAN)) < 0)
  643. X            {
  644. X                if(errno == EINTR)    /* if signal interrupted, ... */
  645. X                    continue;        /* ... read again */
  646. X                termecu(TERMECU_LINE_READ_ERROR);
  647. X            }
  648. X            if(!lgetc_count)
  649. X            {
  650. X                lzero_length_read_detected(); /* maybe terminate program ... */
  651. X                continue;                    /* ... but if not, read again */
  652. X            }
  653. X        }
  654. X        shm->rcvd_chars += lgetc_count;
  655. X        shm->rcvd_chars_this_connect += lgetc_count;
  656. X        lgetc_ptr = lgetc_buf;
  657. X    }
  658. X
  659. X    lgetc_count--;
  660. X
  661. X    if(shm->Lparity)
  662. X        return(*lgetc_ptr++ & 0x7F);
  663. X    else
  664. X        return(*lgetc_ptr++);
  665. X
  666. X}    /* end of lgetc_rcvr */
  667. X
  668. X/*+-------------------------------------------------------------------------
  669. X    ansi_SGR() - Set Graphics Rendition
  670. X
  671. XThe DOS ANSI world expects to be able to be able to chain 0,1 and
  672. X3x,4x params together with semicolons.
  673. X
  674. X  Supported modifiers for non-ansi terminals
  675. X  0       normal
  676. X  1       bold
  677. X  4       underscore
  678. X  5       blink
  679. X  7       reverse video
  680. X--------------------------------------------------------------------------*/
  681. Xvoid
  682. Xansi_SGR()
  683. X{
  684. X    register itmp;
  685. X    register char *cptr;
  686. X    char SGRstr[MAX_ANSI_LEN];
  687. X    char *token;
  688. X    char *str_token();
  689. X
  690. X    if(!tty_is_multiscreen)
  691. X    {
  692. X        ansibuf[ansilen - 1] = 0;    /* get rid of 'm' */
  693. X        cptr = ansibuf + 1;            /* get rid of '[' */
  694. X        if(!strlen(cptr))
  695. X            goto SGR_0;
  696. X        while(token = str_token(cptr,";"))
  697. X        {
  698. X            cptr = (char *)0;    /* further calls to str_token need NULL */
  699. X            switch(atoi(token))
  700. X            {
  701. X                default:
  702. X                case 0:        /* normal */
  703. XSGR_0:
  704. X                    tcap_stand_end();
  705. X                    tcap_blink_off();
  706. X                    tcap_underscore_off();
  707. X                    tcap_bold_off();
  708. X                    break;
  709. X                case 1:        /* bold */
  710. X                    tcap_bold_on();
  711. X                    break;
  712. X                case 4:        /* underscore */
  713. X                    tcap_underscore_on();
  714. X                    break;
  715. X                case 5:        /* blink */
  716. X                    tcap_blink_on();
  717. X                    break;
  718. X                case 7:        /* reverse video */
  719. X                    tcap_stand_out();
  720. X                    break;
  721. X            }
  722. X        }
  723. X        return;
  724. X    }
  725. X
  726. X    if(ansilen <= 3)    /* 'ESC[<0-9>m' and 'ESC[m' - quickly handled */
  727. X    {
  728. X        rcvrdisp(&esc,1);
  729. X        rcvrdisp(ansibuf,ansilen);
  730. X        return;
  731. X    }
  732. X
  733. X/* check XENIX 'ESC[<2,3,7>m' extensions */
  734. X    switch(itmp = atoi(ansibuf + 1))
  735. X    {
  736. X        case 7: /* XENIX 'ESC[7;<0-15>;<0-15>m' set fore/background color */
  737. X            itmp = atoi(ansibuf + 3);    /* second parameter */
  738. X            if(itmp > 15)                /* not XENIX extension */
  739. X                break;
  740. X            /* fall through */
  741. X        case 2:    /* XENIX 'ESC[2;<0-15>;<0-15>m' set fore/background color */
  742. X        case 3:    /* XENIX 'ESC[3;<0-1>m' color only set/clear blink */
  743. X            rcvrdisp(&esc,1);
  744. X            rcvrdisp(ansibuf,ansilen);
  745. X            return;
  746. X        default:
  747. X            break;
  748. X    }
  749. X
  750. X/* not XENIX extension */
  751. X    ansibuf[ansilen - 1] = 0;    /* get rid of 'm' */
  752. X    cptr = ansibuf + 1;            /* get rid of '[' */
  753. X
  754. X    while(token = str_token(cptr,";"))
  755. X    {
  756. X        cptr = (char *)0;    /* further calls to str_token need NULL */
  757. X        sprintf(SGRstr,"\033[%sm",token);
  758. X        rcvrdisp(SGRstr,strlen(SGRstr));
  759. X    }
  760. X
  761. X}    /* end of ansi_SGR */
  762. X
  763. X/*+-------------------------------------------------------------------------
  764. X    ansi_CUP() - cursor position (also HVP horiz/vertical position)
  765. X--------------------------------------------------------------------------*/
  766. Xvoid
  767. Xansi_CUP()
  768. X{
  769. X    register uint param_count = 0;
  770. X    char ansicopy[MAX_ANSI_LEN];
  771. X    register char *cptr = ansicopy;
  772. X    register char *token;
  773. X    char *str_token();
  774. X
  775. X    strcpy(cptr,ansibuf + 1);
  776. X    *(cptr + ansilen - 2) = 0;
  777. X
  778. X    while(token = str_token(cptr,";"))
  779. X    {
  780. X        cptr = (char *)0;    /* further calls to str_token need NULL */
  781. X        switch(++param_count)
  782. X        {
  783. X            case 1:    shm->cursor_y = atoi(token) - 1; break;
  784. X            case 2:    shm->cursor_x = atoi(token) - 1; break;
  785. X        }
  786. X    }
  787. X    switch(param_count)
  788. X    {
  789. X        case 0:
  790. X            shm->cursor_y = 0;
  791. X        case 1:
  792. X            shm->cursor_x = 0;
  793. X    }
  794. X    if(shm->cursor_x >= tcap_COLS)
  795. X        shm->cursor_x = 0;
  796. X    if(shm->cursor_y >= tcap_LINES)
  797. X        shm->cursor_y = 0;
  798. X
  799. X    if(!tty_is_multiscreen)
  800. X        tcap_cursor(shm->cursor_y,shm->cursor_x);
  801. X
  802. X}    /* end of ansi_CUP */
  803. X
  804. X/*+-------------------------------------------------------------------------
  805. X    ansi_CUU() - cursor up
  806. X--------------------------------------------------------------------------*/
  807. Xvoid
  808. Xansi_CUU()
  809. X{
  810. X    register uint count;
  811. X    register uint y;
  812. X
  813. X    if(ansilen == 2)        /* no param */
  814. X        count = 1;
  815. X    else
  816. X        count = atoi(ansibuf + 1);
  817. X
  818. X    y = shm->cursor_y - count;
  819. X    if(y >= tcap_LINES)    /* unsigned comparison */
  820. X        y = 0;
  821. X
  822. X    if(y != shm->cursor_y)
  823. X    {
  824. X        shm->cursor_y = y;
  825. X        if(!tty_is_multiscreen)
  826. X            tcap_cursor(shm->cursor_y,shm->cursor_x);
  827. X    }
  828. X
  829. X}    /* end of ansi_CUU */
  830. X
  831. X/*+-------------------------------------------------------------------------
  832. X    ansi_CUD() - cursor down (also VPR vertical position relative)
  833. X--------------------------------------------------------------------------*/
  834. Xvoid
  835. Xansi_CUD()
  836. X{
  837. X    register uint count;
  838. X    register uint y;
  839. X
  840. X    if(ansilen == 2)        /* no param */
  841. X        count = 1;
  842. X    else
  843. X        count = atoi(ansibuf + 1);
  844. X
  845. X    y = shm->cursor_y + count;
  846. X    if(y >= tcap_LINES)
  847. X        y = tcap_LINES - 1;
  848. X
  849. X    if(y != shm->cursor_y)
  850. X    {
  851. X        shm->cursor_y = y;
  852. X        if(!tty_is_multiscreen)
  853. X            tcap_cursor(shm->cursor_y,shm->cursor_x);
  854. X    }
  855. X
  856. X}    /* end of ansi_CUD */
  857. X
  858. X/*+-------------------------------------------------------------------------
  859. X    ansi_CUF() - cursor forward (also HPR horizontal position relative)
  860. X--------------------------------------------------------------------------*/
  861. Xvoid
  862. Xansi_CUF()
  863. X{
  864. X    register uint count;
  865. X    register uint x;
  866. X
  867. X    if(ansilen == 2)        /* no param */
  868. X        count = 1;
  869. X    else
  870. X        count = atoi(ansibuf + 1);
  871. X
  872. X    x = shm->cursor_x + count;
  873. X    if(x >= tcap_COLS)
  874. X        x = tcap_COLS - 1;
  875. X
  876. X    if(x != shm->cursor_x)
  877. X    {
  878. X        shm->cursor_x = x;
  879. X        if(!tty_is_multiscreen)
  880. X            tcap_cursor(shm->cursor_y,shm->cursor_x);
  881. X    }
  882. X
  883. X}    /* end of ansi_CUF */
  884. X
  885. X/*+-------------------------------------------------------------------------
  886. X    ansi_CUB() - cursor forward
  887. X--------------------------------------------------------------------------*/
  888. Xvoid
  889. Xansi_CUB()
  890. X{
  891. X    register uint count;
  892. X    register uint x;
  893. X
  894. X    if(ansilen == 2)        /* no param */
  895. X        count = 1;
  896. X    else
  897. X        count = atoi(ansibuf + 1);
  898. X
  899. X    x = shm->cursor_x - count;
  900. X    if(x >= tcap_COLS)    /* unsigned comparison */
  901. X        x = 0;
  902. X
  903. X    if(x != shm->cursor_x)
  904. X    {
  905. X        shm->cursor_x = x;
  906. X        if(!tty_is_multiscreen)
  907. X            tcap_cursor(shm->cursor_y,shm->cursor_x);
  908. X    }
  909. X
  910. X}    /* end of ansi_CUB */
  911. X
  912. X/*+-------------------------------------------------------------------------
  913. X    ansi_DSR() - device status report
  914. X--------------------------------------------------------------------------*/
  915. Xvoid
  916. Xansi_DSR()
  917. X{
  918. X    char response[MAX_ANSI_LEN];
  919. X
  920. X    sprintf(response,"\033[%d;%dR",shm->cursor_y + 1,shm->cursor_x + 1);
  921. X    write(shm->Liofd,response,strlen(response));
  922. X
  923. X}    /* end of ansi_DSR */
  924. X
  925. X/*+-------------------------------------------------------------------------
  926. X    ansi_ED() - erase in display
  927. X--------------------------------------------------------------------------*/
  928. Xvoid
  929. Xansi_ED()
  930. X{
  931. X    register uint param;
  932. X    int y;
  933. X
  934. X    if(ansilen == 2)        /* no param */
  935. X        param = 0;
  936. X    else
  937. X        param = atoi(ansibuf + 1);
  938. X
  939. X    switch(param)
  940. X    {
  941. X        case 0:    /* erase to end of display */
  942. X            spaces(&shm->screen[shm->cursor_y][shm->cursor_x],
  943. X                LINESxCOLS - ((shm->cursor_y * tcap_COLS) + shm->cursor_x));
  944. X            if(!tty_is_multiscreen)
  945. X                tcap_eeod();
  946. X            break;
  947. X        case 1:    /* erase from beginning of display */
  948. X            spaces((char *)shm->screen,(shm->cursor_y * tcap_COLS) +
  949. X                shm->cursor_x);
  950. X            if(!tty_is_multiscreen)
  951. X            {
  952. X                for(y = 0; y < shm->cursor_y - 1; y++)
  953. X                {
  954. X                    tcap_cursor(y,0);
  955. X                    tcap_eeol();
  956. X                }
  957. X                if(shm->cursor_x)
  958. X                {
  959. X                    tcap_cursor(shm->cursor_y,0);
  960. X                    tcap_clear_area_char(shm->cursor_x,' ');
  961. X                }
  962. X                else
  963. X                    tcap_cursor(shm->cursor_y,shm->cursor_x);
  964. X            }
  965. X            break;
  966. X        case 2:    /* clear display */
  967. X            shm->cursor_y = 0;
  968. X            shm->cursor_x = 0;
  969. X            spaces((char *)shm->screen,LINESxCOLS);
  970. X            if(!tty_is_multiscreen)
  971. X            {
  972. X                tcap_clear_screen();
  973. X                tcap_cursor(shm->cursor_y,shm->cursor_x);
  974. X            }
  975. X            break;
  976. X    }
  977. X
  978. X}    /* end of ansi_ED */
  979. X
  980. X/*+-------------------------------------------------------------------------
  981. X    ansi_EL() - erase in line
  982. X--------------------------------------------------------------------------*/
  983. Xvoid
  984. Xansi_EL()
  985. X{
  986. X    register uint param;
  987. X    char cr = CRET;
  988. X
  989. X    if(ansilen == 2)        /* no param */
  990. X        param = 0;
  991. X    else
  992. X        param = atoi(ansibuf + 1);
  993. X
  994. X    switch(param)
  995. X    {
  996. X        case 2:    /* clear line */
  997. X            shm->cursor_x = 0;
  998. X            if(!tty_is_multiscreen)
  999. X                rcvrdisp(&cr,1);
  1000. X            /* fall thru */
  1001. X        case 0:    /* erase to end of line */
  1002. X            spaces(&shm->screen[shm->cursor_y][shm->cursor_x],
  1003. X                tcap_COLS - shm->cursor_x);
  1004. X            if(!tty_is_multiscreen)
  1005. X                tcap_eeol();
  1006. X            break;
  1007. X        case 1:    /* erase from beginning of line */
  1008. X            spaces(&shm->screen[shm->cursor_y][0],shm->cursor_x);
  1009. X            if(!tty_is_multiscreen && shm->cursor_x)
  1010. X            {
  1011. X                rcvrdisp(&cr,1);
  1012. X                tcap_clear_area_char(shm->cursor_x,' ');
  1013. X            }
  1014. X            break;
  1015. X    }
  1016. X
  1017. X}    /* end of ansi_EL */
  1018. X
  1019. X/*+-------------------------------------------------------------------------
  1020. X    ansi_ECH() - erase characters
  1021. X--------------------------------------------------------------------------*/
  1022. Xvoid
  1023. Xansi_ECH()
  1024. X{
  1025. X    register uint param;
  1026. X    register uint screen_pos;
  1027. X
  1028. X    if(ansilen == 2)        /* no param */
  1029. X        param = 1;
  1030. X    else
  1031. X        param = atoi(ansibuf + 1);
  1032. X
  1033. X    if((shm->cursor_x + param) >= tcap_COLS)
  1034. X        return;
  1035. X
  1036. X    screen_pos = (shm->cursor_y * tcap_COLS) + shm->cursor_x;
  1037. X    mem_cpy((char *)shm->screen + screen_pos,
  1038. X           (char *)shm->screen + screen_pos + param,param);
  1039. X    spaces((char *)shm->screen + ((shm->cursor_y + 1) * tcap_COLS) -
  1040. X                param,param);
  1041. X
  1042. X    if(!tty_is_multiscreen)
  1043. X        tcap_delete_chars(param);
  1044. X
  1045. X}    /* end of ansi_ECH */
  1046. X
  1047. X/*+-------------------------------------------------------------------------
  1048. X    ansi_SU() - scroll up (new blank lines at the bottom)
  1049. X--------------------------------------------------------------------------*/
  1050. Xvoid
  1051. Xansi_SU()
  1052. X{
  1053. X    register uint param;
  1054. X    register uint count;
  1055. X
  1056. X    if(ansilen == 2)        /* no param */
  1057. X        param = 1;
  1058. X    else
  1059. X        param = atoi(ansibuf + 1);
  1060. X
  1061. X    if(param > tcap_LINES)
  1062. X        param = tcap_LINES;
  1063. X    if(!param)
  1064. X        return;
  1065. X
  1066. X#ifdef ANSI_DEBUG_3
  1067. X    if(wfp)
  1068. X        fprintf(wfp,"SU: param=%u y,x=%d,%d\n",param,
  1069. X            shm->cursor_y,shm->cursor_x);
  1070. X#endif
  1071. X
  1072. X    count = tcap_COLS * param;
  1073. X    mem_cpy((char *)shm->screen,(char *)shm->screen + count,
  1074. X        LINESxCOLS - count);
  1075. X    spaces((char *)shm->screen + LINESxCOLS - count,count);
  1076. X
  1077. X    if(!tty_is_multiscreen)
  1078. X    {
  1079. X        tcap_cursor(tcap_LINES - 1,0);
  1080. X        while(param--)
  1081. X            ff(se,"\r\n");
  1082. X        tcap_cursor(shm->cursor_y,shm->cursor_x);
  1083. X    }
  1084. X
  1085. X}    /* end of ansi_SU */
  1086. X
  1087. X/*+-------------------------------------------------------------------------
  1088. X    ansi_SD() - scroll down (new blank lines at the top)
  1089. X--------------------------------------------------------------------------*/
  1090. Xvoid
  1091. Xansi_SD()
  1092. X{
  1093. X    register uint param;
  1094. X    register uint count;
  1095. X
  1096. X    if(ansilen == 2)        /* no param */
  1097. X        param = 1;
  1098. X    else
  1099. X        param = atoi(ansibuf + 1);
  1100. X
  1101. X    if(param > tcap_LINES)
  1102. X        param = tcap_LINES;
  1103. X    if(!param)
  1104. X        return;
  1105. X
  1106. X#ifdef ANSI_DEBUG_3
  1107. X    if(wfp)
  1108. X        fprintf(wfp,"SD: param=%u y,x=%d,%d\n",param,
  1109. X            shm->cursor_y,shm->cursor_x);
  1110. X#endif
  1111. X
  1112. X    count = tcap_COLS * param;
  1113. X    mem_cpy((char *)shm->screen,(char *)shm->screen + count,
  1114. X        LINESxCOLS - count);
  1115. X    spaces((char *)shm->screen + LINESxCOLS - count,count);
  1116. X
  1117. X    if(!tty_is_multiscreen)
  1118. X    {
  1119. X        tcap_cursor(0,0);
  1120. X        tcap_insert_lines(param);
  1121. X        tcap_cursor(shm->cursor_y,shm->cursor_x);
  1122. X    }
  1123. X
  1124. X}    /* end of ansi_SD */
  1125. X
  1126. X/*+-------------------------------------------------------------------------
  1127. X    ansi_HPA() - horizontal position absolute
  1128. X--------------------------------------------------------------------------*/
  1129. Xvoid
  1130. Xansi_HPA()
  1131. X{
  1132. X    register uint param;
  1133. X
  1134. X    if(ansilen == 2)        /* no param */
  1135. X        param = 1;
  1136. X    else
  1137. X        param = atoi(ansibuf + 1);
  1138. X
  1139. X    if(param >= tcap_LINES)
  1140. X        return;
  1141. X
  1142. X    if((unsigned)(shm->cursor_x = param) >= (unsigned)tcap_COLS)
  1143. X        shm->cursor_x = tcap_COLS - 1;
  1144. X
  1145. X    if(!tty_is_multiscreen)
  1146. X        tcap_cursor(shm->cursor_y,shm->cursor_x);
  1147. X
  1148. X}    /* end of ansi_HPA */
  1149. X
  1150. X/*+-------------------------------------------------------------------------
  1151. X    ansi_VPA() - vertical position absolute
  1152. X--------------------------------------------------------------------------*/
  1153. Xvoid
  1154. Xansi_VPA()
  1155. X{
  1156. X    register uint param;
  1157. X
  1158. X    if(ansilen == 2)        /* no param */
  1159. X        param = 1;
  1160. X    else
  1161. X        param = atoi(ansibuf + 1);
  1162. X
  1163. X    if(param >= tcap_COLS)
  1164. X        return;
  1165. X
  1166. X    if((unsigned)(shm->cursor_y = param) >= (unsigned)tcap_LINES)
  1167. X        shm->cursor_y = tcap_LINES - 1;
  1168. X
  1169. X    if(!tty_is_multiscreen)
  1170. X        tcap_cursor(shm->cursor_y,shm->cursor_x);
  1171. X
  1172. X}    /* end of ansi_VPA */
  1173. X
  1174. X/*+-------------------------------------------------------------------------
  1175. X    ansi_IL() - insert lines
  1176. X--------------------------------------------------------------------------*/
  1177. Xvoid
  1178. Xansi_IL()
  1179. X{
  1180. X    register uint param;
  1181. X    register uint count;
  1182. X    register uint screen_pos;
  1183. X
  1184. X    if(ansilen == 2)        /* no param */
  1185. X        param = 1;
  1186. X    else
  1187. X        param = atoi(ansibuf + 1);
  1188. X
  1189. X    if((shm->cursor_y + param) >= tcap_LINES)
  1190. X        return;
  1191. X
  1192. X    count = tcap_COLS * param;
  1193. X    screen_pos = shm->cursor_y * tcap_COLS;
  1194. X    mem_cpy((char *)shm->screen + screen_pos + count,
  1195. X           (char *)shm->screen + screen_pos,
  1196. X           LINESxCOLS - screen_pos - count);
  1197. X    spaces((char *)shm->screen + screen_pos,count);
  1198. X
  1199. X    if(!tty_is_multiscreen)
  1200. X        tcap_insert_lines(param);
  1201. X
  1202. X}    /* end of ansi_IL */
  1203. X
  1204. X/*+-------------------------------------------------------------------------
  1205. X    ansi_ICH() - insert characters
  1206. X--------------------------------------------------------------------------*/
  1207. Xvoid
  1208. Xansi_ICH()
  1209. X{
  1210. X    register uint param;
  1211. X    register uint count;
  1212. X    register uint screen_pos;
  1213. X
  1214. X    if(ansilen == 2)        /* no param */
  1215. X        param = 1;
  1216. X    else
  1217. X        param = atoi(ansibuf + 1);
  1218. X
  1219. X    if(param > tcap_COLS - shm->cursor_x)
  1220. X        param = tcap_COLS - shm->cursor_x;
  1221. X
  1222. X    if(!param)
  1223. X        return;
  1224. X
  1225. X    screen_pos = (shm->cursor_y * tcap_COLS) + shm->cursor_x;
  1226. X    count = tcap_COLS - shm->cursor_x - param;
  1227. X    mem_cpy((char *)shm->screen + screen_pos + param,
  1228. X           (char *)shm->screen + screen_pos,count);
  1229. X    spaces((char *)shm->screen + screen_pos,param);
  1230. X
  1231. X    if(!tty_is_multiscreen)
  1232. X        tcap_insert_chars(param);
  1233. X
  1234. X}    /* end of ansi_ICH */
  1235. X
  1236. X/*+-------------------------------------------------------------------------
  1237. X    ansi_DL() - delete lines
  1238. X--------------------------------------------------------------------------*/
  1239. Xvoid
  1240. Xansi_DL()
  1241. X{
  1242. X    register uint param;
  1243. X    register uint count;
  1244. X    register uint screen_pos;
  1245. X
  1246. X    if(ansilen == 2)        /* no param */
  1247. X        param = 1;
  1248. X    else
  1249. X        param = atoi(ansibuf + 1);
  1250. X
  1251. X    if(param > (tcap_LINES - shm->cursor_y))
  1252. X        param = tcap_LINES - shm->cursor_y;
  1253. X
  1254. X    if(!param)
  1255. X        return;
  1256. X
  1257. X    count = tcap_COLS * param;
  1258. X    screen_pos = shm->cursor_y * tcap_COLS;
  1259. X    mem_cpy((char *)shm->screen + screen_pos,
  1260. X           (char *)shm->screen + screen_pos + count,
  1261. X            LINESxCOLS - screen_pos - count);
  1262. X    spaces((char *)shm->screen + LINESxCOLS - count,count);
  1263. X
  1264. X    if(!tty_is_multiscreen)
  1265. X        tcap_delete_lines(param);
  1266. X
  1267. X}    /* end of ansi_DL */
  1268. X
  1269. X/*+-------------------------------------------------------------------------
  1270. X    ansi_DCH() - delete characters
  1271. X--------------------------------------------------------------------------*/
  1272. Xvoid
  1273. Xansi_DCH()
  1274. X{
  1275. X    register uint param;
  1276. X    register uint count;
  1277. X    register uint screen_pos;
  1278. X
  1279. X    if(ansilen == 2)        /* no param */
  1280. X        param = 1;
  1281. X    else
  1282. X        param = atoi(ansibuf + 1);
  1283. X
  1284. X    if(ansilen == 2)        /* no param */
  1285. X        param = 1;
  1286. X    else
  1287. X        param = atoi(ansibuf + 1);
  1288. X
  1289. X    if(param > tcap_COLS - shm->cursor_x)
  1290. X        param = tcap_COLS - shm->cursor_x;
  1291. X
  1292. X    if(!param)
  1293. X        return;
  1294. X
  1295. X    screen_pos = (shm->cursor_y * tcap_COLS) + shm->cursor_x;
  1296. X    count = tcap_COLS - shm->cursor_x - param;
  1297. X    mem_cpy((char *)shm->screen + screen_pos,
  1298. X            (char *)shm->screen + screen_pos + param,count);
  1299. X    screen_pos = ((shm->cursor_y + 1) * tcap_COLS) - param;
  1300. X    spaces((char *)shm->screen + screen_pos,param);
  1301. X
  1302. X    if(!tty_is_multiscreen)
  1303. X        tcap_delete_chars(param);
  1304. X
  1305. X}    /* end of ansi_DCH */
  1306. X
  1307. X/*+-------------------------------------------------------------------------
  1308. X    ansi_CPL() - cursor to previous line
  1309. X--------------------------------------------------------------------------*/
  1310. Xvoid
  1311. Xansi_CPL()
  1312. X{
  1313. X    register uint param;
  1314. X
  1315. X    if(ansilen == 2)        /* no param */
  1316. X        param = 1;
  1317. X    else
  1318. X        param = atoi(ansibuf + 1);
  1319. X
  1320. X    if((shm->cursor_y -= param) >= tcap_LINES)    /* unsigned comparison */
  1321. X        shm->cursor_y = 0;
  1322. X    shm->cursor_x = 0;
  1323. X
  1324. X    if(!tty_is_multiscreen)
  1325. X        tcap_cursor(shm->cursor_y,shm->cursor_x);
  1326. X
  1327. X}    /* end of ansi_CPL */
  1328. X
  1329. X/*+-------------------------------------------------------------------------
  1330. X    ansi_CNL() - cursor to next line
  1331. X--------------------------------------------------------------------------*/
  1332. Xvoid
  1333. Xansi_CNL()
  1334. X{
  1335. X    register uint param;
  1336. X
  1337. X    if(ansilen == 2)        /* no param */
  1338. X        param = 1;
  1339. X    else
  1340. X        param = atoi(ansibuf + 1);
  1341. X
  1342. X    if((shm->cursor_y += param) >= tcap_LINES)
  1343. X        shm->cursor_y = tcap_LINES - 1;
  1344. X    shm->cursor_x = 0;
  1345. X
  1346. X    if(!tty_is_multiscreen)
  1347. X        tcap_cursor(shm->cursor_y,shm->cursor_x);
  1348. X
  1349. X}    /* end of ansi_CNL */
  1350. X
  1351. X/*+-------------------------------------------------------------------------
  1352. X    saved_cursor_save_cursor() - nice but unfortunate IBM extension
  1353. X
  1354. XI can't find this used anywhere but in the DOS world.  Supporting this
  1355. Xpair of sequences is what started this whole complex mess.
  1356. X--------------------------------------------------------------------------*/
  1357. Xvoid
  1358. Xsaved_cursor_save_cursor()
  1359. X{
  1360. X    saved_cursor_y = shm->cursor_y;
  1361. X    saved_cursor_x = shm->cursor_x;
  1362. X}    /* end of saved_cursor_save_cursor */
  1363. X
  1364. X/*+-------------------------------------------------------------------------
  1365. X    saved_cursor_restore_cursor() - nice but unfortunate IBM extension
  1366. X
  1367. XI can't find this used anywhere but in the DOS world.  Supporting this
  1368. Xpair of sequences is what started this whole complex mess.
  1369. X--------------------------------------------------------------------------*/
  1370. Xvoid
  1371. Xsaved_cursor_restore_cursor()
  1372. X{
  1373. X    shm->cursor_y = saved_cursor_y;
  1374. X    shm->cursor_x = saved_cursor_x;
  1375. X    tcap_cursor(shm->cursor_y,shm->cursor_x);
  1376. X}    /* end of saved_cursor_restore_cursor */
  1377. X
  1378. X/*+-------------------------------------------------------------------------
  1379. X    rcvd_ESC() - ESC seen-prepare to accumulate ansi sequence
  1380. X--------------------------------------------------------------------------*/
  1381. Xvoid
  1382. Xrcvd_ESC()
  1383. X{
  1384. X#ifdef ANSI_DEBUG
  1385. X    if(wfp)
  1386. X        fprintf(wfp,"ESC ");
  1387. X#endif
  1388. X
  1389. X    ansi = ansibuf;
  1390. X    ansilen = 0;
  1391. X    in_ansi_accumulation = 1;
  1392. X
  1393. X}    /* end of rcvd_ESC */
  1394. X
  1395. X/*+-------------------------------------------------------------------------
  1396. X    is_ansi_terminator(rchar) - is character terminator for ansi sequence?
  1397. X--------------------------------------------------------------------------*/
  1398. Xint
  1399. Xis_ansi_terminator(rchar)
  1400. Xregister uint rchar;
  1401. X{
  1402. X    return(isalpha(rchar) || (rchar == '@'));
  1403. X}    /* end of is_ansi_terminator */
  1404. X
  1405. X/*+-------------------------------------------------------------------------
  1406. X    accumulate_ansi_sequence(rchar)
  1407. X--------------------------------------------------------------------------*/
  1408. Xvoid
  1409. Xaccumulate_ansi_sequence(rchar)
  1410. Xuint rchar;
  1411. X{
  1412. X    if(ansilen == (MAX_ANSI_LEN - 2))
  1413. X    {
  1414. X        in_ansi_accumulation = 0;
  1415. X        return;
  1416. X    }
  1417. X
  1418. X#ifdef ANSI_DEBUG_2
  1419. X    if(wfp)
  1420. X    {
  1421. X        fprintf(wfp,"\naas: %02x %c ansilen=%d",
  1422. X            rchar,(rchar & 0x7F < SPACE) ? '.' : (rchar & 0x7F),ansilen);
  1423. X    }
  1424. X#endif
  1425. X
  1426. X    *ansi++ = (uchar)rchar;
  1427. X    *ansi   = 0;
  1428. X    ansilen++;
  1429. X
  1430. X}    /* end of accumulate_ansi_sequence */
  1431. X
  1432. X/*+-------------------------------------------------------------------------
  1433. X    process_ansi_sequence() - a full ansi sequence is to be decoded
  1434. X--------------------------------------------------------------------------*/
  1435. Xvoid
  1436. Xprocess_ansi_sequence()
  1437. X{
  1438. X    register itmp;
  1439. X
  1440. X#ifdef ANSI_DEBUG
  1441. X    if(wfp)
  1442. X        fprintf(wfp,"\npas: len=%d '%s' y,x=%d,%d\n",ansilen,ansibuf,
  1443. X            shm->cursor_y,shm->cursor_x);
  1444. X#endif
  1445. X
  1446. X    if(!in_ansi_accumulation)
  1447. X        return;
  1448. X    in_ansi_accumulation = 0;
  1449. X
  1450. X    itmp = 1;        /* assume write needed */
  1451. X    if((ansilen > 1) && (ansibuf[1] == '='))
  1452. X        ;
  1453. X    else switch(ansibuf[ansilen - 1])
  1454. X    {
  1455. X        case '@': ansi_ICH(); break;
  1456. X        case 'A': ansi_CUU(); break;
  1457. X        case 'B': ansi_CUD(); break;
  1458. X        case 'C': ansi_CUF(); break;
  1459. X        case 'D': ansi_CUB(); break;
  1460. X        case 'E': ansi_CNL(); break;
  1461. X        case 'F': ansi_CPL(); break;
  1462. X        case 'H': ansi_CUP(); break;
  1463. X        case 'J': ansi_ED(); break;
  1464. X        case 'K': ansi_EL(); break;
  1465. X        case 'L': ansi_IL(); break;
  1466. X        case 'M': ansi_DL(); break;
  1467. X        case 'P': ansi_DCH(); break;
  1468. X        case 'S': ansi_SU(); break;
  1469. X        case 'T': ansi_SD(); break;
  1470. X        case 'X': ansi_ECH(); break;
  1471. X        case '`': ansi_HPA(); break;
  1472. X        case 'a': ansi_CUF(); break; /* HPR */
  1473. X        case 'd': ansi_VPA(); break;
  1474. X        case 'e': ansi_CUD(); break; /* VPR */
  1475. X        case 'f': ansi_CUP(); break; /* HVP */
  1476. X        case 'm': ansi_SGR(); itmp = 0; break;
  1477. X        case 'n': ansi_DSR(); itmp = 0; break;
  1478. X        case 's': saved_cursor_save_cursor(); itmp = 0; break;
  1479. X        case 'u': saved_cursor_restore_cursor(); itmp = 0; break;
  1480. X#ifdef FUTURES
  1481. X        case 'h': ansi_SM(); break;    /* Set Mode: SCO: lock keyboard
  1482. X                                     *           MSDOS: host of shit */
  1483. X        case 'i': ansi_MC(); break;    /* Media Copy: send screen to line */
  1484. X        case 'l': ansi_RM(); break;    /* Reset Mode: SCO: unlock keyboard
  1485. X                                     *             MSDOS: host of shit */
  1486. X#endif /* FUTURES */
  1487. X        default:
  1488. X            break;
  1489. X    }
  1490. X
  1491. X/* if proper ansi console and indicated, write the buffer to the screen */
  1492. X    if(tty_is_multiscreen && itmp)
  1493. X    {
  1494. X        rcvrdisp(&esc,1);
  1495. X        rcvrdisp(ansibuf,ansilen);
  1496. X    }
  1497. X
  1498. X#ifdef ANSI_DEBUG
  1499. X    if(wfp)
  1500. X        fprintf(wfp,"pas: new cursor y,x=%d,%d\n",shm->cursor_y,shm->cursor_x);
  1501. X#endif
  1502. X}    /* end of process_ansi_sequence */
  1503. X
  1504. X/*+-------------------------------------------------------------------------
  1505. X    rcvr_log_open()
  1506. X--------------------------------------------------------------------------*/
  1507. Xvoid
  1508. Xrcvr_log_open()
  1509. X{
  1510. X
  1511. X    if(rcvr_log)        /* if xmtr set us up for logging */
  1512. X    {
  1513. X        rcvr_log_fp = fopen(rcvr_log_file,rcvr_log_append ? "a" : "w");
  1514. X        rcvr_log_append = 1;    /* until next %log -s */
  1515. X        if(!rcvr_log_fp)
  1516. X        {
  1517. X            ff(se,"ecu RCVR: Could not open log file: %s\r\n",rcvr_log_file);
  1518. X            ff(se,"recording aborted.\r\n");
  1519. X            rcvr_log = 0;
  1520. X        }
  1521. X        else if(!rcvr_log_raw && rcvr_log_gen_title)
  1522. X        {
  1523. X#if 0 /* decommitted - security risk */
  1524. X            char tstr[80];
  1525. X            get_tod(2,tstr);
  1526. X            fprintf(rcvr_log_fp,"\n====> %s (%s, %s, %s) %s\n\n",
  1527. X                shm->Lrname,shm->Llogical,
  1528. X                shm->Ldescr,(shm->Ltelno[0]) ? shm->Ltelno : "NONE",tstr);
  1529. X#endif
  1530. X        }
  1531. X        rcvr_log_gen_title = 0;
  1532. X    }
  1533. X}    /* end of rcvr_log_open */
  1534. X
  1535. X/*+-------------------------------------------------------------------------
  1536. X    process_rcvd_char(rchar) - process a received character
  1537. X
  1538. XReturn 0 if char should be written to console, 1 otherwise
  1539. X--------------------------------------------------------------------------*/
  1540. Xint
  1541. Xprocess_rcvd_char(rchar)
  1542. Xregister uint rchar;
  1543. X{
  1544. X    register itmp;
  1545. X#ifdef LIMIT_BELL
  1546. X    long now;
  1547. X    static long last_bell_time = -1L;
  1548. X#endif
  1549. X
  1550. X    /*
  1551. X     * automatic ZMODEM frame detection (expensive CPU burners for lazy folks)
  1552. X     */
  1553. X    if(shm->autorz)
  1554. X    {
  1555. X        if((uchar)rchar == autorz_frame[shm->autorz_pos])
  1556. X        {
  1557. X            itmp = shm->autorz_pos;    /* copy to register trying to be quick */
  1558. X            if(++itmp == sizeof(autorz_frame))
  1559. X            {
  1560. X                if(lgetc_count)
  1561. X                {
  1562. X                    rcvrdisp(lgetc_ptr,lgetc_count);
  1563. X                    lgetc_count = 0;
  1564. X                }
  1565. X                shmr_notify_zmodem_frame();
  1566. X                pause();        /* wait for death */
  1567. X                itmp = 0;        /* in case something starts us up */
  1568. X            }
  1569. X            shm->autorz_pos = itmp;
  1570. X            return(!itmp);    /* don't try to print ^X */
  1571. X        }
  1572. X        else
  1573. X            shm->autorz_pos = 0;
  1574. X    }
  1575. X
  1576. X    /*
  1577. X     * BEL and alarm-on-incoming-data processing
  1578. X     */
  1579. X    if(shm->bell_notify_state == 2)
  1580. X    {
  1581. X        shm->bell_notify_state = 1;
  1582. X        bell_notify(XBELL_3T);
  1583. X    }
  1584. X    else if(rchar == BEL)
  1585. X    {
  1586. X#ifdef LIMIT_BELL
  1587. X        time(&now);
  1588. X        if((now - last_bell_time) < 2L)
  1589. X            return(1);
  1590. X        last_bell_time = now;
  1591. X#endif
  1592. X        bell_notify(XBELL_ATTENTION);
  1593. X        return(0);
  1594. X    }
  1595. X
  1596. X    /*
  1597. X     * video control sequences
  1598. X     */
  1599. X    if(rchar == ESC)
  1600. X    {
  1601. X        rcvd_ESC();
  1602. X        return(1);
  1603. X    }
  1604. X    else if(in_ansi_accumulation)
  1605. X    {
  1606. X        accumulate_ansi_sequence(rchar);
  1607. X        if(is_ansi_terminator(rchar))
  1608. X            process_ansi_sequence();
  1609. X        return(1);
  1610. X    }
  1611. X
  1612. X    /*
  1613. X     * the bread and butter of the receiver:
  1614. X     * print printable characters and obey formatting characters
  1615. X     */
  1616. X    if(rchar < SPACE)
  1617. X    {
  1618. X        switch(rchar)
  1619. X        {
  1620. X            case CTL_L:
  1621. X                spaces((char *)shm->screen,LINESxCOLS);
  1622. X                shm->cursor_y = 0;
  1623. X                shm->cursor_x = 0;
  1624. X                break;
  1625. X
  1626. X            case BS:
  1627. X                if(shm->cursor_x)
  1628. X                    shm->cursor_x--;
  1629. X                break;
  1630. X
  1631. X            case NL:
  1632. X                if(shm->cursor_y != tcap_LINES - 1)
  1633. X                    shm->cursor_y++;
  1634. X                else
  1635. X                {
  1636. X                    mem_cpy((char *)shm->screen,(char *)shm->screen + tcap_COLS,
  1637. X                        LINESxCOLS - tcap_COLS);
  1638. X                    spaces(&shm->screen[shm->cursor_y][0],tcap_COLS);
  1639. X                }
  1640. X                break;
  1641. X
  1642. X            case CRET:
  1643. X                shm->cursor_x = 0;
  1644. X                break;
  1645. X
  1646. X            case TAB:
  1647. X                itmp = 8 - (shm->cursor_x % 8);
  1648. X                shm->cursor_x += itmp;
  1649. X                if(shm->cursor_x >= tcap_COLS)
  1650. X                {
  1651. X                    shm->cursor_x = 0;
  1652. X                    if(++shm->cursor_y >= tcap_LINES)
  1653. X                        shm->cursor_y = tcap_LINES - 1;
  1654. X                }
  1655. X                spaces(&shm->screen[shm->cursor_y][shm->cursor_x],itmp);
  1656. X                break;
  1657. X
  1658. X#ifdef TANDEM_ENQ_ACK    /* for my friend John Dashner at Tandem */
  1659. X            case ENQ:
  1660. X                lputc(ACK);
  1661. X                return(0);
  1662. X#endif
  1663. X
  1664. X        }
  1665. X    }
  1666. X    else
  1667. X    {
  1668. X        shm->screen[shm->cursor_y][shm->cursor_x++] = (uchar)rchar;
  1669. X        if(shm->cursor_x >= tcap_COLS)
  1670. X        {
  1671. X            shm->cursor_x = 0;
  1672. X            if(shm->cursor_y != tcap_LINES - 1)
  1673. X                shm->cursor_y++;
  1674. X            else
  1675. X            {
  1676. X                mem_cpy((char *)shm->screen,(char *)shm->screen + tcap_COLS,
  1677. X                    LINESxCOLS - tcap_COLS);
  1678. X                spaces(&shm->screen[shm->cursor_y][shm->cursor_x],tcap_COLS);
  1679. X            }
  1680. X        }
  1681. X    }
  1682. X
  1683. X#ifdef ANSI_DEBUG_2
  1684. X    if(wfp)
  1685. X    {
  1686. X        if((rchar & 0x7F) == NL)
  1687. X            fputs("\n",wfp);
  1688. X        else
  1689. X            fputc(((rchar & 0x7F) < SPACE) ? '.' : (rchar & 0x7F),wfp);
  1690. X    }
  1691. X#endif
  1692. X
  1693. X    /*
  1694. X     * receiver logging
  1695. X     */
  1696. X    if(rcvr_log && rcvr_log_fp)
  1697. X    {
  1698. X        /* if raw mode or character not excluded from "cooked" logging */
  1699. X        if(rcvr_log_raw || ((rchar >= SPACE) && (rchar <= '~')) ||
  1700. X             (rchar == NL) || (rchar == TAB))
  1701. X        {
  1702. X            LOGPUTC(rchar,rcvr_log_fp);
  1703. X        }
  1704. X        /* back if log file if not raw and char is backspace */
  1705. X        else if(!rcvr_log_raw && (rchar == BS))
  1706. X        {
  1707. X        long logpos = 0;
  1708. X            if(logpos = ftell(rcvr_log_fp))
  1709. X                fseek(rcvr_log_fp,logpos - 1,0);
  1710. X        }
  1711. X
  1712. X        if(rcvr_log_flusheach)
  1713. X            fflush(rcvr_log_fp);
  1714. X    }
  1715. X    return(0);
  1716. X
  1717. X}    /* end of process_rcvd_char */
  1718. X
  1719. X/*+-----------------------------------------------------------------------
  1720. X    rcvr() - copy characters from remote line to screen
  1721. X------------------------------------------------------------------------*/
  1722. Xvoid
  1723. Xrcvr()
  1724. X{
  1725. X    uchar rchar;
  1726. X    uchar nlchar = NL;
  1727. X
  1728. X#ifdef ANSI_DEBUG
  1729. Xchar s80[80];
  1730. X    wfp = fopen(ANSI_DEBUG_LOGFILE,"a");
  1731. X    if(ulindex(ANSI_DEBUG_LOGFILE,"/dev/tty") != -1)
  1732. X    {
  1733. X        sprintf(s80,"stty opost ocrnl < %s",ANSI_DEBUG_LOGFILE);
  1734. X        system(s80);
  1735. X    }
  1736. X    fprintf(wfp,"***************\n");
  1737. X#ifdef ANSI_DEBUG_NOBUF
  1738. X    setbuf(wfp,NULL);
  1739. X#endif /* ANSI_DEBUG_NOBUF */
  1740. X#endif /* ANSI_DEBUG */
  1741. X
  1742. X    rcvr_pid = getpid();
  1743. X    shm->autorz_pos = 0;
  1744. X    lgetc_count = 0;
  1745. X    in_ansi_accumulation = 0;
  1746. X    ansi = ansibuf;
  1747. X    ansilen = 0;
  1748. X    shm->rcvrdisp_ptr = shm->rcvrdisp_buffer;
  1749. X    shm->rcvrdisp_count = 0;
  1750. X
  1751. X/* yetch - magic number gretching for lines and columns */
  1752. X    if(!tcap_LINES || !tcap_COLS)
  1753. X    {
  1754. X        tcap_LINES = 25;
  1755. X        tcap_COLS = 80;
  1756. X    }
  1757. X    if(tcap_LINES > SCREEN_LINES_MAX)
  1758. X        tcap_LINES = SCREEN_LINES_MAX;
  1759. X    if(tcap_COLS > SCREEN_COLS_MAX)
  1760. X        tcap_COLS = SCREEN_COLS_MAX;
  1761. X    LINESxCOLS = tcap_LINES * tcap_COLS;
  1762. X
  1763. X    rcvr_signals();
  1764. X    rcvr_log_open();
  1765. X
  1766. X    saved_cursor_y = shm->cursor_y;
  1767. X    saved_cursor_x = shm->cursor_x;
  1768. X
  1769. X/* receive loop - keep tight as possible! */
  1770. X    if(tty_is_multiscreen)
  1771. X    {
  1772. X        while(1)
  1773. X        {
  1774. X            rchar = lgetc_rcvr();
  1775. X
  1776. X            if(process_rcvd_char(rchar))
  1777. X                continue;
  1778. X
  1779. X            rcvrdisp((char *)&rchar,1);
  1780. X
  1781. X            if(shm->Ladd_nl_incoming && (rchar == CRET))
  1782. X                rcvrdisp((char *)&nlchar,1);
  1783. X        }
  1784. X    }
  1785. X    else
  1786. X    {
  1787. X        while(1)
  1788. X        {
  1789. X            rchar = lgetc_rcvr();
  1790. X
  1791. X            if(rchar >= 0x80)
  1792. X                rchar = non_multiscreen_hi_map[rchar - 0x80];
  1793. X
  1794. X            if(process_rcvd_char(rchar))
  1795. X                continue;
  1796. X
  1797. X            rcvrdisp((char *)&rchar,1);
  1798. X
  1799. X            if(shm->Ladd_nl_incoming && (rchar == CRET))
  1800. X                rcvrdisp((char *)&nlchar,1);
  1801. X        }
  1802. X    }
  1803. X}    /* end of rcvr */
  1804. X
  1805. X/* end of ecurcvr.c */
  1806. X/* vi: set tabstop=4 shiftwidth=4: */
  1807. SHAR_EOF
  1808. chmod 0644 ecurcvr.c ||
  1809. echo 'restore of ecurcvr.c failed'
  1810. Wc_c="`wc -c < 'ecurcvr.c'`"
  1811. test 37081 -eq "$Wc_c" ||
  1812.     echo 'ecurcvr.c: original size 37081, current size' "$Wc_c"
  1813. rm -f _shar_wnt_.tmp
  1814. fi
  1815. # ============= ecuscrdump.c ==============
  1816. if test -f 'ecuscrdump.c' -a X"$1" != X"-c"; then
  1817.     echo 'x - skipping ecuscrdump.c (File already exists)'
  1818.     rm -f _shar_wnt_.tmp
  1819. else
  1820. > _shar_wnt_.tmp
  1821. echo 'x - extracting ecuscrdump.c (Text)'
  1822. sed 's/^X//' << 'SHAR_EOF' > 'ecuscrdump.c' &&
  1823. X#define MULTISCREEN_DUMP_BUG
  1824. X/*+-------------------------------------------------------------------------
  1825. X    ecuscrdump.c - screen dump
  1826. X    wht@n4hgf.Mt-Park.GA.US
  1827. X
  1828. X  Defined functions:
  1829. X    screen_dump(scrfile)
  1830. X
  1831. X--------------------------------------------------------------------------*/
  1832. X/*+:EDITS:*/
  1833. X/*:09-10-1992-13:58-wht@n4hgf-ECU release 3.20 */
  1834. X/*:08-22-1992-15:38-wht@n4hgf-ECU release 3.20 BETA */
  1835. X/*:05-29-1992-13:28-wht@n4hgf-no banner - phone numbers are security risk */
  1836. X/*:07-25-1991-12:56-wht@n4hgf-ECU release 3.10 */
  1837. X/*:07-17-1991-07:04-wht@n4hgf-avoid SCO UNIX nap bug */
  1838. X/*:12-21-1990-17:27-wht@n4hgf-non-ansi considerations */
  1839. X/*:08-14-1990-20:40-wht@n4hgf-ecu3.00-flush old edit history */
  1840. X
  1841. X#include "ecu.h"
  1842. X#include "ecukey.h"
  1843. X#include "pc_scr.h"
  1844. X
  1845. Xextern char curr_dir[CURR_DIRSIZ];        /* current working directory */
  1846. Xextern uint tcap_LINES;
  1847. Xextern uint tcap_COLS;
  1848. Xextern struct termio tty_termio_at_entry;
  1849. Xextern int tty_not_char_special;
  1850. Xextern int tty_is_multiscreen;
  1851. X
  1852. Xchar screen_dump_file_name[256];
  1853. X
  1854. X/*+-------------------------------------------------------------------------
  1855. X    screen_dump(scrfile) - dump physical display contents
  1856. Xunless stdin is non-multiscreen and/or /dev/null, in which case,
  1857. Xdump rcvr virtual screen
  1858. Xif scrfile == NULL, default to ~/.ecu/screen.dump
  1859. X--------------------------------------------------------------------------*/
  1860. Xvoid
  1861. Xscreen_dump(scrfile)
  1862. Xchar *scrfile;
  1863. X{
  1864. X    uchar schar;
  1865. X    uchar s256[256];
  1866. X    register uchar *cptr = s256;
  1867. X    uchar *sptr = (uchar *)shm->screen;
  1868. X    int srow = 0;
  1869. X    int scol = 0;
  1870. X    FILE *fp;
  1871. X    struct termio dump_tty_termio_at_entry;
  1872. X    struct termio dump_tty_termio_current;
  1873. X    int restart_rcvr = need_rcvr_restart();
  1874. X    int use_ansi_MC = !(!tty_is_multiscreen || tty_not_char_special);
  1875. X    uint lines_left = tcap_LINES;
  1876. X
  1877. X    kill_rcvr_process(SIGUSR1);
  1878. X
  1879. X    if(use_ansi_MC)
  1880. X    {
  1881. X        /* save keyboard termio at entry */
  1882. X        ioctl(TTYIN,TCGETA,(char *)&dump_tty_termio_at_entry);
  1883. X
  1884. X        /* set keyboard to termio status at staart of execution of program 
  1885. X         * plus a few mods
  1886. X         */
  1887. X
  1888. X        dump_tty_termio_current = tty_termio_at_entry;
  1889. X        dump_tty_termio_current.c_cflag &= ~(PARENB | PARODD);
  1890. X        dump_tty_termio_current.c_cflag |= CS8;
  1891. X        dump_tty_termio_current.c_iflag &= ~(ISTRIP);
  1892. X        dump_tty_termio_current.c_lflag &= ~(ICANON | ISIG | ECHO);
  1893. X        ioctl(TTYIN,TCSETAW,(char *) &dump_tty_termio_current);
  1894. X        ttyflush(2);
  1895. X    }
  1896. X
  1897. X    if(scrfile)
  1898. X        fp = fopen(scrfile,"a");
  1899. X    else
  1900. X    {
  1901. X        get_home_dir(s256);
  1902. X        strcat((char *)s256,"/.ecu/screen.dump");
  1903. X        fp = fopen((char *)s256,"a");
  1904. X    }
  1905. X    if(!fp)
  1906. X    {
  1907. X#if defined(MORSE)
  1908. X        xbell(XBELL_DONE,1);
  1909. X#else
  1910. X        ring_bell();
  1911. X        Nap(50L);
  1912. X        ring_bell();
  1913. X#endif
  1914. X        return;
  1915. X    }
  1916. X
  1917. X#if 0 /* decommitted - security risk */
  1918. X    get_tod(2,s256);
  1919. X    fprintf(fp,"==> %s: %s (phone %s)\n",
  1920. X        s256,shm->Ldescr,(shm->Ltelno[0]) ? shm->Ltelno : "NONE");
  1921. X#endif
  1922. X
  1923. X    if(use_ansi_MC)
  1924. X        write(1,"\033[2i",4);    /* spill your guts, screen */
  1925. X
  1926. X    while(1)
  1927. X    {
  1928. X        if(use_ansi_MC)
  1929. X        {
  1930. X            if(!ttyrdchk())
  1931. X            {
  1932. X                Nap(hzmsec * 3);
  1933. X                if(!ttyrdchk())
  1934. X                    break;
  1935. X            }
  1936. X            read(0,(char *)&schar,1);
  1937. X            if(!lines_left)
  1938. X                continue;
  1939. X        }
  1940. X        else
  1941. X        {
  1942. X            if(srow == tcap_LINES)
  1943. X                break;
  1944. X            if(scol == tcap_COLS)
  1945. X            {
  1946. X                scol = 0;
  1947. X                srow++;
  1948. X                schar = NL;
  1949. X            }
  1950. X            else
  1951. X            {
  1952. X                schar = *sptr++;
  1953. X                scol++;
  1954. X            }
  1955. X        }
  1956. X
  1957. X        if((schar > 0x7E) || (schar < 0x20))
  1958. X        {
  1959. X            switch(schar)
  1960. X            {
  1961. X            case NL:
  1962. X                while((cptr > s256) && (*(cptr - 1) == ' '))
  1963. X                    cptr--;
  1964. X                *cptr++ = 0x0A;
  1965. X                *cptr = 0;
  1966. X                fputs((char *)s256,fp);
  1967. X                cptr = s256;
  1968. X                *cptr = 0;
  1969. X                --lines_left;
  1970. X                continue;
  1971. X
  1972. X            case at_TL:        
  1973. X                schar = vanilla_TL;
  1974. X                break;
  1975. X            case at_TR:
  1976. X                schar = vanilla_TR;
  1977. X                break;
  1978. X            case at_BL:        
  1979. X                schar = vanilla_BL;
  1980. X                break;
  1981. X            case at_BR:        
  1982. X                schar = vanilla_BR;
  1983. X                break;
  1984. X            case at_LT:            /* left hand T */
  1985. X                schar = vanilla_LT;
  1986. X                break;
  1987. X            case at_RT:            /* right hand T */
  1988. X                schar = vanilla_RT;
  1989. X                break;
  1990. X            case at_VR:            /* vertical rule */
  1991. X                schar = vanilla_VR;
  1992. X                break;
  1993. X            case at_HR:            /* horizontal rule */
  1994. X                schar = vanilla_HR;
  1995. X                break;
  1996. X            default:
  1997. X                schar = ' ';
  1998. X            }
  1999. X        }
  2000. X        *cptr++ = schar;
  2001. X    }
  2002. X
  2003. X    if(use_ansi_MC)
  2004. X    {
  2005. X        /* restore keyboard termio at entry */
  2006. X        ioctl(TTYIN,TCSETAW,(char *)&dump_tty_termio_at_entry);
  2007. X        ttyflush(2);
  2008. X#if defined(MULTISCREEN_DUMP_BUG)
  2009. X        /*
  2010. X         * bug in 2.3.1 sco video driver leaves "ESC[2" active;
  2011. X         * use "l" (unlock tty) a noop
  2012. X         */
  2013. X        write(TTYOUT,"l",1);
  2014. X#endif /* MULTISCREEN_DUMP_BUG */
  2015. X    }
  2016. X
  2017. X    fclose(fp);
  2018. X
  2019. X#if defined(MORSE)
  2020. X    xbell(XBELL_DONE,1);
  2021. X#else
  2022. X    ring_bell();
  2023. X#endif
  2024. X
  2025. X    if(restart_rcvr)
  2026. X        start_rcvr_process(0);
  2027. X
  2028. X}    /* end of screen_dump */
  2029. SHAR_EOF
  2030. chmod 0644 ecuscrdump.c ||
  2031. echo 'restore of ecuscrdump.c failed'
  2032. Wc_c="`wc -c < 'ecuscrdump.c'`"
  2033. test 4531 -eq "$Wc_c" ||
  2034.     echo 'ecuscrdump.c: original size 4531, current size' "$Wc_c"
  2035. rm -f _shar_wnt_.tmp
  2036. fi
  2037. # ============= ecusetup.c ==============
  2038. if test -f 'ecusetup.c' -a X"$1" != X"-c"; then
  2039.     echo 'x - skipping ecusetup.c (File already exists)'
  2040.     rm -f _shar_wnt_.tmp
  2041. else
  2042. > _shar_wnt_.tmp
  2043. echo 'x - extracting ecusetup.c (Text)'
  2044. sed 's/^X//' << 'SHAR_EOF' > 'ecusetup.c' &&
  2045. X/*+-------------------------------------------------------------------------
  2046. X    ecusetup.c -- ecu visual "argv"
  2047. X    wht@n4hgf.Mt-Park.GA.US
  2048. X
  2049. X  0000000000111111111122222222223333333333444444444455555555556666
  2050. X  0123456789012345678901234567890123456789012345678901234567890123
  2051. X00.--[ ecu rev ]-------------------------------------------------.
  2052. X01|                                                              |
  2053. X02|  Destination   .......................................       |
  2054. X03|    Telephone     ....................                        |
  2055. X04|    Description   ........................................    |
  2056. X05|                                                              |
  2057. X06|  tty: /dev/........   (opened)                               | 
  2058. X07|                                                              |
  2059. X08|  duplex: .  baud: .....  parity: . (data bits .)             |
  2060. X09|  add NL to transmitted CR: .                                 |
  2061. X10|  add NL to received CR:    .                                 |
  2062. X11|                                                              |
  2063. X12|                                                              |
  2064. X13|   TAB:next ^B:prev END:proceed ^D:phone dir  ESC:quit ecu    |
  2065. X14`--------------------------------------------------------------'
  2066. X
  2067. X  Defined functions:
  2068. X    setup_display_baud()
  2069. X    setup_display_name()
  2070. X    setup_display_screen(write_lits)
  2071. X    setup_display_single_char()
  2072. X    setup_display_tty()
  2073. X    setup_line_open()
  2074. X    setup_screen(argv_logical)
  2075. X    setw_bot_msg(msg)
  2076. X    setw_err_msg(msg)
  2077. X    setw_get_single(nondelim_list)
  2078. X    setw_msg(msg,y,fillch,last_msglen)
  2079. X
  2080. X--------------------------------------------------------------------------*/
  2081. X/*+:EDITS:*/
  2082. X/*:09-10-1992-13:58-wht@n4hgf-ECU release 3.20 */
  2083. X/*:09-05-1992-14:49-wht@n4hgf-parity field was one to the left of proper pos */
  2084. X/*:08-22-1992-15:38-wht@n4hgf-ECU release 3.20 BETA */
  2085. X/*:04-28-1992-01:34-wht@n4hgf-default tty in tty prompt had slash */
  2086. X/*:04-24-1992-21:59-wht@n4hgf-more SCO tty name normalizing */
  2087. X/*:08-28-1991-14:07-wht@n4hgf2-SVR4 cleanup by aega84!lh */
  2088. X/*:08-25-1991-14:39-wht@n4hgf-SVR4 port thanks to aega84!lh */
  2089. X/*:08-12-1991-00:58-wht@n4hgf-ISC tty names */
  2090. X/*:07-25-1991-12:56-wht@n4hgf-ECU release 3.10 */
  2091. X/*:07-17-1991-07:04-wht@n4hgf-avoid SCO UNIX nap bug */
  2092. X/*:06-05-1991-18:07-wht@n4hgf-rework */
  2093. X/*:04-27-1991-01:52-wht@n4hgf-overhaul revision numbers */
  2094. X/*:08-14-1990-20:40-wht@n4hgf-ecu3.00-flush old edit history */
  2095. X
  2096. X#include "ecucurses.h"
  2097. X
  2098. X#define STDIO_H_INCLUDED
  2099. X#define OMIT_TERMIO_REFERENCES
  2100. X#include "ecu.h"
  2101. X#include "ecukey.h"
  2102. X#include "ecuxkey.h"
  2103. X#include "ecupde.h"
  2104. X#include "pc_scr.h"
  2105. X
  2106. XPDE *logical_telno_to_pde();
  2107. X
  2108. X#define SETW_LINES    15
  2109. X#define SETW_COLS    64
  2110. X#define SETW_TLY    1
  2111. X#define SETW_TLX    ((80 - SETW_COLS) / 2)
  2112. X
  2113. X#define NAME_Y        2
  2114. X#define NAME_X        17
  2115. X#define NAME_LEN    DESTREF_LEN
  2116. X#define NAME_LX        3
  2117. X
  2118. X#define PHNUM_Y        3
  2119. X#define PHNUM_X        19
  2120. X#define PHNUM_LEN    DESTREF_LEN
  2121. X#define PHNUM_LX    5
  2122. X
  2123. X#define DESCR_Y        4
  2124. X#define DESCR_X        19
  2125. X#define DESCR_LEN    PDE_DESCR_LEN
  2126. X#define DESCR_LX    5
  2127. X
  2128. X#define TTY_Y        6
  2129. X#define TTY_X        13
  2130. X#define TTY_LEN        8
  2131. X#define TTY_LX        3
  2132. X
  2133. X#define TTYOPN_LY    6
  2134. X#define TTYOPN_LX    24
  2135. X
  2136. X#define DPX_Y        8
  2137. X#define DPX_X        11
  2138. X#define DPX_LX        3
  2139. X
  2140. X#define BAUD_Y        8
  2141. X#define BAUD_X        20
  2142. X#define BAUD_LEN    5
  2143. X#define BAUD_LX        14
  2144. X
  2145. X#define PAR_Y        8
  2146. X#define PAR_X        35
  2147. X#define PAR_LX        27
  2148. X
  2149. X#define DB_Y        8
  2150. X#define DB_X        48
  2151. X#define DB_LX        37
  2152. X#define DB_LX2        49
  2153. X
  2154. X#define XADDNL_Y    9
  2155. X#define XADDNL_X    29
  2156. X#define XADDNL_LX    3
  2157. X
  2158. X#define RADDNL_Y    10
  2159. X#define RADDNL_X    29
  2160. X#define RADDNL_LX    3
  2161. X
  2162. Xextern char *revstr;    /* ecunumrev.c */
  2163. Xextern char errmsg[];
  2164. X
  2165. XWINDOW *setw;
  2166. X
  2167. X#define SETW_MSG_LEFTX 2
  2168. X#define SETW_MSG_MAXLEN    (SETW_COLS - SETW_MSG_LEFTX - 8)
  2169. X#define SETW_MSG_BOT_Y  (SETW_LINES - 1)
  2170. X#define SETW_MSG_ERR_Y  (SETW_LINES - 3)
  2171. X
  2172. X/*+-------------------------------------------------------------------------
  2173. X    setw_msg(msg,y,fillch)
  2174. X--------------------------------------------------------------------------*/
  2175. Xvoid
  2176. Xsetw_msg(msg,y,fillch,last_msglen)
  2177. Xchar *msg;
  2178. Xint y;
  2179. Xchar fillch;
  2180. Xint *last_msglen;
  2181. X{
  2182. X    register itmp;
  2183. X    register itmp2;
  2184. X    char msg2[80];
  2185. X
  2186. X    if(!*last_msglen && !strlen(msg))
  2187. X        return;
  2188. X
  2189. X    wmove(setw,y,SETW_MSG_LEFTX);
  2190. X
  2191. X    if((itmp = strlen(msg)) == 0)
  2192. X    {
  2193. X        itmp2 = *last_msglen + 2;
  2194. X#if defined(SVR4)
  2195. X        whline(setw, (unsigned long)(fillch & 0x00ff), itmp2);
  2196. X#else
  2197. X          for(itmp = 0; itmp < itmp2; itmp++)
  2198. X            waddch(setw,fillch & 0xFF); 
  2199. X#endif
  2200. X        *last_msglen = 0;
  2201. X    }
  2202. X    else
  2203. X    {
  2204. X        waddch(setw,' ');
  2205. X        if(itmp > SETW_MSG_MAXLEN)
  2206. X        {
  2207. X            strncpy(msg2,msg,SETW_MSG_MAXLEN);
  2208. X            msg2[SETW_MSG_MAXLEN + 1] = 0;
  2209. X            waddstr(setw,msg2);
  2210. X            itmp = strlen(msg2);
  2211. X        }
  2212. X        else
  2213. X        {
  2214. X            waddstr(setw,msg);
  2215. X            itmp = strlen(msg);
  2216. X        }
  2217. X        waddch(setw,' ');
  2218. X        if((itmp2 = *last_msglen - itmp) > 0)
  2219. X        {
  2220. X#if defined(SVR4)
  2221. X            whline(setw, (unsigned long)(fillch & 0x00ff), itmp2);
  2222. X#else
  2223. X            while(itmp2--)
  2224. X                  waddch(setw,fillch & 0xFF); 
  2225. X#endif
  2226. X        }
  2227. X        *last_msglen = itmp;        /* remember last message length */
  2228. X    }
  2229. X    wrefresh(setw);
  2230. X}    /* end of setw_msg */
  2231. X
  2232. X/*+-------------------------------------------------------------------------
  2233. X    setw_bot_msg(msg)
  2234. X--------------------------------------------------------------------------*/
  2235. Xvoid
  2236. Xsetw_bot_msg(msg)
  2237. Xchar *msg;
  2238. X{
  2239. X    static int last_msglen = 0;
  2240. X    setw_msg(msg,SETW_MSG_BOT_Y,sHR,&last_msglen);
  2241. X}    /* end of setw_bot_msg */
  2242. X
  2243. X/*+-------------------------------------------------------------------------
  2244. X    setw_err_msg(msg)
  2245. X--------------------------------------------------------------------------*/
  2246. Xvoid
  2247. Xsetw_err_msg(msg)
  2248. Xchar *msg;
  2249. X{
  2250. X    static int last_msglen = 0;
  2251. X
  2252. X    setw_msg(msg,SETW_MSG_ERR_Y,' ',&last_msglen);
  2253. X}    /* end of setw_err_msg */
  2254. X
  2255. X/*+-------------------------------------------------------------------------
  2256. X    setup_display_name()
  2257. X--------------------------------------------------------------------------*/
  2258. Xvoid
  2259. Xsetup_display_name()
  2260. X{
  2261. X    clear_area(setw,NAME_Y,NAME_X,NAME_LEN);
  2262. X    waddstr(setw,shm->Llogical);
  2263. X
  2264. X#if 0
  2265. X    if(!shm->Llogical[0] && (shm->Liofd < 0))
  2266. X    {
  2267. X        clear_area(setw,PHNUM_Y,PHNUM_X,PHNUM_LEN);
  2268. X        clear_area(setw,DESCR_Y,DESCR_X,DESCR_LEN);
  2269. X        return;
  2270. X    }
  2271. X#endif
  2272. X
  2273. X
  2274. X    wmove(setw,PHNUM_Y,PHNUM_LX);
  2275. X    if(shm->Ltelno[0])
  2276. X        waddstr(setw,"Telephone");
  2277. X    else
  2278. X        waddstr(setw,"         ");
  2279. X    clear_area(setw,PHNUM_Y,PHNUM_X,PHNUM_LEN);
  2280. X#if 0
  2281. X    if(!shm->Ltelno[0])
  2282. X    {
  2283. X        if(!isdigit(shm->Llogical[0]) && find_procedure(shm->Llogical))
  2284. X            waddstr(setw,"<procedure connect>");
  2285. X        else
  2286. X            waddstr(setw,"<direct connect>");
  2287. X    }
  2288. X    else
  2289. X#endif
  2290. X        waddstr(setw,shm->Ltelno);
  2291. X
  2292. X    wmove(setw,DESCR_Y,DESCR_LX);
  2293. X    if(shm->Ldescr[0])
  2294. X        waddstr(setw,"Description");
  2295. X    else
  2296. X        waddstr(setw,"           ");
  2297. X    clear_area(setw,DESCR_Y,DESCR_X,DESCR_LEN);
  2298. X    waddstr(setw,shm->Ldescr);
  2299. X
  2300. X}    /* end of setup_display_name */
  2301. SHAR_EOF
  2302. true || echo 'restore of ecusetup.c failed'
  2303. fi
  2304. echo 'End of ecu320 part 11'
  2305. echo 'File ecusetup.c is continued in part 12'
  2306. echo 12 > _shar_seq_.tmp
  2307. exit 0
  2308.  
  2309. exit 0 # Just in case...
  2310.