home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / misc / volume42 / ecu / part25 < prev    next >
Encoding:
Internet Message Format  |  1994-05-24  |  64.4 KB

  1. From: wht@n4hgf.atl.ga.us (Warren Tucker)
  2. Newsgroups: comp.sources.misc
  3. Subject: v42i123:  ecu - ECU Asynchronous Communications v3.30, Part25/37
  4. Date: 24 May 1994 09:07:33 -0500
  5. Organization: Sterling Software
  6. Sender: kent@sparky.sterling.com
  7. Approved: kent@sparky.sterling.com
  8. Message-ID: <2rt1n5$d4r@sparky.sterling.com>
  9. X-Md4-Signature: b0251f95d9ee1ae243c8efabde6eac2c
  10.  
  11. Submitted-by: wht@n4hgf.atl.ga.us (Warren Tucker)
  12. Posting-number: Volume 42, Issue 123
  13. Archive-name: ecu/part25
  14. Environment: SCO,SCOXENIX,MOTOROLA,HP-UX,LINUX,NetBSD,SUNOS,SYSVR4,SOLARIS2
  15. Supersedes: ecu: Volume 32, Issue 36-75
  16.  
  17. #! /bin/sh
  18. # This is a shell archive.  Remove anything before this line, then feed it
  19. # into a shell via "sh file" or similar.  To overwrite existing files,
  20. # type "sh file -c".
  21. # Contents:  ecu330/ecufork.c ecu330/funckeymap.c
  22. #   ecu330/gendial/dceMPAD.c ecu330/pcmdif.c ecu330/termecu.h
  23. # Wrapped by kent@sparky on Mon May 23 13:40:59 1994
  24. PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin:$PATH ; export PATH
  25. echo If this archive is complete, you will see the following message:
  26. echo '          "shar: End of archive 25 (of 37)."'
  27. if test -f 'ecu330/ecufork.c' -a "${1}" != "-c" ; then 
  28.   echo shar: Will not clobber existing file \"'ecu330/ecufork.c'\"
  29. else
  30.   echo shar: Extracting \"'ecu330/ecufork.c'\" \(14274 characters\)
  31.   sed "s/^X//" >'ecu330/ecufork.c' <<'END_OF_FILE'
  32. X/*+-------------------------------------------------------------------------
  33. X    ecufork.c -- ecu spawning ground
  34. X    wht@n4hgf.atl.ga.us
  35. X
  36. X  Defined functions:
  37. X    exec_cmd(cmdstr)
  38. X    expand_wildcard_list(wild,expcmd)
  39. X    find_executable(progname)
  40. X    is_executable(progname)
  41. X    shell(shellcmd)
  42. X    smart_fork()
  43. X
  44. X  This boy is no longer a boy.  Now he is a man.  He is a small
  45. X  boy, but his heart is big.  His name shall be Little Big Man.
  46. X  -- Chief Lodge Skins
  47. X
  48. X--------------------------------------------------------------------------*/
  49. X/*+:EDITS:*/
  50. X/*:05-04-1994-04:38-wht@n4hgf-ECU release 3.30 */
  51. X/*:01-06-1994-05:52-wht@n4hgf-clean up LINUX port */
  52. X/*:12-12-1993-13:27-wht@n4hgf-differentiate MAX_EXEC_ARG only for i286 */
  53. X/*:11-12-1993-11:00-wht@n4hgf-Linux changes by bob@vancouver.zadall.com */
  54. X/*:09-10-1992-13:58-wht@n4hgf-ECU release 3.20 */
  55. X/*:08-22-1992-15:38-wht@n4hgf-ECU release 3.20 BETA */
  56. X/*:04-29-1992-13:29-wht@n4hgf-ignore SIGQUIT when in executing a child */
  57. X/*:09-25-1991-18:02-wht@n4hgf2-find_executable flunks directories now */
  58. X/*:09-06-1991-04:20-wht@n4hgf2-expand_wildcard_list minor bug */
  59. X/*:08-29-1991-01:56-wht@n4hgf2-use max esd size instead of 5120 */
  60. X/*:07-25-1991-12:55-wht@n4hgf-ECU release 3.10 */
  61. X/*:07-17-1991-07:04-wht@n4hgf-avoid SCO UNIX nap bug */
  62. X/*:09-19-1990-19:36-wht@n4hgf-ecu_log_event now gets pid for log from caller */
  63. X/*:08-14-1990-20:40-wht@n4hgf-ecu3.00-flush old edit history */
  64. X
  65. X#include "ecu.h"
  66. X#include "esd.h"
  67. X#include "ecufork.h"
  68. X
  69. Xextern int last_child_wait_status;
  70. Xextern int last_child_wait_pid;
  71. X
  72. X#ifdef M_I286
  73. X#define MAX_EXEC_ARG 512
  74. X#else
  75. X#define MAX_EXEC_ARG 2048
  76. X#endif /* M_I286 */
  77. X
  78. X#ifdef LINUX
  79. Xchar *expander_shell_path = "/bin/bash";
  80. Xchar *expander_shell = "bash";
  81. X
  82. X#else
  83. Xchar *expander_shell_path = "/bin/csh";
  84. Xchar *expander_shell = "csh";
  85. X
  86. X#endif
  87. X
  88. X/*+-------------------------------------------------------------------------
  89. X    smart_fork()
  90. X--------------------------------------------------------------------------*/
  91. Xint
  92. Xsmart_fork()
  93. X{
  94. X    register int count = 5;
  95. X    register int pid;
  96. X
  97. X    while (count--)
  98. X    {
  99. X        if ((pid = fork()) >= 0)
  100. X            return (pid);
  101. X        if (count)
  102. X            Nap(40L);
  103. X    }
  104. X    return (-1);
  105. X}                             /* end of smart_fork */
  106. X
  107. X/*+-----------------------------------------------------------------------
  108. X    shell(shellcmd)
  109. X
  110. X  param 'shellcmd' is a shell command prefixed with either
  111. X  a '!', '$', '>' character.
  112. X
  113. X  '!' causes the command to run as a normal subshell of a process.
  114. X  '$' causes the communications line to be stdin and stdout
  115. X      for the spawned shell
  116. X  '>' causes spawned shell to receive exactly sames files as ecu
  117. X------------------------------------------------------------------------*/
  118. Xvoid
  119. Xshell(shellcmd)
  120. Xchar *shellcmd;
  121. X{
  122. X    register shellpid;
  123. X    register itmp;
  124. X    register char *cptr;
  125. X
  126. X#if defined(FORK_DEBUG)
  127. X    char s80[80];
  128. X
  129. X#endif
  130. X    int wait_status;
  131. X    int restart_rcvr = need_rcvr_restart();
  132. X    char *getenv();
  133. X
  134. X    kill_rcvr_process(SIGUSR1);    /* stop receiver process gracefully */
  135. X
  136. X    signal(SIGINT, SIG_IGN);
  137. X    signal(SIGQUIT, SIG_IGN);
  138. X    signal(SIGUSR1, SIG_IGN);
  139. X    signal(SIGUSR2, SIG_IGN);
  140. X    signal(SIGCLD, SIG_DFL);
  141. X
  142. X    if ((shellpid = smart_fork()) < 0)
  143. X    {
  144. X        ff(se, "Cannot fork\r\n");
  145. X        if (restart_rcvr)
  146. X            start_rcvr_process(1);
  147. X        xmtr_signals();
  148. X        return;
  149. X    }
  150. X
  151. X#ifdef LINUX
  152. X    endwin();
  153. X#endif
  154. X    ttymode(0);                 /* set canonical tty mode */
  155. X    if (shellpid == 0)         /* we are the spawned (going to call shell) */
  156. X    {
  157. X        if (*shellcmd != '>')/* '>' prefix means leave fd's alone! */
  158. X        {
  159. X
  160. X            /*
  161. X             * Hook-up our "standard output" to either the tty or the line
  162. X             * as appropriate for '!' or '$'
  163. X             */
  164. X            close(TTYOUT);
  165. X            fcntl(((*shellcmd == '$') ? shm->Liofd : TTYERR), F_DUPFD, TTYOUT);
  166. X            if (*shellcmd == '$')
  167. X            {
  168. X                close(TTYIN);
  169. X                fcntl(shm->Liofd, F_DUPFD, TTYIN);
  170. X            }
  171. X            close(shm->Liofd);
  172. X        }
  173. X
  174. X        child_signals();     /* signals for child */
  175. X
  176. X        if (*shellcmd == '!')
  177. X        {
  178. X            if (!(cptr = getenv("SHELL")))
  179. X                cptr = expander_shell_path;
  180. X        }
  181. X        else
  182. X            cptr = "/bin/sh";
  183. X
  184. X        shellcmd++;
  185. X        child_signals();
  186. X        if (!*shellcmd)
  187. X            execl(cptr, cptr, (char *)0);
  188. X        else
  189. X            execl(cptr, cptr, "-c", shellcmd, (char *)0);
  190. X        ff(se, "cannot execute %s\r\n", cptr);    /* should not get here */
  191. X        _exit(255);             /* end of spawned process */
  192. X    }                         /* end of if child process */
  193. X
  194. X#if defined(FORK_DEBUG)
  195. X    sprintf(s80, "DEBUG fork shell pid %d", shellpid);
  196. X    ecu_log_event(getpid(), s80);    /* shell */
  197. X#endif
  198. X
  199. X    while (((itmp = wait(&wait_status)) != shellpid) && (itmp != -1))
  200. X        ;
  201. X    last_child_wait_status = wait_status;
  202. X    last_child_wait_pid = shellpid;
  203. X
  204. X    xmtr_signals();             /* restore standard xmtr signals */
  205. X    ttymode(1);                 /* control tty back to raw mode */
  206. X
  207. X/* any comm program will probably doodle with the line characteristics. */
  208. X/* we want to make sure they are restored to normal */
  209. X    lreset_ksr();             /* restore comm line params */
  210. X
  211. X    if (restart_rcvr)
  212. X        start_rcvr_process(1);
  213. X
  214. X}                             /* end of shell */
  215. X
  216. X/*+-------------------------------------------------------------------------
  217. X    is_executable(progname)
  218. X--------------------------------------------------------------------------*/
  219. Xis_executable(progname)
  220. Xchar *progname;
  221. X{
  222. X    struct stat ss;
  223. X
  224. X    if (stat(progname, &ss) < 0)    /* if cannot stat, flunk */
  225. X        return (0);
  226. X    if ((ss.st_mode & 0111) == 0)    /* if no --x--x--x, flunk */
  227. X        return (0);
  228. X    if ((ss.st_mode & S_IFMT) != S_IFREG)    /* if no --x--x--x, flunk */
  229. X        return (0);
  230. X    return (1);                 /* whew, this OUGHT to work */
  231. X
  232. X}                             /* end of is_executable */
  233. X
  234. X/*+-------------------------------------------------------------------------
  235. X    find_executable(progname)
  236. XPATH=':/usr/wht/bin:/bin:/usr/bin:/usr/wht/bin:/etc/tuckerware' len=56
  237. X--------------------------------------------------------------------------*/
  238. Xchar *
  239. Xfind_executable(progname)
  240. Xchar *progname;
  241. X{
  242. X    register itmp;
  243. X    static char *path_buf = (char *)0;
  244. X
  245. X#define PATHNAME_QUAN 32
  246. X    static char *path_name[PATHNAME_QUAN + 1];
  247. X    static char rtn_path[256];
  248. X    static int path_count = 0;
  249. X    char *cptr;
  250. X    char *getenv();
  251. X
  252. X    if (path_buf == (char *)0)
  253. X    {
  254. X        if ((cptr = getenv("PATH")) == (char *)0)
  255. X            return (cptr);
  256. X        if (!(path_buf = malloc(strlen(cptr) + 1)))
  257. X            return ((char *)0);
  258. X        strcpy(path_buf, cptr);
  259. X        path_name[PATHNAME_QUAN + 1] = (char *)0;
  260. X        cptr = path_buf;
  261. X        for (path_count = 0; path_count < PATHNAME_QUAN; path_count++)
  262. X        {
  263. X            if (*cptr == 0)
  264. X                break;
  265. X            path_name[path_count] = cptr;
  266. X            while ((*cptr != ':') && (*cptr != 0))
  267. X                cptr++;
  268. X            if (*cptr == ':')
  269. X                *cptr++ = 0;
  270. X        }
  271. X    }                         /* end of get and process path env variable */
  272. X
  273. X/* look for executable */
  274. X    for (itmp = 0; itmp < path_count; itmp++)
  275. X    {
  276. X        if (*path_name[itmp] == 0)    /* if null path (./) */
  277. X            strcpy(rtn_path, "./");
  278. X        else
  279. X            sprintf(rtn_path, "%s/", path_name[itmp]);
  280. X        strcat(rtn_path, progname);
  281. X        if (is_executable(rtn_path))
  282. X            return (rtn_path);
  283. X    }
  284. X    return ((char *)0);
  285. X}                             /* end of find_executable */
  286. X
  287. X/*+-------------------------------------------------------------------------
  288. X    exec_cmd(cmdstr) - execute an arbitrary program with arguments
  289. Xkills rcvr process if alive and restarts it when done if was alive
  290. X--------------------------------------------------------------------------*/
  291. Xexec_cmd(cmdstr)
  292. Xchar *cmdstr;
  293. X{
  294. X    char *cmdpath;
  295. X    char *cmdargv[MAX_EXEC_ARG];
  296. X    int itmp;
  297. X    int execpid;
  298. X    int restart_rcvr = need_rcvr_restart();
  299. X    int old_ttymode = get_ttymode();
  300. X    int wait_status = 0;
  301. X    char *strrchr();
  302. X
  303. X#if defined(FORK_DEBUG)
  304. X    char s256[256];
  305. X
  306. X    strcpy(s256, "DEBUG exec ");
  307. X    strncat(s256, cmdstr, sizeof(s256) - 12);
  308. X    s256[sizeof(s256) - 12] = 0;
  309. X    ecu_log_event(getpid(), s256);
  310. X#endif
  311. X
  312. X    build_arg_array(cmdstr, cmdargv, MAX_EXEC_ARG, &itmp);
  313. X    if (itmp == MAX_EXEC_ARG)
  314. X    {
  315. X        ff(se, "Too many arguments to command\r\n");
  316. X        return (-1);
  317. X    }
  318. X    else if (!itmp)
  319. X    {
  320. X        ff(se, "null command\r\n");
  321. X        return (-1);
  322. X    }
  323. X
  324. X    if (*cmdargv[0] == '/')
  325. X    {
  326. X        cmdpath = cmdargv[0];
  327. X        cmdargv[0] = strrchr(cmdargv[0], '/') + 1;
  328. X    }
  329. X    else
  330. X    {
  331. X        if ((cmdpath = find_executable(cmdargv[0])) == (char *)0)
  332. X        {
  333. X            ff(se, "Cannot find %s\r\n", cmdargv[0]);
  334. X            return (-1);
  335. X        }
  336. X    }
  337. X
  338. X    kill_rcvr_process(SIGUSR1);    /* stop receiver process gracefully */
  339. X
  340. X/* this code executed by the father (forking) process */
  341. X/* wait on death of child (morbid in life, but ok here) */
  342. X
  343. X    signal(SIGINT, SIG_IGN);
  344. X    signal(SIGQUIT, SIG_IGN);
  345. X    signal(SIGUSR1, SIG_IGN);
  346. X    signal(SIGUSR2, SIG_IGN);
  347. X    signal(SIGCLD, SIG_DFL);
  348. X
  349. X    if ((execpid = smart_fork()) < 0)
  350. X    {
  351. X        ff(se, "Cannot fork\r\n");
  352. X        if (restart_rcvr)
  353. X            start_rcvr_process(1);
  354. X        xmtr_signals();
  355. X        return (-1);
  356. X    }
  357. X
  358. X    if (execpid == 0)         /* we are the spawned (going to call exec) */
  359. X    {
  360. X        ttymode(0);             /* set canonical tty mode */
  361. X        child_signals();
  362. X        execv(cmdpath, cmdargv);
  363. X        perror(cmdpath);
  364. X        _exit(255);             /* end of spawned process */
  365. X    }                         /* end of if child process */
  366. X
  367. X    wait_status = 0;
  368. X    while (((itmp = wait(&wait_status)) != execpid) && (itmp != -1))
  369. X        ;
  370. X    last_child_wait_status = wait_status;
  371. X    last_child_wait_pid = execpid;
  372. X
  373. X/* resume our normally scheduled program */
  374. X    lreset_ksr();             /* restore comm line params */
  375. X    ttymode(old_ttymode);     /* control tty back to original */
  376. X    if (restart_rcvr)
  377. X        start_rcvr_process(1);
  378. X    xmtr_signals();
  379. X    return (last_child_wait_status);
  380. X
  381. X}                             /* end of exec_cmd */
  382. X
  383. X/*+-------------------------------------------------------------------------
  384. X    expand_wildcard_list(wild,&expcmd)
  385. X
  386. Xcalled with 'foo <wildcardlist>' for command expansion prior to exec()
  387. X         or '<wildcardlist>' to expand a list of files.
  388. X
  389. XIf called with 'foo'-style wild, anything you want to protect from csh
  390. Xglobbing or other interpretation must be properly protected (quoted) --
  391. XAND quoting will be removed one level by the csh.
  392. X
  393. Xif return 0, wild has been expanded, expcmd must be free()'d when done
  394. Xif return -1, error, expcmd has error message (static message: DO NOT FREE)
  395. X--------------------------------------------------------------------------*/
  396. Xexpand_wildcard_list(wild, expcmd)
  397. Xchar *wild;
  398. Xchar **expcmd;
  399. X{
  400. X    register char *cptr;
  401. X
  402. X#define P_READ 0
  403. X#define P_WRITE 1
  404. X    PID_T pipe_pid;
  405. X    int stdout_pipe[2];
  406. X    int stderr_pipe[2];
  407. X    int count;
  408. X    int expcmd_size = 0;
  409. X    int itmp;
  410. X    int wait_status;
  411. X    int restart_rcvr = need_rcvr_restart();
  412. X    FILE *fp_pipe = (FILE *) 0;
  413. X    char *echo_cmd;
  414. X    static char static_s256[256];    /* MUST BE STATIC */
  415. X    static char *pipe_err_msg = "system error: no pipe";
  416. X    static char *mem_err_msg = "system error: no memory";
  417. X
  418. X    if (strchr(wild, '<') || strchr(wild, '>') || strchr(wild, '&'))
  419. X    {
  420. X        *expcmd = "illegal characters: '<', '>' or '&'";
  421. X        return (-1);
  422. X    }
  423. X
  424. X    if (pipe(stdout_pipe) < 0)
  425. X    {
  426. X        *expcmd = pipe_err_msg;
  427. X        return (-1);
  428. X    }
  429. X    if (pipe(stderr_pipe) < 0)
  430. X    {
  431. X        close(stdout_pipe[P_READ]);
  432. X        close(stdout_pipe[P_WRITE]);
  433. X        *expcmd = pipe_err_msg;
  434. X        return (-1);
  435. X    }
  436. X    if (!(echo_cmd = malloc(strlen(wild) + 10)))
  437. X    {
  438. X        close(stdout_pipe[P_READ]);
  439. X        close(stdout_pipe[P_WRITE]);
  440. X        close(stderr_pipe[P_READ]);
  441. X        close(stderr_pipe[P_WRITE]);
  442. X        *expcmd = mem_err_msg;
  443. X        return (-1);
  444. X    }
  445. X
  446. X    strcpy(echo_cmd, "echo ");
  447. X    strcat(echo_cmd, wild);
  448. X
  449. X    kill_rcvr_process(SIGUSR1);    /* stop receiver process gracefully */
  450. X
  451. X    signal(SIGINT, SIG_IGN);
  452. X    signal(SIGQUIT, SIG_IGN);
  453. X    signal(SIGUSR1, SIG_IGN);
  454. X    signal(SIGUSR2, SIG_IGN);
  455. X    signal(SIGCLD, SIG_DFL);
  456. X
  457. X    if ((pipe_pid = smart_fork()) == 0)
  458. X    {
  459. X        int null = open("/dev/null", O_WRONLY, 0);
  460. X
  461. X        close(stdout_pipe[P_READ]);
  462. X        close(TTYOUT);
  463. X        dup(stdout_pipe[P_WRITE]);
  464. X        close(stdout_pipe[P_WRITE]);
  465. X        close(TTYERR);
  466. X        dup(stderr_pipe[P_WRITE]);
  467. X        close(stderr_pipe[P_WRITE]);
  468. X        close(null);
  469. X        child_signals();
  470. X        execl(expander_shell_path, expander_shell, "-e", "-c", echo_cmd, (char *)0);
  471. X        _exit(255);
  472. X    }
  473. X
  474. X#if defined(FORK_DEBUG)
  475. X    sprintf(static_s256, "DEBUG expand pid %d", pipe_pid);
  476. X    ecu_log_event(getpid(), static_s256);    /* expand_wildcard_list */
  477. X#endif
  478. X
  479. X    free(echo_cmd);
  480. X
  481. X    close(stdout_pipe[P_WRITE]);
  482. X    close(stderr_pipe[P_WRITE]);
  483. X    if (pipe_pid == -1)
  484. X    {
  485. X        close(stdout_pipe[P_READ]);
  486. X        close(stderr_pipe[P_READ]);
  487. X        *expcmd = "could not fork";
  488. X        if (restart_rcvr)
  489. X            start_rcvr_process(0);
  490. X        xmtr_signals();
  491. X        return (-1);
  492. X    }
  493. X
  494. X    if (!(*expcmd = malloc(expcmd_size = ESD_MAXSZ)))
  495. X    {
  496. X        close(stdout_pipe[P_READ]);
  497. X        close(stderr_pipe[P_READ]);
  498. X        kill(pipe_pid, SIGKILL);
  499. X        *expcmd = mem_err_msg;
  500. X        if (restart_rcvr)
  501. X            start_rcvr_process(0);
  502. X        xmtr_signals();
  503. X        return (-1);
  504. X    }
  505. X
  506. X    if (!(fp_pipe = fdopen(stdout_pipe[P_READ], "r")) ||
  507. X        ((count = fread(*expcmd, 1, expcmd_size, fp_pipe)) < 0))
  508. X    {
  509. X        free(*expcmd);
  510. X        kill(pipe_pid, SIGKILL);
  511. X        close(stdout_pipe[P_READ]);
  512. X        close(stderr_pipe[P_READ]);
  513. X        *expcmd = "error reading wild list expansion";
  514. X        if (restart_rcvr)
  515. X            start_rcvr_process(0);
  516. X        xmtr_signals();
  517. X        return (-1);
  518. X    }
  519. X
  520. X    /*
  521. X     * make sure stdout is closed
  522. X     */
  523. X    if (fp_pipe)
  524. X        fclose(fp_pipe);
  525. X    close(stdout_pipe[P_READ]);
  526. X
  527. X    /*
  528. X     * place trailing null kill trailing new line
  529. X     */
  530. X    if (count)
  531. X    {
  532. X        cptr = (*expcmd) + count;
  533. X        *cptr-- = 0;
  534. X        if (*cptr == '\n')
  535. X        {
  536. X            *cptr = 0;
  537. X            count--;
  538. X        }
  539. X    }
  540. X
  541. X    /*
  542. X     * if no expansion, read stderr to find out why
  543. X     */
  544. X    if (!count)
  545. X    {
  546. X        free(*expcmd);
  547. X        count = read(stderr_pipe[P_READ], static_s256, sizeof(static_s256) - 1);
  548. X        if (count < 0)
  549. X            strcpy(static_s256, errno_text(errno));
  550. X        else
  551. X            static_s256[count] = 0;
  552. X        if (static_s256[count - 1] == '\n')
  553. X            static_s256[count - 1] = 0;
  554. X        close(stderr_pipe[P_READ]);
  555. X        if (strncmp(static_s256, "echo: ", 6))
  556. X            *expcmd = static_s256;
  557. X        else
  558. X            *expcmd = static_s256 + 6;
  559. X        if (restart_rcvr)
  560. X            start_rcvr_process(0);
  561. X        return (-1);
  562. X    }
  563. X
  564. X    /*
  565. X     * clean up zombie
  566. X     */
  567. X    wait_status = 0;
  568. X    while (((itmp = wait(&wait_status)) != pipe_pid) && (itmp != -1))
  569. X        ;
  570. X
  571. X    xmtr_signals();
  572. X
  573. X    /*
  574. X     * if bad termination status, read stderr
  575. X     */
  576. X    if (wait_status)
  577. X    {
  578. X        free(*expcmd);
  579. X        count = read(stderr_pipe[P_READ], static_s256, sizeof(static_s256) - 1);
  580. X        if (count < 0)
  581. X            strcpy(static_s256, errno_text(errno));
  582. X        else
  583. X            static_s256[count] = 0;
  584. X        if (static_s256[count - 1] == '\n')
  585. X            static_s256[count - 1] = 0;
  586. X        close(stderr_pipe[P_READ]);
  587. X        if (strncmp(static_s256, "echo: ", 6))
  588. X            *expcmd = static_s256;
  589. X        else
  590. X            *expcmd = static_s256 + 6;
  591. X        if (restart_rcvr)
  592. X            start_rcvr_process(0);
  593. X        return (-1);
  594. X    }
  595. X    close(stderr_pipe[P_READ]);
  596. X
  597. X    /*
  598. X     * whew: we have (I think) a file list expansion
  599. X     */
  600. X    if (restart_rcvr)
  601. X        start_rcvr_process(0);
  602. X
  603. X    return (0);
  604. X}                             /* end of expand_wildcard_list */
  605. X
  606. X/* vi: set tabstop=4 shiftwidth=4: */
  607. X/* end of ecufork.c */
  608. END_OF_FILE
  609.   if test 14274 -ne `wc -c <'ecu330/ecufork.c'`; then
  610.     echo shar: \"'ecu330/ecufork.c'\" unpacked with wrong size!
  611.   fi
  612.   # end of 'ecu330/ecufork.c'
  613. fi
  614. if test -f 'ecu330/funckeymap.c' -a "${1}" != "-c" ; then 
  615.   echo shar: Will not clobber existing file \"'ecu330/funckeymap.c'\"
  616. else
  617.   echo shar: Extracting \"'ecu330/funckeymap.c'\" \(14339 characters\)
  618.   sed "s/^X//" >'ecu330/funckeymap.c' <<'END_OF_FILE'
  619. X/* #define NONANSI_DEBUG */
  620. X/*+-----------------------------------------------------------------
  621. X    funckeymap.c - keyboard function key -> ECU internal
  622. X    wht@n4hgf.atl.ga.us
  623. X
  624. X  Defined functions:
  625. X    fkmap_command(argc,argv)
  626. X    funckeymap(buf,buflen)
  627. X    funckeymap_define(bufptr)
  628. X    funckeymap_display(fp)
  629. X    funckeymap_display_single(tkde,fp)
  630. X    funckeymap_init()
  631. X    funckeymap_read(name)
  632. X
  633. X------------------------------------------------------------------*/
  634. X/*+:EDITS:*/
  635. X/*:05-04-1994-04:39-wht@n4hgf-ECU release 3.30 */
  636. X/*:03-27-1993-17:48-wht@n4hgf-SVR4 found mk_char_graphic decl out of scope */
  637. X/*:09-16-1992-13:33-wht@n4hgf-add fkmap -l name */
  638. X/*:09-10-1992-13:59-wht@n4hgf-ECU release 3.20 */
  639. X/*:08-30-1992-23:06-wht@n4hgf-add fkmap_command */
  640. X/*:08-22-1992-15:38-wht@n4hgf-ECU release 3.20 BETA */
  641. X/*:08-28-1991-14:51-wht@n4hgf2-look correctly for funckeymap in ECULIBDIR */
  642. X/*:08-26-1991-05:45-wht@n4hgf2-# got included in key def */
  643. X/*:08-06-1991-13:19-wht@n4hgf-allow any code as first in key sequence */
  644. X/*:08-03-1991-14:44-wht@n4hgf-look for funckeymap in ECULIBDIR too */
  645. X/*:07-25-1991-12:58-wht@n4hgf-ECU release 3.10 */
  646. X/*:03-20-1991-03:06-root@n4hgf-no Metro Link problems here */
  647. X/*:03-20-1991-01:04-root@n4hgf-diagnose Metro Link xterm differences */
  648. X/*:01-10-1991-23:15-wht@n4hgf-string overflow rptd by spooley@compulink.co.uk */
  649. X/*:12-01-1990-12:51-wht@n4hgf-creation, borrowing from and using ecufkey.c */
  650. X
  651. X#include "ecu.h"
  652. X#include "ecuerror.h"
  653. X#include "ecukey.h"
  654. X#include "ecufkey.h"
  655. X#include "ecuxkey.h"
  656. X#include "ecufork.h"
  657. X
  658. Xchar *make_char_graphic();
  659. X
  660. Xextern int tty_not_char_special;
  661. Xextern char *dash_f_funckeytype;
  662. X
  663. XKDE funckeymap_table[KDE_COUNT];
  664. Xchar funckeymap_name[32] = "";
  665. X
  666. X#if defined(NONANSI_DEBUG)
  667. Xstatic FILE *nadbg = (FILE *) 0;
  668. X
  669. X#endif
  670. X
  671. X/*+-------------------------------------------------------------------------
  672. X    funckeymap_init() - initialize function key mapping (recognition)
  673. X--------------------------------------------------------------------------*/
  674. Xvoid
  675. Xfunckeymap_init()
  676. X{
  677. X    register itmp;
  678. X    register KDE *tkde;
  679. X
  680. X    for (itmp = 0; itmp < KDE_COUNT; itmp++)
  681. X    {
  682. X        tkde = &funckeymap_table[itmp];
  683. X        tkde->logical[0] = 0;
  684. X        tkde->count = 0;
  685. X        tkde->ikde = 0;
  686. X    }
  687. X
  688. X    funckeymap_name[0] = 0;
  689. X
  690. X}                             /* end of funckeymap_init */
  691. X
  692. X/*+-------------------------------------------------------------------------
  693. X    funckeymap_define(bufptr) - use funckeymap line to define a mapping
  694. X
  695. X  returns 0 good keydef
  696. X         -1 if syntax error
  697. X--------------------------------------------------------------------------*/
  698. Xint
  699. Xfunckeymap_define(bufptr)
  700. Xregister char *bufptr;
  701. X{
  702. X    register itmp;
  703. X    register token_number = 0;
  704. X    KDE *tkde = (KDE *) 0;
  705. X    int ikde = 0;
  706. X    int octothorpe = 0;
  707. X    char *token;
  708. X    char *arg_token();
  709. X    char *str_token();
  710. X    char *skip_ld_break();
  711. X
  712. X    while (!octothorpe &&
  713. X        (token = (token_number < 2) ? str_token(bufptr, ":")
  714. X            : arg_token(bufptr, " \t")))
  715. X    {
  716. X        bufptr = (char *)0;     /* further calls to arg_token need NULL */
  717. X        token = skip_ld_break(token);
  718. X        strip_trail_break(token);
  719. X
  720. X        switch (token_number)
  721. X        {
  722. X            case 0:         /* first field is key identifier */
  723. X                if ((ikde = kde_name_to_ikde(token)) < 0)
  724. X                {
  725. X                    pprintf("  %s is not a legal key identifier\r\n", token);
  726. X                    return (-1);
  727. X                }
  728. X                tkde = &funckeymap_table[ikde];
  729. X                tkde->logical[0] = 0;
  730. X                tkde->count = 0;
  731. X                tkde->ikde = ikde;
  732. X                break;
  733. X
  734. X            case 1:         /* second field is logical key name */
  735. X                if (*token == '#')
  736. X                    goto MISSING_LABEL;
  737. X                strncpy(tkde->logical, token, sizeof(tkde->logical));
  738. X                tkde->logical[sizeof(tkde->logical) - 1] = 0;
  739. X                break;
  740. X
  741. X            case 2:         /* third field is first token of sequence */
  742. X                if (*token == '#')
  743. X                    goto MISSING_SEQUENCE;
  744. X
  745. X            default:         /* third and subsequent to define key */
  746. X                if (*token == '#')
  747. X                {
  748. X                    octothorpe = 1;
  749. X                    break;
  750. X                }
  751. X                if (tkde->count == sizeof(tkde->str))
  752. X                {
  753. X                    pprintf("  %s: output count too long",
  754. X                        keyset_idstr(ikde));
  755. X                    return (-1);
  756. X                }
  757. X                if ((itmp = ascii_to_hex(token)) < 0)
  758. X                {
  759. X                    pprintf("  %s: '%s' invalid\r\n",
  760. X                        keyset_idstr(ikde), token);
  761. X                    return (-1);
  762. X                }
  763. X                tkde->str[tkde->count] = itmp;
  764. X                tkde->count++;
  765. X                break;
  766. X        }                     /* end of switch(token_number) */
  767. X
  768. X        if (octothorpe)
  769. X            break;
  770. X
  771. X        token_number++;
  772. X
  773. X    }                         /* end while not end of record */
  774. X
  775. X    switch (token_number)
  776. X    {
  777. X        case 0:
  778. X            pprintf("funckeymap_define logic error\n");
  779. X            termecu(TERMECU_LOGIC_ERROR);
  780. X            break;
  781. X
  782. X        case 1:
  783. X          MISSING_LABEL:
  784. X            pprintf("%s: missing key label\r\n", keyset_idstr(ikde));
  785. X            break;
  786. X
  787. X        case 2:
  788. X          MISSING_SEQUENCE:
  789. X            pprintf("%s: missing char sequence\r\n", keyset_idstr(ikde));
  790. X            break;
  791. X        default:
  792. X            /* special init string entry */
  793. X            if (ikde == IKDE_InitStr)
  794. X                fwrite(tkde->str, 1, tkde->count, stderr);
  795. X            else if (tkde->count)
  796. X            {
  797. X                uchar ch = tkde->str[0];
  798. X                extern uchar kbdeof;    /* current input EOF */
  799. X                extern uchar kbdeol2;    /* current secondary input EOL */
  800. X                extern uchar kbdeol;    /* current input EOL */
  801. X                extern uchar kbderase;    /* current input ERASE */
  802. X                extern uchar kbdintr;    /* current input INTR */
  803. X                extern uchar kbdkill;    /* current input KILL */
  804. X                extern uchar kbdquit;    /* current input QUIT */
  805. X
  806. X                if ((ch == kbdeof) || (ch == kbdeol2) ||
  807. X                    (ch == kbdeol) || (ch == kbderase) ||
  808. X                    (ch == kbdintr) || (ch == kbdkill) ||
  809. X                    (ch == kbdquit))
  810. X                {
  811. X                    pprintf(
  812. X                        "%s: 1st char cannot be input control character\r\n",
  813. X                        keyset_idstr(ikde));
  814. X                    break;
  815. X                }
  816. X            }
  817. X            return (0);
  818. X    }
  819. X
  820. X    return (-1);             /* error */
  821. X
  822. X}                             /* end of funckeymap_define */
  823. X
  824. X/*+-------------------------------------------------------------------------
  825. X    funckeymap_read(name) - read key-sequence-to-fkey map from funckeymap
  826. X--------------------------------------------------------------------------*/
  827. Xvoid
  828. Xfunckeymap_read(name)
  829. Xchar *name;
  830. X{
  831. X    register itmp;
  832. X    char buf[128];
  833. X    FILE *fp_keys;
  834. X    int errstat = 0;
  835. X    static char ecukeys_name[128];
  836. X
  837. X#if defined(NONANSI_DEBUG)
  838. X    if (!nadbg)
  839. X    {
  840. X        nadbg = fopen("/tmp/nadbg.log", "w");
  841. X        setbuf(nadbg, NULL);
  842. X    }
  843. X#endif
  844. X
  845. X    funckeymap_init();         /* clear any previous key defns */
  846. X
  847. X    if (!ecukeys_name[0])
  848. X    {
  849. X        get_home_dir(ecukeys_name);
  850. X        strcat(ecukeys_name, "/.ecu/funckeymap");
  851. X    }
  852. X
  853. X    if (!(fp_keys = fopen(ecukeys_name, "r")))
  854. X    {
  855. X        strcpy(ecukeys_name, eculibdir);
  856. X        strcat(ecukeys_name, "/funckeymap");
  857. X        if (!(fp_keys = fopen(ecukeys_name, "r")))
  858. X        {
  859. X            ff(stderr, "'funckeymap' not in ~/.ecu or %s; unable to proceed\r\n",
  860. X                eculibdir);
  861. X            termecu(TERMECU_UNRECOVERABLE);
  862. X        }
  863. X    }
  864. X
  865. X/* find funckeymap name */
  866. X    errstat = 1;
  867. X    while ((itmp = kde_fgets(buf, sizeof(buf), fp_keys)) != KDETYPE_EOF)
  868. X    {
  869. X        if ((itmp == KDETYPE_COMMENT) || (itmp == KDETYPE_ENTRY))
  870. X            continue;
  871. X        if (!strcmp(buf, name))
  872. X        {
  873. X            errstat = 0;     /* indicate success */
  874. X            break;
  875. X        }
  876. X    }
  877. X    if (errstat)
  878. X    {
  879. X        ff(stderr, "terminal type '%s'\r\n", name);
  880. X        ff(stderr, "not found in %s; unable to proceed\r\n", ecukeys_name);
  881. X        termecu(TERMECU_UNRECOVERABLE);
  882. X    }
  883. X
  884. X/* read past any other funckeymap names matching this set */
  885. X    errstat = 1;
  886. X    while ((itmp = kde_fgets(buf, sizeof(buf), fp_keys)) != KDETYPE_EOF)
  887. X    {
  888. X        if (itmp == KDETYPE_ENTRY)
  889. X        {
  890. X            errstat = 0;     /* indicate success */
  891. X            break;
  892. X        }
  893. X    }
  894. X    if (errstat)
  895. X    {
  896. X        ff(stderr,
  897. X            "terminal type '%s' has null entry in %s; unable to proceed\r\n",
  898. X            name, ecukeys_name);
  899. X        termecu(TERMECU_UNRECOVERABLE);
  900. X    }
  901. X
  902. X/* we found the definition ... process it */
  903. X    errstat = 0;
  904. X    itmp = KDETYPE_ENTRY;
  905. X    do
  906. X    {
  907. X        if (itmp == KDETYPE_NAME)
  908. X            break;
  909. X        else if (itmp == KDETYPE_ENTRY)
  910. X        {
  911. X            if (funckeymap_define(buf))
  912. X                errstat = 1;
  913. X        }
  914. X    }
  915. X    while ((itmp = kde_fgets(buf, sizeof(buf), fp_keys)) != KDETYPE_EOF);
  916. X
  917. X/* finish up */
  918. X    strncpy(funckeymap_name, name, sizeof(funckeymap_name));
  919. X    funckeymap_name[sizeof(funckeymap_name) - 1] = 0;
  920. X    fclose(fp_keys);
  921. X
  922. X    if (!funckeymap_table[IKDE_HOME].count)
  923. X    {
  924. X        ff(stderr, "You MUST have a 'Home' key defined\r\n");
  925. X        errstat = 2;
  926. X    }
  927. X    if (!funckeymap_table[IKDE_END].count)
  928. X    {
  929. X        ff(stderr, "You MUST have a 'End' key defined\r\n");
  930. X        errstat = 2;
  931. X    }
  932. X    if ((errstat == 2) || (errstat && tty_not_char_special))
  933. X        termecu(TERMECU_UNRECOVERABLE);
  934. X
  935. X    if (errstat)
  936. X    {
  937. X        ff(stderr,
  938. X            "WARNING: key mapping syntax errors\r\nContinue anyway (y,[n])? ");
  939. X        if ((itmp = ttygetc(0)) == 'Y' || (itmp == 'y'))
  940. X        {
  941. X            ff(stderr, "YES\r\n");
  942. X            return;
  943. X        }
  944. X        ff(stderr, "NO\r\n");
  945. X        termecu(TERMECU_UNRECOVERABLE);
  946. X    }
  947. X
  948. X}                             /* end of funckeymap_read */
  949. X
  950. X/*+-------------------------------------------------------------------------
  951. X    funckeymap(buf,buflen) - map char sequence to ikde code
  952. X
  953. Xreturn XF_ code or XF_not_yet if no match yet, XF_no_way if no match possible
  954. X--------------------------------------------------------------------------*/
  955. Xuchar
  956. Xfunckeymap(buf, buflen)
  957. Xuchar *buf;
  958. Xint buflen;
  959. X{
  960. X    register ikde;
  961. X    register KDE *tkde;
  962. X    int err_rtn = XF_no_way;
  963. X
  964. X    if (!buflen)
  965. X        return (XF_not_yet);
  966. X
  967. X#if defined(NONANSI_DEBUG)
  968. X    if (nadbg)
  969. X        hex_dump_fp(nadbg, buf, -buflen, "mapna", 1);
  970. X#endif
  971. X
  972. X    for (ikde = 0, tkde = funckeymap_table; ikde <= IKDE_lastKey;
  973. X        ikde++, tkde++)
  974. X    {
  975. X#if defined(NONANSI_DEBUG)
  976. X        if (nadbg)
  977. X            fprintf(nadbg, "--> %s ", tkde->logical);
  978. X#endif
  979. X        if ((tkde->count == buflen) && !memcmp(tkde->str, buf, buflen))
  980. X        {
  981. X#if defined(NONANSI_DEBUG)
  982. X            if (nadbg)
  983. X                fprintf(nadbg, "yes\n");
  984. X#endif
  985. X            return (tkde->ikde);
  986. X        }
  987. X#if defined(NONANSI_DEBUG)
  988. X        if (nadbg)
  989. X            fprintf(nadbg, "no\n");
  990. X#endif
  991. X        if ((tkde->count > buflen) &&
  992. X            ((uchar) * (tkde->str + buflen) == *(buf + buflen)))
  993. X        {
  994. X            err_rtn = XF_not_yet;
  995. X        }
  996. X    }
  997. X    return (err_rtn);
  998. X}                             /* end of funckeymap */
  999. X
  1000. X/*+-------------------------------------------------------------------------
  1001. X    funckeymap_display_single(tkde,fp) - display single mapping on FILE fp
  1002. X--------------------------------------------------------------------------*/
  1003. Xvoid
  1004. Xfunckeymap_display_single(ikde, fp)
  1005. Xint ikde;
  1006. XFILE *fp;
  1007. X{
  1008. X    int keys_left;
  1009. X    char *keys;
  1010. X    char s64[64];
  1011. X    KDE *tkde;
  1012. X
  1013. X    if ((unsigned)ikde > IKDE_lastKey)
  1014. X        return;
  1015. X
  1016. X    tkde = &funckeymap_table[ikde];
  1017. X    sprintf(s64, " %s:%s:                   ",
  1018. X        keyset_idstr(ikde), tkde->logical);
  1019. X    s64[16] = 0;
  1020. X    if (fp == stderr)
  1021. X        pputs(s64);
  1022. X    else
  1023. X        fputs(s64, fp);
  1024. X    keys_left = tkde->count;
  1025. X    keys = tkde->str;
  1026. X    while (keys_left--)
  1027. X    {
  1028. X        if (fp == stderr)
  1029. X        {
  1030. X            pprintf("%s%s",
  1031. X                make_char_graphic(*keys++, 0),
  1032. X                (keys_left) ? " " : "");
  1033. X        }
  1034. X        else
  1035. X        {
  1036. X            fprintf(fp, "%s%s",
  1037. X                make_char_graphic(*keys++, 0),
  1038. X                (keys_left) ? " " : "");
  1039. X        }
  1040. X    }
  1041. X    if (fp == stderr)
  1042. X        pputs("\n");
  1043. X    else
  1044. X        fputs("\n", fp);
  1045. X
  1046. X}                             /* end of funckeymap_display_single */
  1047. X
  1048. X/*+-------------------------------------------------------------------------
  1049. X    funckeymap_display(fp) - display function key table of FILE fp
  1050. X--------------------------------------------------------------------------*/
  1051. Xvoid
  1052. Xfunckeymap_display(fp)
  1053. XFILE *fp;
  1054. X{
  1055. X    int ikde;
  1056. X    char *ftype = 0;
  1057. X
  1058. X    if (dash_f_funckeytype)
  1059. X        ftype = dash_f_funckeytype;
  1060. X    else
  1061. X        ftype = getenv("ECUFUNCKEY");
  1062. X
  1063. X    if (ttype && ftype)
  1064. X    {
  1065. X        fprintf(fp, "#$TERM=%s -F/$ECUFUNCKEY=%s", ftype, ttype);
  1066. X        if (fp == stderr)
  1067. X            fputs("\r\n", fp);
  1068. X        else
  1069. X            fputs("\n", fp);
  1070. X    }
  1071. X
  1072. X    if (ttype || ftype)
  1073. X    {
  1074. X        fputs((ftype) ? ftype : ttype, fp);
  1075. X        if (fp == stderr)
  1076. X            fputs("\r\n", fp);
  1077. X        else
  1078. X            fputs("\n", fp);
  1079. X    }
  1080. X
  1081. X    for (ikde = 0; ikde <= IKDE_lastKey; ikde++)
  1082. X        funckeymap_display_single(ikde, fp);
  1083. X
  1084. X}                             /* end of funckeymap_display */
  1085. X
  1086. X/*+-------------------------------------------------------------------------
  1087. X    fkmap_command(argc,argv) - common interactive and procedure 'fkmap' cmd
  1088. X
  1089. Xreturn procedure error codes
  1090. X--------------------------------------------------------------------------*/
  1091. Xint
  1092. Xfkmap_command(argc, argv)
  1093. Xint argc;
  1094. Xchar **argv;
  1095. X{
  1096. X    register itmp;
  1097. X    int err = 0;
  1098. X    char *ftype = 0;
  1099. X    int iargv = 1;
  1100. X    char *arg;
  1101. X    char fkcmd[512 + 1];
  1102. X    char *fkcptr = fkcmd;
  1103. X    int fkclen = 0;
  1104. X    int ikde;
  1105. X    KDE save;
  1106. X    FILE *fp;
  1107. X
  1108. X    while ((iargv < argc) && (*(arg = argv[iargv]) == '-'))
  1109. X    {
  1110. X        switch (*++arg)
  1111. X        {
  1112. X            case 'r':         /* reset */
  1113. X                if (err)
  1114. X                    break;
  1115. X                if (iargv != (argc - 1))
  1116. X                {
  1117. X                    pputs("no arguments allowed for -r\n");
  1118. X                    err = 1;
  1119. X                    break;
  1120. X                }
  1121. X                if (dash_f_funckeytype)
  1122. X                    ftype = dash_f_funckeytype;
  1123. X                else
  1124. X                    ftype = getenv("ECUFUNCKEY");
  1125. X                if (ttype || ftype)
  1126. X                    funckeymap_read((ftype) ? ftype : ttype);
  1127. X                if (!proc_level || proc_trace)
  1128. X                    pputs("funckeymap reset to startup configuration\n");
  1129. X                return (0);
  1130. X
  1131. X            case 's':         /* save in file */
  1132. X                if (err)
  1133. X                    break;
  1134. X                if (iargv != (argc - 2))
  1135. X                {
  1136. X                    pputs("exactly one argument required for -s\n");
  1137. X                    err = 1;
  1138. X                    break;
  1139. X                }
  1140. X                iargv++;
  1141. X                if (!(fp = fopen(argv[iargv], "a")))
  1142. X                {
  1143. X                    pperror(argv[iargv]);
  1144. X                    return (eFATAL_ALREADY);
  1145. X                }
  1146. X                funckeymap_display(fp);
  1147. X                fclose(fp);
  1148. X                if (!proc_level || proc_trace)
  1149. X                    pprintf("current mapping saved in %s\n", argv[iargv]);
  1150. X                return (0);
  1151. X
  1152. X            case 'l':         /* load entire */
  1153. X                if (err)
  1154. X                    break;
  1155. X                if (iargv != (argc - 2))
  1156. X                {
  1157. X                    pputs("exactly one argument required for -l\n");
  1158. X                    err = 1;
  1159. X                    break;
  1160. X                }
  1161. X                iargv++;
  1162. X                funckeymap_read(argv[iargv]);
  1163. X                return (0);
  1164. X
  1165. X            default:
  1166. X                pprintf("unknown switch -%c\n", *arg);
  1167. X                err = 1;
  1168. X        }
  1169. X        iargv++;
  1170. X    }
  1171. X
  1172. X    if (err)
  1173. X    {
  1174. X        fkmap_cmd_usage();
  1175. X        return (eFATAL_ALREADY);
  1176. X    }
  1177. X
  1178. X    if (iargv == argc)
  1179. X    {
  1180. X        funckeymap_display(stderr);
  1181. X        return (0);
  1182. X    }
  1183. X
  1184. X    arg = argv[iargv++];
  1185. X    if ((ikde = kde_name_to_ikde(arg)) < 0)
  1186. X    {
  1187. X        pprintf("key name '%s' not recognized\n", arg);
  1188. X        return (eFATAL_ALREADY);
  1189. X    }
  1190. X    sprintf(fkcptr, " %s:%s: ", keyset_idstr(ikde), keyset_idstr(ikde));
  1191. X    fkcptr += (itmp = strlen(fkcptr));
  1192. X    fkclen += itmp;
  1193. X
  1194. X    if (iargv == argc)
  1195. X    {
  1196. X        funckeymap_display_single(&funckeymap_table[ikde], stderr);
  1197. X        return (0);
  1198. X    }
  1199. X
  1200. X    while (iargv < argc)
  1201. X    {
  1202. X        arg = argv[iargv++];
  1203. X        itmp = strlen(arg);
  1204. X        if ((fkclen + itmp + 2) > sizeof(fkcmd))
  1205. X        {
  1206. X            pprintf("fkmap command may be no longer than %d characters\n",
  1207. X                sizeof(fkcmd) - 1);
  1208. X            return (eFATAL_ALREADY);
  1209. X        }
  1210. X        strcpy(fkcptr, arg);
  1211. X        fkcptr += itmp;
  1212. X        fkclen += itmp;
  1213. X        if (iargv != argc)
  1214. X        {
  1215. X            *fkcptr++ = ' ';
  1216. X            *fkcptr = 0;
  1217. X            fkclen++;
  1218. X        }
  1219. X    }
  1220. X
  1221. X    save = funckeymap_table[ikde];
  1222. X    if (err = funckeymap_define(fkcmd))
  1223. X        funckeymap_table[ikde] = save;
  1224. X
  1225. X    if (!err && (!proc_level || proc_trace))
  1226. X        funckeymap_display_single(ikde, stderr);
  1227. X
  1228. X    return ((err) ? eFATAL_ALREADY : 0);
  1229. X
  1230. X}                             /* end of fkmap_command */
  1231. X
  1232. X/* end of funckeymap.c */
  1233. X/* vi: set tabstop=4 shiftwidth=4: */
  1234. END_OF_FILE
  1235.   if test 14339 -ne `wc -c <'ecu330/funckeymap.c'`; then
  1236.     echo shar: \"'ecu330/funckeymap.c'\" unpacked with wrong size!
  1237.   fi
  1238.   # end of 'ecu330/funckeymap.c'
  1239. fi
  1240. if test -f 'ecu330/gendial/dceMPAD.c' -a "${1}" != "-c" ; then 
  1241.   echo shar: Will not clobber existing file \"'ecu330/gendial/dceMPAD.c'\"
  1242. else
  1243.   echo shar: Extracting \"'ecu330/gendial/dceMPAD.c'\" \(14780 characters\)
  1244.   sed "s/^X//" >'ecu330/gendial/dceMPAD.c' <<'END_OF_FILE'
  1245. X/* CHK=0xFF53 */
  1246. X/*+-------------------------------------------------------------------------
  1247. X    dceMPAD.c - DCE-specific portion of generic SCO UUCP dialer
  1248. X    Driver for ATT Tridom MPAD VSAT modem emulation
  1249. X    wht@n4hgf.atl.ga.us
  1250. X--------------------------------------------------------------------------*/
  1251. X/*+:EDITS:*/
  1252. X/*:05-04-1994-04:39-wht@n4hgf-ECU release 3.30 */
  1253. X/*:09-10-1992-13:59-wht@n4hgf-ECU release 3.20 */
  1254. X/*:08-22-1992-15:38-wht@n4hgf-ECU release 3.20 BETA */
  1255. X/*:02-02-1992-18:01-root@n4hgf-proper ordering of DCE_result entries */
  1256. X/*:01-26-1992-15:30-wht@n4hgf-gendial 1.2 for ecu 3.20- better hangup */
  1257. X/*:07-25-1991-12:58-wht@n4hgf-ECU release 3.10 */
  1258. X/*:03-12-1991-19:11-wht@n4hgf-if ecu dialing, show complete call progress */
  1259. X/*:11-29-1990-18:31-r@n4hgf-revision/1st releasable */
  1260. X/*:11-29-1990-17:48-wht@n4hgf-creation */
  1261. X
  1262. X#include "dialer.h"
  1263. X
  1264. X/*
  1265. X * DCE_DTR_low_msec - milliseconds to hold DTR low to ensure DCE
  1266. X *                    sees the transition; this value may be changed
  1267. X *                    as necessary before each call to lflash_DTR(),
  1268. X * but, generally, a constant value will do.
  1269. X */
  1270. Xlong DCE_DTR_low_msec = 50;
  1271. X
  1272. X/*
  1273. X * DCE_DTR_high_msec - milliseconds DTR must remain high before the
  1274. X *                     DCE may be expected to be ready to be commanded
  1275. X */
  1276. Xlong DCE_DTR_high_msec = 50;
  1277. X
  1278. X/*
  1279. X * DCE_write_pace_msec - milliseconds to pause between each character
  1280. X *                       sent to the DCE (zero if streaming I/O is
  1281. X *                       permitted); this value may be changed as
  1282. X * necessary before each call to lwrite(), but, generally, a constant
  1283. X * value will do.  Note that this value is used to feed a value to Nap(),
  1284. X * which has a granularity of .010 seconds on UNIX/386, .020 on XENIX/286
  1285. X * and .050 seconds on XENIX/86.
  1286. X */
  1287. Xlong DCE_write_pace_msec = 0;
  1288. X
  1289. X/*
  1290. X * DCE_name     - short name for DCE
  1291. X * DCE_revision - revision number for this module
  1292. X */
  1293. Xchar *DCE_name = "ATT Tridom MPAD";
  1294. Xchar *DCE_revision = "1.37";
  1295. X
  1296. X/*
  1297. X * DCE_hangup_CBAUD - baud rate to use for hanging up DCE
  1298. X *                    and readying it for dial in access
  1299. X *                    (BXXX mask); use a value of zero if the speed
  1300. X *                    specified by the invoker is to be used.
  1301. X * This value is useful for DCEs such as the early Hayes 2400
  1302. X * which are so unfortunately compatible with their 1200 predecessor
  1303. X * that they refuse to answer at 2400 baud unless you last spoke to
  1304. X * them at that rate. For such bad boys, use B2400 below.
  1305. X */
  1306. Xint DCE_hangup_CBAUD = 0;
  1307. X
  1308. X/* int DCE_hangup_CBAUD = B2400; */
  1309. X
  1310. X/*
  1311. X * DCE_results - a table of DCE response strings and a token
  1312. X *               code for each; when you call lread() or lread_ignore(),
  1313. X *               if the read routine detects one of the strings,
  1314. X * the appropriate code is returned.  If no string matches, then
  1315. X * lread()/lread_ignore examines the DCE result string for a
  1316. X * numeric value; if one is found, the numeric value or'd with
  1317. X * 0x40000000 is returned (in this way, e.g., you can read "modem
  1318. X * S registers").  If nothing agrees with this search, lread()
  1319. X * will abort the program with RC|FAIL|RCE_TIMOUT, lread_ignore()
  1320. X * will return -1.  You may use any value between 0 and 0x3FFFFFFF.
  1321. X * This module is the only consumer  of the codes, although they
  1322. X * are decoded by gendial.c's _lread().
  1323. X *
  1324. X * If one possible result is an "early substring" of another, like
  1325. X * "CONNECT" is of "CONNECT 1200", then put such results later in the
  1326. X * table than the larger result.
  1327. X *
  1328. X */
  1329. X
  1330. X/* flag bits */
  1331. X#define rfConnect        0x00800000
  1332. X#define rfMASK            0x0000FFFF    /* mask off rfBits */
  1333. X
  1334. X/* unique codes */
  1335. X#define rOk                0
  1336. X#define rNoCarrier        1
  1337. X#define rError            2
  1338. X#define rNoDialTone     3
  1339. X#define rBusy            4
  1340. X#define rNoAnswer        5
  1341. X#define rRring            6
  1342. X#define rConnect300        (  300  | rfConnect)
  1343. X#define rConnect1200    ( 1200  | rfConnect)
  1344. X#define rConnect2400    ( 2400  | rfConnect)
  1345. X#define rConnect4800    ( 4800  | rfConnect)
  1346. X#define rConnect9600    ( 9600  | rfConnect)
  1347. X#define rConnect9600    ( 9600  | rfConnect)
  1348. X#define rConnect19200    (19200  | rfConnect)
  1349. X#define rConnect38400    (38400  | rfConnect)
  1350. X
  1351. XDCE_RESULT DCE_results[] =
  1352. X{
  1353. X    {"OK", rOk,},
  1354. X    {"NO CARRIER", rNoCarrier,},
  1355. X    {"ERROR", rError},
  1356. X    {"BUSY", rBusy},
  1357. X    {"NO ANSWER", rNoAnswer},
  1358. X    {"NO DIAL TONE", rNoDialTone},
  1359. X    {"KDIR SENDX ERROR", rNoDialTone},    /* MPAD software error */
  1360. X    {"KDIR UNRESPONSIVE", rNoDialTone},
  1361. X    {"KDIR BUSY", rBusy},
  1362. X    {"KDIR BAD REQUEST", rError},    /* number 0 or >11 length */
  1363. X    {"NO SUCH NUMBER", rNoAnswer},
  1364. X    {"KDIR LOGIC ERROR", rNoDialTone},    /* MPAD software error */
  1365. X    {"KDIR NOT AVAIL", rNoDialTone},
  1366. X    {"TP4 STATE ERROR", rNoDialTone},    /* rain fade */
  1367. X    {"TP4 GIVE UP", rBusy},     /* rain fade */
  1368. X    {"TP4 ERROR RESP", rBusy},    /* transient problem */
  1369. X    {"NET DEACT", rNoDialTone},    /* net op deactivated port */
  1370. X    {"CONNECT 300", rConnect300},
  1371. X    {"CONNECT 1200", rConnect1200},
  1372. X    {"CONNECT 4800", rConnect4800},
  1373. X    {"CONNECT 9600", rConnect9600},
  1374. X    {"CONNECT 19200", rConnect19200},
  1375. X    {"CONNECT 38400", rConnect38400},
  1376. X    {(char *)0, -1}             /* end table */
  1377. X};
  1378. X
  1379. X/*+-------------------------------------------------------------------------
  1380. X    DCE_baud_to_CBAUD(baud) - check for valid baud rates supported by DCE
  1381. X
  1382. X  DCE dependent function must validate baud rates supported by DCE
  1383. X  returns baud rate in struct termio c_cflag fashion
  1384. X  or terminates program with error
  1385. X--------------------------------------------------------------------------*/
  1386. Xint
  1387. XDCE_baud_to_CBAUD(baud)
  1388. Xunsigned int baud;
  1389. X{
  1390. X    switch (baud)
  1391. X    {
  1392. X        case 110:
  1393. X            return (B110);
  1394. X        case 300:
  1395. X            return (B300);
  1396. X        case 1200:
  1397. X            return (B1200);
  1398. X        case 2400:
  1399. X            return (B2400);
  1400. X        case 9600:
  1401. X            return (B9600);
  1402. X
  1403. X#if defined(B19200)
  1404. X        case 19200:
  1405. X            return (B19200);
  1406. X#else
  1407. X#ifdef EXTA
  1408. X        case 19200:
  1409. X            return (EXTA);
  1410. X#endif
  1411. X#endif
  1412. X
  1413. X#if defined(B38400)
  1414. X        case 38400:
  1415. X            return (B38400);
  1416. X#else
  1417. X#ifdef EXTB
  1418. X        case 38400:
  1419. X            return (EXTB);
  1420. X#endif
  1421. X#endif
  1422. X
  1423. X    }
  1424. X    myexit(RC_FAIL | RCE_SPEED);
  1425. X#if defined(OPTIMIZE) || defined(__OPTIMIZE__)    /* don't complain */
  1426. X    return (0);                 /* keep gcc from complaining about no rtn at
  1427. X                              * end */
  1428. X#endif
  1429. X}                             /* end of DCE_baud_to_CBAUD */
  1430. X
  1431. X/*+-------------------------------------------------------------------------
  1432. X    sync_MPAD() - sync modem with our DTE speed
  1433. X--------------------------------------------------------------------------*/
  1434. Xvoid
  1435. Xsync_MPAD()
  1436. X{
  1437. X    register int maxretry = 8;
  1438. X    register int count;
  1439. X    unsigned char rdchar;
  1440. X
  1441. X    while (maxretry--)
  1442. X    {
  1443. X        lflush();
  1444. X        write(dce_fd, "a", 1);
  1445. X        count = 5;
  1446. X        while (count)         /* wait 50-200 msec for character, depending
  1447. X                              * on HZ */
  1448. X        {
  1449. X            if (rdchk(dce_fd))
  1450. X                break;
  1451. X            Nap(50L);
  1452. X            count--;
  1453. X        }
  1454. X        if (count && (read(dce_fd, &rdchar, 1) == 1) && (rdchar == 'a'))
  1455. X            return;
  1456. X        write(dce_fd, "atq0v1e1\r", 9);
  1457. X        Nap(500L);
  1458. X    }
  1459. X
  1460. X    DEBUG(1, "MPAD SYNC FAILED\n", 0);
  1461. X    myexit(RC_FAIL | RCE_TIMOUT);
  1462. X
  1463. X}                             /* end of sync_MPAD */
  1464. X
  1465. X/*+-------------------------------------------------------------------------
  1466. X    init_MPAD() - init MPAD from scratch, assuming nothing
  1467. X--------------------------------------------------------------------------*/
  1468. Xvoid
  1469. Xinit_MPAD()
  1470. X{
  1471. X    register itmp;
  1472. X    int maxretry = 4;
  1473. X    char *init0 = "ATE0Q0V1X99S0=1S2=255\r";
  1474. X
  1475. X    DEBUG(1, "--> reseting %s\n", dce_name);
  1476. X    lflash_DTR();
  1477. X    sync_MPAD();
  1478. X
  1479. X    /*
  1480. X     * set to factory default (bless them for this command) and a few
  1481. X     * initial beachhead values
  1482. X     */
  1483. X    for (itmp = 0; itmp < maxretry; itmp++)
  1484. X    {
  1485. X        lwrite(init0);
  1486. X        if (lread(5) == rOk)
  1487. X            break;
  1488. X    }
  1489. X    if (itmp == maxretry)
  1490. X    {
  1491. X        DEBUG(1, "reset failed\n", 0);
  1492. X        myexit(RC_FAIL | RCE_TIMOUT);
  1493. X    }
  1494. X
  1495. X}                             /* end of init_MPAD */
  1496. X
  1497. X/*+-------------------------------------------------------------------------
  1498. X    DCE_hangup() - issue hangup command to DCE
  1499. X
  1500. XThis function should do whatever is necessary to ensure
  1501. X1) any active connection is terminated
  1502. X2) the DCE is ready to receive an incoming call if DTR is asserted
  1503. X3) the DCE will not accept an incoming call if DTR is false
  1504. X
  1505. XThe function should return when done.
  1506. X
  1507. XAny necessary switch setting or other configuration necessary for this
  1508. Xfunction to succeed should be documented at the top of the module.
  1509. X--------------------------------------------------------------------------*/
  1510. Xvoid
  1511. XDCE_hangup()
  1512. X{
  1513. X    DEBUG(1, "--> hanging up %s\n", dce_name);
  1514. X    lflash_DTR();
  1515. X    init_MPAD();
  1516. X
  1517. X}                             /* end of DCE_hangup */
  1518. X
  1519. X/*+-------------------------------------------------------------------------
  1520. X    DCE_dial(telno_str) - dial a remote DCE
  1521. X
  1522. XThis function should connect to the remote DCE and use any success
  1523. Xindication to modify the tty baud rate if necessary before returning.
  1524. X
  1525. XUpon successful connection, return 0.
  1526. X
  1527. XUpon unsuccessful connection, return RC_FAIL or'd with an appropriate
  1528. XRCE_XXX value from dialer.h.
  1529. X
  1530. Xlwrite() is used to write to the DCE.
  1531. X
  1532. Xlread() and lread_ignore() are used to read from the DCE.  Read timeouts
  1533. Xfrom calling lread() will result automatically in the proper error
  1534. Xtermination of the program.  Read timeouts from calling lread_ignore()
  1535. Xreturn -1; you handle the execption here.
  1536. X
  1537. XAny necessary coding of phone numbers, switch settings or other
  1538. Xconfiguration necessary for this function to succeed should be
  1539. Xdocumented at the top of the module.
  1540. X
  1541. XMPAD Plus-specific comments:
  1542. X Q0          do not be quiet
  1543. X E0          do not echo
  1544. X V1          verbal result codes
  1545. X S0=0        dont allow connect while dialing
  1546. X X99         full result codes
  1547. X--------------------------------------------------------------------------*/
  1548. Xint
  1549. XDCE_dial(telno_str)
  1550. Xchar *telno_str;
  1551. X{
  1552. X    char cmd[128];
  1553. X    char phone[50];
  1554. X    int timeout;
  1555. X    int result;
  1556. X    char *cptr;
  1557. X    char *dialout_default = "ATQ0E0V1E0S0=0X99\r";
  1558. X
  1559. X#define MDVALID     "0123456789NnSs()-"
  1560. X
  1561. X/* preliminary setup */
  1562. X    translate("=,-,", telno_str);
  1563. X    if (strspn(telno_str, MDVALID) != strlen(telno_str))
  1564. X    {
  1565. X        DEBUG(1, "phone number has invalid characters\n", 0);
  1566. X        return (RC_FAIL | RCE_PHNO);
  1567. X    }
  1568. X    if (decode_phone_number(telno_str, phone, sizeof(phone)))
  1569. X    {
  1570. X        DEBUG(1, "phone number too long\n", 0);
  1571. X        return (RC_FAIL | RCE_PHNO);
  1572. X    }
  1573. X
  1574. X/* walk through dialer codes, doing custom setup */
  1575. X    strcpy(cmd, "AT");
  1576. X    cptr = cmd + strlen(cmd);
  1577. X
  1578. X    DEBUG(1, "--> issuing default setup command\n", 0);
  1579. X    sync_MPAD();
  1580. X    lwrite(dialout_default);
  1581. X    if (lread(5) != rOk)
  1582. X    {
  1583. X        DEBUG(1, "default dialout setup failed\n", 0);
  1584. X        return (RC_FAIL | RCE_NULL);
  1585. X    }
  1586. X
  1587. X/* issue the custom setup command */
  1588. X    if (*cptr)
  1589. X    {
  1590. X        DEBUG(1, "--> issuing custom setup cmd\n", 0);
  1591. X        strcat(cmd, "\r");
  1592. X        sync_MPAD();
  1593. X        lwrite(cmd);
  1594. X        if (lread(5) != rOk)
  1595. X        {
  1596. X            DEBUG(1, "custom modem setup failed\n", 0);
  1597. X            return (RC_FAIL | RCE_NULL);
  1598. X        }
  1599. X    }
  1600. X
  1601. X/*
  1602. X * calculate a timeout for the connect
  1603. X */
  1604. X    timeout = 20;
  1605. X    DEBUG(6, "wait for connect = %d seconds\n", timeout);
  1606. X
  1607. X/* indicate non-root should not see DTE->DCE traffic */
  1608. X    secure = 1;
  1609. X
  1610. X/*
  1611. X * build and issue the actual dialing command
  1612. X * if root, let him see number, otherwise just say "remote system"
  1613. X */
  1614. X    DEBUG(1, "--> dialing %s\n", (!ecu_calling & uid) ? "remote system" : phone);
  1615. X    sprintf(cmd, "ATS7=%dDT%s\r", (timeout * 9) / 10, phone);
  1616. X
  1617. X    /* cmd string can only be 40 characters including "AT" */
  1618. X    if (strlen(cmd) > 40)
  1619. X    {
  1620. X        DEBUG(1, "phone number string too long\n", 0);
  1621. X        cleanup(RC_FAIL | RCE_PHNO);
  1622. X    }
  1623. X
  1624. X    sync_MPAD();
  1625. X    lwrite(cmd);
  1626. X
  1627. X/* indicate non-root can see DTE->DCE traffic */
  1628. X    secure = 0;
  1629. X
  1630. X/* wait for connect */
  1631. X    result = lread(timeout);
  1632. X    if (!(result & rfConnect))
  1633. X    {
  1634. X        switch (result & rfMASK)
  1635. X        {
  1636. X            case rNoCarrier:
  1637. X                return (RC_FAIL | RCE_NOCARR);
  1638. X            case rNoDialTone:
  1639. X                return (RC_FAIL | RCE_NOTONE);
  1640. X            case rBusy:
  1641. X                return (RC_FAIL | RCE_BUSY);
  1642. X            case rNoAnswer:
  1643. X                return (RC_FAIL | RCE_ANSWER);
  1644. X            case rError:
  1645. X            default:
  1646. X                return (RC_FAIL | RCE_NULL);
  1647. X        }
  1648. X    }
  1649. X
  1650. X    return (0);                 /* succeeded */
  1651. X
  1652. X}                             /* end of DCE_dial */
  1653. X
  1654. X/**********************************************************
  1655. X*  You probably do not need to modify the code below here *
  1656. X**********************************************************/
  1657. X
  1658. X/*+-------------------------------------------------------------------------
  1659. X    DCE_abort(sig) - dial attempt aborted
  1660. X
  1661. X sig =  0 if non-signal abort (read timeout, most likely)
  1662. X     != 0 if non-SIGALRM signal caught
  1663. X
  1664. X extern int dialing set  1 if dialing request was active,
  1665. X                    else 0 if hangup request was active
  1666. X
  1667. XThis is a chance for the DCE-specific code to do anything it
  1668. Xneeds to cl,ean up after a failure.  Note that if a dialing
  1669. Xcall fails, it is the responsibility of the higher-level
  1670. Xprogram calling the dialer to call it again with a hangup request, so
  1671. Xthis function is usually a no-op.
  1672. X--------------------------------------------------------------------------*/
  1673. Xvoid
  1674. XDCE_abort(sig)
  1675. Xint sig;
  1676. X{
  1677. X    DEBUG(10, "DCE_abort(%d);\n", sig);
  1678. X}                             /* end of DCE_abort */
  1679. X
  1680. X/*+-------------------------------------------------------------------------
  1681. X    DCE_exit(exitcode) - "last chance for gas" in this incarnation
  1682. X
  1683. XThe independent portion of the dialer program calls this routine in
  1684. Xlieu of exit() in every case except one (see DCE_argv_hook() below).
  1685. XNormally, this function just passes it's argument to exit(), but
  1686. Xany necessary post-processing can be done.  The function must,
  1687. Xhowever, eventually call exit(exitcode);
  1688. X--------------------------------------------------------------------------*/
  1689. Xvoid
  1690. XDCE_exit(exitcode)
  1691. Xint exitcode;
  1692. X{
  1693. X    DEBUG(10, "DCE_exit(%d);\n", exitcode);
  1694. X    exit(exitcode);
  1695. X}                             /* end of DCE_exit */
  1696. X
  1697. X/*+-------------------------------------------------------------------------
  1698. X    DCE_argv_hook(argc,argv,optind,unrecognized_switches)
  1699. X
  1700. XThis hook gives DCE-specific code a chance to look over the entire
  1701. Xcommand line, such as for -z processing.
  1702. X
  1703. Xargc andf argv are the same values passed to main(),
  1704. X
  1705. Xoptind is the value of optind at the end of normal getopt processing.
  1706. X
  1707. Xunrecognized_switches is the count of switches not handled by main().
  1708. XSpecifically, -h and -x are standard switches.
  1709. X
  1710. XNormally, this function should just return RC_FAIL|RCE_ARGS if there are
  1711. Xany unrecognized switches, otherwise zero.  If you keep your nose clean
  1712. Xthough, you can do anything you need to do here and exit the program.
  1713. X
  1714. XNote: only simple switches (with no argument) may be used with this
  1715. Xfacility if the functrion is to return,' since main()'s getopt() will
  1716. Xstop processing switches if it runs into an unrecognized switch with an
  1717. Xargument.
  1718. X
  1719. XIf the function returns a non-zero value, then the value will be passed
  1720. XDIRECTLY to exit() with no further ado.  Thus, a non-zero value must be
  1721. Xof the format expected by dialer program callers, with RC_FAIL set as a
  1722. Xminimum.
  1723. X--------------------------------------------------------------------------*/
  1724. Xint
  1725. XDCE_argv_hook(argc, argv, optind, unrecognized_switches)
  1726. Xint argc;
  1727. Xchar **argv;
  1728. Xint optind;
  1729. Xint unrecognized_switches;
  1730. X{
  1731. X    if (unrecognized_switches)
  1732. X        return (RC_FAIL | RCE_ARGS);
  1733. X    return (0);
  1734. X}                             /* end of DCE_argv_hook */
  1735. X
  1736. X/* vi: set tabstop=4 shiftwidth=4: */
  1737. END_OF_FILE
  1738.   if test 14780 -ne `wc -c <'ecu330/gendial/dceMPAD.c'`; then
  1739.     echo shar: \"'ecu330/gendial/dceMPAD.c'\" unpacked with wrong size!
  1740.   fi
  1741.   # end of 'ecu330/gendial/dceMPAD.c'
  1742. fi
  1743. if test -f 'ecu330/pcmdif.c' -a "${1}" != "-c" ; then 
  1744.   echo shar: Will not clobber existing file \"'ecu330/pcmdif.c'\"
  1745. else
  1746.   echo shar: Extracting \"'ecu330/pcmdif.c'\" \(14664 characters\)
  1747.   sed "s/^X//" >'ecu330/pcmdif.c' <<'END_OF_FILE'
  1748. X/*+-------------------------------------------------------------------------
  1749. X    pcmdif.c - ecu if procedure commands
  1750. X    wht@n4hgf.atl.ga.us
  1751. X
  1752. X  Defined functions:
  1753. X    _cmd_ifrel_common(param,relop)
  1754. X    _if_common(param,truth)
  1755. X    get_logicop(param,op_returned)
  1756. X    get_relop(param,op_returned)
  1757. X    get_truth_int(param,truth)
  1758. X    get_truth_str(param,truth)
  1759. X    pcmd_else(param)
  1760. X    pcmd_ifge(param)
  1761. X    pcmd_ifgt(param)
  1762. X    pcmd_ifi(param)
  1763. X    pcmd_ifle(param)
  1764. X    pcmd_iflt(param)
  1765. X    pcmd_ifnz(param)
  1766. X    pcmd_ifs(param)
  1767. X    pcmd_ifz(param)
  1768. X    test_truth_int(int1,relop,int2)
  1769. X
  1770. X--------------------------------------------------------------------------*/
  1771. X/*+:EDITS:*/
  1772. X/*:05-04-1994-04:39-wht@n4hgf-ECU release 3.30 */
  1773. X/*:12-20-1992-00:25-wht@n4hgf-flunk << or >> as relational operator */
  1774. X/*:11-14-1992-22:37-wht@n4hgf-multiple else loses track of truth */
  1775. X/*:09-10-1992-14:00-wht@n4hgf-ECU release 3.20 */
  1776. X/*:08-22-1992-15:39-wht@n4hgf-ECU release 3.20 BETA */
  1777. X/*:07-25-1991-12:59-wht@n4hgf-ECU release 3.10 */
  1778. X/*:08-26-1990-22:23-wht@n4hgf-fix zero-relative if commands */
  1779. X/*:08-14-1990-20:40-wht@n4hgf-ecu3.00-flush old edit history */
  1780. X
  1781. X#include <ctype.h>
  1782. X#include "ecu.h"
  1783. X#include "ecuerror.h"
  1784. X#include "esd.h"
  1785. X#include "var.h"
  1786. X#include "proc.h"
  1787. X#include "relop.h"
  1788. X
  1789. Xextern PCB *pcb_stack[];
  1790. Xextern int proc_trace;
  1791. X
  1792. X#define MAX_IF 40             /* damn enough */
  1793. Xuchar if_level = 0;
  1794. Xuchar truth_already[MAX_IF];
  1795. X
  1796. X/*+-------------------------------------------------------------------------
  1797. X    get_relop(param,&op_returned)
  1798. X--------------------------------------------------------------------------*/
  1799. Xint
  1800. Xget_relop(param, op_returned)
  1801. XESD *param;
  1802. Xint *op_returned;
  1803. X{
  1804. X    if (end_of_cmd(param))
  1805. X        return (eInvalidRelOp);
  1806. X
  1807. X    switch (param->pb[param->index++])    /* index decremented in default */
  1808. X    {
  1809. X        case '=':
  1810. X            if ((param->cb != param->index) && (param->pb[param->index] == '='))
  1811. X                param->index++;
  1812. X            *op_returned = OP_EQ;
  1813. X            return (0);
  1814. X
  1815. X        case '!':
  1816. X            if (param->cb == param->index)
  1817. X                return (eInvalidRelOp);
  1818. X            switch (param->pb[param->index])
  1819. X            {
  1820. X                case '=':
  1821. X                    param->index++;
  1822. X                    *op_returned = OP_NE;
  1823. X                    return (0);
  1824. X                default:
  1825. X                    return (eInvalidRelOp);
  1826. X            }
  1827. X
  1828. X        case '<':
  1829. X            if (param->cb == param->index)
  1830. X            {
  1831. X                *op_returned = OP_LT;
  1832. X                return (0);
  1833. X            }
  1834. X            switch (param->pb[param->index])
  1835. X            {
  1836. X                case '<':
  1837. X                    param->index++;
  1838. X                    return (eInvalidRelOp);
  1839. X                case '>':
  1840. X                    param->index++;
  1841. X                    *op_returned = OP_NE;
  1842. X                    return (0);
  1843. X                case '=':
  1844. X                    param->index++;
  1845. X                    *op_returned = OP_LE;
  1846. X                    return (0);
  1847. X                default:
  1848. X                    *op_returned = OP_LT;
  1849. X                    return (0);
  1850. X            }
  1851. X
  1852. X        case '>':
  1853. X            if (param->cb == param->index)
  1854. X            {
  1855. X                *op_returned = OP_LT;
  1856. X                return (0);
  1857. X            }
  1858. X            switch (param->pb[param->index])
  1859. X            {
  1860. X                case '>':
  1861. X                    param->index++;
  1862. X                    return (eInvalidRelOp);
  1863. X                case '=':
  1864. X                    param->index++;
  1865. X                    *op_returned = OP_GE;
  1866. X                    return (0);
  1867. X                default:
  1868. X                    *op_returned = OP_GT;
  1869. X                    return (0);
  1870. X            }
  1871. X        default:
  1872. X            param->index--;
  1873. X    }
  1874. X    return (eInvalidRelOp);
  1875. X}                             /* end of get_relop */
  1876. X
  1877. X/*+-------------------------------------------------------------------------
  1878. X    get_logicop(param,op_returned)
  1879. X--------------------------------------------------------------------------*/
  1880. Xint
  1881. Xget_logicop(param, op_returned)
  1882. XESD *param;
  1883. Xint *op_returned;
  1884. X{
  1885. X    register erc;
  1886. X    register char *cptr;
  1887. X
  1888. X    if (erc = skip_cmd_break(param))
  1889. X        return (eInvalidLogicOp);
  1890. X
  1891. X    if ((param->cb - param->index) < 2)
  1892. X        return (eInvalidLogicOp);
  1893. X
  1894. X    cptr = param->pb + param->index;
  1895. X    erc = eInvalidLogicOp;
  1896. X    if (!strncmp(cptr, "&&", 2))
  1897. X    {
  1898. X        *op_returned = OP_AND;
  1899. X        erc = 0;
  1900. X    }
  1901. X    else if (!strncmp(cptr, "||", 2))
  1902. X    {
  1903. X        *op_returned = OP_OR;
  1904. X        erc = 0;
  1905. X    }
  1906. X    if (!erc)
  1907. X        param->index += 2;
  1908. X    return (erc);
  1909. X
  1910. X}                             /* end of get_logicop */
  1911. X
  1912. X/*+-------------------------------------------------------------------------
  1913. X    test_truth_int(int1,relop,int2)
  1914. X--------------------------------------------------------------------------*/
  1915. Xint
  1916. Xtest_truth_int(int1, relop, int2)
  1917. Xlong int1;
  1918. Xint relop;
  1919. Xlong int2;
  1920. X{
  1921. X    register truth = 0;
  1922. X
  1923. X    switch (relop)
  1924. X    {
  1925. X        case OP_EQ:
  1926. X            truth = (int1 == int2);
  1927. X            break;
  1928. X        case OP_NE:
  1929. X            truth = (int1 != int2);
  1930. X            break;
  1931. X        case OP_GT:
  1932. X            truth = (int1 > int2);
  1933. X            break;
  1934. X        case OP_LT:
  1935. X            truth = (int1 < int2);
  1936. X            break;
  1937. X        case OP_GE:
  1938. X            truth = (int1 >= int2);
  1939. X            break;
  1940. X        case OP_LE:
  1941. X            truth = (int1 <= int2);
  1942. X            break;
  1943. X    }
  1944. X    return (truth);
  1945. X
  1946. X}                             /* end of test_truth_int */
  1947. X
  1948. X/*+-------------------------------------------------------------------------
  1949. X    get_truth_int(param,truth)
  1950. X--------------------------------------------------------------------------*/
  1951. Xint
  1952. Xget_truth_int(param, truth)
  1953. XESD *param;
  1954. Xint *truth;
  1955. X{
  1956. X    register erc;
  1957. X    long int1;
  1958. X    long int2;
  1959. X    int operator;
  1960. X    int truth2;
  1961. X
  1962. X    if (erc = gint(param, &int1))
  1963. X        return (erc);
  1964. X    if (erc = get_relop(param, &operator))
  1965. X        return (erc);
  1966. X    if (erc = gint(param, &int2))
  1967. X        return (erc);
  1968. X    *truth = test_truth_int(int1, operator, int2);
  1969. X
  1970. X    while (!get_logicop(param, &operator))
  1971. X    {
  1972. X        if (erc = get_truth_int(param, &truth2))
  1973. X            return (erc);
  1974. X        switch (operator)
  1975. X        {
  1976. X            case OP_AND:
  1977. X                *truth &= truth2;
  1978. X                break;
  1979. X
  1980. X            case OP_OR:
  1981. X                *truth |= truth2;
  1982. X                break;
  1983. X        }
  1984. X    }
  1985. X    return (0);
  1986. X
  1987. X}                             /* end of get_truth_int */
  1988. X
  1989. X/*+-------------------------------------------------------------------------
  1990. X    get_truth_str(param,truth)
  1991. X--------------------------------------------------------------------------*/
  1992. Xint
  1993. Xget_truth_str(param, truth)
  1994. XESD *param;
  1995. Xint *truth;
  1996. X{
  1997. X    register erc;
  1998. X    ESD *tesd1 = (ESD *) 0;
  1999. X    ESD *tesd2 = (ESD *) 0;
  2000. X    int operator;
  2001. X    int strcmp_result;
  2002. X    int truth2;
  2003. X
  2004. X    if (!(tesd1 = esdalloc(ESD_NOMSZ)) || !(tesd2 = esdalloc(ESD_NOMSZ)))
  2005. X    {
  2006. X        erc = eNoMemory;
  2007. X        goto FUNC_RETURN;
  2008. X    }
  2009. X
  2010. X    if (erc = gstr(param, tesd1, 1))
  2011. X        goto FUNC_RETURN;
  2012. X    if (erc = get_relop(param, &operator))
  2013. X        goto FUNC_RETURN;
  2014. X    if (erc = gstr(param, tesd2, 1))
  2015. X        goto FUNC_RETURN;
  2016. X
  2017. X    strcmp_result = strcmp(tesd1->pb, tesd2->pb);
  2018. X
  2019. X    switch (operator)
  2020. X    {
  2021. X        case OP_EQ:
  2022. X            *truth = (strcmp_result == 0);
  2023. X            break;
  2024. X        case OP_NE:
  2025. X            *truth = (strcmp_result != 0);
  2026. X            break;
  2027. X        case OP_GT:
  2028. X            *truth = (strcmp_result > 0);
  2029. X            break;
  2030. X        case OP_LT:
  2031. X            *truth = (strcmp_result < 0);
  2032. X            break;
  2033. X        case OP_GE:
  2034. X            *truth = (strcmp_result >= 0);
  2035. X            break;
  2036. X        case OP_LE:
  2037. X            *truth = (strcmp_result <= 0);
  2038. X            break;
  2039. X        default:
  2040. X            return (eInvalidStrOp);
  2041. X    }
  2042. X
  2043. X    while (!get_logicop(param, &operator))
  2044. X    {
  2045. X        if (erc = get_truth_str(param, &truth2))
  2046. X            return (erc);
  2047. X        switch (operator)
  2048. X        {
  2049. X            case OP_AND:
  2050. X                *truth &= truth2;
  2051. X                break;
  2052. X
  2053. X            case OP_OR:
  2054. X                *truth |= truth2;
  2055. X                break;
  2056. X        }
  2057. X    }
  2058. X
  2059. X    erc = 0;
  2060. X
  2061. X  FUNC_RETURN:
  2062. X    if (tesd1)
  2063. X        esdfree(tesd1);
  2064. X    if (tesd2)
  2065. X        esdfree(tesd2);
  2066. X    return (erc);
  2067. X
  2068. X}                             /* end of get_truth_str */
  2069. X
  2070. X/*+-------------------------------------------------------------------------
  2071. X    _if_common(param,truth)
  2072. X--------------------------------------------------------------------------*/
  2073. Xint
  2074. X_if_common(param, truth)
  2075. XESD *param;
  2076. Xint truth;
  2077. X{
  2078. X    register erc = 0;
  2079. X    char s80[80];
  2080. X    PCB *pcb;
  2081. X    ESD *else_line;
  2082. X    int label_on_else_line;
  2083. X    int truth2;
  2084. X    int save_index;
  2085. X    long int1;
  2086. X
  2087. X    if (proc_trace > 1)
  2088. X    {
  2089. X        pprintf("if condition %s", (truth) ? "TRUE: " : "FALSE\n");
  2090. X        if (truth)
  2091. X        {
  2092. X            skip_cmd_break(param);
  2093. X            pputs(param->pb + param->index);
  2094. X            pputc('\n');
  2095. X        }
  2096. X    }
  2097. X
  2098. X    truth_already[if_level] |= truth;
  2099. X
  2100. X/* if end of command, execute frame else conditionally execute rest of esd */
  2101. X    s80[0] = 0;
  2102. X    if (end_of_cmd(param))
  2103. X        erc = execute_frame(truth);
  2104. X    else if (truth)
  2105. X        erc = execute_esd(param);
  2106. X    else
  2107. X        param->index = param->cb;
  2108. X
  2109. X    if (erc)
  2110. X        return (erc);
  2111. X
  2112. X/* check for else statement */
  2113. X    pcb = pcb_stack[proc_level - 1];
  2114. X    if (!pcb->current->next) /* if no next line, no "else" */
  2115. X        return (0);
  2116. X
  2117. X    else_line = pcb->current->next->text;
  2118. X    else_line->index = else_line->old_index = 0;
  2119. X    if (label_on_else_line = (*else_line->pb != 0x20))
  2120. X    {                         /* strip label */
  2121. X        if (get_alphanum_zstr(else_line, s80, sizeof(s80)))
  2122. X            return (eInvalidLabel);
  2123. X    }
  2124. X    if (get_alphanum_zstr(else_line, s80, sizeof(s80)))
  2125. X        return (0);             /* not "else" */
  2126. X    if (strcmp(s80, "else"))
  2127. X        return (0);             /* not "else" */
  2128. X    if (label_on_else_line)
  2129. X    {
  2130. X        else_line->old_index = 0;
  2131. X        pputs("label not allowed on else statement\n");
  2132. X        return (eFATAL_ALREADY);
  2133. X    }
  2134. X
  2135. X/* we have an "else" condition */
  2136. X    pcb->current = pcb->current->next;
  2137. X
  2138. X    trace_proc_cmd(pcb);
  2139. X
  2140. X    if (end_of_cmd(else_line))
  2141. X    {
  2142. X        truth = !truth_already[if_level];
  2143. X        erc = execute_frame(truth);
  2144. X    }
  2145. X    else
  2146. X    {
  2147. X        save_index = else_line->old_index = else_line->index;
  2148. X        s80[0] = 0;
  2149. X        if ((*(else_line->pb + else_line->index) != '$') &&
  2150. X            get_alpha_zstr(else_line, s80, sizeof(s80)))
  2151. X        {
  2152. X            pputs("illegal command after 'else'\n");
  2153. X            return (eFATAL_ALREADY);
  2154. X        }
  2155. X        if (!strcmp(s80, "ifi"))
  2156. X        {
  2157. X            if (erc = get_truth_int(else_line, &truth2))
  2158. X                return (erc);
  2159. X            erc = _if_common(else_line, !truth_already[if_level] & truth2);
  2160. X            truth_already[if_level] |= truth2;
  2161. X        }
  2162. X        else if (!strcmp(s80, "ifs"))
  2163. X        {
  2164. X            if (erc = get_truth_str(else_line, &truth2))
  2165. X                return (erc);
  2166. X            erc = _if_common(else_line, !truth_already[if_level] & truth2);
  2167. X            truth_already[if_level] |= truth2;
  2168. X        }
  2169. X        else if (!strcmp(s80, "ifz"))
  2170. X        {
  2171. X            if (erc = gint(else_line, &int1))
  2172. X                return (erc);
  2173. X            truth2 = test_truth_int(int1, OP_EQ, 0L);
  2174. X            erc = _if_common(else_line, !truth_already[if_level] & truth2);
  2175. X            truth_already[if_level] |= truth2;
  2176. X        }
  2177. X        else if (!strcmp(s80, "ifnz"))
  2178. X        {
  2179. X            if (erc = gint(else_line, &int1))
  2180. X                return (erc);
  2181. X            truth2 = test_truth_int(int1, OP_NE, 0L);
  2182. X            erc = _if_common(else_line, !truth_already[if_level] & truth2);
  2183. X            truth_already[if_level] |= truth2;
  2184. X        }
  2185. X        else if (!strcmp(s80, "iflt"))
  2186. X        {
  2187. X            if (erc = gint(else_line, &int1))
  2188. X                return (erc);
  2189. X            truth2 = test_truth_int(int1, OP_LT, 0L);
  2190. X            erc = _if_common(else_line, !truth_already[if_level] & truth2);
  2191. X            truth_already[if_level] |= truth2;
  2192. X        }
  2193. X        else if (!strcmp(s80, "ifle"))
  2194. X        {
  2195. X            if (erc = gint(else_line, &int1))
  2196. X                return (erc);
  2197. X            truth2 = test_truth_int(int1, OP_LE, 0L);
  2198. X            erc = _if_common(else_line, !truth_already[if_level] & truth2);
  2199. X            truth_already[if_level] |= truth2;
  2200. X        }
  2201. X        else if (!strcmp(s80, "ifgt"))
  2202. X        {
  2203. X            if (erc = gint(else_line, &int1))
  2204. X                return (erc);
  2205. X            truth2 = test_truth_int(int1, OP_GT, 0L);
  2206. X            erc = _if_common(else_line, !truth_already[if_level] & truth2);
  2207. X            truth_already[if_level] |= truth2;
  2208. X        }
  2209. X        else if (!strcmp(s80, "ifge"))
  2210. X        {
  2211. X            if (erc = gint(else_line, &int1))
  2212. X                return (erc);
  2213. X            truth2 = test_truth_int(int1, OP_GE, 0L);
  2214. X            erc = _if_common(else_line, !truth_already[if_level] & truth2);
  2215. X            truth_already[if_level] |= truth2;
  2216. X        }
  2217. X        else if (!strncmp(s80, "while", 5))
  2218. X        {
  2219. X            pputs("'while' command not allowed as 'else' conditional\n");
  2220. X            pputs("put the statement inside braces\n");
  2221. X            return (eFATAL_ALREADY);
  2222. X        }
  2223. X        else
  2224. X        {
  2225. X            else_line->index = save_index;
  2226. X            if (truth)
  2227. X                erc = execute_esd(else_line);
  2228. X        }
  2229. X    }
  2230. X
  2231. X    return (erc);
  2232. X}                             /* end of _if_common */
  2233. X
  2234. X/*+-------------------------------------------------------------------------
  2235. X    pcmd_ifi(param)
  2236. X--------------------------------------------------------------------------*/
  2237. Xint
  2238. Xpcmd_ifi(param)
  2239. XESD *param;
  2240. X{
  2241. X    register erc;
  2242. X    int truth;
  2243. X
  2244. X    if (!proc_level)
  2245. X        return (eNotExecutingProc);
  2246. X
  2247. X    if (if_level == MAX_IF)
  2248. X    {
  2249. X        pputs("if statements nested too deeply\n");
  2250. X        return (eFATAL_ALREADY);
  2251. X    }
  2252. X    if_level++;
  2253. X    truth_already[if_level] = 0;
  2254. X
  2255. X    if (!(erc = get_truth_int(param, &truth)))
  2256. X        erc = _if_common(param, truth);
  2257. X    if_level--;
  2258. X    return (erc);
  2259. X
  2260. X}                             /* end of pcmd_ifi */
  2261. X
  2262. X/*+-------------------------------------------------------------------------
  2263. X    _cmd_ifrel_common(param,relop)
  2264. X--------------------------------------------------------------------------*/
  2265. Xint
  2266. X_cmd_ifrel_common(param, relop)
  2267. XESD *param;
  2268. Xint relop;
  2269. X{
  2270. X    register erc;
  2271. X    int truth;
  2272. X    long int1;
  2273. X
  2274. X    if (!proc_level)
  2275. X        return (eNotExecutingProc);
  2276. X
  2277. X    if (if_level == MAX_IF)
  2278. X    {
  2279. X        pputs("if statements nested too deeply\n");
  2280. X        return (eFATAL_ALREADY);
  2281. X    }
  2282. X    if_level++;
  2283. X    truth_already[if_level] = 0;
  2284. X
  2285. X    if (erc = gint(param, &int1))
  2286. X        return (erc);
  2287. X    truth = test_truth_int(int1, relop, 0L);
  2288. X    erc = _if_common(param, truth);
  2289. X    if_level--;
  2290. X    return (erc);
  2291. X
  2292. X}                             /* end of _cmd_ifrel_common */
  2293. X
  2294. X/*+-------------------------------------------------------------------------
  2295. X    pcmd_ifz(param)
  2296. X--------------------------------------------------------------------------*/
  2297. Xint
  2298. Xpcmd_ifz(param)
  2299. XESD *param;
  2300. X{
  2301. X    return (_cmd_ifrel_common(param, OP_EQ));
  2302. X}                             /* end of pcmd_ifz */
  2303. X
  2304. X/*+-------------------------------------------------------------------------
  2305. X    pcmd_ifnz(param)
  2306. X--------------------------------------------------------------------------*/
  2307. Xint
  2308. Xpcmd_ifnz(param)
  2309. XESD *param;
  2310. X{
  2311. X    return (_cmd_ifrel_common(param, OP_NE));
  2312. X}                             /* end of pcmd_ifnz */
  2313. X
  2314. X/*+-------------------------------------------------------------------------
  2315. X    pcmd_ifle(param)
  2316. X--------------------------------------------------------------------------*/
  2317. Xint
  2318. Xpcmd_ifle(param)
  2319. XESD *param;
  2320. X{
  2321. X    return (_cmd_ifrel_common(param, OP_LE));
  2322. X}                             /* end of pcmd_ifle */
  2323. X
  2324. X/*+-------------------------------------------------------------------------
  2325. X    pcmd_ifge(param)
  2326. X--------------------------------------------------------------------------*/
  2327. Xint
  2328. Xpcmd_ifge(param)
  2329. XESD *param;
  2330. X{
  2331. X    return (_cmd_ifrel_common(param, OP_GE));
  2332. X}                             /* end of pcmd_ifge */
  2333. X
  2334. X/*+-------------------------------------------------------------------------
  2335. X    pcmd_iflt(param)
  2336. X--------------------------------------------------------------------------*/
  2337. Xint
  2338. Xpcmd_iflt(param)
  2339. XESD *param;
  2340. X{
  2341. X    return (_cmd_ifrel_common(param, OP_LT));
  2342. X}                             /* end of pcmd_iflt */
  2343. X
  2344. X/*+-------------------------------------------------------------------------
  2345. X    pcmd_ifgt(param)
  2346. X--------------------------------------------------------------------------*/
  2347. Xint
  2348. Xpcmd_ifgt(param)
  2349. XESD *param;
  2350. X{
  2351. X    return (_cmd_ifrel_common(param, OP_GT));
  2352. X}                             /* end of pcmd_ifgt */
  2353. X
  2354. X/*+-------------------------------------------------------------------------
  2355. X    pcmd_ifs(param)
  2356. X--------------------------------------------------------------------------*/
  2357. Xint
  2358. Xpcmd_ifs(param)
  2359. XESD *param;
  2360. X{
  2361. X    register erc;
  2362. X    int truth;
  2363. X
  2364. X    if (!proc_level)
  2365. X        return (eNotExecutingProc);
  2366. X
  2367. X    if (if_level == MAX_IF)
  2368. X    {
  2369. X        pputs("if statements nested too deeply\n");
  2370. X        return (eFATAL_ALREADY);
  2371. X    }
  2372. X    if_level++;
  2373. X    truth_already[if_level] = 0;
  2374. X
  2375. X    if (!(erc = get_truth_str(param, &truth)))
  2376. X        erc = _if_common(param, truth);
  2377. X    if_level--;
  2378. X    return (erc);
  2379. X
  2380. X}                             /* end of pcmd_ifs */
  2381. X
  2382. X/*+-------------------------------------------------------------------------
  2383. X    pcmd_else(param)
  2384. X--------------------------------------------------------------------------*/
  2385. X/*ARGSUSED*/
  2386. Xint
  2387. Xpcmd_else(param)
  2388. XESD *param;
  2389. X{
  2390. X    return (eElseCommand);
  2391. X}                             /* end of pcmd_else */
  2392. X
  2393. X/* vi: set tabstop=4 shiftwidth=4: */
  2394. X/* end of pcmdif.c */
  2395. END_OF_FILE
  2396.   if test 14664 -ne `wc -c <'ecu330/pcmdif.c'`; then
  2397.     echo shar: \"'ecu330/pcmdif.c'\" unpacked with wrong size!
  2398.   fi
  2399.   # end of 'ecu330/pcmdif.c'
  2400. fi
  2401. if test -f 'ecu330/termecu.h' -a "${1}" != "-c" ; then 
  2402.   echo shar: Will not clobber existing file \"'ecu330/termecu.h'\"
  2403. else
  2404.   echo shar: Extracting \"'ecu330/termecu.h'\" \(1750 characters\)
  2405.   sed "s/^X//" >'ecu330/termecu.h' <<'END_OF_FILE'
  2406. X/*+-------------------------------------------------------------------------
  2407. X    termecu.h -- termecu (exit()) codes
  2408. X    wht@n4hgf.atl.ga.us
  2409. X
  2410. X  1 - 64    reserved for signals
  2411. X  193 - 223 reserved for procedure 'exit' codes
  2412. X--------------------------------------------------------------------------*/
  2413. X/*+:EDITS:*/
  2414. X/*:05-04-1994-04:40-wht@n4hgf-ECU release 3.30 */
  2415. X/*:12-20-1992-12:02-wht@n4hgf-add TERMECU_SVC_NOT_AVAIL */
  2416. X/*:09-16-1992-03:29-wht@n4hgf-add TERMECU_UNRECOVERABLE */
  2417. X/*:09-10-1992-14:00-wht@n4hgf-ECU release 3.20 */
  2418. X/*:08-22-1992-15:39-wht@n4hgf-ECU release 3.20 BETA */
  2419. X/*:03-27-1992-16:21-wht@n4hgf-re-include protection for all .h files */
  2420. X/*:07-25-1991-12:59-wht@n4hgf-ECU release 3.10 */
  2421. X/*:08-14-1990-20:40-wht@n4hgf-ecu3.00-flush old edit history */
  2422. X
  2423. X#ifndef _termecu_h
  2424. X#define _termecu_h
  2425. X
  2426. X#define TERMECU_OK                    0
  2427. X#define TERMECU_SIG1                1
  2428. X#define TERMECU_SIGN                64
  2429. X#define TERMECU_LINE_READ_ERROR        129
  2430. X#define TERMECU_XMTR_WRITE_ERROR    130
  2431. X#define TERMECU_XMTR_FATAL_ERROR    131
  2432. X#define TERMECU_BSD4_IOCTL            132
  2433. X#define TERMECU_SHM_ABL                133
  2434. X#define TERMECU_SHM_RTL                134
  2435. X#define TERMECU_NO_FORK_FOR_RCVR    135
  2436. X#define TERMECU_TTYIN_READ_ERROR    136
  2437. X#define TERMECU_LINE_OPEN_ERROR        137
  2438. X#define TERMECU_PWENT_ERROR            138
  2439. X#define TERMECU_USAGE                139
  2440. X#define TERMECU_CONFIG_ERROR        140
  2441. X#define TERMECU_CURSES_ERROR        141
  2442. X#define TERMECU_RCVR_FATAL_ERROR    142
  2443. X#define TERMECU_MALLOC                143
  2444. X#define TERMECU_LOGIC_ERROR            144
  2445. X#define TERMECU_GEOMETRY            145
  2446. X#define TERMECU_IPC_ERROR            146
  2447. X#define TERMECU_UNRECOVERABLE        147
  2448. X#define TERMECU_SVC_NOT_AVAIL        148
  2449. X
  2450. X#define TERMECU_INIT_PROC_ERROR        192
  2451. X
  2452. X#define TERMECU_USER1                193
  2453. X#define TERMECU_USERN                223
  2454. X
  2455. X#endif /* _termecu_h */
  2456. X
  2457. X/* vi: set tabstop=4 shiftwidth=4: */
  2458. X/* end of termecu.h */
  2459. END_OF_FILE
  2460.   if test 1750 -ne `wc -c <'ecu330/termecu.h'`; then
  2461.     echo shar: \"'ecu330/termecu.h'\" unpacked with wrong size!
  2462.   fi
  2463.   # end of 'ecu330/termecu.h'
  2464. fi
  2465. echo shar: End of archive 25 \(of 37\).
  2466. cp /dev/null ark25isdone
  2467. MISSING=""
  2468. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 ; do
  2469.     if test ! -f ark${I}isdone ; then
  2470.     MISSING="${MISSING} ${I}"
  2471.     fi
  2472. done
  2473. if test "${MISSING}" = "" ; then
  2474.     echo You have unpacked all 37 archives.
  2475.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  2476. else
  2477.     echo You still must unpack the following archives:
  2478.     echo "        " ${MISSING}
  2479. fi
  2480. exit 0
  2481. exit 0 # Just in case...
  2482.