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

  1. Newsgroups: comp.sources.misc
  2. Path: sparky!kent
  3. From: wht@n4hgf.Mt-Park.GA.US (Warren Tucker)
  4. Subject:  v32i053:  ecu - ECU Asynchronous Communications v3.20, Part18/40
  5. Message-ID: <1992Sep13.153743.5724@sparky.imd.sterling.com>
  6. Followup-To: comp.sources.d
  7. X-Md4-Signature: fe8c6728dbcc0f7990d998733a66f3a8
  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:37:43 GMT
  12. Approved: kent@sparky.imd.sterling.com
  13. Lines: 2272
  14.  
  15. Submitted-by: wht@n4hgf.Mt-Park.GA.US (Warren Tucker)
  16. Posting-number: Volume 32, Issue 53
  17. Archive-name: ecu/part18
  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.18 (part 18 of ecu320)
  24. # do not concatenate these parts, unpack them in order with /bin/sh
  25. # file kbdtest3.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" != 18; 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 kbdtest3.c'
  41. else
  42. echo 'x - continuing file kbdtest3.c'
  43. sed 's/^X//' << 'SHAR_EOF' >> 'kbdtest3.c' &&
  44. X/*+-----------------------------------------------------------------------
  45. X    kbdtest3.c -- test keyboard values
  46. X    wht@n4hgf.Mt-Park.GA.US
  47. X
  48. X  See ecu manual section titled Function Key Recognition
  49. X
  50. X  Defined functions:
  51. X    dump_putc(ch)
  52. X    dump_puts(str)
  53. X    hex_dump16(int16)
  54. X    hex_dump32(int32)
  55. X    hex_dump4(int4)
  56. X    hex_dump8(int8)
  57. X    hex_dump_fp(fp,str,len,title,terse_flag)
  58. X    k3ttymode(arg)
  59. X    main(argc,argv)
  60. X    read_kbd_string(buf,max)
  61. X    termio_parity_text(cflag)
  62. X    tputstrs(strs)
  63. X    write_funckeymap_desc(fp,buf,buflen,name)
  64. X    xtoasc(ch,incl_3char)
  65. X
  66. X------------------------------------------------------------------------*/
  67. X/*+:EDITS:*/
  68. X/*:09-10-1992-13:59-wht@n4hgf-ECU release 3.20 */
  69. X/*:08-22-1992-15:39-wht@n4hgf-ECU release 3.20 BETA */
  70. X/*:04-19-1992-20:59-wht@n4hgf-nonansikeys to funckeymap */
  71. X/*:02-22-1992-12:46-root@n4hgf-thank markd@phoenix.pub.uu.oz.au for typo fix */
  72. X/*:01-06-1992-17:56-wht@tridom-much more error checking */
  73. X/*:01-06-1992-17:56-wht@tridom-eliminate sun stty - causes problems */
  74. X/*:08-28-1991-14:07-wht@n4hgf2-SVR4 cleanup by aega84!lh */
  75. X/*:08-17-1991-13:58-root@n4hgf-make kbd entirely raw */
  76. X/*:08-06-1991-13:12-wht@n4hgf-add parity reporting */
  77. X/*:08-06-1991-13:12-wht@n4hgf-some terminals reinvent parity bit's use */
  78. X/*:07-25-1991-12:58-wht@n4hgf-ECU release 3.10 */
  79. X/*:04-29-1991-18:24-wht@n4hgf-let us see what keyboards say */
  80. X
  81. X#include <stdio.h>
  82. X#include <signal.h>
  83. X#include <ctype.h>
  84. X#include "ecu_types.h"
  85. X#include <sys/errno.h>
  86. X#include "ecu_stat.h"
  87. X#include <string.h>
  88. X#include <termio.h>
  89. X
  90. Xchar *ctime();
  91. Xchar *getenv();
  92. X
  93. X#define VMIN_VALUE  32
  94. X#define VTIME_VALUE 2
  95. X
  96. X#define TTYIN   0                /* mnemonic */
  97. X#define TTYOUT  1                /* mnemonic */
  98. X#define TTYERR  2                /* mnemonic */
  99. X
  100. Xstruct termio lv;        /* attributes for the line to remote */
  101. Xstruct termio tv0;        /* for saving, changing TTY atributes */
  102. Xstruct termio tv;        /* for saving, changing TTY atributes */
  103. X
  104. Xchar *strs_intro[] = {
  105. X    "\n",
  106. X    "Let's learn your keyboard.  I'll be making a file named kbdtest3.out\n",
  107. X    "For each of the key names shown below, please press the key and wait.\n",
  108. X    "\n",
  109. X    "If you do not have a key on your keyboard, make an alternate choice\n",
  110. X    "or press the space bar if nothing seems reasonable.\n",
  111. X    "\n",
  112. X    "If you press a key but don't see further activity after a second or two\n",
  113. X    "press the slash '/' key unless you can choose a reasonable alternate.\n",
  114. X    "Keys which produce duplicate the keystroke sequence of other keys are\n",
  115. X    "not acceptable.\n",
  116. X    "\n",
  117. X    "Do not use the same key for more than one function.\n",
  118. X    "\n",
  119. X    (char *)0
  120. X};
  121. X
  122. Xchar *strs_thanks[] = {
  123. X    "\n",
  124. X    "Thank you.  If you wish to mail me the contents of kbdtest3.out,\n",
  125. X    "please include  a detailed description of the system and software\n",
  126. X    "(i.e., \"Metrolink xterm keyboard on SCO 3.2r2\")\n",
  127. X    "(I WANT you to mail me results for non-SCO/non-ISC-console keyboards.)\n",
  128. X    "If you had to hack this program, mail it in its entirety as well.\n",
  129. X    "\n",
  130. X    "My address: wht@n4hgf.Mt-Park.GA.US or emory!n4hgf!wht\n",
  131. X    (char *)0
  132. X};
  133. X
  134. Xchar *strs_bktab[] = {
  135. X    "You'll have to pick another function key (like F11?).  If you are\n",
  136. X    "using an xterm here perhaps a <Shift>Tab VT100 override will help.\n",
  137. X    (char *)0
  138. X};
  139. X
  140. Xstruct keystruc {
  141. X    char *ecuname;
  142. X    char *peoplename;
  143. X    int count;
  144. X    unsigned char str[VMIN_VALUE + 1];
  145. X};
  146. X
  147. Xstruct keystruc need_names[] = {
  148. X    { "BkTab",    "Back Tab (Shift Tab)" },    /*  0 */
  149. X    { "CU5",    "Unshifted Keypad 5" },        /*  1 */
  150. X    { "F1",        "F1" },                        /*  2 */
  151. X    { "F2",        "F2" },                        /*  3 */
  152. X    { "F3",        "F3" },                        /*  4 */
  153. X    { "F4",        "F4" },                        /*  5 */
  154. X    { "F5",        "F5" },                        /*  6 */
  155. X    { "F6",        "F6" },                        /*  7 */
  156. X    { "F7",        "F7" },                        /*  8 */
  157. X    { "F8",        "F8" },                        /*  9 */
  158. X    { "F9",        "F9" },                        /* 10 */
  159. X    { "F10",    "F10" },                    /* 11 */
  160. X    { "F11",    "F11" },                    /* 12 */
  161. X    { "F12",    "F12" },                    /* 13 */
  162. X    { "Ins",    "Ins" },                    /* 14 */
  163. X#define I_HOME    15
  164. X    { "Home",    "Home" },                    /* 15 */
  165. X#define I_END    16
  166. X    { "End",    "End" },                    /* 16 */
  167. X    { "PgUp",    "PgUp" },                    /* 17 */
  168. X    { "PgDn",    "PgDn" },                    /* 18 */
  169. X    { "CUU",    "Cursor Up" },                /* 19 */
  170. X    { "CUD",    "Cursor Down" },            /* 21 */
  171. X    { "CUL",    "Cursor Left" },            /* 22 */
  172. X    { "CUR",    "Cursor Right" },            /* 23 */
  173. X    {(char *)0,(char *)0}
  174. X};
  175. X
  176. Xchar *parity_text = "<undetermined>";
  177. Xstatic FILE *dumpfp;
  178. X
  179. X/*+-------------------------------------------------------------------------
  180. X    dump_putc(ch)
  181. X--------------------------------------------------------------------------*/
  182. Xvoid
  183. Xdump_putc(ch)
  184. Xchar ch;
  185. X{
  186. X    fputc(ch,dumpfp);
  187. X}    /* end of dump_putc */
  188. X
  189. X
  190. X/*+-------------------------------------------------------------------------
  191. X    dump_puts(str)
  192. X--------------------------------------------------------------------------*/
  193. Xvoid
  194. Xdump_puts(str)
  195. Xchar *str;
  196. X{
  197. X    fputs(str,dumpfp);
  198. X}    /* end of dump_puts */
  199. X
  200. X/*+-----------------------------------------------------------------------
  201. X    hex_dump#... subservient routines
  202. X------------------------------------------------------------------------*/
  203. Xvoid hex_dump4(int4)
  204. Xunsigned char int4;
  205. X{
  206. X    int4 &= 15;
  207. X    dump_putc((int4 >= 10) ? (int4 + 'A' - 10) : (int4 + '0'));
  208. X}
  209. X
  210. Xvoid hex_dump8(int8)
  211. Xunsigned char int8;
  212. X{
  213. X    hex_dump4(int8 >> 4);
  214. X    hex_dump4(int8);
  215. X}
  216. X
  217. Xvoid hex_dump16(int16)
  218. Xunsigned short int16;
  219. X{
  220. X    hex_dump8(int16 >> 8);
  221. X    hex_dump8(int16);
  222. X}
  223. X
  224. Xvoid hex_dump32(int32)
  225. Xunsigned long int32;
  226. X{
  227. X    hex_dump16(int32 >> 16);
  228. X    hex_dump16(int32);
  229. X}
  230. X
  231. X/*+-----------------------------------------------------------------
  232. X    hex_dump_fp(fp,str,len,title,terse_flag)
  233. X
  234. X  if 'title' not NULL, title is printed... 'terse_flag'
  235. X  controls whether or not the title is "conspicuous" with
  236. X  hyphens before and after it making title line >70 chars long
  237. X------------------------------------------------------------------*/
  238. Xvoid
  239. Xhex_dump_fp(fp,str,len,title,terse_flag)
  240. XFILE *fp;
  241. Xchar *str;
  242. Xint len;
  243. Xchar *title;
  244. Xint terse_flag;
  245. X{
  246. Xint istr;
  247. Xregister ipos = 0;
  248. Xregister itmp;
  249. X
  250. X    dumpfp = fp;
  251. X
  252. X    if(title && (istr = strlen(title)))
  253. X    {
  254. X        if(!terse_flag)
  255. X        {
  256. X            ipos = (73 - istr) / 2;
  257. X            itmp = ipos;
  258. X            while(itmp--)
  259. X                dump_putc('-');
  260. X            dump_putc(' ');
  261. X            if(istr & 1)
  262. X                ipos--;
  263. X        }
  264. X        dump_puts(title);
  265. X        if(!terse_flag)
  266. X        {
  267. X            dump_putc(' ');
  268. X            while(ipos--)
  269. X                dump_putc('-');
  270. X        }
  271. X        dump_puts("\n");
  272. X
  273. X    }
  274. X
  275. X    istr = 0;
  276. X    while(istr < len)
  277. X    {
  278. X        hex_dump16(istr);
  279. X        dump_putc(' ');
  280. X        for(itmp = 0; itmp < 16; ++itmp)
  281. X        {
  282. X            ipos = istr + itmp;
  283. X            if(ipos >= len)
  284. X            {
  285. X                if(!terse_flag)
  286. X                    dump_puts("   ");
  287. X                continue;
  288. X            }
  289. X            dump_putc(' ');
  290. X            hex_dump8(str[ipos]);
  291. X        }
  292. X        dump_puts(" | ");
  293. X        for(itmp = 0; itmp < 16; ++itmp)
  294. X        {
  295. X            ipos = istr + itmp;
  296. X            if( (ipos) >= len)
  297. X            {
  298. X                if(!terse_flag)
  299. X                    dump_putc(' ');
  300. X            }
  301. X            else
  302. X            {
  303. X                dump_putc((str[ipos] >= ' ' && str[ipos] < 0x7f)
  304. X                     ? str[ipos] : '.' );
  305. X            }
  306. X        }
  307. X        if(dumpfp == stdout)
  308. X            dump_puts(" |\r\n");
  309. X        else
  310. X            dump_puts(" |\n");
  311. X        istr += 16;
  312. X    }   /* end of while(istr < len) */
  313. X
  314. X}    /* end of hex_dump_fp */
  315. X
  316. X/*+-----------------------------------------------------------------------
  317. X    xtoasc(character) - Make all chars "printable"
  318. X
  319. X  returns pointer to a static string containing printable version
  320. X  of a character.  If control char, printed as "^A", etc.
  321. X  if incl_3char set true, then space + ASCII assignment (e.g. "NUL") is
  322. X  appended to the string for non-printable graphics
  323. X------------------------------------------------------------------------*/
  324. Xchar *
  325. Xxtoasc(ch,incl_3char)
  326. Xregister unsigned char ch;
  327. Xint incl_3char;
  328. X{
  329. Xstatic char gg[8];
  330. Xchar *ascii_ctlstr =
  331. X"nulsohstxetxeotenqackbelbs ht nl vt ff cr so si dledc1dc2dc3dc4naksynetbcanem subescfs gs rs us sp ";
  332. X
  333. X    if(ch == 0x7F)
  334. X        strcpy(gg,"del");
  335. X    else if(ch == 0x9b)
  336. X        strcpy(gg,"csi");
  337. X    else if(ch > 0x7F)
  338. X        sprintf(gg,"0x%02x",(unsigned char)ch);
  339. X    else if(ch > 0x20)
  340. X    {
  341. X        gg[0] = ch;
  342. X        gg[1] = 0;
  343. X    }
  344. X    else
  345. X    {
  346. X        strncpy(gg,ascii_ctlstr + (ch * 3),3);
  347. X        gg[3] = 0;
  348. X    }
  349. X    return(gg);
  350. X}    /* end of xtoasc */
  351. X
  352. X/*+-------------------------------------------------------------------------
  353. X    write_funckeymap_desc(fp,buf,buflen,name)
  354. X--------------------------------------------------------------------------*/
  355. Xvoid
  356. Xwrite_funckeymap_desc(fp,buf,buflen,name)
  357. XFILE *fp;
  358. Xunsigned char *buf;
  359. Xint buflen;
  360. Xchar *name;
  361. X{
  362. Xchar s256[256];
  363. X
  364. X    sprintf(s256,"    %s:%s:",name,name);
  365. X    while(strlen(s256) < (unsigned)20)
  366. X        strcat(s256," ");
  367. X
  368. X    while(buflen--)
  369. X    {
  370. X        strcat(s256,xtoasc(*buf++));
  371. X        if(buflen)
  372. X            strcat(s256," ");
  373. X    }
  374. X    strcat(s256,"\n");
  375. X
  376. X    fputs(s256,fp);
  377. X
  378. X}    /* end of write_funckeymap_desc */
  379. X
  380. X/*+-------------------------------------------------------------------------
  381. X    tputstrs(strs)
  382. X--------------------------------------------------------------------------*/
  383. Xvoid
  384. Xtputstrs(strs)
  385. Xchar **strs;
  386. X{
  387. X    while(*strs)
  388. X        fputs(*strs++,stdout);
  389. X}    /* end of tputstrs */
  390. X
  391. X/*+-----------------------------------------------------------------------
  392. X    k3ttymode(arg) -- control user console (kbd/screen)
  393. X
  394. X  Where arg ==
  395. X    0 restore attributes saved at start of execution
  396. X    1 raw mode 
  397. X
  398. X------------------------------------------------------------------------*/
  399. Xvoid k3ttymode(arg)
  400. Xint arg;
  401. X{
  402. X    if(arg)
  403. X    {
  404. X        (void)ioctl(TTYIN,TCGETA,&tv);
  405. X        tv.c_cflag &= ~(CS8 | PARENB | PARODD);
  406. X        tv.c_cflag |= CS8;
  407. X        tv.c_iflag &= ~(INLCR | ICRNL | IGNCR | IXOFF | IUCLC | ISTRIP);
  408. X        tv.c_lflag &= ~(ICANON | ISIG | ECHO);
  409. X        tv.c_cc[VEOF] = '\01';
  410. X        tv.c_cc[VEOL] = '\0';
  411. X        tv.c_cc[VMIN] = VMIN_VALUE;
  412. X        tv.c_cc[VTIME] = VTIME_VALUE;
  413. X        (void)ioctl(TTYIN,TCSETAW,&tv);
  414. X    }
  415. X    else
  416. X        (void)ioctl(TTYIN,TCSETAW,&tv0);
  417. X}
  418. X
  419. X/*+-------------------------------------------------------------------------
  420. X    read_kbd_string(buf,max)
  421. X--------------------------------------------------------------------------*/
  422. Xint
  423. Xread_kbd_string(buf,maxsize)
  424. Xunsigned char *buf;
  425. Xint maxsize;
  426. X{
  427. X    int count = read(TTYIN,buf,maxsize);
  428. X
  429. X#if 0
  430. X    int itmp;
  431. X    for(itmp = 0; itmp < count; itmp++)
  432. X        buf[itmp] &= 0x7F;
  433. X#endif
  434. X    return(count);
  435. X
  436. X}    /* end of read_kbd_string */
  437. X
  438. X/*+-------------------------------------------------------------------------
  439. X    termio_parity_text(cflag)
  440. X--------------------------------------------------------------------------*/
  441. Xchar *
  442. Xtermio_parity_text(cflag)
  443. Xunsigned short cflag;
  444. X{
  445. X     return((cflag & PARENB) ? ((cflag & PARODD) ? "odd" : "even") : "none");
  446. X}    /* end of termio_parity_text */
  447. X
  448. X/*+-----------------------------------------------------------------------
  449. X    main()
  450. X------------------------------------------------------------------------*/
  451. Xmain(argc,argv)
  452. Xint argc;
  453. Xchar **argv;
  454. X{
  455. Xint itmp;
  456. Xint count;
  457. Xint got_ctrl;
  458. Xint found_dup;
  459. Xint unusable = 0;
  460. Xchar ch;
  461. Xchar *ttype;
  462. Xchar *cptr;
  463. Xstruct keystruc *key = need_names;
  464. Xstruct keystruc *key2;
  465. Xunsigned char instr[VMIN_VALUE + 1];
  466. X#if !defined(sun)
  467. Xchar s128[128];
  468. X#endif
  469. XFILE *fpout;
  470. Xlong now;
  471. Xint errflg = 0;
  472. Xchar *outfile = "kbdtest3.out";
  473. X/* extern char *optarg; */
  474. Xextern int optind;
  475. X
  476. X    setbuf(stdout,NULL);
  477. X    setbuf(stderr,NULL);
  478. X
  479. X    while((itmp = getopt(argc,argv,"")) != -1)
  480. X    {
  481. X        switch(itmp)
  482. X        {
  483. X            case '?':
  484. X                errflg++;
  485. X        }
  486. X    }
  487. X
  488. X    if(optind == (argc - 1))
  489. X        outfile = argv[optind++];
  490. X
  491. X    if(errflg || (optind != argc))
  492. X    {
  493. X        (void)fprintf(stderr,"usage: %s [-hx] [outfile]\n");
  494. X        exit(1);
  495. X    }
  496. X
  497. X    printf("\n\n\necu kbdtest3 revision %s\n",revision);
  498. X    tputstrs(strs_intro);
  499. X    if(!(fpout = fopen(outfile,"a")))
  500. X    {
  501. X        perror(outfile);
  502. X        exit(1);
  503. X    }
  504. X
  505. X    ioctl(TTYIN,TCGETA,&tv0);        /* get original status */
  506. X    parity_text = termio_parity_text(tv0.c_cflag);
  507. X
  508. X    if(!(ttype = getenv("TERM")))
  509. X        ttype = "??";
  510. X    time(&now);
  511. X    fprintf(fpout,"# funckeymap for '%s' under ",ttype);
  512. X#if defined(M_SYSV)
  513. X    fputs("SCO\n",fpout);
  514. X#else
  515. X#if defined(ISC)
  516. X    fputs("ISC\n",fpout);
  517. X#else
  518. X#if defined(sun)
  519. X    fputs("SunOS\n",fpout);
  520. X#else
  521. X    fputs("??? OS\n",fpout);
  522. X#endif /* sun */
  523. X#endif /* ISC */
  524. X#endif /* M_SYSV */
  525. X
  526. X    fprintf(fpout,"# built by kbdtest3 %s %s",revision,ctime(&now));
  527. X    fprintf(fpout,"# keyboard parity required = %s\n",parity_text);
  528. X#if !defined(sun)
  529. X    fprintf(fpout,"# stty -a at kbdtest3 execution time:\n");
  530. X    fclose(fpout);
  531. X    strcpy(s128,"/bin/stty -a | /bin/sed -e 's/^/# /' >> ");
  532. X    strcat(s128,outfile);
  533. X    system(s128);
  534. X    if(!(fpout = fopen(outfile,"a")))
  535. X    {
  536. X        perror(outfile);
  537. X        exit(1);
  538. X    }
  539. X#endif
  540. X    fprintf(fpout,"%s\n",ttype);
  541. X
  542. X    printf("Your keyboard driver parity is set to %s\n",parity_text);
  543. X    printf("press ^D (0x04) to terminate program early\n\n");
  544. X    k3ttymode(1);
  545. X
  546. X    while(key->ecuname)
  547. X    {
  548. X        key->count = -1;
  549. X        printf("%-20.20s: ",key->peoplename);
  550. X        count = read_kbd_string(instr,VMIN_VALUE);
  551. X        if(!count)
  552. X        {
  553. X            printf("whoops ..... zero length read\n");
  554. X            break;
  555. X        }
  556. X        if(!count)
  557. X        {
  558. X            perror("keyboard");
  559. X            break;
  560. X        }
  561. X
  562. X        if(!strcmp(key->ecuname,"BkTab") && (count == 1) &&
  563. X            (instr[0] == 9))
  564. X        {
  565. X            printf("produced the same keystroke sequence as TAB\n");
  566. X            tputstrs(strs_bktab);
  567. X            continue;
  568. X        }
  569. X
  570. X        if((count == 1) && ((instr[0] & 0x7F) == 4))
  571. X        {
  572. X            printf("--abort--\n");
  573. X            fputs("# User aborted entry.\n",fpout);
  574. X            unusable = 2;
  575. X            goto DONE;
  576. X        }
  577. X
  578. X
  579. X        if((count == 1) && (instr[0] == '/'))
  580. X        {
  581. X            printf("--dead key--\n");
  582. X            fprintf(fpout,"# %s: dead key and no reasonable alternate\n",
  583. X                key->ecuname);
  584. X        }
  585. X        else if((count == 1) && (instr[0] == ' '))
  586. X        {
  587. X            printf("--no key--\n");
  588. X            fprintf(fpout,"# %s: no key and no reasonable alternate\n",
  589. X                key->ecuname);
  590. X        }
  591. X        else
  592. X        {
  593. X            for(itmp = 0; itmp < count; itmp++)
  594. X                printf("%02x ",instr[itmp]);
  595. X            fputc(' ',stdout);
  596. X            got_ctrl = 0;
  597. X            for(itmp = 0; itmp < count; itmp++)
  598. X            {
  599. X                ch = instr[itmp] & 0x7F;
  600. X                if((ch < ' ') || (ch > '~'))
  601. X                    ch = '.',got_ctrl = 1;
  602. X                fputc(ch,stdout);
  603. X            }
  604. X            printf("\n");
  605. X
  606. X            key->count = count;
  607. X            memcpy(key->str,instr,sizeof(key->str));
  608. X            write_funckeymap_desc(fpout,(unsigned char *)instr,count,
  609. X                key->ecuname);
  610. X            if(!got_ctrl)
  611. X            {
  612. X                printf("This looks like a printable character string.\n");
  613. X                printf("You might want to reconsider another key.\n");
  614. X                fprintf(fpout,"# the above entry is suspect\n");
  615. X            }
  616. X        }
  617. X
  618. X        key++;
  619. X    }
  620. X    printf("\n");
  621. X
  622. X    /*
  623. X     * check for dup sequences
  624. X     */
  625. X    found_dup = 0;
  626. X    for(key = need_names,key2 = key + 1; ; key2++)
  627. X    {
  628. X        if(!key2->ecuname)
  629. X        {
  630. X            key++;
  631. X            if(!key->ecuname)
  632. X                break;
  633. X            key2 = key + 1;
  634. X            if(!key2->ecuname)
  635. X                break;
  636. X        }
  637. X        if((key->count < 0) || (key2->count < 0) || (key->count != key2->count))
  638. X            continue;
  639. X        if(!memcmp(key->str,key2->str,key->count))
  640. X        {
  641. X            printf("'%s' and '%s' produced the same key sequence\n",
  642. X                key->peoplename,key2->peoplename);
  643. X            found_dup++;
  644. X        }
  645. X    }
  646. X
  647. X    if(found_dup)
  648. X    {
  649. X        fprintf(fpout,
  650. X            "# found %d keystroke sequence duplication(s)\n",found_dup);
  651. X        unusable = 1;
  652. X    }
  653. X
  654. X    if(need_names[I_HOME].count < 0)
  655. X    {
  656. X        cptr = "# No Home key was successfully defined!\n";
  657. X        printf(cptr + 2);
  658. X        fprintf(fpout,cptr);
  659. X        unusable = 1;
  660. X    }
  661. X    if(need_names[I_END].count < 0)
  662. X    {
  663. X        cptr = "# No End key was successfully defined!\n";
  664. X        printf(cptr + 2);
  665. X        fprintf(fpout,cptr);
  666. X        unusable = 1;
  667. X    }
  668. X
  669. XDONE:
  670. X    if(unusable)
  671. X    {
  672. X        printf("\nThis will be unusable.  Please try again.\n");
  673. X        fprintf(fpout,"# above entry is unusable\n");
  674. X    }
  675. X    else
  676. X    {
  677. X        printf("\nRemember to set keyboard parity to \"%s\" ",
  678. X            parity_text);
  679. X        fputs("when using this entry.\n",stdout);
  680. X        tputstrs(strs_thanks);
  681. X    }
  682. X
  683. X    fputs("\n",fpout);
  684. X    fclose(fpout);
  685. X    k3ttymode(0);
  686. X    exit(0);
  687. X
  688. X}    /* end of main */
  689. X/* vi: set tabstop=4 shiftwidth=4: */
  690. SHAR_EOF
  691. echo 'File kbdtest3.c is complete' &&
  692. chmod 0644 kbdtest3.c ||
  693. echo 'restore of kbdtest3.c failed'
  694. Wc_c="`wc -c < 'kbdtest3.c'`"
  695. test 15128 -eq "$Wc_c" ||
  696.     echo 'kbdtest3.c: original size 15128, current size' "$Wc_c"
  697. rm -f _shar_wnt_.tmp
  698. fi
  699. # ============= logevent.c ==============
  700. if test -f 'logevent.c' -a X"$1" != X"-c"; then
  701.     echo 'x - skipping logevent.c (File already exists)'
  702.     rm -f _shar_wnt_.tmp
  703. else
  704. > _shar_wnt_.tmp
  705. echo 'x - extracting logevent.c (Text)'
  706. sed 's/^X//' << 'SHAR_EOF' > 'logevent.c' &&
  707. X/*+-------------------------------------------------------------------------
  708. X    logevent.c - log ecu event
  709. X    wht@n4hgf.Mt-Park.GA.US
  710. X--------------------------------------------------------------------------*/
  711. X/*+:EDITS:*/
  712. X/*:09-10-1992-13:59-wht@n4hgf-ECU release 3.20 */
  713. X/*:08-22-1992-15:39-wht@n4hgf-ECU release 3.20 BETA */
  714. X/*:08-21-1991-02:00-wht@n4hgf-sun does not have xenix locking - fix later */
  715. X/*:08-07-1991-14:23-wht@n4hgf-use static logname */
  716. X/*:07-25-1991-12:58-wht@n4hgf-ECU release 3.10 */
  717. X/*:09-19-1990-19:36-wht@n4hgf-ecu_log_event now gets pid for log from caller */
  718. X/*:08-14-1990-20:40-wht@n4hgf-ecu3.00-flush old edit history */
  719. X
  720. X#include <stdio.h>
  721. X#if defined(USE_LOCKING)
  722. X# include <sys/locking.h>
  723. X#endif
  724. X#ifdef USE_PROTOS
  725. X# include "protos.h"
  726. X#endif
  727. X
  728. X/*+-------------------------------------------------------------------------
  729. X    ecu_log_event(pid,event_note)
  730. X--------------------------------------------------------------------------*/
  731. Xvoid
  732. Xecu_log_event(pid,event_note)
  733. Xint pid;
  734. Xchar *event_note;
  735. X{
  736. Xchar s32[32];
  737. XFILE *ecu_log_fp;
  738. Xstatic char logname[256] = "";
  739. X
  740. X    if(!logname[0])
  741. X    {
  742. X        get_home_dir(logname);
  743. X        strcat(logname,"/.ecu/log");
  744. X    }
  745. X    if(ecu_log_fp = fopen(logname,"a"))
  746. X    {
  747. X#if defined(USE_LOCKING)
  748. X        locking(fileno(ecu_log_fp),LK_LOCK,0L);
  749. X#endif
  750. X        get_tod(2,s32);
  751. X        s32[10] = '-';
  752. X        fputs(s32,ecu_log_fp);
  753. X        fprintf(ecu_log_fp,"-%05d-",pid);
  754. X        fputs(event_note,ecu_log_fp);
  755. X        fputs("\n",ecu_log_fp);
  756. X#if defined(USE_LOCKING)
  757. X        fflush(ecu_log_fp);
  758. X        locking(fileno(ecu_log_fp),LK_UNLCK,0L);
  759. X#endif
  760. X        fclose(ecu_log_fp);
  761. X    }
  762. X}    /* end of ecu_log_event */
  763. X
  764. X/* vi: set tabstop=4 shiftwidth=4: */
  765. X/* end of logevent.c */
  766. SHAR_EOF
  767. chmod 0644 logevent.c ||
  768. echo 'restore of logevent.c failed'
  769. Wc_c="`wc -c < 'logevent.c'`"
  770. test 1647 -eq "$Wc_c" ||
  771.     echo 'logevent.c: original size 1647, current size' "$Wc_c"
  772. rm -f _shar_wnt_.tmp
  773. fi
  774. # ============= lstat.c ==============
  775. if test -f 'lstat.c' -a X"$1" != X"-c"; then
  776.     echo 'x - skipping lstat.c (File already exists)'
  777.     rm -f _shar_wnt_.tmp
  778. else
  779. > _shar_wnt_.tmp
  780. echo 'x - extracting lstat.c (Text)'
  781. sed 's/^X//' << 'SHAR_EOF' > 'lstat.c' &&
  782. X/*+-------------------------------------------------------------------------
  783. X    lstat.c - SCO 3.2v4OS with 3.2v2DS interim hack
  784. X    wht@n4hgf.Mt-Park.GA.US
  785. X
  786. XUsing 3.2v2 DS with 3.2v4 is wrought with troubles, but some
  787. Xain't ready to go the trip yet, so here is a piece of projectile vomitus
  788. X--------------------------------------------------------------------------*/
  789. X/*+:EDITS:*/
  790. X/*:09-10-1992-13:59-wht@n4hgf-ECU release 3.20 */
  791. X/*:09-09-1992-06:05-wht@n4hgf-creation */
  792. X
  793. X#include <sys/types.h>
  794. X#include <sys/stat.h>
  795. X
  796. X#if defined(M_UNIX) && defined(S_IFLNK) && !defined(SCO32v4)
  797. X
  798. X#include <errno.h>
  799. X
  800. X/*+-------------------------------------------------------------------------
  801. X    lstat(path,statptr)
  802. X--------------------------------------------------------------------------*/
  803. Xint
  804. Xlstat(path,statptr)
  805. Xchar *path;
  806. Xstruct stat *statptr;
  807. X{
  808. X    int err = EINVAL;
  809. X    /*
  810. X     * try lstat system call first 
  811. X     * if it fails with EINVAL, we are not on 3.2v4
  812. X     */
  813. X    if(err = syscall(0x5b,path,statptr) && (err == EINVAL))
  814. X        err = stat(path,statptr);
  815. X    return(err);
  816. X
  817. X}    /* end of lstat */
  818. X
  819. X#endif /* if defined(M_UNIX) && defined(S_IFLNK) && !defined(SCO32v4) */
  820. X
  821. X/* vi: set tabstop=4 shiftwidth=4: */
  822. X/* end of lstat.c */
  823. SHAR_EOF
  824. chmod 0644 lstat.c ||
  825. echo 'restore of lstat.c failed'
  826. Wc_c="`wc -c < 'lstat.c'`"
  827. test 1197 -eq "$Wc_c" ||
  828.     echo 'lstat.c: original size 1197, current size' "$Wc_c"
  829. rm -f _shar_wnt_.tmp
  830. fi
  831. # ============= makedirs.c ==============
  832. if test -f 'makedirs.c' -a X"$1" != X"-c"; then
  833.     echo 'x - skipping makedirs.c (File already exists)'
  834.     rm -f _shar_wnt_.tmp
  835. else
  836. > _shar_wnt_.tmp
  837. echo 'x - extracting makedirs.c (Text)'
  838. sed 's/^X//' << 'SHAR_EOF' > 'makedirs.c' &&
  839. X/*+-------------------------------------------------------------------------
  840. X    makedirs.c
  841. X--------------------------------------------------------------------------*/
  842. X/*+:EDITS:*/
  843. X/*:09-10-1992-13:59-wht@n4hgf-ECU release 3.20 */
  844. X/*:08-22-1992-15:39-wht@n4hgf-ECU release 3.20 BETA */
  845. X/*:08-30-1991-00:37-wht@n4hgf2-force umask to 022 for installation */
  846. X/*:08-23-1991-14:38-wht@n4hgf-was not making last subdirectory in list */
  847. X/*:08-09-1991-02:13-root@n4hgf-need smart_fork for XENIX */
  848. X/*:07-25-1991-12:58-wht@n4hgf-ECU release 3.10 */
  849. X/*:07-15-1991-14:24-wht@n4hgf-creation */
  850. X
  851. X#include <stdio.h>
  852. X#include <sys/errno.h>
  853. X#include "ecu_types.h"
  854. X#include "ecu_stat.h"
  855. X
  856. Xextern int errno;
  857. X
  858. X/*+-------------------------------------------------------------------------
  859. X    main(argc,argv)
  860. X--------------------------------------------------------------------------*/
  861. Xmain(argc,argv)
  862. Xint argc;
  863. Xchar **argv;
  864. X{
  865. X    int itmp;
  866. X    int errflg = 0;
  867. X    int dmode = 0755;
  868. X    char *dname;
  869. X    struct stat stat_buf,*st = &stat_buf;
  870. X    char s512[512];
  871. X    extern char *optarg;
  872. X    extern int optind;
  873. X
  874. X    umask(022);
  875. X
  876. X    while((itmp = getopt(argc,argv,"m:")) != -1)
  877. X    {
  878. X        switch(itmp)
  879. X        {
  880. X            case 'm':
  881. X                sscanf(optarg,"%o",&dmode);
  882. X                dmode &= 0777;
  883. X                if(!dmode)
  884. X                    dmode = 0755;
  885. X        }
  886. X    }
  887. X    if(errflg || (optind == argc))
  888. X    {
  889. X        (void)fprintf(stderr,"usage: makedirs [-m mode] dir ...\n");
  890. X        exit(1);
  891. X    }
  892. X
  893. X    for(; optind < argc; optind++)
  894. X    {
  895. X        if(!stat(dname = argv[optind],st))
  896. X        {
  897. X            if((st->st_mode & S_IFMT) != S_IFDIR)
  898. X            {
  899. X                fprintf(stderr,"%s exists and is not a directory\n",dname);
  900. X                exit(1);
  901. X            }
  902. X            chmod(dname,(unsigned short)dmode);
  903. X        }
  904. X        else
  905. X        {
  906. X            strcpy(s512,dname);
  907. X            strcat(s512,"/dummy");
  908. X            errno = ENOENT;        /* fake make_dirs() into always trying */
  909. X            if(!make_dirs(s512,dmode))
  910. X            {
  911. X                perror(dname);
  912. X                exit(1);
  913. X            }
  914. X            else
  915. X                printf("Made directory %s\n",dname);
  916. X        }
  917. X    }
  918. X    exit(0);
  919. X}    /* end of main */
  920. X
  921. X/*+-------------------------------------------------------------------------
  922. X    smart_fork() - needed for mkdirs.c under XENIX
  923. X--------------------------------------------------------------------------*/
  924. X#if defined(M_XENIX)
  925. Xint
  926. Xsmart_fork()
  927. X{
  928. Xregister int count = 5;
  929. Xregister int pid;
  930. X
  931. X    while(count--)
  932. X    {
  933. X        if((pid = fork()) >= 0)
  934. X            return(pid);
  935. X        if(count)
  936. X            nap(40L);
  937. X    }
  938. X    return(-1);
  939. X}    /* end of smart_fork */
  940. X#endif
  941. X
  942. X/* vi: set tabstop=4 shiftwidth=4: */
  943. X/* end of makedirs.c */
  944. SHAR_EOF
  945. chmod 0644 makedirs.c ||
  946. echo 'restore of makedirs.c failed'
  947. Wc_c="`wc -c < 'makedirs.c'`"
  948. test 2371 -eq "$Wc_c" ||
  949.     echo 'makedirs.c: original size 2371, current size' "$Wc_c"
  950. rm -f _shar_wnt_.tmp
  951. fi
  952. # ============= mkdirs.c ==============
  953. if test -f 'mkdirs.c' -a X"$1" != X"-c"; then
  954.     echo 'x - skipping mkdirs.c (File already exists)'
  955.     rm -f _shar_wnt_.tmp
  956. else
  957. > _shar_wnt_.tmp
  958. echo 'x - extracting mkdirs.c (Text)'
  959. sed 's/^X//' << 'SHAR_EOF' > 'mkdirs.c' &&
  960. X/* CHK=0x9A80 */
  961. X/*+-------------------------------------------------------------------------
  962. X    mkdirs.c - make multiple directories
  963. X    wht@n4hgf.Mt-Park.GA.US
  964. X
  965. XXENIX lacks mkdir() so use elegant PD version by John Gilmore
  966. X--------------------------------------------------------------------------*/
  967. X/*+:EDITS:*/
  968. X/*:09-10-1992-13:59-wht@n4hgf-ECU release 3.20 */
  969. X/*:08-22-1992-15:39-wht@n4hgf-ECU release 3.20 BETA */
  970. X/*:08-25-1991-14:21-wht@n4hgf-XENIX code hinges on M_XENIX not !sun&&!isc etc */
  971. X/*:08-09-1991-00:30-wht@n4hgf-no need for sys/wait.h + XENIX doesn't have it */
  972. X/*:08-06-1991-02:37-root@n4hgf-how did compile succeed without signal.h? */
  973. X/*:07-25-1991-12:58-wht@n4hgf-ECU release 3.10 */
  974. X/*:07-15-1991-14:20-wht@n4hgf-creation */
  975. X
  976. X#include <string.h>
  977. X#include <errno.h>
  978. X#include "ecu_types.h"
  979. X#include "ecu_stat.h"
  980. X
  981. Xextern int errno;
  982. Xextern char *sys_errlist[];
  983. Xextern int sys_nerr;
  984. X
  985. X#ifdef M_UNIX
  986. X#undef M_XENIX
  987. X#endif
  988. X
  989. X#if defined(M_XENIX)
  990. X#include <signal.h>
  991. X#endif
  992. X
  993. X/*+-------------------------------------------------------------------------
  994. X    mkdir(dpath,dmode)
  995. X
  996. X Directory-creating routines from Public Domain TAR by John Gilmore
  997. X Make a directory.  Compatible with the mkdir() system call on 4.2BSD.
  998. X--------------------------------------------------------------------------*/
  999. X#if defined(M_XENIX)
  1000. X#define    TERM_SIGNAL(status)        ((status) & 0x7F)
  1001. X#define TERM_COREDUMP(status)    (((status) & 0x80) != 0)
  1002. X#define TERM_VALUE(status)        ((status) >> 8)
  1003. Xmkdir(dpath,dmode)
  1004. Xchar *dpath;
  1005. Xint dmode;
  1006. X{
  1007. X    int cpid,status;
  1008. X    struct stat statbuf;
  1009. X    SIGTYPE (*original_sighdlr)();
  1010. X
  1011. X    if(stat(dpath,&statbuf) == 0)
  1012. X    {
  1013. X        errno = EEXIST;        /* Stat worked,so it already exists */
  1014. X        return(-1);
  1015. X    }
  1016. X
  1017. X    /* If stat fails for a reason other than non-existence,return error */
  1018. X    if(errno != ENOENT)
  1019. X        return(-1);
  1020. X
  1021. X    original_sighdlr = signal(SIGCLD,SIG_DFL);
  1022. X    switch(cpid = smart_fork())
  1023. X    {
  1024. X
  1025. X    case -1:            /* Error in fork() */
  1026. X        return(-1);        /* Errno is set already */
  1027. X
  1028. X    case 0:                /* Child process */
  1029. X        /*
  1030. X         * Cheap hack to set mode of new directory.  Since this
  1031. X         * child process is going away anyway,we zap its umask.
  1032. X         * FIXME,this won't suffice to set SUID,SGID,etc. on this
  1033. X         * directory.  Does anybody care?
  1034. X         */
  1035. X        status = umask(0);    /* Get current umask */
  1036. X        status = umask(status | (0777 & ~dmode)); /* Set for mkdir */
  1037. X        execl("/bin/mkdir","mkdir",dpath,(char *)0);
  1038. X        _exit(-1);        /* Can't exec /bin/mkdir */
  1039. X
  1040. X    default:            /* Parent process */
  1041. X        while((cpid != wait(&status)) && (cpid != -1))
  1042. X            ;    /* Wait for kid to finish */
  1043. X    }
  1044. X
  1045. X    signal(SIGCLD,original_sighdlr);
  1046. X
  1047. X    if(TERM_SIGNAL(status) != 0 || TERM_VALUE(status) != 0)
  1048. X    {
  1049. X        errno = EIO;        /* We don't know why,but */
  1050. X        return(-1);        /* /bin/mkdir failed */
  1051. X    }
  1052. X
  1053. X    return(0);
  1054. X}    /* end of mkdir */
  1055. X#endif
  1056. X
  1057. X/*+-------------------------------------------------------------------------
  1058. X    make_dirs(pathname)
  1059. X
  1060. X  Directory-creating routines from Public Domain TAR by John Gilmore
  1061. X  After a file/link/symlink/dir creation has failed, see if it's because
  1062. X  some required directory was not present, and if so, create all
  1063. X  required dirs.
  1064. X
  1065. X  returns 0 if no directory made, else # levels required to get target
  1066. X--------------------------------------------------------------------------*/
  1067. Xint
  1068. Xmake_dirs(pathname)
  1069. Xregister char *pathname;
  1070. X{
  1071. X    register char *p;            /* Points into path */
  1072. X    int madeone = 0;            /* Did we do anything yet? */
  1073. X    int save_errno = errno;        /* Remember caller's errno */
  1074. X    struct stat fst;
  1075. X
  1076. X    if(errno != ENOENT)
  1077. X        return(0);        /* Not our problem */
  1078. X
  1079. X    for(p = strchr(pathname,'/'); p; p = strchr(p+1,'/'))
  1080. X    {
  1081. X        /* Avoid mkdir of empty string,if leading or double '/' */
  1082. X        if(p == pathname || p[-1] == '/')
  1083. X            continue;
  1084. X        /* Avoid mkdir where last part of path is '.' */
  1085. X        if(p[-1] == '.' && (p == pathname+1 || p[-2] == '/'))
  1086. X            continue;
  1087. X        *p = 0;                /* Truncate the path there */
  1088. X        if(!stat(pathname,&fst))
  1089. X        {
  1090. X            if((fst.st_mode & S_IFMT) == S_IFDIR)
  1091. X            {
  1092. X                *p = '/';
  1093. X                continue;
  1094. X            }
  1095. X#ifdef S_IFLNK
  1096. X            if(((fst.st_mode & S_IFMT) == S_IFLNK) && !lstat(pathname,&fst))
  1097. X            {
  1098. X                if((fst.st_mode & S_IFMT) == S_IFDIR)
  1099. X                {
  1100. X                    *p = '/';
  1101. X                    continue;
  1102. X                }
  1103. X            }
  1104. X#endif /* S_IFLNK */
  1105. X            errno = ENOTDIR;
  1106. X            return(0);
  1107. X        }
  1108. X
  1109. X        if( !mkdir(pathname,0777))
  1110. X        {    /* Try to create it as a dir */
  1111. X            madeone++;        /* Remember if we made one */
  1112. X            *p = '/';
  1113. X            continue;
  1114. X        }
  1115. X        *p = '/';
  1116. X        if(errno == EEXIST)        /* Directory already exists */
  1117. X            continue;
  1118. X        /*
  1119. X         * Some other error in the mkdir.  We return to the caller.
  1120. X         */
  1121. X        break;
  1122. X    }
  1123. X    errno = save_errno;        /* Restore caller's errno */
  1124. X    return(madeone);        /* Tell them to retry if we made one */
  1125. X}    /* end of make_dirs */
  1126. X
  1127. X/* vi: set tabstop=4 shiftwidth=4: */
  1128. X/* end of mkdirs.c */
  1129. SHAR_EOF
  1130. chmod 0644 mkdirs.c ||
  1131. echo 'restore of mkdirs.c failed'
  1132. Wc_c="`wc -c < 'mkdirs.c'`"
  1133. test 4860 -eq "$Wc_c" ||
  1134.     echo 'mkdirs.c: original size 4860, current size' "$Wc_c"
  1135. rm -f _shar_wnt_.tmp
  1136. fi
  1137. # ============= nap.c ==============
  1138. if test -f 'nap.c' -a X"$1" != X"-c"; then
  1139.     echo 'x - skipping nap.c (File already exists)'
  1140.     rm -f _shar_wnt_.tmp
  1141. else
  1142. > _shar_wnt_.tmp
  1143. echo 'x - extracting nap.c (Text)'
  1144. sed 's/^X//' << 'SHAR_EOF' > 'nap.c' &&
  1145. X/* CHK=0x24D1 */
  1146. X/*+-------------------------------------------------------------------------
  1147. X    nap.c - nap() support
  1148. X    wht@n4hgf.Mt-Park.GA.US
  1149. X--------------------------------------------------------------------------*/
  1150. X/*+:EDITS:*/
  1151. X/*:09-10-1992-14:00-wht@n4hgf-ECU release 3.20 */
  1152. X/*:08-22-1992-15:39-wht@n4hgf-ECU release 3.20 BETA */
  1153. X/*:08-10-1992-03:04-wht@n4hgf-add init_Nap */
  1154. X/*:07-17-1992-18:19-wht@n4hgf-creation of common module for all binaries */
  1155. X
  1156. X#include "ecu.h"
  1157. X
  1158. X#undef NULL    /* some stdio and param.h define these differently */
  1159. X#include <sys/param.h>
  1160. X#ifndef NULL        /* fake usual sys/param.h value */
  1161. X#define NULL 0
  1162. X#endif
  1163. X
  1164. Xint hz;                    /* HZ from environ or sys/param.h */
  1165. Xulong hzmsec;            /* clock period in msec rounded up */
  1166. X
  1167. X/*+-------------------------------------------------------------------------
  1168. X    Nap(msec) - wrapper for nap()
  1169. X
  1170. Xearly/most ISC and SCO UNIX nap() misbehave.  This kludge doesn't return the
  1171. Xproper value (the actual time slept), but at least it does not make
  1172. Xa mockery of the manual page.  It says:
  1173. X
  1174. X     NAP(S)               UNIX System V            NAP(S)
  1175. X
  1176. X     Name
  1177. X      nap -    suspends execution for a short interval
  1178. X
  1179. X     Syntax
  1180. X      long nap(period)
  1181. X      long period;
  1182. X
  1183. X     Description
  1184. X      The current process is suspended from    execution for at least
  1185. X      the number of    milliseconds specified by period, or until a
  1186. X      signal is received.
  1187. X
  1188. X     Return Value
  1189. X      On successful    completion, a long integer indicating the
  1190. X      number of milliseconds actually slept    is returned. If    the
  1191. X      process received a signal while napping, the return value
  1192. X      will be -1, and errno    will be    set to EINTR.
  1193. X
  1194. X     See Also
  1195. X      sleep(S)
  1196. X
  1197. X     Notes
  1198. X      This function    is driven by the system    clock, which in    most
  1199. X      cases    has a granularity of tens of milliseconds.  This
  1200. X      function must    be linked with the linker option -lx.
  1201. X
  1202. XIt appears nap() under UNIX 3.2.x has departed virtually entirely from
  1203. Xthe manual page.  I'm beginning to look rather silly in several
  1204. Xmilleus since I keep telling people SCO UNIX is a viable upgrade from
  1205. XXENIX.  But process control people need some kind of timing capability
  1206. Xless than one second and we can't do it with nap or select.
  1207. X
  1208. Xnap(msec) is supposed to nap *at least* msec milliseconds.  However,
  1209. Xif msec is specified less than 1000/HZ + 1, it will not nap at all.
  1210. XThis was true for 3.2.0 and 3.2.1.
  1211. X
  1212. XIt is supposed to return the number of milliseconds it actually
  1213. Xslept.  Instead, it appears to "save up" the values and return them in
  1214. Xlots of 1000. This behavior is true for 3.2.2.
  1215. X
  1216. XAs it is nap() is nearly useless for accurate timing.  I believe
  1217. Xselect() suffers from the same deficiency (< 1000 msec timeout
  1218. Xbecomes 1000 msec) but I haven't "proven" it yet.  [[ It was later
  1219. Xproven for SCO 3.2v2 at least ... see READMEs and *HISTORY ]]
  1220. X
  1221. XOn systems with a working select(), we use a relatively complex select
  1222. Xarrangement to accomplish the nap requirement, but with an improvement.
  1223. XThe "nap" survives any EINTR except for SIGINT (as indicated by sigint
  1224. Xgetting set).  On SIGINT, the nap is aborted.
  1225. X
  1226. XA "working select" means
  1227. X1. the system tries to support it (all but XENIX 286)
  1228. X2. it is in libc.a (all but XENIX; see directory xsel386 to fix XENIX 386)
  1229. X3. it is not broken (XENIX 386 select fails on ttys, but can be
  1230. X      fixed: see xsel386; even an "unfixed" XENIX select would work
  1231. X      here because we are only interested in timeouts)
  1232. X4. it times out properly (SCO UNIX 3.2.[1-2] screws up by ROUNDING
  1233. X      timeouts UP to ONE SECOND).
  1234. X
  1235. Xselect() and nap() works very well on SCO 3.2v4
  1236. X--------------------------------------------------------------------------*/
  1237. Xlong
  1238. XNap(msec)
  1239. Xlong msec;
  1240. X{
  1241. X#if defined(M_XENIX) || defined(SCO32v4) || defined(WORKING_NAP)
  1242. X    return(nap(msec));
  1243. X#else
  1244. X#if defined(WORKING_SELECT)
  1245. X/* precision guard */
  1246. X#define SECDELTA 684300000L    /* sometime in 9/91 */
  1247. X/*
  1248. X * Compute  A -= B for timeval structs A, B (thanks to ping.c)
  1249. X */
  1250. X#ifdef USE_GETTIMEOFDAY
  1251. X
  1252. X#define tvsub(A, B) \
  1253. X    if(1) { \
  1254. X        (A)->tv_sec -= (B)->tv_sec ;\
  1255. X        if (((A)->tv_usec -= (B)->tv_usec) < 0)\
  1256. X            { (A)->tv_sec--; (A)->tv_usec += 1000000; } \
  1257. X    } else /* ; supplied by invocation */
  1258. X
  1259. X    struct timeval timer;
  1260. X    struct timeval start;
  1261. X    struct timeval now;
  1262. X    struct timezone trash;
  1263. X
  1264. X    gettimeofday(&start,&trash);
  1265. X    start.tv_sec -= SECDELTA;
  1266. X    timer.tv_sec = msec / 1000;
  1267. X    timer.tv_usec = (msec % 1000L) * 1000L;
  1268. X    while(((timer.tv_sec * 1000000) + timer.tv_usec) > 0)
  1269. X    {
  1270. X        if(!select(0,0,0,0,&timer))
  1271. X            break;
  1272. X        if(errno != EINTR)
  1273. X            break;
  1274. X        if(sigint)        /* if SIGINT posted, exit now */
  1275. X            return(-1);
  1276. X        gettimeofday(&now,&trash);
  1277. X        now.tv_sec -= SECDELTA;
  1278. X        tvsub(&now,&start);
  1279. X        timer.tv_sec = msec / 1000;
  1280. X        timer.tv_usec = (msec % 1000L) * 1000L;
  1281. X        tvsub(&timer,&now);
  1282. X    }
  1283. X    gettimeofday(&now,&trash);
  1284. X    now.tv_sec -= SECDELTA;
  1285. X    tvsub(&now,&start);
  1286. X    msec = (now.tv_sec * 1000) + (now.tv_usec / 1000);
  1287. X#else
  1288. X
  1289. X#define tbsub(t, t0) \
  1290. X    if(1) { \
  1291. X        register long delta_msec = ((((t)->time * 1000L) + ( t)->millitm) - \
  1292. X                                   (((t0)->time * 1000L) + (t0)->millitm)); \
  1293. X        (t)->time = delta_msec / 1000; \
  1294. X        (t)->millitm = delta_msec % 1000; \
  1295. X    } else /* ; supplied by invoker */
  1296. X
  1297. X    struct timeb timer;
  1298. X    struct timeb start;
  1299. X    struct timeb now;
  1300. X
  1301. X    ftime(&start);
  1302. X    start.time -= SECDELTA;
  1303. X    timer.time = msec / 1000;
  1304. X    timer.millitm = msec % 1000;
  1305. X    while(((timer.time * 1000) + timer.millitm) > 0)
  1306. X    {
  1307. X        struct timeval tval;
  1308. X        tval.tv_sec = timer.time;
  1309. X        tval.tv_usec = timer.millitm * 1000;
  1310. X        if(!select(0,0,0,0,&tval))
  1311. X            break;
  1312. X        if(errno != EINTR)
  1313. X            break;
  1314. X        if(sigint)        /* if SIGINT posted, exit now */
  1315. X            return(-1);
  1316. X        ftime(&now);
  1317. X        now.time -= SECDELTA;
  1318. X        tbsub(&now,&start);
  1319. X        timer.time = msec / 1000;
  1320. X        timer.millitm = msec % 1000;
  1321. X        tbsub(&timer,&now);
  1322. X    }
  1323. X    ftime(&now);
  1324. X    now.time -= SECDELTA;
  1325. X    tbsub(&now,&start);
  1326. X    msec = (now.time * 1000) + now.millitm;
  1327. X#endif /* USE_GETTIMEOFDAY */
  1328. X
  1329. X    return(msec);
  1330. X#else
  1331. X#if defined(M_UNIX) || defined(ISC) 
  1332. X    if(msec < hzmsec)
  1333. X        msec = hzmsec;
  1334. X    if(nap(msec) < 0)
  1335. X        return(-1);
  1336. X    return(msec);
  1337. X#else
  1338. Xporting_attention_needed_here;
  1339. X#endif /* use hacked nap */
  1340. X#endif /* WORKING_SELECT */
  1341. X#endif /* working nap */
  1342. X
  1343. X}    /* end of Nap */
  1344. X
  1345. X
  1346. X/*+-------------------------------------------------------------------------
  1347. X    init_Nap()
  1348. X--------------------------------------------------------------------------*/
  1349. Xvoid
  1350. Xinit_Nap()
  1351. X{
  1352. X
  1353. X    /*
  1354. X     * learn tick rate for various timers
  1355. X     */
  1356. X    if(getenv("HZ"))
  1357. X        hz = (ulong)atoi(getenv("HZ"));
  1358. X    else
  1359. X        hz = HZ;
  1360. X    hzmsec = (ulong)(1000 / hz) + 2;
  1361. X
  1362. X}    /* end of init_Nap */
  1363. X
  1364. X/* vi: set tabstop=4 shiftwidth=4: */
  1365. X/* end of nap.c */
  1366. SHAR_EOF
  1367. chmod 0644 nap.c ||
  1368. echo 'restore of nap.c failed'
  1369. Wc_c="`wc -c < 'nap.c'`"
  1370. test 6533 -eq "$Wc_c" ||
  1371.     echo 'nap.c: original size 6533, current size' "$Wc_c"
  1372. rm -f _shar_wnt_.tmp
  1373. fi
  1374. # ============= patchlevel.h ==============
  1375. if test -f 'patchlevel.h' -a X"$1" != X"-c"; then
  1376.     echo 'x - skipping patchlevel.h (File already exists)'
  1377.     rm -f _shar_wnt_.tmp
  1378. else
  1379. > _shar_wnt_.tmp
  1380. echo 'x - extracting patchlevel.h (Text)'
  1381. sed 's/^X//' << 'SHAR_EOF' > 'patchlevel.h' &&
  1382. X#define PATCHLEVEL 20
  1383. SHAR_EOF
  1384. chmod 0644 patchlevel.h ||
  1385. echo 'restore of patchlevel.h failed'
  1386. Wc_c="`wc -c < 'patchlevel.h'`"
  1387. test 22 -eq "$Wc_c" ||
  1388.     echo 'patchlevel.h: original size 22, current size' "$Wc_c"
  1389. rm -f _shar_wnt_.tmp
  1390. fi
  1391. # ============= pc_scr.h ==============
  1392. if test -f 'pc_scr.h' -a X"$1" != X"-c"; then
  1393.     echo 'x - skipping pc_scr.h (File already exists)'
  1394.     rm -f _shar_wnt_.tmp
  1395. else
  1396. > _shar_wnt_.tmp
  1397. echo 'x - extracting pc_scr.h (Text)'
  1398. sed 's/^X//' << 'SHAR_EOF' > 'pc_scr.h' &&
  1399. X/*+-------------------------------------------------------------------------
  1400. X    pc_scr.h - PC/AT screen definitions
  1401. X    wht@n4hgf.Mt-Park.GA.US
  1402. X--------------------------------------------------------------------------*/
  1403. X/*+:EDITS:*/
  1404. X/*:09-10-1992-14:00-wht@n4hgf-ECU release 3.20 */
  1405. X/*:08-22-1992-15:39-wht@n4hgf-ECU release 3.20 BETA */
  1406. X/*:03-27-1992-16:21-wht@n4hgf-re-include protection for all .h files */
  1407. X/*:07-25-1991-12:58-wht@n4hgf-ECU release 3.10 */
  1408. X/*:12-04-1990-02:48-wht@n4hgf-for nonansi terminals provide either ruling set */
  1409. X/*:08-14-1990-20:40-wht@n4hgf-ecu3.00-flush old edit history */
  1410. X
  1411. X#ifndef _pc_scr_h
  1412. X#define _pc_scr_h
  1413. X
  1414. X/*
  1415. X * AT ROM ruling characters
  1416. X */
  1417. X#define at_TL        0xDA    /* top left single rule */
  1418. X#define at_TR        0xBF    /* top right single rule */
  1419. X#define at_BL        0xC0    /* bottom left single rule */
  1420. X#define at_BR        0xD9    /* bottom right single rule */
  1421. X#define at_LT        0xC3    /* left hand T */
  1422. X#define at_RT        0xB4    /* right hand T */
  1423. X#define at_VR        0xB3    /* vertical rule */
  1424. X#define at_HR        0xC4    /* horizontal rule */
  1425. X/*
  1426. X * non-ANSI equivalents
  1427. X */
  1428. X#define vanilla_TL        '.'
  1429. X#define vanilla_TR        '.'
  1430. X#define vanilla_BL        '`'
  1431. X#define vanilla_BR        '\''
  1432. X#define vanilla_LT        '+'
  1433. X#define vanilla_RT        '+'
  1434. X#define vanilla_VR        '|'
  1435. X#define vanilla_HR        '-'
  1436. X
  1437. Xextern unsigned char sTL;
  1438. Xextern unsigned char sTR;
  1439. Xextern unsigned char sBL;
  1440. Xextern unsigned char sBR;
  1441. Xextern unsigned char sLT;
  1442. Xextern unsigned char sRT;
  1443. Xextern unsigned char sVR;
  1444. Xextern unsigned char sHR;
  1445. X
  1446. X#endif /* _pc_scr_h */
  1447. X
  1448. X/* vi: set tabstop=4 shiftwidth=4: */
  1449. X/* end of pc_scr.h */
  1450. SHAR_EOF
  1451. chmod 0644 pc_scr.h ||
  1452. echo 'restore of pc_scr.h failed'
  1453. Wc_c="`wc -c < 'pc_scr.h'`"
  1454. test 1547 -eq "$Wc_c" ||
  1455.     echo 'pc_scr.h: original size 1547, current size' "$Wc_c"
  1456. rm -f _shar_wnt_.tmp
  1457. fi
  1458. # ============= pcmd.c ==============
  1459. if test -f 'pcmd.c' -a X"$1" != X"-c"; then
  1460.     echo 'x - skipping pcmd.c (File already exists)'
  1461.     rm -f _shar_wnt_.tmp
  1462. else
  1463. > _shar_wnt_.tmp
  1464. echo 'x - extracting pcmd.c (Text)'
  1465. sed 's/^X//' << 'SHAR_EOF' > 'pcmd.c' &&
  1466. X/*+-------------------------------------------------------------------------
  1467. X    pcmd.c - ecu miscellaneous procedure commands
  1468. X    wht@n4hgf.Mt-Park.GA.US
  1469. X
  1470. X  Defined functions:
  1471. X    get_big_endian_16(ptr)
  1472. X    get_big_endian_32(ptr)
  1473. X    pcmd_autorz(param)
  1474. X    pcmd_baud(param)
  1475. X    pcmd_cd(param)
  1476. X    pcmd_clrx(param)
  1477. X    pcmd_dcdwatch(param)
  1478. X    pcmd_dial(param)
  1479. X    pcmd_duplex(param)
  1480. X    pcmd_echo(param)
  1481. X    pcmd_exec(param)
  1482. X    pcmd_exit(param)
  1483. X    pcmd_flush(param)
  1484. X    pcmd_getf(param)
  1485. X    pcmd_hangup(param)
  1486. X    pcmd_hexdump(param)
  1487. X    pcmd_lbreak(param)
  1488. X    pcmd_lgets(param)
  1489. X    pcmd_logevent(param)
  1490. X    pcmd_lookfor(param)
  1491. X    pcmd_nap(param)
  1492. X    pcmd_nice(param)
  1493. X    pcmd_parity(param)
  1494. X    pcmd_popd(param)
  1495. X    pcmd_prompt(param)
  1496. X    pcmd_ptrace(param)
  1497. X    pcmd_pushd(param)
  1498. X    pcmd_putf(param)
  1499. X    pcmd_rname(param)
  1500. X    pcmd_rtscts(param)
  1501. X    pcmd_send(param)
  1502. X    pcmd_set(param)
  1503. X    pcmd_setline(param)
  1504. X    pcmd_system(param)
  1505. X    pcmd_xon(param)
  1506. X
  1507. X--------------------------------------------------------------------------*/
  1508. X/*+:EDITS:*/
  1509. X/*:09-10-1992-14:00-wht@n4hgf-ECU release 3.20 */
  1510. X/*:09-06-1992-13:44-wht@n4hgf-rtscts would not accept a numeric argument */
  1511. X/*:08-22-1992-15:39-wht@n4hgf-ECU release 3.20 BETA */
  1512. X/*:01-12-1992-20:54-wht@n4hgf-add autorz command */
  1513. X/*:12-12-1991-05:27-wht@n4hgf-proctrace of intvar shows char value if 0-255 */
  1514. X/*:11-11-1991-14:38-wht@n4hgf-add pcmd_dcdwatch code */
  1515. X/*:10-09-1991-21:54-wht@n4hgf-add -p and -v switch to send */
  1516. X/*:10-09-1991-20:32-wht@n4hgf-proctrace code for send */
  1517. X/*:09-01-1991-19:10-wht@n4hgf2-baud cmd can set rate even if no line open */
  1518. X/*:09-01-1991-18:10-wht@n4hgf2-add setline */
  1519. X/*:08-25-1991-14:39-wht@n4hgf-SVR4 port thanks to aega84!lh */
  1520. X/*:08-06-1991-21:18-wht@n4hgf-nap -m test wrong sense ... old bug! */
  1521. X/*:08-05-1991-16:22-wht@n4hgf-add nap -1 return and proctrace */
  1522. X/*:07-25-1991-12:58-wht@n4hgf-ECU release 3.10 */
  1523. X/*:07-17-1991-07:04-wht@n4hgf-avoid SCO UNIX nap bug */
  1524. X/*:06-05-1991-22:50-wht@n4hgf-fix parity cmd not taking alpha str */
  1525. X/*:05-21-1991-18:52-wht@n4hgf-add pcmd_pushd and pcmd_popd */
  1526. X/*:03-16-1991-15:12-wht@n4hgf-add pcmd_nice */
  1527. X/*:01-09-1991-22:31-wht@n4hgf-ISC port */
  1528. X/*:12-26-1990-02:34-wht@n4hgf-add cmd_rtscts */
  1529. X/*:12-03-1990-04:59-wht@n4hgf-beef up pcmd_exit */
  1530. X/*:09-19-1990-19:36-wht@n4hgf-ecu_log_event now gets pid for log from caller */
  1531. X/*:08-14-1990-20:40-wht@n4hgf-ecu3.00-flush old edit history */
  1532. X
  1533. X#include "ecu.h"
  1534. X#include "ecuerror.h"
  1535. X#include "termecu.h"
  1536. X#include "ecukey.h"
  1537. X#include "esd.h"
  1538. X#include "var.h"
  1539. X#include "proc.h"
  1540. X
  1541. X#define NAMED_VARIABLE_FLAG 0x1000L
  1542. X
  1543. X#if defined(SVR4)
  1544. X# include <sys/termiox.h>
  1545. Xextern int hx_flag;
  1546. X#endif
  1547. X
  1548. Xextern int rc_ep_has_run;
  1549. Xextern ulong colors_current;
  1550. Xextern char errmsg[];
  1551. Xextern char curr_dir[CURR_DIRSIZ];        /* current working directory */
  1552. X
  1553. X/*+-------------------------------------------------------------------------
  1554. X    pcmd_autorz(param)
  1555. X--------------------------------------------------------------------------*/
  1556. Xint
  1557. Xpcmd_autorz(param)
  1558. XESD *param;
  1559. X{
  1560. Xchar s8[8];
  1561. X
  1562. X    if(get_alpha_zstr(param,s8,sizeof(s8)))
  1563. X        return(eSyntaxError);
  1564. X    if(!strcmp(s8,"on"))
  1565. X        shm->autorz = 1;
  1566. X    else if(!strcmp(s8,"off"))
  1567. X        shm->autorz = 0;
  1568. X    else
  1569. X        return(eSyntaxError);
  1570. X    shm->autorz_pos = 0;
  1571. X    return(0);
  1572. X}    /* end of pcmd_autorz */
  1573. X
  1574. X/*+-------------------------------------------------------------------------
  1575. X    pcmd_baud(param) - set line or default baud rate
  1576. X
  1577. XThe command sets shm->Lbaud whether or not a line is open.
  1578. XIf a line is open, the baud rate is actually set.
  1579. X--------------------------------------------------------------------------*/
  1580. Xint
  1581. Xpcmd_baud(param)
  1582. XESD *param;
  1583. X{
  1584. Xlong new_baud;
  1585. Xint erc;
  1586. X
  1587. X
  1588. X    if(erc = gint(param,&new_baud))
  1589. X        return(erc);
  1590. X    if(!valid_baud_rate((uint)new_baud))
  1591. X    {
  1592. X        pprintf("invalid baud rate: %lu\n",new_baud);
  1593. X        return(eFATAL_ALREADY);
  1594. X    }
  1595. X    shm->Lbaud = (uint)new_baud;
  1596. X    if(shm->Liofd >= 0)
  1597. X        lset_baud_rate(1);
  1598. X    if(proctrace)
  1599. X    {
  1600. X        pprintf("baud rate set to %u\n",shm->Lbaud);
  1601. X    }
  1602. X    return(0);
  1603. X
  1604. X}    /* end of pcmd_baud */
  1605. X
  1606. X/*+-------------------------------------------------------------------------
  1607. X    pcmd_cd(param)
  1608. X--------------------------------------------------------------------------*/
  1609. Xint
  1610. Xpcmd_cd(param)
  1611. XESD *param;
  1612. X{
  1613. Xint erc;
  1614. XESD *tesd = esdalloc(256);
  1615. X
  1616. X    if(!tesd)
  1617. X        return(eNoMemory);
  1618. X    if(erc = gstr(param,tesd,0))
  1619. X        goto RETURN;
  1620. X    if(expand_dirname(tesd->pb,tesd->maxcb))
  1621. X    {
  1622. X        pprintf("%s\n",errmsg);
  1623. X        param->index = param->old_index;
  1624. X        erc = eFATAL_ALREADY;
  1625. X        goto RETURN;
  1626. X    }
  1627. X    if(chdir(tesd->pb) < 0)        /* now change to the new directory */
  1628. X    {
  1629. X        pperror(tesd->pb);        /* print error if we get one */
  1630. X        pputs("\n");
  1631. X        erc = eFATAL_ALREADY;
  1632. X        goto RETURN;
  1633. X    }
  1634. X    get_curr_dir(curr_dir,256);
  1635. X
  1636. XRETURN:
  1637. X    esdfree(tesd);
  1638. X    return(erc);
  1639. X}    /* end of pcmd_cd */
  1640. X
  1641. X/*+-------------------------------------------------------------------------
  1642. X    pcmd_pushd(param)
  1643. X--------------------------------------------------------------------------*/
  1644. Xint
  1645. Xpcmd_pushd(param)
  1646. XESD *param;
  1647. X{
  1648. Xint erc = 0;
  1649. Xint arg_present;
  1650. XESD *tesd = (ESD *)0;
  1651. X
  1652. X    if(arg_present = !!end_of_cmd(param))
  1653. X    {
  1654. X        if(!(tesd = esdalloc(256)))
  1655. X            return(eNoMemory);
  1656. X        if(erc = gstr(param,tesd,0))
  1657. X            goto RETURN;
  1658. X    }
  1659. X
  1660. X    if(!push_directory((arg_present) ? tesd->pb : "",arg_present,1))
  1661. X    {
  1662. X        param->index = param->old_index;
  1663. X        erc = eFATAL_ALREADY;
  1664. X    }
  1665. X
  1666. XRETURN:
  1667. X    if(tesd)
  1668. X        esdfree(tesd);
  1669. X    return(erc);
  1670. X
  1671. X}    /* end of pcmd_pushd */
  1672. X
  1673. X/*+-------------------------------------------------------------------------
  1674. X    pcmd_popd(param)
  1675. X--------------------------------------------------------------------------*/
  1676. Xint
  1677. Xpcmd_popd(param)
  1678. XESD *param;
  1679. X{
  1680. Xint erc = 0;
  1681. Xint arg_present;
  1682. Xchar allstr[8];
  1683. X
  1684. X    allstr[0] = 0;
  1685. X    if(arg_present = !!end_of_cmd(param))
  1686. X    {
  1687. X        if(get_alpha_zstr(param,allstr,sizeof(allstr)))
  1688. X        {
  1689. X            param->index = param->old_index;
  1690. X            return(eSyntaxError);
  1691. X        } 
  1692. X    }
  1693. X
  1694. X    if(!pop_directory(allstr,arg_present,1))
  1695. X    {
  1696. X        param->index = param->old_index;
  1697. X        erc = eFATAL_ALREADY;
  1698. X    }
  1699. X
  1700. X    return(erc);
  1701. X
  1702. X}    /* end of pcmd_popd */
  1703. X
  1704. X/*+-------------------------------------------------------------------------
  1705. X    pcmd_clrx(param)
  1706. X--------------------------------------------------------------------------*/
  1707. X/*ARGSUSED*/
  1708. Xint
  1709. Xpcmd_clrx(param)
  1710. XESD *param;
  1711. X{
  1712. X    if(shm->Liofd < 0)
  1713. X        return(eNoLineAttached);
  1714. X
  1715. X    lclear_xmtr_xoff();
  1716. X    if(proctrace)
  1717. X        pputs("transmitter XOFF cleared\n");
  1718. X    return(0);
  1719. X}    /* end of pcmd_clrx */
  1720. X
  1721. X/*+-------------------------------------------------------------------------
  1722. X    pcmd_dcdwatch(param)
  1723. X--------------------------------------------------------------------------*/
  1724. Xint
  1725. Xpcmd_dcdwatch(param)
  1726. XESD *param;
  1727. X{
  1728. Xint erc;
  1729. Xchar s16[16];
  1730. Xchar *cptr;
  1731. X
  1732. X    if(shm->Liofd < 0)
  1733. X        return(eNoLineAttached);
  1734. X
  1735. X    if(erc = get_alpha_zstr(param,s16,sizeof(s16)))
  1736. X        return(erc);
  1737. X
  1738. X    erc = (ldcdwatch_str(s16)) ? eSyntaxError : 0;
  1739. X    if(!erc && proctrace)
  1740. X    {
  1741. X        pputs("DCD watch set to ");
  1742. X        cptr = "???";
  1743. X        switch(shm->Ldcdwatch)
  1744. X        {
  1745. X            case DCDW_OFF:            cptr = "off"; break;
  1746. X            case DCDW_ON:            cptr = "on"; break;
  1747. X            case DCDW_TERMINATE:    cptr = "TERMINATE"; break;
  1748. X        }
  1749. X        pprintf("%s\n",cptr);
  1750. X    }
  1751. X    return(0);
  1752. X
  1753. X}    /* end of pcmd_dcdwatch */
  1754. X
  1755. X/*+-------------------------------------------------------------------------
  1756. X    pcmd_dial(param) - connect to a remote DTE or to local DCE
  1757. X
  1758. X  sets I0 to 0==connect,
  1759. X             1==failed to connect,
  1760. X             2==interrupted,
  1761. X             3==modem error
  1762. X  sets S0 to modem result code
  1763. X--------------------------------------------------------------------------*/
  1764. Xint
  1765. Xpcmd_dial(param)
  1766. XESD *param;
  1767. X{
  1768. Xint erc;
  1769. XESD *tesd = (ESD *)0;
  1770. X
  1771. X    if(shm->Lconnected)
  1772. X    {
  1773. X        pprintf("Already connected (to %s)\n",shm->Llogical);
  1774. X        return(eFATAL_ALREADY);
  1775. X    }
  1776. X
  1777. X    if(!(tesd = esdalloc(64)))
  1778. X        return(eNoMemory);
  1779. X
  1780. X    if(erc = gstr(param,tesd,0))
  1781. X    {
  1782. X        esdfree(tesd);
  1783. X        return(erc);
  1784. X    }
  1785. X
  1786. X    if((erc = call_logical_telno(tesd->pb)) && (erc == eConnectFailed))
  1787. X        erc = 0;
  1788. X
  1789. X    if(!erc && (shm->Liofd < 0))
  1790. X        erc = eNoLineAttached;
  1791. X
  1792. X    esdfree(tesd);
  1793. X
  1794. X    return(erc);
  1795. X}    /* end of pcmd_dial */
  1796. X
  1797. X/*+-------------------------------------------------------------------------
  1798. X    pcmd_duplex(param)
  1799. X
  1800. Xduplex [f | h]
  1801. Xduplex ['f' | 'h']
  1802. Xduplex <int>  0 == half, non-0 == full
  1803. X--------------------------------------------------------------------------*/
  1804. Xint
  1805. Xpcmd_duplex(param)
  1806. XESD *param;
  1807. X{
  1808. Xint erc;
  1809. Xint new_duplex;
  1810. XESD *tesd;
  1811. X
  1812. X    if(erc = skip_cmd_break(param))
  1813. X        return(erc);
  1814. X    if(!(tesd = esdalloc(64)))
  1815. X        return(eNoMemory);
  1816. X    erc = gstr(param,tesd,0);
  1817. X    new_duplex = to_lower((erc) ? param->pb[param->index] : *tesd->pb);
  1818. X    esdfree(tesd);
  1819. X    erc = 0;
  1820. X
  1821. X    switch(new_duplex)
  1822. X    {
  1823. X        case 'f':
  1824. X            shm->Lfull_duplex = 1;
  1825. X            break;
  1826. X        case 'h':
  1827. X            shm->Lfull_duplex = 0;
  1828. X            break;
  1829. X        default:
  1830. X            erc = eBadParameter;
  1831. X    }
  1832. X    if(proctrace && !erc)
  1833. X        pprintf("duplex set to %s\n",(shm->Lfull_duplex) ? "full" : "half");
  1834. X    return(erc);
  1835. X
  1836. X}    /* end of pcmd_duplex */
  1837. X
  1838. X/*+-------------------------------------------------------------------------
  1839. X    pcmd_echo(param)
  1840. Xecho [-n] <str>
  1841. X--------------------------------------------------------------------------*/
  1842. Xint
  1843. Xpcmd_echo(param)
  1844. XESD *param;
  1845. X{
  1846. Xint erc;
  1847. XESD *tesd;
  1848. Xchar switches[8];
  1849. X
  1850. X    if((tesd = esdalloc(256)) == (ESD *)0)
  1851. X        return(eNoMemory);
  1852. X
  1853. X    get_switches(param,switches,sizeof(switches));
  1854. X
  1855. X    if(erc = gstr(param,tesd,1))
  1856. X    {
  1857. X        esdfree(tesd);
  1858. X        return(erc);
  1859. X    }
  1860. X    pputs(tesd->pb);
  1861. X    if(!strchr(switches,'n'))    /* if no -n */
  1862. X        pputs("\n");
  1863. X    esdfree(tesd);
  1864. X    return(0);
  1865. X
  1866. X}    /* end of pcmd_echo */
  1867. X
  1868. X/*+-------------------------------------------------------------------------
  1869. X    pcmd_exec(param)
  1870. X--------------------------------------------------------------------------*/
  1871. Xint
  1872. Xpcmd_exec(param)
  1873. XESD *param;
  1874. X{
  1875. X    int erc = 0;
  1876. X    ESD *tesd = (ESD *)0;
  1877. X
  1878. X    if(!(tesd = esdalloc(64)))
  1879. X        return(eNoMemory);
  1880. X    if(erc = gstr(param,tesd,1))
  1881. X        goto RETURN;
  1882. X
  1883. X    /* reset indices */
  1884. X    tesd->index = 0;
  1885. X    tesd->old_index = 0;
  1886. X
  1887. X    if(proctrace)
  1888. X        pprintf("executing: <%s>\n",tesd->pb);
  1889. X    if(erc = execute_esd(tesd))
  1890. X    {
  1891. X        esdshow(tesd,"error executing dynamic statement:");
  1892. X        proc_error(erc);
  1893. X        erc = eFATAL_ALREADY;
  1894. X    }
  1895. X
  1896. XRETURN:
  1897. X    if(tesd)
  1898. X        esdfree(tesd);
  1899. X    return(erc);
  1900. X
  1901. X}    /* end of pcmd_exec */
  1902. X
  1903. X/*+-------------------------------------------------------------------------
  1904. X    pcmd_exit(param)
  1905. X--------------------------------------------------------------------------*/
  1906. Xint
  1907. Xpcmd_exit(param)
  1908. XESD *param;
  1909. X{
  1910. Xlong int1;
  1911. Xulong colors_at_entry = colors_current;
  1912. X
  1913. X    if(!gint(param,&int1) && int1)
  1914. X    {
  1915. X        setcolor(colors_error);
  1916. X        pprintf("[procedure terminating ecu: user code %ld]\n",int1);
  1917. X        setcolor(colors_at_entry);
  1918. X        if((int1 += TERMECU_USER1 - 1) > TERMECU_USERN)
  1919. X        {
  1920. X            int1 = TERMECU_USERN;
  1921. X            pprintf("user exit code too large, using %d\r\n",
  1922. X                TERMECU_USERN - TERMECU_USER1);
  1923. X        }
  1924. X        termecu((int)int1);
  1925. X    }
  1926. X    setcolor(colors_success);
  1927. X    pputs("[procedure terminating ecu: normal exit]\n");
  1928. X    setcolor(colors_at_entry);
  1929. X    termecu(0);
  1930. X}    /* end of pcmd_exit */
  1931. X
  1932. X/*+-------------------------------------------------------------------------
  1933. X    pcmd_lgets(param)
  1934. X
  1935. Xlgets [-er] <strvar> <int1> <int2> [<str>]
  1936. X
  1937. Xread string into string variable number <stvar>
  1938. Xwaiting <int1> 1/10th secs for first char,
  1939. Xwaiting <int2> 1/10th secs for subsequent chars,
  1940. Xoptionally terminating read upon detection of <str>
  1941. X-e echos to screen
  1942. X-r completely raw, else strip CRs & NLs from either end of string
  1943. X$i0 receives the length of the read
  1944. X<strvar> receives the string
  1945. X--------------------------------------------------------------------------*/
  1946. Xint
  1947. Xpcmd_lgets(param)
  1948. XESD *param;
  1949. X{
  1950. Xint erc;
  1951. Xlong int2;
  1952. Xlong int3;
  1953. XESD *tesd1 = (ESD *)0;
  1954. XESD *svptr;
  1955. XLRWT lr;
  1956. Xchar switches[8];
  1957. XESD *esdalloc();
  1958. Xchar ctmp;
  1959. X
  1960. X    if(shm->Liofd < 0)
  1961. X        return(eNoLineAttached);
  1962. X
  1963. X    get_switches(param,switches,sizeof(switches));
  1964. X
  1965. X    skip_cmd_char(param,'$');
  1966. X    if(erc = get_cmd_char(param,&ctmp))
  1967. X        return(erc);
  1968. X    if(to_lower(ctmp) != 's')
  1969. X        return(eIllegalVarType);
  1970. X    if(erc = get_svptr(param,&svptr,1))
  1971. X        return(erc);
  1972. X
  1973. X    if(erc = gint(param,&int2))
  1974. X        return(erc);
  1975. X
  1976. X    if(erc = gint(param,&int3))
  1977. X        return(erc);
  1978. X
  1979. X    if((tesd1 = esdalloc(64)) == (ESD *)0)
  1980. X        return(eNoMemory);
  1981. X    if(gstr(param,tesd1,1))    /* optional delimiter */
  1982. X    {
  1983. X        esdfree(tesd1);
  1984. X        tesd1 = (ESD *)0;
  1985. X    }    
  1986. X
  1987. X    esdzero(svptr);
  1988. X
  1989. X    lr.to1 = int2 * 100L;
  1990. X    lr.to2 = int3 * 100L;
  1991. X    /* allow interrupts + raw read per -r */
  1992. X    lr.raw_flag = (strchr(switches,'r')) ? 0x81 : 0x80;
  1993. X    lr.buffer = svptr->pb;
  1994. X    lr.bufsize = svptr->maxcb;
  1995. X    lr.delim = (tesd1) ? tesd1->pb : (char *)0;
  1996. X    lr.echo_flag = (strchr(switches,'e') != (char *)0);
  1997. X    (void)lgets_timeout(&lr);
  1998. X    if(tesd1)
  1999. X        esdfree(tesd1);
  2000. X
  2001. X    svptr->cb = lr.count;
  2002. X    esd_null_terminate(svptr);
  2003. X    iv[0] = (long)lr.count;
  2004. X    if(zero_length_read_detected)
  2005. X    {
  2006. X        zero_length_read_detected = 0;
  2007. X        erc = eProcAttn_DCDloss;
  2008. X    }
  2009. X    if(proctrace)
  2010. X        pprintf("lgets read %d chars\n",lr.count);
  2011. X    return(erc);
  2012. X
  2013. X}    /* end of pcmd_lgets */
  2014. X
  2015. X/*+-------------------------------------------------------------------------
  2016. X    pcmd_flush(param)
  2017. X--------------------------------------------------------------------------*/
  2018. X/*ARGSUSED*/
  2019. Xint
  2020. Xpcmd_flush(param)
  2021. XESD *param;
  2022. X{
  2023. X    if(shm->Liofd < 0)
  2024. X        return(eNoLineAttached);
  2025. X
  2026. X    lflush(2);
  2027. X    if(proctrace)
  2028. X        pputs("line flushed\n");
  2029. X    return(0);
  2030. X}    /* end of pcmd_flush */
  2031. X
  2032. X/*+-------------------------------------------------------------------------
  2033. X    pcmd_hangup(param)
  2034. X--------------------------------------------------------------------------*/
  2035. X/*ARGSUSED*/
  2036. Xint
  2037. Xpcmd_hangup(param)
  2038. XESD *param;
  2039. X{
  2040. X    if(shm->Liofd < 0)
  2041. X    {
  2042. X        if(proctrace)
  2043. X            pputs("no line attached ... hangup ignored\n");
  2044. X        DCE_now_on_hook();
  2045. X        return(0);
  2046. X    }
  2047. X
  2048. X    if(proctrace)
  2049. X        pputs("hanging up ... ");
  2050. X    DCE_hangup();
  2051. X    if(proctrace)
  2052. X        pputs("line on hook\n");
  2053. X    return(0);
  2054. X}    /* end of pcmd_hangup */
  2055. X
  2056. X/*+-------------------------------------------------------------------------
  2057. X    pcmd_hexdump(param)
  2058. X
  2059. Xhexdump [-s] <str>
  2060. Xhexdump -t[s] <str1> <str>
  2061. X<str> buf to dump
  2062. X<str1> title (if -t)
  2063. X-s short (terse) dump
  2064. X--------------------------------------------------------------------------*/
  2065. Xint
  2066. Xpcmd_hexdump(param)
  2067. XESD *param;
  2068. X{
  2069. Xint erc;
  2070. XESD *title = (ESD *)0;
  2071. XESD *buf;
  2072. Xchar switches[8];
  2073. Xextern FILE *plog_fp;
  2074. X
  2075. X    if((buf = esdalloc(256)) == (ESD *)0)
  2076. X        return(eNoMemory);
  2077. X
  2078. X    get_switches(param,switches,sizeof(switches));
  2079. X
  2080. X    if(strchr(switches,'t'))    /* if -t */
  2081. X    {
  2082. X        if((title = esdalloc(256)) == (ESD *)0)
  2083. X        {
  2084. X            erc = eNoMemory;
  2085. X            goto RETURN;
  2086. X        }
  2087. X        if(erc = gstr(param,title,0))
  2088. X            goto RETURN;
  2089. X    }
  2090. X
  2091. X    if(erc = gstr(param,buf,1))
  2092. X        goto RETURN;
  2093. X
  2094. X    hex_dump(buf->pb,buf->cb,(title) ? title->pb : "",
  2095. X        (strchr(switches,'s')) ? 1 : 0);
  2096. X
  2097. X    if(plog_fp)
  2098. X        hex_dump_fp(plog_fp,buf->pb,buf->cb,(title) ? title->pb : "",
  2099. X            (strchr(switches,'s')) ? 1 : 0);
  2100. X
  2101. XRETURN:
  2102. X    esdfree(buf);
  2103. X    if(title)
  2104. X        esdfree(title);
  2105. X    return(erc);
  2106. X
  2107. X}    /* end of pcmd_hexdump */
  2108. X
  2109. X/*+-------------------------------------------------------------------------
  2110. X    pcmd_lbreak(param)
  2111. X--------------------------------------------------------------------------*/
  2112. X/*ARGSUSED*/
  2113. Xint
  2114. Xpcmd_lbreak(param)
  2115. XESD *param;
  2116. X{
  2117. X    if(shm->Liofd < 0)
  2118. X        return(eNoLineAttached);
  2119. X
  2120. X    lbreak();
  2121. X    return(0);
  2122. X}    /* end of pcmd_lbreak */
  2123. X
  2124. X/*+-------------------------------------------------------------------------
  2125. X    pcmd_logevent(param)
  2126. X
  2127. Xlogevent 'cmd'
  2128. X--------------------------------------------------------------------------*/
  2129. Xint
  2130. Xpcmd_logevent(param)
  2131. XESD *param;
  2132. X{
  2133. Xint erc;
  2134. XESD *eventstr;
  2135. Xchar switches[8];
  2136. X
  2137. X    if((eventstr = esdalloc(256)) == (ESD *)0)
  2138. X        return(eNoMemory);
  2139. X
  2140. X    get_switches(param,switches,sizeof(switches));
  2141. X
  2142. X/* a hack */
  2143. X    strcpy(eventstr->pb,"PROC ");
  2144. X    eventstr->pb += 5;
  2145. X    eventstr->maxcb -= 5;
  2146. X
  2147. X    if(erc = gstr(param,eventstr,0))
  2148. X    {
  2149. X        eventstr->pb -= 5;        /* be nice */
  2150. X        eventstr->maxcb += 5;    /* or surely this will haunt us one day */
  2151. X        esdfree(eventstr);
  2152. X        return(erc);
  2153. X    }
  2154. X
  2155. X/* rehack */
  2156. X    eventstr->pb -= 5;
  2157. X    eventstr->maxcb += 5;
  2158. X    eventstr->cb += 5;
  2159. X
  2160. X    ecu_log_event(getpid(),eventstr->pb);
  2161. X    esdfree(eventstr);
  2162. X    return(0);
  2163. X
  2164. X}    /* end of eventstr_logevent */
  2165. X
  2166. X/*+-------------------------------------------------------------------------
  2167. X    pcmd_lookfor(param)
  2168. X
  2169. Xlookfor [-e] [quiet | <str>] [<int>]
  2170. X
  2171. X-e echo to screen while looking
  2172. Xquiet means look for quiet
  2173. X<str> means look for string
  2174. X<int> number 1/10ths secs (default 5.0 second) for timeout
  2175. X
  2176. Xin case of lookfor <str>, $i0 plugged 1 if found, else 0
  2177. X--------------------------------------------------------------------------*/
  2178. Xint
  2179. Xpcmd_lookfor(param)
  2180. XESD *param;
  2181. X{
  2182. Xint erc;
  2183. Xchar switches[8];
  2184. Xchar *cptr = (char *)0;
  2185. XESD *tesd = (ESD *)0;
  2186. Xulong decisecs = 50; /* default wait is 5 seconds */
  2187. Xint echo_flag;
  2188. Xchar s8[8];
  2189. Xlong start_secs;
  2190. X
  2191. X
  2192. X    if(shm->Liofd < 0)
  2193. X        return(eNoLineAttached);
  2194. X
  2195. X    get_switches(param,switches,sizeof(switches));
  2196. X    echo_flag = (strchr(switches,'e') != (char *)0);
  2197. X
  2198. X    if(!get_alpha_zstr(param,s8,sizeof(s8)))
  2199. X    {
  2200. X        if(strcmp(s8,"quiet"))
  2201. X            return(eSyntaxError);
  2202. X    } 
  2203. X    else
  2204. X    {
  2205. X        if((tesd = esdalloc(64)) == (ESD *)0)
  2206. X            return(eNoMemory);
  2207. X        if(erc = gstr(param,tesd,0))
  2208. X            goto RETURN;
  2209. X        if(!tesd->cb)
  2210. X        {
  2211. X            pputs("lookfor null string\n");
  2212. X            erc = eFATAL_ALREADY;
  2213. X            goto RETURN;
  2214. X        }
  2215. X        cptr = tesd->pb;
  2216. X    }
  2217. X
  2218. X    if(erc = gint(param,&decisecs))
  2219. X    {
  2220. X        /* if something there non-integer */
  2221. X        if(!end_of_cmd(param))
  2222. X        {
  2223. X            erc = eSyntaxError;
  2224. X            goto RETURN;
  2225. X        }
  2226. X    }
  2227. X    erc = 0;
  2228. X
  2229. X    if(proctrace)
  2230. X        time(&start_secs);
  2231. X
  2232. X    if(cptr)
  2233. X    {
  2234. X        iv[0] = (long)llookfor(cptr,decisecs * 100L,echo_flag);
  2235. X        if(proctrace)
  2236. X            pprintf("lookfor set $i00 = %ld\n",iv[0]);
  2237. X    }
  2238. X    else
  2239. X        lquiet(decisecs * 100L,echo_flag);
  2240. X
  2241. X    if(proctrace)
  2242. X        pprintf("waited %ld secs\n",time((long *)0) - start_secs);
  2243. X
  2244. XRETURN:
  2245. X    if(tesd)
  2246. X        esdfree(tesd);
  2247. X    if(zero_length_read_detected)
  2248. X    {
  2249. X        zero_length_read_detected = 0;
  2250. X        erc = eProcAttn_DCDloss;
  2251. X    }
  2252. X    return(erc);
  2253. X
  2254. X}    /* end of pcmd_lookfor */
  2255. X
  2256. X/*+-------------------------------------------------------------------------
  2257. X    pcmd_nap(param)
  2258. Xnap [-m] <int>
  2259. X<int> number 1/10ths secs, except if -m, nap <int> milliseconds
  2260. X--------------------------------------------------------------------------*/
  2261. Xint
  2262. Xpcmd_nap(param)
  2263. XESD *param;
  2264. X{
  2265. Xint erc;
  2266. Xchar switches[8];
  2267. Xulong interval;
  2268. X
  2269. X    get_switches(param,switches,sizeof(switches));
  2270. X
  2271. X    if(erc = gint(param,&interval))
  2272. X        return(erc);
  2273. X    if(interval)
  2274. X    {
  2275. X        if(!strchr(switches,'m'))
  2276. X            interval *= 100L;
  2277. X        if(interval < hzmsec)        /* SCO nap bug */
  2278. SHAR_EOF
  2279. true || echo 'restore of pcmd.c failed'
  2280. fi
  2281. echo 'End of ecu320 part 18'
  2282. echo 'File pcmd.c is continued in part 19'
  2283. echo 19 > _shar_seq_.tmp
  2284. exit 0
  2285.  
  2286. exit 0 # Just in case...
  2287.