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

  1. Newsgroups: comp.sources.misc
  2. Path: sparky!kent
  3. From: wht@n4hgf.mt-park.ga.us (Warren Tucker)
  4. Subject:  v32i042:  ecu - ECU Asynchronous Communications v3.20, Part07/40
  5. Message-ID: <1992Sep11.192654.7262@sparky.imd.sterling.com>
  6. Followup-To: comp.sources.d
  7. X-Md4-Signature: 0d7fbd07d4f42b73dd1b7e3d67c52050
  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: Fri, 11 Sep 1992 19:26:54 GMT
  12. Approved: kent@sparky.imd.sterling.com
  13. Lines: 2328
  14.  
  15. Submitted-by: wht@n4hgf.mt-park.ga.us (Warren Tucker)
  16. Posting-number: Volume 32, Issue 42
  17. Archive-name: ecu/part07
  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.07 (part 7 of ecu320)
  24. # do not concatenate these parts, unpack them in order with /bin/sh
  25. # file ecufinsert.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" != 7; 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 ecufinsert.c'
  41. else
  42. echo 'x - continuing file ecufinsert.c'
  43. sed 's/^X//' << 'SHAR_EOF' >> 'ecufinsert.c' &&
  44. X{
  45. Xint itmp;
  46. Xregister rchar;
  47. Xint old_ttymode = get_ttymode();
  48. Xlong total_chars = 0L;
  49. Xlong total_lines = 0L;
  50. Xulong colors_at_entry = colors_current;
  51. Xlong timeout_msecs;
  52. XFILE *fp;
  53. Xchar file_string[256];
  54. Xchar s256[256];
  55. Xchar xmit_mode;
  56. Xuchar delim;
  57. X#ifdef USE_XON_XOFF
  58. Xint ixon;
  59. Xint ixoff;
  60. X#endif
  61. Xchar *make_char_graphic();
  62. X
  63. X    sigint = 0;
  64. X
  65. X    if(narg > 1)
  66. X    {
  67. X        strncpy(s256,arg[1],sizeof(s256));    
  68. X        s256[sizeof(s256) - 1] = 0;
  69. X    }
  70. X    else
  71. X    {
  72. X        ff(se,"\r\n--> File to insert on comm line: ");
  73. X        ttygets(s256,sizeof(s256),TG_CRLF,&delim,(int *)0);
  74. X        if((delim == ESC) || !strlen(s256)) 
  75. X        {
  76. X            ff(se," --> transmission aborted\r\n");
  77. X            return(0);
  78. X        }
  79. X    }
  80. X    if((itmp = expand_filename(s256,sizeof(s256))) < 0)
  81. X        return(-1);
  82. X    else if(itmp)
  83. X        ff(se,"\r\n--> wild card match: %s",s256);
  84. X
  85. X    if((fp = fopen(s256,"r")) == (FILE *)0)
  86. X    {
  87. X        ff(se,"\r\n--> ");
  88. X        pperror(s256);            /* print error if we get one */
  89. X        return(-1);
  90. X    }
  91. X
  92. X    if(narg > 1)
  93. X        ff(se,"\r\n");
  94. X
  95. X    if(narg > 2)
  96. X        xmit_mode = *arg[2];
  97. X    else
  98. X    {
  99. XASK_OPTION:
  100. X        ff(se,"(S)ingle line at a time\r\n");
  101. X        ff(se,"(E)cho pacing\r\n");
  102. X        ff(se,"(F)ull speed transmission\r\n");
  103. X        ff(se,"(P)aced transmission (20 msec/char)\r\n");
  104. X        ff(se,"(Q)uit (or ESC)          press a key:   ");
  105. X        xmit_mode = ttygetc(0) & 0x7F;
  106. X        if(xmit_mode > 0x20)
  107. X            fputs(make_char_graphic(xmit_mode,0),se);
  108. X        fputs("\r\n",se);
  109. X    }
  110. X
  111. X    kill_rcvr_process(SIGUSR1);
  112. X
  113. X    switch(xmit_mode = to_lower(xmit_mode))
  114. X    {
  115. X        case 's':
  116. X            setcolor(colors_alert);
  117. X            fputs("--> press SPACE to continue or ESC/'s' to stop\r\n",se);
  118. X            setcolor(colors_at_entry);
  119. X            break;
  120. X
  121. X        case 'e':
  122. X            /* fall through */
  123. X
  124. X        case 'f':
  125. X        case 'p':
  126. X            setcolor(colors_alert);
  127. X            ff(se,"--> press %s to abort\r\n",make_char_graphic(kbdintr,0));
  128. X            setcolor(colors_at_entry);
  129. X            ttymode(2);
  130. X            break;
  131. X
  132. X        case 'q':
  133. X        case ESC:
  134. X            goto INSERT_DONE2;
  135. X
  136. X        default:
  137. X            ring_bell();
  138. X            fputs("\r\n",se);
  139. X            goto ASK_OPTION;
  140. X    }
  141. X
  142. X#ifdef USE_XON_XOFF
  143. X    lget_xon_xoff(&ixon,&ixoff);        /* get current line xon/xoff status */
  144. X    lxon_xoff(IXON);                    /* set it for us */
  145. X#endif
  146. X
  147. X    while(fgets(file_string,sizeof(file_string),fp))
  148. X    {
  149. X    int xmit_len = strlen(file_string);
  150. X    int xmit_cr = xmit_len && (file_string[xmit_len - 1] == NL);
  151. X
  152. X        if(xmit_cr)
  153. X        {
  154. X            xmit_len--;
  155. X            file_string[xmit_len] = 0;
  156. X        }
  157. X        total_chars += xmit_len;
  158. X        total_lines++;
  159. X
  160. X/* some destinations, like BBS msg entry, take a blank line to mean
  161. Xend of message, so do not send completely blank lines */
  162. X        if(!xmit_len && xmit_cr)
  163. X        {
  164. X            lputc(' ');
  165. X            xmit_len = 1;
  166. X        }
  167. X        else if(xmit_mode == 'p')
  168. X        {
  169. X        register char *cptr = file_string;
  170. X            while(*cptr)
  171. X            {
  172. X                lputc(*cptr++);
  173. X                Nap(20L);
  174. X                while(rdchk(shm->Liofd))
  175. X                {
  176. X                    rchar = lgetc_xmtr();
  177. X                    process_xmtr_rcvd_char((char)rchar,1);
  178. X                }
  179. X            }
  180. X        }
  181. X        else
  182. X            lputs(file_string);
  183. X        if(xmit_cr)
  184. X        {
  185. X            if(xmit_mode == 'p')
  186. X                Nap(20L);
  187. X            lputc('\r');
  188. X            xmit_len++;
  189. X        }
  190. X
  191. X        if(sigint)
  192. X            break;
  193. X
  194. X        switch(xmit_mode)
  195. X        {
  196. X            case 's':
  197. X                while(1)
  198. X                {
  199. X                    if(ttyrdchk())
  200. X                        break;
  201. X                    rchar = lgetc_timeout(5 * 1000L);
  202. X                    if(rchar < 0)
  203. X                        file_insert_clear_xoff();
  204. X                    else
  205. X                        process_xmtr_rcvd_char((char)rchar,1);
  206. X                    if(rchar == 0x0A)
  207. X                        break;
  208. X                }
  209. X                rchar = to_lower(ttygetc(1));
  210. X                if((rchar == 's') || (rchar == ESC))
  211. X                    goto INSERT_DONE;
  212. X                break;
  213. X
  214. X            case 'e':
  215. X                timeout_msecs = 5 * 1000L;
  216. X                while(1)
  217. X                {
  218. X                    if(sigint)
  219. X                        break;
  220. X                    rchar = lgetc_timeout(timeout_msecs);
  221. X                    if(rchar < 0)
  222. X                    {
  223. X                        if(!xmit_len)
  224. X                            break;
  225. X                        file_insert_clear_xoff();
  226. X                        timeout_msecs = 1 * 1000L;
  227. X                    }
  228. X                    else
  229. X                    {
  230. X                        process_xmtr_rcvd_char((char)rchar,1);
  231. X                        timeout_msecs = 100L;
  232. X                        if(xmit_len)
  233. X                            xmit_len--;
  234. X                    }
  235. X                    if(rchar == 0x0A)
  236. X                        break;
  237. X                }
  238. X                break;
  239. X
  240. X            case 'f':
  241. X            case 'p':
  242. X                while(rdchk(shm->Liofd))
  243. X                {
  244. X                    rchar = lgetc_xmtr();
  245. X                    process_xmtr_rcvd_char((char)rchar,1);
  246. X                }
  247. X                break;
  248. X        }
  249. X        if(sigint)
  250. X            break;
  251. X    }
  252. X
  253. XINSERT_DONE:
  254. X
  255. X    if(sigint)
  256. X    {
  257. X        sigint = 0;
  258. X        setcolor(colors_error);
  259. X        ff(se,"--> Interrupted\r\n");
  260. X        setcolor(colors_at_entry);
  261. X    }
  262. X
  263. XINSERT_DONE2:
  264. X
  265. X    fclose(fp);
  266. X
  267. X    ttymode(old_ttymode);        /* restore old console mode */
  268. X    sigint = 0;                /* reset SIGINT flag */
  269. X
  270. X    while(((rchar = lgetc_timeout(200L)) >= 0) && !sigint)
  271. X        process_xmtr_rcvd_char((char)rchar,1);
  272. X
  273. X    setcolor(colors_success);
  274. X    ff(se,"\r\n-->  done ... sent %ld lines, %ld characters\r\n",
  275. X                total_lines,total_chars);
  276. X    setcolor(colors_at_entry);
  277. X    lclear_xmtr_xoff();
  278. X#ifdef USE_XON_XOFF
  279. X    lxon_xoff(ixon | ixoff);    /* restore old line xon/xoff status */
  280. X#endif
  281. X    start_rcvr_process(1);
  282. X    return(0);
  283. X
  284. X}    /* end of file_insert_to_line */
  285. X
  286. X/* vi: set tabstop=4 shiftwidth=4: */
  287. X/* end of ecufinsert.c */
  288. SHAR_EOF
  289. echo 'File ecufinsert.c is complete' &&
  290. chmod 0644 ecufinsert.c ||
  291. echo 'restore of ecufinsert.c failed'
  292. Wc_c="`wc -c < 'ecufinsert.c'`"
  293. test 7262 -eq "$Wc_c" ||
  294.     echo 'ecufinsert.c: original size 7262, current size' "$Wc_c"
  295. rm -f _shar_wnt_.tmp
  296. fi
  297. # ============= ecufkey.c ==============
  298. if test -f 'ecufkey.c' -a X"$1" != X"-c"; then
  299.     echo 'x - skipping ecufkey.c (File already exists)'
  300.     rm -f _shar_wnt_.tmp
  301. else
  302. > _shar_wnt_.tmp
  303. echo 'x - extracting ecufkey.c (Text)'
  304. sed 's/^X//' << 'SHAR_EOF' > 'ecufkey.c' &&
  305. X/*+-----------------------------------------------------------------
  306. X    ecufkey.c -- function key definition
  307. X    wht@n4hgf.Mt-Park.GA.US
  308. X
  309. X  Defined functions:
  310. X    ffso(str)
  311. X    idke_to_xf(ikde)
  312. X    kde_fgets(buf,bufsize,fp)
  313. X    kde_name_to_ikde(keystr)
  314. X    kde_text(ikde)
  315. X    keyset_define_key(bufptr)
  316. X    keyset_display()
  317. X    keyset_idstr(ikde)
  318. X    keyset_init()
  319. X    keyset_read(name)
  320. X    xf_text(xf)
  321. X    xf_to_ikde(xf)
  322. X
  323. X------------------------------------------------------------------*/
  324. X/*+:EDITS:*/
  325. X/*:09-10-1992-13:58-wht@n4hgf-ECU release 3.20 */
  326. X/*:08-22-1992-15:38-wht@n4hgf-ECU release 3.20 BETA */
  327. X/*:04-17-1992-16:29-wht@n4hgf-initialize keyset to SCO "ANSI" send strings */
  328. X/*:09-01-1991-05:16-wht@n4hgf2-allow comments and whitespace after names */
  329. X/*:08-31-1991-13:21-wht@n4hgf2-look for keys file in ECULIBDIR */
  330. X/*:08-16-1991-00:11-wht@n4hgf-keyset_init loads default keyset if found */
  331. X/*:07-25-1991-12:55-wht@n4hgf-ECU release 3.10 */
  332. X/*:07-12-1991-13:57-wht@n4hgf-GCC140 fix update */
  333. X/*:05-21-1991-00:45-wht@n4hgf-added -3 error code to keyset_read */
  334. X/*:05-21-1991-00:37-wht@n4hgf-improve fkey load error detection */
  335. X/*:05-16-1991-15:05-wht@n4hgf-gcc binary exploded in keyset_display */
  336. X/*:08-14-1990-20:40-wht@n4hgf-ecu3.00-flush old edit history */
  337. X
  338. X#include "ecu.h"
  339. X#include "ecukey.h"
  340. X#include "ecufkey.h"
  341. X#include "ecuxkey.h"
  342. X#include "ecufork.h"
  343. X
  344. Xchar *str_token();
  345. X
  346. Xextern char kbdintr;    /* current input INTR */
  347. Xextern char curr_dir[CURR_DIRSIZ];    /* current working key defns */
  348. X
  349. XKDE keyset_table[KDE_COUNT];
  350. Xchar keyset_name[256] = "";
  351. X
  352. XKDEMAP kdemap[] = {
  353. X    { XFcurup,    IKDE_CUU,    "CUU",    "\033[A"    },
  354. X    { XFcurdn,    IKDE_CUD,    "CUD",    "\033[B"    },
  355. X    { XFcurrt,    IKDE_CUR,    "CUR",    "\033[C"    },
  356. X    { XFcurlf,    IKDE_CUL,    "CUL",    "\033[D"    },
  357. X    { XFcur5,    IKDE_CU5,    "CU5",    "\033[E"    },
  358. X    { XFend,    IKDE_END,    "End",    "\033[F"    },
  359. X    { XFpgdn,    IKDE_PGDN,    "PgDn",    "\033[G"    },
  360. X    { XFhome,    IKDE_HOME,    "Home",    "\033[H"    },
  361. X    { XFpgup,    IKDE_PGUP,    "PgUp",    "\033[I"    },
  362. X    { XFins,    IKDE_INS,    "Ins",    "\033[L"    },
  363. X    { XF1,        IKDE_F1,    "F1",    "\033[M"    },
  364. X    { XF2,        IKDE_F2,    "F2",    "\033[N"    },
  365. X    { XF3,        IKDE_F3,    "F3",    "\033[O"    },
  366. X    { XF4,        IKDE_F4,    "F4",    "\033[P"    },
  367. X    { XF5,        IKDE_F5,    "F5",    "\033[Q"    },
  368. X    { XF6,        IKDE_F6,    "F6",    "\033[R"    },
  369. X    { XF7,        IKDE_F7,    "F7",    "\033[S"    },
  370. X    { XF8,        IKDE_F8,    "F8",    "\033[T"    },
  371. X    { XF9,        IKDE_F9,    "F9",    "\033[U"    },
  372. X    { XF10,        IKDE_F10,    "F10",    "\033[V"    },
  373. X    { XF11,        IKDE_F11,    "F11",    "\033[W"    },
  374. X    { XF12,        IKDE_F12,    "F12",    "\033[X"    },
  375. X    { XFbktab,    IKDE_BKTAB,    "BkTab","\033[Z"    },
  376. X    { 255,        IKDE_InitStr,"IS",    ""            },
  377. X    { 0,0,"",""}
  378. X};
  379. X
  380. X/*+-------------------------------------------------------------------------
  381. X    keyset_init()
  382. X--------------------------------------------------------------------------*/
  383. Xvoid
  384. Xkeyset_init()
  385. X{
  386. X    register itmp;
  387. X    register KDE *tkde;
  388. X    register KDEMAP *kmap;
  389. X
  390. X    for(itmp = 0; itmp < KDE_COUNT; itmp++)
  391. X    {
  392. X        tkde = &keyset_table[itmp];
  393. X        tkde->logical[0] = 0;
  394. X        tkde->ikde = (uchar)itmp;
  395. X    }
  396. X
  397. X    kmap = kdemap;
  398. X    while(kmap->xf)
  399. X    {
  400. X        if(kmap->ikde <= IKDE_lastKey)
  401. X        {
  402. X            tkde = &keyset_table[kmap->ikde];
  403. X            sprintf(tkde->logical,"SCO %s",kmap->name);
  404. X            strcpy(tkde->str,kmap->init);
  405. X            tkde->count  = strlen(tkde->str);
  406. X        }
  407. X        kmap++;
  408. X    }
  409. X
  410. X    keyset_name[0] = 0;
  411. X
  412. X    tkde = &keyset_table[IKDE_BKTAB];
  413. X    strcpy(tkde->logical,"redisplay");
  414. X    tkde->count = KACT_REDISPLAY;
  415. X
  416. X    tkde = &keyset_table[IKDE_HOME];
  417. X    strcpy(tkde->logical,"ecu cmd");
  418. X    tkde->count = KACT_COMMAND;
  419. X
  420. X    tkde = &keyset_table[IKDE_INS];
  421. X    strcpy(tkde->logical,"local shell");
  422. X    tkde->count = KACT_LOCAL_SHELL;
  423. X
  424. X    tkde = &keyset_table[IKDE_CU5];
  425. X    strcpy(tkde->logical,"screen dump");
  426. X    tkde->str[0] = 0x7F;    /* this key is intercepted by kbd read routine */
  427. X    tkde->count = 0;
  428. X
  429. X}    /* end of keyset_init */
  430. X
  431. X/*+-------------------------------------------------------------------------
  432. X    kde_fgets(buf,bufsize,fp) - read and evaluate key file line
  433. X
  434. XReturns:
  435. X    KDETYPE_COMMENT     comment or blank line (null, all blank or "#"
  436. X                        as non-blank)
  437. X    KDETYPE_NAME        "name" (non "#\t " in column 1)
  438. X    KDETYPE_ENTRY       "entry" ("\t " in column 1)
  439. X    KDETYPE_EOF         end of file
  440. X--------------------------------------------------------------------------*/
  441. Xint
  442. Xkde_fgets(buf,bufsize,fp)
  443. Xchar *buf;
  444. Xint bufsize;
  445. XFILE *fp;
  446. X{
  447. X    register itmp;
  448. X    register char *cptr;
  449. X
  450. X    if(!fgets(buf,bufsize,fp))
  451. X    {
  452. X        return(KDETYPE_EOF);
  453. X    }
  454. X
  455. X    if(!(itmp = strlen(buf)))
  456. X        return(KDETYPE_COMMENT);
  457. X    if(buf[itmp - 1] == NL)
  458. X    {
  459. X        buf[itmp - 1] = 0;
  460. X        itmp--;
  461. X    }
  462. X    if(!itmp)
  463. X        return(KDETYPE_COMMENT);
  464. X
  465. X    cptr = buf;
  466. X    itmp = (strchr(" \t",*cptr)) ? KDETYPE_ENTRY : KDETYPE_NAME;
  467. X    while(*cptr && ((*cptr == SPACE) || (*cptr == TAB)))
  468. X        cptr++;
  469. X
  470. X    if(!*cptr || (*cptr == '#'))
  471. X        return(KDETYPE_COMMENT);
  472. X
  473. X    return(itmp);
  474. X    
  475. X}    /* end of kde_fgets */
  476. X
  477. X/*+-------------------------------------------------------------------------
  478. X    kde_name_to_ikde(keystr)
  479. X--------------------------------------------------------------------------*/
  480. Xint
  481. Xkde_name_to_ikde(keystr)
  482. Xchar *keystr;
  483. X{
  484. X    KDEMAP *kmap = kdemap;
  485. X
  486. X    while(kmap->xf != 0)
  487. X    {
  488. X        if(!strcmpi(kmap->name,keystr))
  489. X            return((int)kmap->ikde);
  490. X        kmap++;
  491. X    }
  492. X    return(-1);
  493. X}    /* end of kde_name_to_ikde */
  494. X
  495. X/*+-------------------------------------------------------------------------
  496. X    keyset_idstr(ikde)
  497. X--------------------------------------------------------------------------*/
  498. Xchar *
  499. Xkeyset_idstr(ikde)
  500. Xint ikde;
  501. X{
  502. X    KDEMAP *kmap = kdemap;
  503. X
  504. X    while(kmap->xf)
  505. X    {
  506. X        if((int)kmap->ikde == ikde)
  507. X            return(kmap->name);
  508. X        kmap++;
  509. X    }
  510. X    return((char *)0);
  511. X}    /* end of keyset_idstr */
  512. X
  513. X/*+-------------------------------------------------------------------------
  514. X    xf_to_ikde(xf)
  515. X--------------------------------------------------------------------------*/
  516. Xint
  517. Xxf_to_ikde(xf)
  518. Xuchar xf;
  519. X{
  520. X    KDEMAP *kmap = kdemap;
  521. X
  522. X    while(kmap->xf)
  523. X    {
  524. X        if(kmap->xf == xf)
  525. X            return((int)kmap->ikde & 0xFF);
  526. X        kmap++;
  527. X    }
  528. X    return(-1);
  529. X}    /* end of xf_to_ikde */
  530. X
  531. X/*+-------------------------------------------------------------------------
  532. X    ikde_to_xf(ikde)
  533. X--------------------------------------------------------------------------*/
  534. Xint
  535. Xikde_to_xf(ikde)
  536. Xuchar ikde;
  537. X{
  538. X    KDEMAP *kmap = kdemap;
  539. X
  540. X    while(kmap->xf)
  541. X    {
  542. X        if(kmap->ikde == ikde)
  543. X            return((int)kmap->xf & 0xFF);
  544. X        kmap++;
  545. X    }
  546. X    return(-1);
  547. X}    /* end of ikde_to_xf */
  548. X
  549. X/*+-------------------------------------------------------------------------
  550. X    kde_text(ikde) - ikde value to text
  551. X--------------------------------------------------------------------------*/
  552. Xchar *
  553. Xkde_text(ikde)
  554. Xint ikde;
  555. X{
  556. X    KDEMAP *kmap = kdemap;
  557. X
  558. X    while(kmap->xf)
  559. X    {
  560. X        if(kmap->ikde == (char)ikde)
  561. X            return(kmap->name);
  562. X        kmap++;
  563. X    }
  564. X    return("??");
  565. X}    /* end of xf_to_ikde */
  566. X
  567. X/*+-------------------------------------------------------------------------
  568. X    xf_text(xf) - XFkey to text
  569. X--------------------------------------------------------------------------*/
  570. Xchar *
  571. Xxf_text(xf)
  572. Xuchar xf;
  573. X{
  574. X    static char sc8[8];
  575. X
  576. X    switch(xf)
  577. X    {
  578. X        case XFcurup:    return("CUU");
  579. X        case XFcurdn:    return("CUD");
  580. X        case XFcurrt:    return("CUR");
  581. X        case XFcurlf:    return("CUL");
  582. X        case XFcur5:    return("CU5");
  583. X        case XFend:        return("End");
  584. X        case XFpgdn:    return("PgDn");
  585. X        case XFhome:    return("Home");
  586. X        case XFpgup:    return("PgUp");
  587. X        case XFins:        return("Ins");
  588. X        case XF1:        return("F1");
  589. X        case XF2:        return("F2");
  590. X        case XF3:        return("F3");
  591. X        case XF4:        return("F4");
  592. X        case XF5:        return("F5");
  593. X        case XF6:        return("F6");
  594. X        case XF7:        return("F7");
  595. X        case XF8:        return("F8");
  596. X        case XF9:        return("F9");
  597. X        case XF10:        return("F10");
  598. X        case XF11:        return("F11");
  599. X        case XF12:        return("F12");
  600. X        case XFbktab:    return("BkTab");
  601. X    }
  602. X
  603. X    if((xf >= XF_ALTA) && (xf <= XF_ALTZ))
  604. X    {
  605. X        sprintf(sc8,"Alt-%c",'a' + xf - XF_ALTA);
  606. X        return(sc8);
  607. X    }
  608. X    sprintf(sc8,"XF_%02x\n",xf);
  609. X    return(sc8);
  610. X}    /* end of xf_text */
  611. X
  612. X/*+-------------------------------------------------------------------------
  613. X    keyset_define_key(bufptr)
  614. X
  615. Xreturn 0 if no error, -1 if error
  616. X--------------------------------------------------------------------------*/
  617. Xint
  618. Xkeyset_define_key(bufptr)
  619. Xchar *bufptr;
  620. X{
  621. X    register itmp;
  622. X    register token_number;
  623. X    register KDE *tkde = (KDE *)0;
  624. X    int ikde = 0;
  625. X    char token_separator[8];
  626. X    char *token;
  627. X    char *syntax = "syntax error in key definition: %s\n";
  628. X
  629. X    if((itmp = strlen(bufptr)) && (bufptr[itmp - 1] == NL))
  630. X        bufptr[--itmp] = 0;        /* strip trailing NL */
  631. X    if(!itmp)
  632. X        return(0);
  633. X
  634. X    if((*bufptr != SPACE) && (*bufptr != TAB))    /* if no leading space */
  635. X        return(0);
  636. X
  637. X    while((*bufptr == SPACE) || (*bufptr == TAB))    /* strip lding sp/tab */
  638. X        bufptr++;
  639. X
  640. X    token_number = 0;
  641. X    strcpy(token_separator,":");
  642. X    while(token = str_token(bufptr,token_separator))
  643. X    {
  644. X        bufptr = (char *)0;    /* further calls to str_token need NULL */
  645. X        switch(token_number)
  646. X        {
  647. X            case 0:        /* first field is key identifier */
  648. X                if((ikde = kde_name_to_ikde(token)) < 0)
  649. X                {
  650. X                    pprintf(syntax,keyset_name);
  651. X                    pprintf("  %s is not a legal key identifier\n",token);
  652. X                    return(-1);
  653. X                }
  654. X                if(ikde == IKDE_HOME)
  655. X                {
  656. X                    pprintf(syntax,keyset_name);
  657. X                    pprintf("  HOME cannot be redefined!\n");
  658. X                    return(-1);
  659. X                }
  660. X                if(ikde == IKDE_CU5)
  661. X                {
  662. X                    pprintf(syntax,keyset_name);
  663. X                    pprintf("  CUR5 cannot be redefined!\n");
  664. X                    return(-1);
  665. X                }
  666. X                if(ikde == IKDE_BKTAB)
  667. X                {
  668. X                    pprintf(syntax,keyset_name);
  669. X                    pprintf("  BkTab cannot be redefined!\n");
  670. X                    return(-1);
  671. X                }
  672. X                tkde = &keyset_table[ikde];
  673. X                tkde->logical[0] = 0;
  674. X                tkde->count = 0;
  675. X                break;
  676. X
  677. X            case 1:        /* second field is logical key name */
  678. X                strncpy(tkde->logical,token,sizeof(tkde->logical));
  679. X                tkde->logical[sizeof(tkde->logical) - 1] = 0;
  680. X                strcpy(token_separator," \t"); /* whitespace is tok sep now */
  681. X                break;
  682. X
  683. X            default:    /* third and subsequent to define key */
  684. X                if(!strlen(token))
  685. X                    continue;
  686. X                if(tkde->count == sizeof(tkde->str))
  687. X                {
  688. X                    pprintf(syntax,keyset_name);
  689. X                    pprintf("  %s: output count too long",
  690. X                        keyset_idstr(ikde));
  691. X                    return(-1);
  692. X                }
  693. X                if((itmp = ascii_to_hex(token)) < 0)
  694. X                {
  695. X                    pprintf(syntax,keyset_name);
  696. X                    pprintf("  %s: '%s' invalid code\n",
  697. X                        keyset_idstr(ikde),token);
  698. X                    return(0);
  699. X                }
  700. X                tkde->str[tkde->count] = itmp;
  701. X                tkde->count++;
  702. X                break;
  703. X        }    /* end of switch(token_number) */
  704. X        token_number++;
  705. X    }        /* end while not end of record */
  706. X
  707. X    return(0);
  708. X}    /* end of keyset_define_key */
  709. X
  710. X/*+-------------------------------------------------------------------------
  711. X    keyset_read(name)
  712. Xreturns 0 on success, -1 if no .ecu/keys, -2 if no 'name', -3 if error
  713. X--------------------------------------------------------------------------*/
  714. Xint
  715. Xkeyset_read(name)
  716. Xchar *name;
  717. X{
  718. X    int itmp;
  719. X    int ikde;
  720. X    char ecukeys_name[128];
  721. X    char s128[128];
  722. X    FILE *fp_keys;
  723. X
  724. X    get_home_dir(ecukeys_name);
  725. X    strcat(ecukeys_name,"/.ecu/keys");    /* someone may core dump here one day */
  726. X
  727. X    if(!(fp_keys = fopen(ecukeys_name,"r")))
  728. X    {
  729. X        strcpy(ecukeys_name,eculibdir);
  730. X        strcat(ecukeys_name,"/keys");
  731. X        if(!(fp_keys = fopen(ecukeys_name,"r")))
  732. X            return(-1);
  733. X    }
  734. X
  735. X/* find keyset name */
  736. X    itmp = 0;
  737. X    while((ikde = kde_fgets(s128,sizeof(s128),fp_keys)) != KDETYPE_EOF)
  738. X    {
  739. X        if((ikde == KDETYPE_NAME) && !strcmp(s128,name))
  740. X        {
  741. X            itmp = 1; /* success */
  742. X            break;
  743. X        }
  744. X    }
  745. X    if(!itmp)                /* find match? */
  746. X    {
  747. X        fclose(fp_keys);    /* nope */
  748. X        return(-2);
  749. X    }
  750. X
  751. X/*
  752. X * read past any other keyset names matching this set
  753. X * process 1st line of definition when found
  754. X */
  755. X    while((ikde = kde_fgets(s128,sizeof(s128),fp_keys)) != KDETYPE_EOF)
  756. X    {
  757. X        if((ikde == KDETYPE_NAME) || (ikde == KDETYPE_COMMENT))
  758. X            continue;
  759. X        else if(ikde == KDETYPE_ENTRY)
  760. X        {
  761. X            if(keyset_define_key(s128) < 0)
  762. X            {
  763. X                fclose(fp_keys);
  764. X                keyset_init();
  765. X                return(-3);
  766. X            }
  767. X            break;
  768. X        }
  769. X    }
  770. X
  771. X/*
  772. X * read rest of definition
  773. X */
  774. X    while((ikde = kde_fgets(s128,sizeof(s128),fp_keys)) != KDETYPE_EOF)
  775. X    {
  776. X        switch(ikde)
  777. X        {
  778. X            case KDETYPE_COMMENT:
  779. X                continue;
  780. X            case KDETYPE_ENTRY:
  781. X                if(keyset_define_key(s128) < 0)
  782. X                {
  783. X                    fclose(fp_keys);
  784. X                    keyset_init();
  785. X                    return(-3);
  786. X                }
  787. X                break;
  788. X            default:
  789. X                goto DONE;
  790. X        }
  791. X    }
  792. X
  793. XDONE:
  794. X    strncpy(keyset_name,name,sizeof(keyset_name));
  795. X    keyset_name[sizeof(keyset_name) - 1] = 0;
  796. X    fclose(fp_keys);
  797. X    return(0);
  798. X}    /* end of keyset_read */
  799. X
  800. X/*+-------------------------------------------------------------------------
  801. X    ffso(str)
  802. X--------------------------------------------------------------------------*/
  803. Xvoid
  804. Xffso(str)
  805. Xchar *str;
  806. X{
  807. X    tcap_stand_out();
  808. X    fputs(str,se);
  809. X    tcap_stand_end();
  810. X}    /* end of ffso */
  811. X
  812. X/*+-------------------------------------------------------------------------
  813. X    keyset_display()
  814. X
  815. X F1  xxxxx  F2   xxxxx   HOME xxxxx  PGUP xxxxx
  816. X F3  xxxxx  F4   xxxxx   END  xxxxx  PGDN xxxxx
  817. X F5  xxxxx  F6   xxxxx   INS  xxxxx  CUR5 xxxxx
  818. X F7  xxxxx  F8   xxxxx   BkTab xxxxx
  819. X F9  xxxxx  F10  xxxxx   CUR^ xxxxx  CUR> xxxxx
  820. X F11 xxxxx  F12  xxxxx   CUR< xxxxx  CURv xxxxx
  821. X--------------------------------------------------------------------------*/
  822. Xvoid
  823. Xkeyset_display()
  824. X{
  825. X    int itmp;
  826. X    int itmp2;
  827. X    int clen1 = 0;
  828. X    char cfmt1[32];
  829. X    int clen2 = 0;
  830. X    char cfmt2[32];
  831. X    int clen3 = 0;
  832. X    char cfmt3[32];
  833. X    char cfmt4[32];
  834. X    KDE *tkde;
  835. X
  836. X    if(!keyset_name[0])
  837. X        keyset_init();
  838. X
  839. X    for(itmp = 0; itmp < KDE_COUNT; itmp++)
  840. X    {
  841. X        tkde = &keyset_table[itmp];
  842. X        itmp2 = strlen(tkde->logical);
  843. X#if defined(__GNUC__) && !defined(GCC140)
  844. X        /*
  845. X         * do absolutely nothing except defeat optimization
  846. X         * see top of source; function is in ecuutil.c
  847. X         * GCC 1.40 fixed the bug
  848. X         */
  849. X        defeat_optimize_to_work_around_bug(&itmp);
  850. X#endif /* __GNUC__ */
  851. X        switch(itmp)
  852. X        {
  853. X            case IKDE_F1: case IKDE_F3: case IKDE_F5: case IKDE_F7:
  854. X            case IKDE_F9: case IKDE_F11:
  855. X                if(clen1 < itmp2)
  856. X                    clen1 = itmp2;
  857. X                break;
  858. X
  859. X            case IKDE_F2: case IKDE_F4: case IKDE_F6: case IKDE_F8:
  860. X            case IKDE_F10: case IKDE_F12:
  861. X                if(clen2 < itmp2)
  862. X                    clen2 = itmp2;
  863. X                break;
  864. X
  865. X            case IKDE_HOME: case IKDE_END: case IKDE_INS:
  866. X            case IKDE_CUU: case IKDE_CUL:
  867. X                if(clen3 < itmp2)
  868. X                    clen3 = itmp2;
  869. X                break;
  870. X
  871. X            case IKDE_InitStr:    /* initialization string excluded */
  872. X                break;
  873. X        }
  874. X    }
  875. X    sprintf(cfmt1," %%-%d.%ds",clen1,clen1);
  876. X    sprintf(cfmt2," %%-%d.%ds",clen2,clen2);
  877. X    sprintf(cfmt3," %%-%d.%ds",clen3,clen3);
  878. X    strcpy(cfmt4," %s");
  879. X    ff(se,"   key definition: %s\r\n\r\n",keyset_name);
  880. X
  881. X    ffso(" F1  ");ff(se,cfmt1,keyset_table[IKDE_F1].logical);
  882. X    fputs("  ",se);
  883. X    ffso(" F2  ");ff(se,cfmt2,keyset_table[IKDE_F2].logical);
  884. X    fputs("  ",se);
  885. X    ffso(" Home ");ff(se,cfmt3,keyset_table[IKDE_HOME].logical);
  886. X    fputs("  ",se);
  887. X    ffso(" PgUp ");ff(se,cfmt4,keyset_table[IKDE_PGUP].logical);
  888. X    fputs("\r\n",se);
  889. X
  890. X    ffso(" F3  ");ff(se,cfmt1,keyset_table[IKDE_F3].logical);
  891. X    fputs("  ",se);
  892. X    ffso(" F4  ");ff(se,cfmt2,keyset_table[IKDE_F4].logical);
  893. X    fputs("  ",se);
  894. X    ffso(" End  ");ff(se,cfmt3,keyset_table[IKDE_END].logical);
  895. X    fputs("  ",se);
  896. X    ffso(" PgDn ");ff(se,cfmt4,keyset_table[IKDE_PGDN].logical);
  897. X    fputs("\r\n",se);
  898. X
  899. X    ffso(" F5  ");ff(se,cfmt1,keyset_table[IKDE_F5].logical);
  900. X    fputs("  ",se);
  901. X    ffso(" F6  ");ff(se,cfmt2,keyset_table[IKDE_F6].logical);
  902. X    fputs("  ",se);
  903. X    ffso(" Ins  ");ff(se,cfmt3,keyset_table[IKDE_INS].logical);
  904. X    fputs("  ",se);
  905. X    ffso(" CUR5 ");ff(se,cfmt4,keyset_table[IKDE_CU5].logical);
  906. X    fputs("\r\n",se);
  907. X
  908. X    ffso(" F7  ");ff(se,cfmt1,keyset_table[IKDE_F7].logical);
  909. X    fputs("  ",se);
  910. X    ffso(" F8  ");ff(se,cfmt2,keyset_table[IKDE_F8].logical);
  911. X    fputs("  ",se);
  912. X    ffso(" BkTab");ff(se,cfmt3,keyset_table[IKDE_BKTAB].logical);
  913. X    fputs("\r\n",se);
  914. X
  915. X    ffso(" F9  ");ff(se,cfmt1,keyset_table[IKDE_F9].logical);
  916. X    fputs("  ",se);
  917. X    ffso(" F10 ");ff(se,cfmt2,keyset_table[IKDE_F10].logical);
  918. X    fputs("  ",se);
  919. X    ffso(" CUR^ ");ff(se,cfmt3,keyset_table[IKDE_CUU].logical);
  920. X    fputs("  ",se);
  921. X    ffso(" CUR> ");ff(se,cfmt4,keyset_table[IKDE_CUR].logical);
  922. X    fputs("\r\n",se);
  923. X
  924. X    ffso(" F11 ");ff(se,cfmt1,keyset_table[IKDE_F11].logical);
  925. X    fputs("  ",se);
  926. X    ffso(" F12 ");ff(se,cfmt2,keyset_table[IKDE_F12].logical);
  927. X    fputs("  ",se);
  928. X    ffso(" CUR< ");ff(se,cfmt3,keyset_table[IKDE_CUL].logical);
  929. X    fputs("  ",se);
  930. X    ffso(" CURv ");ff(se,cfmt4,keyset_table[IKDE_CUD].logical);
  931. X    fputs("\r\n\r\n",se);
  932. X
  933. X}    /* end of keyset_display */
  934. X
  935. X/* end of ecufkey.c */
  936. X/* vi: set tabstop=4 shiftwidth=4: */
  937. SHAR_EOF
  938. chmod 0644 ecufkey.c ||
  939. echo 'restore of ecufkey.c failed'
  940. Wc_c="`wc -c < 'ecufkey.c'`"
  941. test 15916 -eq "$Wc_c" ||
  942.     echo 'ecufkey.c: original size 15916, current size' "$Wc_c"
  943. rm -f _shar_wnt_.tmp
  944. fi
  945. # ============= ecufkey.h ==============
  946. if test -f 'ecufkey.h' -a X"$1" != X"-c"; then
  947.     echo 'x - skipping ecufkey.h (File already exists)'
  948.     rm -f _shar_wnt_.tmp
  949. else
  950. > _shar_wnt_.tmp
  951. echo 'x - extracting ecufkey.h (Text)'
  952. sed 's/^X//' << 'SHAR_EOF' > 'ecufkey.h' &&
  953. X/*+-------------------------------------------------------------------------
  954. X    ecufkey.h -- AT XENIX/UNIX function key phrases
  955. X    wht@n4hgf.Mt-Park.GA.US
  956. X--------------------------------------------------------------------------*/
  957. X/*+:EDITS:*/
  958. X/*:09-10-1992-13:58-wht@n4hgf-ECU release 3.20 */
  959. X/*:08-22-1992-15:38-wht@n4hgf-ECU release 3.20 BETA */
  960. X/*:03-27-1992-16:21-wht@n4hgf-re-include protection for all .h files */
  961. X/*:07-25-1991-12:55-wht@n4hgf-ECU release 3.10 */
  962. X/*:08-14-1990-20:40-wht@n4hgf-ecu3.00-flush old edit history */
  963. X
  964. X#ifndef _ecufkey_h
  965. X#define _ecufkey_h
  966. X
  967. X/*
  968. X * indices to key mapping tables
  969. X *
  970. X * these are close to being magic numbers - don't change w/o looking
  971. X * at IKDE_to_XF in ecutty.c
  972. X */
  973. Xenum ikde_enum {
  974. X    IKDE_HOME,
  975. X    IKDE_END,
  976. X    IKDE_PGUP,
  977. X    IKDE_PGDN,
  978. X    IKDE_F1,
  979. X    IKDE_F2,
  980. X    IKDE_F3,
  981. X    IKDE_F4,
  982. X    IKDE_F5,
  983. X    IKDE_F6,
  984. X    IKDE_F7,
  985. X    IKDE_F8,
  986. X    IKDE_F9,
  987. X    IKDE_F10,
  988. X    IKDE_F11,
  989. X    IKDE_F12,
  990. X    IKDE_CUU,
  991. X    IKDE_CUD,
  992. X    IKDE_CUR,
  993. X    IKDE_CUL,
  994. X    IKDE_CU5,
  995. X    IKDE_INS,
  996. X    IKDE_BKTAB
  997. X};
  998. X#define IKDE_lastKey    IKDE_BKTAB
  999. X#define IKDE_InitStr    (IKDE_BKTAB + 1)    /* initialization string kludge */
  1000. X#define KDE_COUNT        (IKDE_BKTAB + 2)
  1001. X
  1002. X#define KDE_LOGICAL_MAX        12    /* max length of keystroke sequence */
  1003. X#define KDE_OUTSTR_MAX        32    /* max length of output sequence */
  1004. X
  1005. X/*
  1006. X * KDE input line types
  1007. X*/
  1008. X#define KDETYPE_NAME        1
  1009. X#define KDETYPE_ENTRY        2
  1010. X#define KDETYPE_COMMENT        3
  1011. X#define KDETYPE_EOF            4
  1012. X
  1013. Xtypedef struct kde
  1014. X{
  1015. X    int count;
  1016. X    uchar ikde;
  1017. X    char logical[KDE_LOGICAL_MAX];
  1018. X    char str[KDE_OUTSTR_MAX];
  1019. X}    KDE;
  1020. X
  1021. X/* when a count is not a count but an action: */
  1022. X#define KACT_COMMAND            -1
  1023. X#define KACT_LOCAL_SHELL        -2
  1024. X#define KACT_REDISPLAY            -3
  1025. X
  1026. Xtypedef struct kdemap
  1027. X{
  1028. X    uchar xf;            /* extended function code (0x80+ from ttygetc()) */
  1029. X    short ikde;            /* index into keyset */
  1030. X    char *name;            /* ECU "formal" name for key */
  1031. X    char *init;            /* key sends this string to port by default */
  1032. X}    KDEMAP;
  1033. X
  1034. Xchar *keyset_idstr();
  1035. X
  1036. X#endif /* _ecufkey_h */
  1037. X
  1038. X/* vi: set tabstop=4 shiftwidth=4: */
  1039. X/* end of ecufkey.h */
  1040. SHAR_EOF
  1041. chmod 0644 ecufkey.h ||
  1042. echo 'restore of ecufkey.h failed'
  1043. Wc_c="`wc -c < 'ecufkey.h'`"
  1044. test 1988 -eq "$Wc_c" ||
  1045.     echo 'ecufkey.h: original size 1988, current size' "$Wc_c"
  1046. rm -f _shar_wnt_.tmp
  1047. fi
  1048. # ============= ecufork.c ==============
  1049. if test -f 'ecufork.c' -a X"$1" != X"-c"; then
  1050.     echo 'x - skipping ecufork.c (File already exists)'
  1051.     rm -f _shar_wnt_.tmp
  1052. else
  1053. > _shar_wnt_.tmp
  1054. echo 'x - extracting ecufork.c (Text)'
  1055. sed 's/^X//' << 'SHAR_EOF' > 'ecufork.c' &&
  1056. X/*+-------------------------------------------------------------------------
  1057. X    ecufork.c -- ecu spawning ground
  1058. X    wht@n4hgf.Mt-Park.GA.US
  1059. X
  1060. X  Defined functions:
  1061. X    exec_cmd(cmdstr)
  1062. X    expand_wildcard_list(wild,expcmd)
  1063. X    find_executable(progname)
  1064. X    is_executable(progname)
  1065. X    shell(shellcmd)
  1066. X    smart_fork()
  1067. X
  1068. X--------------------------------------------------------------------------*/
  1069. X/*+:EDITS:*/
  1070. X/*:09-10-1992-13:58-wht@n4hgf-ECU release 3.20 */
  1071. X/*:08-22-1992-15:38-wht@n4hgf-ECU release 3.20 BETA */
  1072. X/*:04-29-1992-13:29-wht@n4hgf-ignore SIGQUIT when in executing a child */
  1073. X/*:09-25-1991-18:02-wht@n4hgf2-find_executable flunks directories now */
  1074. X/*:09-06-1991-04:20-wht@n4hgf2-expand_wildcard_list minor bug */
  1075. X/*:08-29-1991-01:56-wht@n4hgf2-use max esd size instead of 5120 */
  1076. X/*:07-25-1991-12:55-wht@n4hgf-ECU release 3.10 */
  1077. X/*:07-17-1991-07:04-wht@n4hgf-avoid SCO UNIX nap bug */
  1078. X/*:09-19-1990-19:36-wht@n4hgf-ecu_log_event now gets pid for log from caller */
  1079. X/*:08-14-1990-20:40-wht@n4hgf-ecu3.00-flush old edit history */
  1080. X
  1081. X#include "ecu.h"
  1082. X#include "esd.h"
  1083. X#include "ecufork.h"
  1084. X
  1085. Xextern int last_child_wait_status;
  1086. Xextern int last_child_wait_pid;
  1087. X
  1088. X#ifdef M_I286
  1089. X#define MAX_EXEC_ARG 512
  1090. X#else
  1091. X#if defined(M_UNIX) || defined(ISC)
  1092. X#define MAX_EXEC_ARG 1024
  1093. X#else
  1094. X#define MAX_EXEC_ARG 2048
  1095. X#endif    /* M_UNIX || ISC */
  1096. X#endif    /* M_I286 */
  1097. X
  1098. X/*+-------------------------------------------------------------------------
  1099. X    smart_fork()
  1100. X--------------------------------------------------------------------------*/
  1101. Xint
  1102. Xsmart_fork()
  1103. X{
  1104. X    register int count = 5;
  1105. X    register int pid;
  1106. X
  1107. X    while(count--)
  1108. X    {
  1109. X        if((pid = fork()) >= 0)
  1110. X            return(pid);
  1111. X        if(count)
  1112. X            Nap(40L);
  1113. X    }
  1114. X    return(-1);
  1115. X}    /* end of smart_fork */
  1116. X
  1117. X/*+-----------------------------------------------------------------------
  1118. X    shell(shellcmd)
  1119. X
  1120. X  param 'shellcmd' is a shell command prefixed with either
  1121. X  a '!', '$', '>' character.
  1122. X
  1123. X  '!' causes the command to run as a normal subshell of a process.
  1124. X  '$' causes the communications line to be stdin and stdout
  1125. X      for the spawned shell
  1126. X  '>' causes spawned shell to receive exactly sames files as ecu
  1127. X------------------------------------------------------------------------*/
  1128. Xvoid
  1129. Xshell(shellcmd)
  1130. Xchar *shellcmd;
  1131. X{
  1132. X    register shellpid;
  1133. X    register itmp;
  1134. X    register char *cptr;
  1135. X#if defined(FORK_DEBUG)
  1136. X    char s40[40];
  1137. X#endif
  1138. X    int wait_status;
  1139. X    int restart_rcvr = need_rcvr_restart();
  1140. X    char *getenv();
  1141. X
  1142. X    kill_rcvr_process(SIGUSR1);        /* stop receiver process gracefully */
  1143. X
  1144. X    signal(SIGINT,SIG_IGN);
  1145. X    signal(SIGQUIT,SIG_IGN);
  1146. X    signal(SIGUSR1,SIG_IGN);
  1147. X    signal(SIGUSR2,SIG_IGN);
  1148. X    signal(SIGCLD,SIG_DFL);
  1149. X
  1150. X    if((shellpid = smart_fork()) < 0)
  1151. X    {
  1152. X        ff(se,"Cannot fork\r\n");
  1153. X        if(restart_rcvr)
  1154. X            start_rcvr_process(1);
  1155. X        xmtr_signals();
  1156. X        return;
  1157. X    }
  1158. X
  1159. X    ttymode(0);                   /* set canonical tty mode */
  1160. X    if(shellpid == 0)            /* we are the spawned (going to call shell) */
  1161. X    {
  1162. X        if(*shellcmd != '>')    /* '>' prefix means leave fd's alone! */
  1163. X        {
  1164. X            /* Hook-up our "standard output" to either the tty or
  1165. X             * the line as appropriate for '!' or '$' */
  1166. X            close(TTYOUT);
  1167. X            fcntl(((*shellcmd == '$') ? shm->Liofd : TTYERR),F_DUPFD,TTYOUT);
  1168. X            if(*shellcmd == '$')
  1169. X            {
  1170. X                close(TTYIN);
  1171. X                fcntl(shm->Liofd,F_DUPFD,TTYIN);
  1172. X            }
  1173. X            close(shm->Liofd);
  1174. X        }
  1175. X
  1176. X        child_signals();        /* signals for child */
  1177. X
  1178. X        if(*shellcmd == '!')
  1179. X        {
  1180. X            cptr = getenv("SHELL");
  1181. X            if(cptr == (char *)0)
  1182. X                cptr = "/bin/csh";
  1183. X        }
  1184. X        else
  1185. X            cptr = "/bin/sh";
  1186. X
  1187. X        shellcmd++;
  1188. X        child_signals();
  1189. X        if(ulindex(cptr,"csh") > -1)
  1190. X        {
  1191. X            if(*shellcmd == '\0')
  1192. X                execl(cptr,"csh",(char *)0);
  1193. X            else
  1194. X                execl(cptr,"csh","-c",shellcmd,(char *)0);
  1195. X        }
  1196. X        else
  1197. X        {
  1198. X            if(*shellcmd == '\0')
  1199. X                execl(cptr,"sh",(char *)0);
  1200. X            else
  1201. X                execl(cptr,"sh","-c",shellcmd,(char *)0);
  1202. X        }
  1203. X
  1204. X        ff(se,"cannot execute %s\r\n",cptr);    /* should not get here */
  1205. X        _exit(255);                                /* end of spawned process */
  1206. X    }    /* end of if child process */
  1207. X
  1208. X#if defined(FORK_DEBUG)
  1209. X    sprintf(s40,"DEBUG fork shell pid %d",shellpid);
  1210. X    ecu_log_event(getpid(),s40); /* shell */
  1211. X#endif
  1212. X
  1213. X    while(((itmp = wait(&wait_status)) != shellpid) && (itmp != -1))
  1214. X        ;
  1215. X    last_child_wait_status = wait_status;
  1216. X    last_child_wait_pid = shellpid;
  1217. X
  1218. X    xmtr_signals();            /* restore standard xmtr signals */
  1219. X    ttymode(1);                /* control tty back to raw mode */
  1220. X
  1221. X/* any comm program will probably doodle with the line characteristics. */
  1222. X/* we want to make sure they are restored to normal */
  1223. X    lreset_ksr();            /* restore comm line params */
  1224. X
  1225. X    if(restart_rcvr)
  1226. X        start_rcvr_process(1);
  1227. X
  1228. X}    /* end of shell */
  1229. X
  1230. X/*+-------------------------------------------------------------------------
  1231. X    is_executable(progname)
  1232. X--------------------------------------------------------------------------*/
  1233. Xis_executable(progname)
  1234. Xchar *progname;
  1235. X{
  1236. X    struct stat ss;
  1237. X
  1238. X    if(stat(progname,&ss) < 0)            /* if cannot stat, flunk */
  1239. X        return(0);
  1240. X    if((ss.st_mode & 0111) == 0)        /* if no --x--x--x, flunk */
  1241. X        return(0);
  1242. X    if((ss.st_mode & S_IFMT) != S_IFREG)/* if no --x--x--x, flunk */
  1243. X        return(0);
  1244. X    return(1);    /* whew, this OUGHT to work */
  1245. X
  1246. X}    /* end of is_executable */
  1247. X
  1248. X/*+-------------------------------------------------------------------------
  1249. X    find_executable(progname)
  1250. XPATH=':/usr/wht/bin:/bin:/usr/bin:/usr/wht/bin:/etc/tuckerware' len=56
  1251. X--------------------------------------------------------------------------*/
  1252. Xchar *
  1253. Xfind_executable(progname)
  1254. Xchar *progname;
  1255. X{
  1256. X    register itmp;
  1257. X    static char *path_buf = (char *)0;
  1258. X#define PATHNAME_QUAN 32
  1259. X    static char *path_name[PATHNAME_QUAN + 1];
  1260. X    static char rtn_path[256];
  1261. X    static int path_count = 0;
  1262. X    char *cptr;
  1263. X    char *getenv();
  1264. X
  1265. X    if(path_buf == (char *)0)
  1266. X    {
  1267. X        if((cptr = getenv("PATH")) == (char *)0)
  1268. X            return(cptr);
  1269. X        if(!(path_buf = malloc(strlen(cptr) + 1)))
  1270. X            return((char *)0);
  1271. X        strcpy(path_buf,cptr);
  1272. X        path_name[PATHNAME_QUAN + 1] = (char *)0;
  1273. X        cptr = path_buf;
  1274. X        for(path_count = 0; path_count < PATHNAME_QUAN; path_count++)
  1275. X        {
  1276. X            if(*cptr == 0)
  1277. X                break;
  1278. X            path_name[path_count] = cptr;
  1279. X            while((*cptr != ':') && (*cptr != 0))
  1280. X                cptr++;
  1281. X            if(*cptr == ':')
  1282. X                *cptr++ = 0;
  1283. X        }
  1284. X    }    /* end of get and process path env variable */
  1285. X
  1286. X/* look for executable */
  1287. X    for(itmp = 0; itmp < path_count; itmp++)
  1288. X    {
  1289. X        if(*path_name[itmp] == 0)    /* if null path (./) */
  1290. X            strcpy(rtn_path,"./");
  1291. X        else
  1292. X            sprintf(rtn_path,"%s/",path_name[itmp]);
  1293. X        strcat(rtn_path,progname);
  1294. X        if(is_executable(rtn_path))
  1295. X            return(rtn_path);
  1296. X    }
  1297. X    return((char *)0);
  1298. X}    /* end of find_executable */
  1299. X
  1300. X/*+-------------------------------------------------------------------------
  1301. X    exec_cmd(cmdstr) - execute an arbitrary program with arguments
  1302. Xkills rcvr process if alive and restarts it when done if was alive
  1303. X--------------------------------------------------------------------------*/
  1304. Xexec_cmd(cmdstr)
  1305. Xchar *cmdstr;
  1306. X{
  1307. X    char *cmdpath;
  1308. X    char *cmdargv[MAX_EXEC_ARG];
  1309. X    int itmp;
  1310. X    int execpid;
  1311. X    int restart_rcvr = need_rcvr_restart();
  1312. X    int old_ttymode = get_ttymode();
  1313. X    int wait_status = 0;
  1314. X    char *strrchr();
  1315. X
  1316. X#if defined(FORK_DEBUG)
  1317. X    char s80[80];
  1318. X    strcpy(s80,"DEBUG exec ");
  1319. X    strncat(s80,cmdstr,sizeof(s80)-12);
  1320. X    s80[sizeof(s80)-12] = 0;
  1321. X    ecu_log_event(getpid(),s80);
  1322. X#endif
  1323. X
  1324. X    build_arg_array(cmdstr,cmdargv,MAX_EXEC_ARG,&itmp);
  1325. X    if(itmp == MAX_EXEC_ARG)
  1326. X    {
  1327. X        ff(se,"Too many arguments to command\r\n");
  1328. X        return(-1);
  1329. X    }
  1330. X    else if(!itmp)
  1331. X    {
  1332. X        ff(se,"null command\r\n");
  1333. X        return(-1);
  1334. X    }
  1335. X
  1336. X    if(*cmdargv[0] == '/')
  1337. X    {
  1338. X        cmdpath = cmdargv[0];
  1339. X        cmdargv[0] = strrchr(cmdargv[0],'/') + 1;
  1340. X    }
  1341. X    else
  1342. X    {
  1343. X        if((cmdpath = find_executable(cmdargv[0])) == (char *)0)
  1344. X        {
  1345. X            ff(se,"Cannot find %s\r\n",cmdargv[0]);
  1346. X            return(-1);
  1347. X        }
  1348. X    }
  1349. X
  1350. X    kill_rcvr_process(SIGUSR1);        /* stop receiver process gracefully */
  1351. X
  1352. X/* this code executed by the father (forking) process */
  1353. X/* wait on death of child (morbid in life, but ok here) */
  1354. X
  1355. X    signal(SIGINT,SIG_IGN);
  1356. X    signal(SIGQUIT,SIG_IGN);
  1357. X    signal(SIGUSR1,SIG_IGN);
  1358. X    signal(SIGUSR2,SIG_IGN);
  1359. X    signal(SIGCLD,SIG_DFL);
  1360. X
  1361. X    if((execpid = smart_fork()) < 0)
  1362. X    {
  1363. X        ff(se,"Cannot fork\r\n");
  1364. X        if(restart_rcvr)
  1365. X            start_rcvr_process(1);
  1366. X        xmtr_signals();
  1367. X        return(-1);
  1368. X    }
  1369. X
  1370. X    if(execpid == 0)            /* we are the spawned (going to call exec) */
  1371. X    {
  1372. X        ttymode(0);               /* set canonical tty mode */
  1373. X        child_signals();
  1374. X        execv(cmdpath,cmdargv);
  1375. X        perror(cmdpath);
  1376. X        _exit(255);                /* end of spawned process */
  1377. X    }    /* end of if child process */
  1378. X
  1379. X    wait_status = 0;
  1380. X    while(((itmp = wait(&wait_status)) != execpid) && (itmp != -1))
  1381. X        ;
  1382. X    last_child_wait_status = wait_status;
  1383. X    last_child_wait_pid = execpid;
  1384. X
  1385. X/* resume our normally scheduled program */
  1386. X    lreset_ksr();                /* restore comm line params */
  1387. X    ttymode(old_ttymode);        /* control tty back to original */
  1388. X    if(restart_rcvr)
  1389. X        start_rcvr_process(1);
  1390. X    xmtr_signals();
  1391. X    return(last_child_wait_status);
  1392. X
  1393. X}    /* end of exec_cmd */
  1394. X
  1395. X/*+-------------------------------------------------------------------------
  1396. X    expand_wildcard_list(wild,&expcmd)
  1397. X
  1398. Xcalled with 'foo <wildcardlist>' for command expansion prior to exec()
  1399. X         or '<wildcardlist>' to expand a list of files.
  1400. X
  1401. XIf called with 'foo'-style wild, anything you want to protect from csh 
  1402. Xglobbing or other interpretation must be properly protected (quoted) --
  1403. XAND quoting will be removed one level by the csh.
  1404. X
  1405. Xif return 0, wild has been expanded, expcmd must be free()'d when done
  1406. Xif return -1, error, expcmd has error message (static message: DO NOT FREE)
  1407. X--------------------------------------------------------------------------*/
  1408. Xexpand_wildcard_list(wild,expcmd)
  1409. Xchar *wild;
  1410. Xchar **expcmd;
  1411. X{
  1412. X    register char *cptr;
  1413. X#define P_READ 0
  1414. X#define P_WRITE 1
  1415. X    PID_T pipe_pid;
  1416. X    int stdout_pipe[2];
  1417. X    int stderr_pipe[2];
  1418. X    int count;
  1419. X    int expcmd_size = 0;
  1420. X    int itmp;
  1421. X    int wait_status;
  1422. X    int restart_rcvr = need_rcvr_restart();
  1423. X    FILE *fp_pipe = (FILE *)0;
  1424. X    char *echo_cmd;
  1425. X    static char s132[132];
  1426. X    char *strchr();
  1427. X    static char *pipe_err_msg = "system error: no pipe";
  1428. X    static char *mem_err_msg = "system error: no memory";
  1429. X
  1430. X    if(strchr(wild,'<') || strchr(wild,'>') || strchr(wild,'&'))
  1431. X    {
  1432. X        *expcmd = "illegal characters: '<', '>' or '&'";
  1433. X        return(-1);
  1434. X    }
  1435. X
  1436. X    if(pipe(stdout_pipe) < 0)
  1437. X    {
  1438. X        *expcmd = pipe_err_msg;
  1439. X        return(-1);
  1440. X    }
  1441. X    if(pipe(stderr_pipe) < 0)
  1442. X    {
  1443. X        close(stdout_pipe[P_READ]);
  1444. X        close(stdout_pipe[P_WRITE]);
  1445. X        *expcmd = pipe_err_msg;
  1446. X        return(-1);
  1447. X    }
  1448. X    if(!(echo_cmd = malloc(strlen(wild) + 10)))
  1449. X    {
  1450. X        close(stdout_pipe[P_READ]);
  1451. X        close(stdout_pipe[P_WRITE]);
  1452. X        close(stderr_pipe[P_READ]);
  1453. X        close(stderr_pipe[P_WRITE]);
  1454. X        *expcmd = mem_err_msg;
  1455. X        return(-1);
  1456. X    }
  1457. X
  1458. X    strcpy(echo_cmd,"echo ");
  1459. X    strcat(echo_cmd,wild);
  1460. X
  1461. X    kill_rcvr_process(SIGUSR1);        /* stop receiver process gracefully */
  1462. X
  1463. X    signal(SIGINT,SIG_IGN);
  1464. X    signal(SIGQUIT,SIG_IGN);
  1465. X    signal(SIGUSR1,SIG_IGN);
  1466. X    signal(SIGUSR2,SIG_IGN);
  1467. X    signal(SIGCLD,SIG_DFL);
  1468. X
  1469. X    if((pipe_pid = smart_fork()) == 0)
  1470. X    {
  1471. X    int null = open("/dev/null",O_WRONLY,0);
  1472. X
  1473. X        close(stdout_pipe[P_READ]);
  1474. X        close(TTYOUT);
  1475. X        dup(stdout_pipe[P_WRITE]);
  1476. X        close(stdout_pipe[P_WRITE]);
  1477. X        close(TTYERR);
  1478. X        dup(stderr_pipe[P_WRITE]);
  1479. X        close(stderr_pipe[P_WRITE]);
  1480. X        close(null);
  1481. X        child_signals();
  1482. X        execl("/bin/csh","csh","-e","-f","-c",echo_cmd,(char *)0);
  1483. X        _exit(255);
  1484. X    }
  1485. X
  1486. X#if defined(FORK_DEBUG)
  1487. X    sprintf(s132,"DEBUG expand pid %d",pipe_pid);
  1488. X    ecu_log_event(getpid(),s132);        /* expand_wildcard_list */
  1489. X#endif
  1490. X
  1491. X    free(echo_cmd);
  1492. X
  1493. X    close(stdout_pipe[P_WRITE]);
  1494. X    close(stderr_pipe[P_WRITE]);
  1495. X    if(pipe_pid == -1)
  1496. X    {
  1497. X        close(stdout_pipe[P_READ]);
  1498. X        close(stderr_pipe[P_READ]);
  1499. X        *expcmd = "could not fork";
  1500. X        if(restart_rcvr)
  1501. X            start_rcvr_process(0);
  1502. X        xmtr_signals();
  1503. X        return(-1);
  1504. X    }
  1505. X
  1506. X    if(!(*expcmd = malloc(expcmd_size = ESD_MAXSIZE)))
  1507. X    {
  1508. X        close(stdout_pipe[P_READ]);
  1509. X        close(stderr_pipe[P_READ]);
  1510. X        kill(pipe_pid,SIGKILL);
  1511. X        *expcmd = mem_err_msg;
  1512. X        if(restart_rcvr)
  1513. X            start_rcvr_process(0);
  1514. X        xmtr_signals();
  1515. X        return(-1);
  1516. X    }
  1517. X
  1518. X    if(!(fp_pipe = fdopen(stdout_pipe[P_READ],"r")) ||
  1519. X        ((count = fread(*expcmd,1,expcmd_size,fp_pipe)) < 0))
  1520. X    {
  1521. X            free(*expcmd);
  1522. X            kill(pipe_pid,SIGKILL);
  1523. X            close(stdout_pipe[P_READ]);
  1524. X            close(stderr_pipe[P_READ]);
  1525. X            *expcmd = "error reading wild list expansion";
  1526. X            if(restart_rcvr)
  1527. X                start_rcvr_process(0);
  1528. X            xmtr_signals();
  1529. X            return(-1);
  1530. X    }
  1531. X
  1532. X    /*
  1533. X     * make sure stdout is closed
  1534. X     */
  1535. X    if(fp_pipe)
  1536. X        fclose(fp_pipe);
  1537. X    close(stdout_pipe[P_READ]);
  1538. X
  1539. X    /*
  1540. X     * place trailing null
  1541. X     * kill trailing new line
  1542. X     */
  1543. X    if(count)
  1544. X    {
  1545. X        cptr = (*expcmd) + count;
  1546. X        *cptr-- = 0;
  1547. X        if(*cptr == '\n')
  1548. X        {
  1549. X            *cptr = 0;
  1550. X            count--;
  1551. X        }
  1552. X    }
  1553. X
  1554. X    /*
  1555. X     * if no expansion, read stderr to find out why
  1556. X     */
  1557. X    if(!count)
  1558. X    {
  1559. X        free(*expcmd);
  1560. X        count = read(stderr_pipe[P_READ],s132,sizeof(s132) - 1);
  1561. X        if(count < 0)
  1562. X            strcpy(s132,errno_text(errno));
  1563. X        else
  1564. X            s132[count] = 0;
  1565. X        if(s132[count - 1] == '\n')
  1566. X            s132[count - 1] = 0;
  1567. X        close(stderr_pipe[P_READ]);
  1568. X        if(strncmp(s132,"echo: ",6))
  1569. X            *expcmd = s132;
  1570. X        else
  1571. X            *expcmd = s132 + 6;
  1572. X        if(restart_rcvr)
  1573. X            start_rcvr_process(0);
  1574. X        return(-1);
  1575. X    }
  1576. X
  1577. X    /*
  1578. X     * clean up zombie
  1579. X     */
  1580. X    wait_status = 0;
  1581. X    while(((itmp = wait(&wait_status)) != pipe_pid) && (itmp != -1))
  1582. X        ;
  1583. X
  1584. X    xmtr_signals();
  1585. X
  1586. X    /*
  1587. X     * if bad termination status, read stderr
  1588. X     */
  1589. X    if(wait_status)
  1590. X    {
  1591. X        free(*expcmd);
  1592. X        count = read(stderr_pipe[P_READ],s132,sizeof(s132) - 1);
  1593. X        if(count < 0)
  1594. X            strcpy(s132,errno_text(errno));
  1595. X        else
  1596. X            s132[count] = 0;
  1597. X        if(s132[count - 1] == '\n')
  1598. X            s132[count - 1] = 0;
  1599. X        close(stderr_pipe[P_READ]);
  1600. X        if(strncmp(s132,"echo: ",6))
  1601. X            *expcmd = s132;
  1602. X        else
  1603. X            *expcmd = s132 + 6;
  1604. X        if(restart_rcvr)
  1605. X            start_rcvr_process(0);
  1606. X        return(-1);
  1607. X    }
  1608. X    close(stderr_pipe[P_READ]);
  1609. X
  1610. X    /*
  1611. X     * whew: we have (I think) a file list expansion
  1612. X     */
  1613. X    if(restart_rcvr)
  1614. X        start_rcvr_process(0);
  1615. X
  1616. X    return(0);
  1617. X}    /* end of expand_wildcard_list */
  1618. X
  1619. X/* vi: set tabstop=4 shiftwidth=4: */
  1620. X/* end of ecufork.c */
  1621. SHAR_EOF
  1622. chmod 0644 ecufork.c ||
  1623. echo 'restore of ecufork.c failed'
  1624. Wc_c="`wc -c < 'ecufork.c'`"
  1625. test 13563 -eq "$Wc_c" ||
  1626.     echo 'ecufork.c: original size 13563, current size' "$Wc_c"
  1627. rm -f _shar_wnt_.tmp
  1628. fi
  1629. # ============= ecufork.h ==============
  1630. if test -f 'ecufork.h' -a X"$1" != X"-c"; then
  1631.     echo 'x - skipping ecufork.h (File already exists)'
  1632.     rm -f _shar_wnt_.tmp
  1633. else
  1634. > _shar_wnt_.tmp
  1635. echo 'x - extracting ecufork.h (Text)'
  1636. sed 's/^X//' << 'SHAR_EOF' > 'ecufork.h' &&
  1637. X/*+-------------------------------------------------------------------------
  1638. X    ecufork.h 
  1639. X    wht@n4hgf.Mt-Park.GA.US
  1640. X
  1641. Xfor now just vehicle for deciding whether or not to debug fork/waits
  1642. X--------------------------------------------------------------------------*/
  1643. X/*+:EDITS:*/
  1644. X/*:09-10-1992-13:58-wht@n4hgf-ECU release 3.20 */
  1645. X/*:08-22-1992-15:38-wht@n4hgf-ECU release 3.20 BETA */
  1646. X/*:03-27-1992-16:21-wht@n4hgf-re-include protection for all .h files */
  1647. X/*:07-25-1991-12:55-wht@n4hgf-ECU release 3.10 */
  1648. X/*:08-14-1990-20:40-wht@n4hgf-ecu3.00-flush old edit history */
  1649. X
  1650. X#ifndef _ecufork_h
  1651. X#define _ecufork_h
  1652. X
  1653. X/* #define FORK_DEBUG */
  1654. X
  1655. X#endif /* _ecufork_h */
  1656. X
  1657. X/* vi: set tabstop=4 shiftwidth=4: */
  1658. X/* end of ecufork.h */
  1659. SHAR_EOF
  1660. chmod 0644 ecufork.h ||
  1661. echo 'restore of ecufork.h failed'
  1662. Wc_c="`wc -c < 'ecufork.h'`"
  1663. test 717 -eq "$Wc_c" ||
  1664.     echo 'ecufork.h: original size 717, current size' "$Wc_c"
  1665. rm -f _shar_wnt_.tmp
  1666. fi
  1667. # ============= ecugrabbag.c ==============
  1668. if test -f 'ecugrabbag.c' -a X"$1" != X"-c"; then
  1669.     echo 'x - skipping ecugrabbag.c (File already exists)'
  1670.     rm -f _shar_wnt_.tmp
  1671. else
  1672. > _shar_wnt_.tmp
  1673. echo 'x - extracting ecugrabbag.c (Text)'
  1674. sed 's/^X//' << 'SHAR_EOF' > 'ecugrabbag.c' &&
  1675. X/*+-----------------------------------------------------------------
  1676. X    ecugrabbag.c -- very machine/OS dependent functions
  1677. X    wht@n4hgf.Mt-Park.GA.US
  1678. X
  1679. X  Defined functions:
  1680. X    bell_alarm(xbell_type)
  1681. X    bell_notify(xbell_type)
  1682. X    bell_notify_text(bn)
  1683. X    kbd_escape(xkey)
  1684. X    morse_bell(xbell_type,count)
  1685. X    parse_bell_notify_argument(strarg)
  1686. X    rename(from,to)
  1687. X    send_bell_fd(fd,count,nap_msec)
  1688. X    send_get_response(narg,arg)
  1689. X    set_bell_fd(fd,pitch,duration)
  1690. X    set_default_escape_prompt()
  1691. X    show_escape_prompt()
  1692. X    signal_name_text(sig)
  1693. X    xbell(type,count)
  1694. X    xbell_fd(fd,type,count)
  1695. X    xterm_title(text,code)
  1696. X
  1697. X  This module is a grab bag for historical reasons.  Needs reorg.
  1698. X------------------------------------------------------------------*/
  1699. X/*+:EDITS:*/
  1700. X/*:09-10-1992-13:58-wht@n4hgf-ECU release 3.20 */
  1701. X/*:08-22-1992-15:38-wht@n4hgf-ECU release 3.20 BETA */
  1702. X/*:04-09-1992-05:47-wht@n4hgf-cleanup new "bn" argument parsing */
  1703. X/*:02-16-1992-01:41-wht@n4hgf-turn off xterm_title */
  1704. X/*:12-13-1991-17:14-wht@n4hgf-add bell_notify_text */
  1705. X/*:12-13-1991-17:14-wht@n4hgf-add parse_bell_notify_argument */
  1706. X/*:09-03-1991-18:23-wht@n4hgf-sigint rearrangement in send_get_response */
  1707. X/*:08-28-1991-14:07-wht@n4hgf2-SVR4 cleanup by aega84!lh */
  1708. X/*:08-13-1991-15:28-wht@n4hgf-more problems with history manager */
  1709. X/*:07-25-1991-12:57-wht@n4hgf-ECU release 3.10 */
  1710. X/*:07-17-1991-07:04-wht@n4hgf-avoid SCO UNIX nap bug */
  1711. X/*:07-14-1991-18:18-wht@n4hgf-new ttygets functions */
  1712. X/*:06-29-1991-15:42-wht@n4hgf-if WHT and xterm, play with title bar */
  1713. X/*:06-04-1991-13:19-wht@n4hgf-WHT version always gets morse for bells */
  1714. X/*:05-07-1991-06:10-wht@n4hgf-subtle changes in send_and_get_response */
  1715. X/*:03-18-1991-22:31-wht@n4hgf-ISC 2.2 has rename() */
  1716. X/*:01-16-1991-23:54-wht@n4hgf-if WHT, bell_notify always available */
  1717. X/*:01-09-1991-22:31-wht@n4hgf-ISC port */
  1718. X/*:12-04-1990-03:55-wht@n4hgf-bell_notify only if on multiscreen */
  1719. X/*:09-19-1990-19:36-wht@n4hgf-ecu_log_event now gets pid for log from caller */
  1720. X/*:08-14-1990-20:40-wht@n4hgf-ecu3.00-flush old edit history */
  1721. X
  1722. X#include "ecu.h"
  1723. X#include "ecukey.h"
  1724. X#include "ecufkey.h"
  1725. X#include "ecuxkey.h"
  1726. X#include "ecutty.h"
  1727. X#include "ecufork.h"
  1728. X#include "esd.h"
  1729. X
  1730. X#if defined(MORSE)
  1731. X/* the space between # and include prevents make depend from seeing this */
  1732. X# include <local/morse_dvr.h>
  1733. X#endif
  1734. X
  1735. Xchar *get_ttyname();
  1736. X
  1737. Xextern char curr_dir[]; /* current working key defns */
  1738. Xextern KDE keyset_table[];
  1739. Xextern char keyset_name[];
  1740. X
  1741. XESD *icmd_prompt;        /* interactive command prompt */
  1742. Xint icmd_prompt_len;
  1743. X
  1744. X/*+-------------------------------------------------------------------------
  1745. X    show_escape_prompt()
  1746. Xreturns number of character positions written to screen
  1747. X--------------------------------------------------------------------------*/
  1748. Xshow_escape_prompt()
  1749. X{
  1750. X    char prompt_last;
  1751. X
  1752. X    prompt_last = 'd';    /* dummy */
  1753. X    if(icmd_prompt->cb)
  1754. X        prompt_last = *(icmd_prompt->pb + icmd_prompt->cb - 1);
  1755. X
  1756. X    icmd_prompt_len = 0;
  1757. X    shmx_make_rcvr_sleep(1);
  1758. X    if(!(colors_current & 0xFFFF0000L) || !(colors_current & 0xFFFFL))
  1759. X        setcolor(colors_normal);
  1760. X    else
  1761. X        setcolor(colors_current);
  1762. X    tcap_stand_out();
  1763. X    if(icmd_prompt->cb)
  1764. X    {
  1765. X        ff(se," %s",icmd_prompt->pb);
  1766. X        icmd_prompt_len += icmd_prompt->cb + 1;
  1767. X    }
  1768. X    if(isalnum(prompt_last))
  1769. X    {
  1770. X        fputs(" %",se);
  1771. X        icmd_prompt_len += 2;
  1772. X    }
  1773. X    tcap_stand_end();
  1774. X    fputc(' ',se);
  1775. X    icmd_prompt_len++;
  1776. X    return(icmd_prompt_len);
  1777. X
  1778. X}    /* end of show_escape_prompt */
  1779. X
  1780. X/*+-------------------------------------------------------------------------
  1781. X    set_default_escape_prompt()
  1782. X--------------------------------------------------------------------------*/
  1783. Xvoid
  1784. Xset_default_escape_prompt()
  1785. X{
  1786. X    register char *cptr;
  1787. X    char *getenv();
  1788. X
  1789. X    if((cptr = getenv("ECUPROMPT")) != (char *)0)
  1790. X    {
  1791. X        strncpy(icmd_prompt->pb,cptr,icmd_prompt->maxcb);
  1792. X        *(icmd_prompt->pb + icmd_prompt->maxcb - 1) = 0;
  1793. X        icmd_prompt->cb = strlen(icmd_prompt->pb);
  1794. X        esd_null_terminate(icmd_prompt);
  1795. X    }
  1796. X
  1797. X}    /* end of set_default_escape_prompt */
  1798. X
  1799. X/*+-------------------------------------------------------------------------
  1800. X    kbd_escape() -- xmtr got extended key -- process it
  1801. Xreturns(1)
  1802. X--------------------------------------------------------------------------*/
  1803. Xkbd_escape(xkey)
  1804. Xuchar xkey;
  1805. X{
  1806. X    register itmp;
  1807. X    int ttygets_flags = TG_XDELIM;
  1808. X    uchar delim;
  1809. X    int strpos;
  1810. X    int old_ttymode = get_ttymode();
  1811. X    register backspace_count;
  1812. X    register KDE *tkde;
  1813. X    uchar icmd_buf[128];
  1814. X
  1815. X    if((xkey >= XF_ALTA) && (xkey <= XF_ALTZ))
  1816. X    {
  1817. X        char alt_key_proc_name[8];
  1818. X        char *arg = alt_key_proc_name;
  1819. X        int narg = 1;
  1820. X        int restart_rcvr = need_rcvr_restart();
  1821. X        kill_rcvr_process(SIGUSR1);
  1822. X        sprintf(alt_key_proc_name,"alt_%c",xkey - XF_ALTA + 'a');
  1823. X        ttymode(2);
  1824. X        ttyflush(0);
  1825. X        if(do_proc(narg,&arg))
  1826. X            ring_bell();
  1827. X        sigint = 0;
  1828. X        proc_file_reset();
  1829. X        ttymode(old_ttymode);
  1830. X        if(restart_rcvr)
  1831. X            start_rcvr_process(0);
  1832. X        return(1);
  1833. X    }
  1834. X
  1835. X    switch(xkey)
  1836. X    {
  1837. X        case XFhome:     /* home key pressed ? */
  1838. X            icmd_buf[0] = 0;
  1839. X            backspace_count = show_escape_prompt();
  1840. X            strpos = 0;
  1841. X            icmd_buf[0] = 0;
  1842. XGET_ICMD:
  1843. X            ttygets(icmd_buf,sizeof(icmd_buf),ttygets_flags,&delim,&strpos);
  1844. X            switch(delim)
  1845. X            {
  1846. X                case XFhome:
  1847. X                case XFpgup:
  1848. X                case XFcurup:
  1849. X                    if(icmd_history_manager(delim,icmd_buf,sizeof(icmd_buf)))
  1850. X                    {
  1851. X                        ring_bell();
  1852. X                        ttygets_flags |= 4;
  1853. X                        goto GET_ICMD;
  1854. X                    }
  1855. X                    break;
  1856. X                case ESC:
  1857. X                case NL:
  1858. X                    break;
  1859. X                default:
  1860. X                    ring_bell();
  1861. X                    itmp = strlen((char *)icmd_buf);
  1862. X                    while(itmp--)
  1863. X                        ff(se,"\b \b");
  1864. X                    ttygets_flags |= 4;
  1865. X                    goto GET_ICMD;
  1866. X            }
  1867. X            if((delim == ESC) || !icmd_buf[0])
  1868. X            {
  1869. X                while(backspace_count--)
  1870. X                    ff(se,"\b \b");
  1871. X                break;
  1872. X            }
  1873. X            if(icmd(icmd_buf))
  1874. X                termecu(TERMECU_OK);
  1875. X            break;
  1876. X
  1877. X        default:
  1878. X            if((itmp = xf_to_ikde(xkey)) < 0)
  1879. X            {
  1880. X                ring_bell();
  1881. X                break;
  1882. X            }
  1883. X            tkde = &keyset_table[itmp];
  1884. X            if((itmp = tkde->count) > 0)
  1885. X            {
  1886. X            register char *cptr = tkde->str;
  1887. X                while(itmp--)
  1888. X                    lputc(*cptr++);
  1889. X            }
  1890. X            else if(tkde->count < 0)
  1891. X            {
  1892. X                switch(tkde->count)
  1893. X                {
  1894. X                    case KACT_LOCAL_SHELL:
  1895. X                        fputs("\r\n",se);
  1896. X                        tcap_stand_out();
  1897. X                        ff(se," local shell in %s ",curr_dir);
  1898. X                        tcap_stand_end();
  1899. X                        ff(se,"\r\n");
  1900. X                        shell("!");
  1901. X                        break;
  1902. X                    case KACT_REDISPLAY:
  1903. X                        redisplay_rcvr_screen();
  1904. X                }
  1905. X            }
  1906. X            else
  1907. X                ring_bell();
  1908. X            break;
  1909. X    }
  1910. X    return(1);
  1911. X}    /* end of kbd_escape */
  1912. X
  1913. X/*+-------------------------------------------------------------------------
  1914. X    set_bell_fd(fd,pitch,duration)
  1915. XExample: 1B 5B 3D 34 30 30 30 3B 31 42 | .[=4000;1B
  1916. X--------------------------------------------------------------------------*/
  1917. Xvoid
  1918. Xset_bell_fd(fd,pitch,duration)
  1919. Xint fd;
  1920. Xint pitch;
  1921. Xint duration;
  1922. X{
  1923. X#if defined(M_SYSV)
  1924. X    char bell_cmd[32];
  1925. X
  1926. X    if(!tty_is_multiscreen)
  1927. X        return;
  1928. X
  1929. X    sprintf(bell_cmd,"\033[=%d;%dB",pitch,duration);
  1930. X    write(fd,bell_cmd,strlen(bell_cmd));
  1931. X#endif
  1932. X}    /* end of set_bell_fd */
  1933. X
  1934. X/*+-------------------------------------------------------------------------
  1935. X    send_bell_fd(fd,count,nap_msec)
  1936. X--------------------------------------------------------------------------*/
  1937. Xvoid
  1938. Xsend_bell_fd(fd,count,nap_msec)
  1939. Xregister fd;
  1940. Xregister count;
  1941. Xregister nap_msec;
  1942. X{
  1943. X    static char bellch = 0x07;
  1944. X
  1945. X    if(count)
  1946. X    {
  1947. X        while(count--)
  1948. X        {
  1949. X            write(fd,&bellch,1);    
  1950. X            Nap((long)nap_msec);
  1951. X        }
  1952. X    }
  1953. X}    /* end of send_bell_fd */
  1954. X
  1955. X/*+-------------------------------------------------------------------------
  1956. X    xbell_fd(fd,type,count)
  1957. X--------------------------------------------------------------------------*/
  1958. Xvoid
  1959. Xxbell_fd(fd,type,count)
  1960. Xregister fd;
  1961. Xregister type;
  1962. Xregister count;
  1963. X{
  1964. X#if defined(M_SYSV)
  1965. X    register itmp;
  1966. X
  1967. X    if(!tty_is_multiscreen)
  1968. X    {
  1969. X        ring_bell();
  1970. X        return;
  1971. X    }
  1972. X
  1973. X    if(count)
  1974. X    {
  1975. X        while(count--)
  1976. X        {
  1977. X            switch(type)
  1978. X            {
  1979. X                case XBELL_DONE:        /* octaves */
  1980. X                    set_bell_fd(fd,1000,1);
  1981. X                    send_bell_fd(fd,1,100);
  1982. X                    set_bell_fd(fd,2000,1);
  1983. X                    send_bell_fd(fd,1,100);
  1984. X                    set_bell_fd(fd,4000,1);
  1985. X                    send_bell_fd(fd,1,100);
  1986. X                    break;
  1987. X                case XBELL_ATTENTION:        /* morse .-.-.- ATTENTION */
  1988. X                    for(itmp = 0; itmp < 3; itmp++)
  1989. X                    {
  1990. X                        set_bell_fd(fd,2000,1);
  1991. X                        send_bell_fd(fd,1,140);
  1992. X                        set_bell_fd(fd,2000,3);
  1993. X                        send_bell_fd(fd,1,340);
  1994. X                    }
  1995. X                    break;
  1996. X                case XBELL_C:        /* morse -.-. C */
  1997. X                    for(itmp = 0; itmp < 2; itmp++)
  1998. X                    {
  1999. X                        set_bell_fd(fd,2000,3);
  2000. X                        send_bell_fd(fd,1,320);
  2001. X                        set_bell_fd(fd,2000,1);
  2002. X                        send_bell_fd(fd,1,120);
  2003. X                    }
  2004. X                    break;
  2005. X                case XBELL_3T:        /* 3 morse T's */
  2006. X                    set_bell_fd(fd,2000,3);
  2007. X                    send_bell_fd(fd,3,460);
  2008. X                    break;
  2009. X                default:
  2010. X                    set_bell_fd(fd,2000,4);
  2011. X                    send_bell_fd(fd,1,100);
  2012. X                    break;
  2013. X            }
  2014. X        }
  2015. X    }
  2016. X                
  2017. X    set_bell_fd(fd,4000,1);
  2018. X#endif    
  2019. X}    /* end of xbell_fd */
  2020. X
  2021. X/*+-------------------------------------------------------------------------
  2022. X    morse_bell(xbell_type,count)
  2023. X--------------------------------------------------------------------------*/
  2024. X#if defined(MORSE)
  2025. Xmorse_bell(xbell_type,count)
  2026. Xint xbell_type;
  2027. Xint count;
  2028. X{
  2029. X    register morse_fd;
  2030. X    int morse_frequency = 800;
  2031. X    char morse_char;
  2032. X    static int morse_ticks = 0;
  2033. X
  2034. X#if !defined(WHT)
  2035. X    if(!tty_is_multiscreen)
  2036. X    {
  2037. X        ring_bell();
  2038. X        return(0);
  2039. X    }
  2040. X#endif
  2041. X
  2042. X    if(!morse_ticks)
  2043. X        morse_ticks = hz / 25;
  2044. X
  2045. X    if((morse_fd = open("/dev/morse",O_WRONLY,0)) < 0)
  2046. X        return(-1);
  2047. X
  2048. X    ioctl(morse_fd,MORSE_SET_SPEED,&morse_ticks);
  2049. X    ioctl(morse_fd,MORSE_SET_FREQUENCY,&morse_frequency);
  2050. X    switch(xbell_type)
  2051. X    {
  2052. X        case XBELL_DONE:
  2053. X            morse_char = 'd';
  2054. X/*
  2055. X            morse_frequency = 400;
  2056. X            ioctl(morse_fd,MORSE_SET_FREQUENCY,&morse_frequency);
  2057. X*/
  2058. X            break;
  2059. X        case XBELL_ATTENTION:
  2060. X            morse_char = '.';
  2061. X            break;
  2062. X        case XBELL_C:
  2063. X            morse_char = 'c';
  2064. X            break;
  2065. X        case XBELL_3T:
  2066. X            morse_char = 'o';
  2067. X            break;
  2068. X        default:
  2069. X            morse_char = BT;
  2070. X            break;
  2071. X    }
  2072. X    while(count--)
  2073. X        write(morse_fd,&morse_char,1);
  2074. X    close(morse_fd);
  2075. X    return(0);
  2076. X}    /* end of morse_bell */
  2077. X#endif
  2078. X
  2079. X/*+-------------------------------------------------------------------------
  2080. X    xbell(type,count)
  2081. X--------------------------------------------------------------------------*/
  2082. Xvoid
  2083. Xxbell(type,count)
  2084. Xint type;
  2085. Xint count;
  2086. X{
  2087. X#if defined(WHT) && defined(MORSE)
  2088. X    if(morse_bell(type,count))
  2089. X        ring_bell();
  2090. X#else
  2091. X#if defined(WHT) && defined(AUDIO)
  2092. X    void audio_notify();
  2093. X    audio_notify(type);
  2094. X#else
  2095. X    if(!tty_is_multiscreen)
  2096. X    {
  2097. X        ring_bell();
  2098. X        return;
  2099. X    }
  2100. X
  2101. X#if defined(MORSE)
  2102. X    if(morse_bell(type,count))
  2103. X#endif
  2104. X        xbell_fd(1,type,count);
  2105. X#endif /* WHT && AUDIO */
  2106. X#endif /* WHT && MORSE */
  2107. X
  2108. X}    /* end of xbell */
  2109. X
  2110. X/*+-------------------------------------------------------------------------
  2111. X    bell_alarm(xbell_type)
  2112. X  ring bell on multiscreens; if morse driver included, use it instead
  2113. X--------------------------------------------------------------------------*/
  2114. Xint
  2115. Xbell_alarm(xbell_type)
  2116. Xint xbell_type;
  2117. X{
  2118. X#if defined(M_SYSV)
  2119. X    register notify_fd;
  2120. X    register fork_pid;
  2121. X    static long notify_time = 0L;
  2122. X    char *get_ttyname();
  2123. X    char devname[64];
  2124. X    int devnum;
  2125. X    int ttnum;
  2126. X
  2127. X#if !(defined(WHT) && defined(MORSE))
  2128. X    if(!tty_is_multiscreen)
  2129. X    {
  2130. X        ring_bell();
  2131. X        return(1);
  2132. X    }
  2133. X#endif
  2134. X
  2135. X    ttnum = atoi(get_ttyname() + 8);
  2136. X
  2137. X/* if happened less than 15 secs ago, forget it */
  2138. X    if((time((long *)0) - notify_time) < 15L)
  2139. X        return(0);
  2140. X
  2141. X    notify_time = time((long *)0);
  2142. X
  2143. X#if defined(MORSE)
  2144. X    if(morse_bell(xbell_type,1))
  2145. X    {
  2146. X#endif
  2147. X        if((fork_pid = smart_fork()) != 0)
  2148. X        {
  2149. X#if defined(FORK_DEBUG)
  2150. X            sprintf(devname,"DEBUG bell notify pid %d",fork_pid);
  2151. X            ecu_log_event(getpid(),devname);    /* bell notify */
  2152. X#endif
  2153. X            return(fork_pid > 0);
  2154. X        }
  2155. X
  2156. X        for(devnum = 1; devnum < 13; devnum++)
  2157. X        {
  2158. X            if(devnum == ttnum)        /* don't bell notify ecu's tty */
  2159. X                continue;
  2160. X            sprintf(devname,"/dev/tty%02d",devnum);
  2161. X            if((notify_fd = open(devname,O_WRONLY,0)) >= 0)
  2162. X            {
  2163. X                xbell_fd(notify_fd,xbell_type,1);
  2164. X                close(notify_fd);
  2165. X            }
  2166. X        }
  2167. X
  2168. X        _exit(0);        /* end of child tine (of the fork, naturally) */
  2169. X#if defined(MORSE)
  2170. X    }
  2171. X    /*NOTREACHED*/
  2172. X#endif
  2173. X#else /* not SCO (M_SYSV) */
  2174. X    ring_bell();
  2175. X#endif
  2176. X    return(1);
  2177. X}    /* end of bell_alarm */
  2178. X
  2179. X/*+-------------------------------------------------------------------------
  2180. X    bell_notify(xbell_type)
  2181. X--------------------------------------------------------------------------*/
  2182. Xvoid
  2183. Xbell_notify(xbell_type)
  2184. Xint xbell_type;
  2185. X{
  2186. X#if defined(M_SYSV)
  2187. X    if(
  2188. X#if !defined(WHT) && !defined(PTY_BELL_NOTIFY)
  2189. X        tty_is_multiscreen &&
  2190. X#endif
  2191. X             shm->bell_notify_state)
  2192. X    {
  2193. X        bell_alarm(xbell_type);
  2194. X    }
  2195. X#endif
  2196. X}    /* end of bell_notify */
  2197. X
  2198. X/*+-------------------------------------------------------------------------
  2199. X    parse_bell_notify_argument(strarg) - parse "bell notify" argument
  2200. X
  2201. X  Returns 0,1,2 according to parsing rules
  2202. X          -1 on error
  2203. X--------------------------------------------------------------------------*/
  2204. Xint
  2205. Xparse_bell_notify_argument(strarg)
  2206. Xchar *strarg;
  2207. X{
  2208. X    static STR_CLASSIFY sc[] = {
  2209. X        { "off",    3,0 },
  2210. X        { "on",        2,1 },
  2211. X        { "alert",  1,2 },
  2212. X        { (char *)0,0,-1 },
  2213. X    };
  2214. X    int itmp;
  2215. X
  2216. X    if(isdigit(*strarg))
  2217. X    {
  2218. X        if( ( (itmp = atoi(strarg)) >= 0) && (itmp < 3) )
  2219. X            return(itmp);
  2220. X        return(-1);
  2221. X    }
  2222. X
  2223. X    return(str_classify(sc,strarg));
  2224. X
  2225. X}    /* end of parse_bell_notify_argument */
  2226. X
  2227. X/*+-------------------------------------------------------------------------
  2228. X    bell_notify_text(bn) - text for bell notify status
  2229. X--------------------------------------------------------------------------*/
  2230. Xchar *
  2231. Xbell_notify_text(bn)
  2232. Xint bn;
  2233. X{
  2234. X    char *cptr = "?";
  2235. X
  2236. X    switch(bn)
  2237. X    {
  2238. X        case 0: cptr = "OFF"; break;
  2239. X        case 1: cptr = "ON"; break;
  2240. X        case 2: cptr = "ON+ALERT"; break;
  2241. X        default: cptr = "???"; break;
  2242. X    }
  2243. X    return(cptr);
  2244. X}    /* end of bell_notify_text */
  2245. X
  2246. X/*+-------------------------------------------------------------------------
  2247. X    signal_name_text(sig)
  2248. X--------------------------------------------------------------------------*/
  2249. Xchar *
  2250. Xsignal_name_text(sig)
  2251. Xint sig;
  2252. X{
  2253. X    register char *cptr;
  2254. X    static char sigunknown[20];
  2255. X
  2256. X    sig &= 0x7F;
  2257. X    switch(sig)
  2258. X    {
  2259. X        case SIGHUP:    cptr = "SIGHUP"; break;
  2260. X        case SIGINT:    cptr = "SIGINT"; break;
  2261. X        case SIGQUIT:    cptr = "SIGQUIT"; break;
  2262. X        case SIGILL:    cptr = "SIGILL"; break;
  2263. X        case SIGTRAP:    cptr = "SIGTRAP"; break;
  2264. X#ifdef SIGIOT
  2265. X        case SIGIOT:    cptr = "SIGIOT"; break;
  2266. X#endif
  2267. X#ifdef SIGEMT
  2268. X        case SIGEMT:    cptr = "SIGEMT"; break;
  2269. X#endif
  2270. X        case SIGFPE:    cptr = "SIGFPE"; break;
  2271. X        case SIGKILL:    cptr = "SIGKILL"; break;
  2272. X        case SIGBUS:    cptr = "SIGBUS"; break;
  2273. X        case SIGSEGV:    cptr = "SIGSEGV"; break;
  2274. X        case SIGSYS:    cptr = "SIGSYS"; break;
  2275. X        case SIGPIPE:    cptr = "SIGPIPE"; break;
  2276. X        case SIGALRM:    cptr = "SIGALRM"; break;
  2277. X        case SIGTERM:    cptr = "SIGTERM"; break;
  2278. X        case SIGUSR1:    cptr = "SIGUSR1"; break;
  2279. X        case SIGUSR2:    cptr = "SIGUSR2"; break;
  2280. X        case SIGCLD:    cptr = "SIGCLD"; break;
  2281. X#if    defined(SIGPWR)
  2282. X        case SIGPWR:    cptr = "SIGPWR"; break;
  2283. X#endif
  2284. X#if    defined(SIGSTOP)
  2285. X        case SIGSTOP:   cptr = "SIGSTOP"; break;
  2286. X#endif
  2287. X#if    defined(SIGTSOP)
  2288. X        case SIGTSTP:   cptr = "SIGTSTP"; break;
  2289. X#endif
  2290. X#if    defined(SIGCONT)
  2291. X        case SIGCONT:   cptr = "SIGCONT"; break;
  2292. X#endif
  2293. X#if    defined(SIGTTIN)
  2294. X        case SIGTTIN:   cptr = "SIGTTIN"; break;
  2295. X#endif
  2296. X#if    defined(SIGTTOU)
  2297. X        case SIGTTOU:   cptr = "SIGTTOU"; break;
  2298. X#endif
  2299. X        default:
  2300. X            sprintf(sigunknown,"SIGNAL %u",sig);
  2301. X            return(sigunknown);
  2302. X    }
  2303. X    return(cptr);
  2304. X
  2305. X}    /* end of signal_name_text */
  2306. X
  2307. X/*+-------------------------------------------------------------------------
  2308. X    rename(from,to)
  2309. X--------------------------------------------------------------------------*/
  2310. X#if defined(M_XENIX) && !defined(BUILDING_LINT_ARGS)
  2311. Xint
  2312. Xrename(from,to)
  2313. Xchar *from;
  2314. Xchar *to;
  2315. X{
  2316. X    struct stat ss;
  2317. X    int save_errno;
  2318. X    extern int errno;
  2319. X
  2320. X    if(!stat(to,&ss))    /* if to exists, flunk */
  2321. X    {
  2322. X        errno = EEXIST;    /* fake "file exists" error */
  2323. X        return(-1);
  2324. X    }
  2325. X
  2326. X    if(link(from,to))    /* if cannot link, flunk */
  2327. X        return(-1);
  2328. X
  2329. X    if(unlink(from))    /* if cannot unlink, flunk */
  2330. X    {
  2331. X        save_errno = errno;
  2332. X        unlink(to);
  2333. X        errno = save_errno;
  2334. SHAR_EOF
  2335. true || echo 'restore of ecugrabbag.c failed'
  2336. fi
  2337. echo 'End of ecu320 part 7'
  2338. echo 'File ecugrabbag.c is continued in part 8'
  2339. echo 8 > _shar_seq_.tmp
  2340. exit 0
  2341.  
  2342. exit 0 # Just in case...
  2343.