home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #20 / NN_1992_20.iso / spool / comp / sources / misc / 3938 < prev    next >
Encoding:
Text File  |  1992-09-13  |  57.1 KB  |  2,316 lines

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