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

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