home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume8 / micrognu / part08 < prev    next >
Encoding:
Internet Message Format  |  1987-01-26  |  56.4 KB

  1. Subject:  v08i015:  A Micro-Emacs variant that resembles GNU Emacs
  2. Newsgroups: mod.sources
  3. Approved: mirror!rs
  4.  
  5. Submitted by: Bob Larson <seismo!usc-oberon!blarson>
  6. Mod.sources: Volume 8, Issue 15
  7. Archive-name: micrognu/Part08
  8.  
  9.  
  10. #! /bin/sh
  11. # This is a shell archive, meaning:
  12. # 1. Remove everything above the #! /bin/sh line.
  13. # 2. Save the resulting text in a file.
  14. # 3. Execute the file with /bin/sh (not csh) to create the files:
  15. #    sys/eunice/Makefile
  16. #    sys/eunice/fileio.c
  17. #    sys/eunice/readme
  18. #    sys/eunice/spawn.c
  19. #    sys/eunice/sysdef.h
  20. #    sys/eunice/ttyio.c
  21. #    sys/vms/aaareadme.1st
  22. #    sys/vms/bcopy.mar
  23. #    sys/vms/ccom.com
  24. #    sys/vms/make.com
  25. #    sys/vms/mg.com
  26. #    sys/vms/mglink.com
  27. #    sys/vms/mgmailedit.com
  28. #    sys/vms/emacs.opt
  29. #    sys/vms/fileio.c
  30. #    sys/vms/spawn.c
  31. #    sys/vms/trnlnm.c
  32. #    sys/vms/ttyio.c
  33. #    sys/vms/sysdef.h
  34. # This archive created: Sat Nov 15 15:40:17 1986
  35. export PATH; PATH=/bin:$PATH
  36. if test ! -d sys/eunice
  37. then
  38. mkdir sys/eunice
  39. fi
  40. if test ! -d sys/vms
  41. then
  42. mkdir sys/vms
  43. fi
  44. if test ! -d sys/vms/termcap
  45. then
  46. mkdir sys/vms/termcap
  47. fi
  48. if test -f 'sys/eunice/Makefile'
  49. then
  50.     echo shar: will not over-write existing file "'sys/eunice/Makefile'"
  51. else
  52. cat << \SHAR_EOF > 'sys/eunice/Makefile'
  53. # Makefile for MicroEMACS, under Eunice
  54.  
  55. SYS    =eunice
  56. TTY    =termcap
  57.  
  58. LIBS    = -ltermcap
  59. # CDEFS gets defines, and gets passed to lint. CFLAGS gets flags, and doesn't
  60. # get passed to lint.
  61. CDEFS    =  -Isys/$(SYS)/ -Itty/$(TTY)/ -DDO_METAKEY -DSTARTUP
  62. CFLAGS    = -g $(CDEFS)
  63.  
  64. OBJ =    basic.o buffer.o cinfo.o display.o echo.o extend.o file.o kbd.o \
  65.     line.o main.o match.o random.o region.o search.o symbol.o version.o \
  66.     window.o paragraph.o prefix.o word.o \
  67.     fileio.o spawn.o ttyio.o tty.o ttykbd.o
  68.  
  69. OSRCS = fileio.c spawn.c ttyio.c tty.c ttykbd.c
  70. SRCS =    basic.c buffer.c cinfo.c display.c echo.c extend.c file.c kbd.c \
  71.     line.c main.c match.c random.c region.c search.c symbol.c version.c \
  72.     window.c word.c paragraph.c prefix.c
  73. INCS =    def.h
  74.  
  75. mg:        $(OBJ) $(XOBJ)
  76.     cc $(CFLAGS) -o mg $(OBJ) $(LIBS)
  77.     rm -f $(OSRCS)
  78.  
  79. # the v arg to lint turns off all the complaints about args f, n & k.
  80. # It's a good idea to take that out and rerun make lint after getting
  81. # a clean lint, just to verify that f, n & k are the ONLY unused args.
  82. lint: $(SRCS) $(OSRCS)
  83.     lint -ahb $(CDEFS) $(SRCS) $(OSRCS)
  84.  
  85. clean:    rm -f *.o $(OSRCS)
  86.  
  87. $(OBJ):        def.h sys/$(SYS)/sysdef.h tty/$(TTY)/ttydef.h
  88.  
  89. fileio.c:    sys/$(SYS)/fileio.c
  90.     cp sys/$(SYS)/fileio.c .
  91.  
  92. spawn.c:    sys/$(SYS)/spawn.c
  93.     cp sys/$(SYS)/spawn.c .
  94.  
  95. tty.c:        tty/$(TTY)/tty.c
  96.     cp tty/$(TTY)/tty.c .
  97.  
  98. ttyio.c:    sys/$(SYS)/ttyio.c
  99.     cp sys/$(SYS)/ttyio.c .
  100.  
  101. ttykbd.c:    tty/$(TTY)/ttykbd.c
  102.     cp tty/$(TTY)/ttykbd.c .
  103. SHAR_EOF
  104. fi # end of overwriting check
  105. if test -f 'sys/eunice/fileio.c'
  106. then
  107.     echo shar: will not over-write existing file "'sys/eunice/fileio.c'"
  108. else
  109. cat << \SHAR_EOF > 'sys/eunice/fileio.c'
  110. /*
  111.  *     Eunice BSD 4.2 file I/O
  112.  */
  113. #include    "def.h"
  114.  
  115. #ifndef    F_OK
  116. #define    F_OK FRDONLY
  117. #endif
  118.  
  119. static    FILE    *ffp;
  120. extern    char    *getenv();
  121.  
  122. /*
  123.  * handle C-shell style names
  124.  */
  125. static char *bsd(fn, buf, bufsiz) char *fn, *buf; int bufsiz;
  126. {
  127.     if (*fn != '~')
  128.         return (fn);
  129.     else {    /* C-shell $HOME-relative names */
  130.         strncpy(buf, getenv("HOME"), bufsiz);
  131.         strncat(buf, fn + 1, bufsiz);
  132.         return (buf);
  133.     }
  134. }
  135.  
  136. /*
  137.  * Open a file for reading.
  138.  */
  139. ffropen(fn) char *fn; {
  140.     char buf[NFILEN];
  141.     fn = bsd(fn, buf, sizeof(buf));
  142.     if ((ffp=fopen(fn, "r")) == NULL)
  143.         return (FIOFNF);
  144.     return (FIOSUC);
  145. }
  146.  
  147. /*
  148.  * Open a file for writing.
  149.  * Return TRUE if all is well, and
  150.  * FALSE on error (cannot create).
  151.  */
  152. ffwopen(fn) char *fn; {
  153.     char buf[NFILEN];
  154.     fn = bsd(fn, buf, sizeof(buf));
  155.     if ((ffp=fopen(fn, "w")) == NULL) {
  156.         ewprintf("Cannot open file for writing");
  157.         return (FIOERR);
  158.     }
  159.     return (FIOSUC);
  160. }
  161.  
  162. /*
  163.  * Close a file.
  164.  * Should look at the status.
  165.  */
  166. ffclose() {
  167.     (VOID) fclose(ffp);
  168.     return (FIOSUC);
  169. }
  170.  
  171. /*
  172.  * Write a line to the already
  173.  * opened file. The "buf" points to the
  174.  * buffer, and the "nbuf" is its length, less
  175.  * the free newline. Return the status.
  176.  * Check only at the newline.
  177.  */
  178. ffputline(buf, nbuf) register char buf[]; {
  179.     register int    i;
  180.  
  181.     /* What's with putc? */
  182.     for (i=0; i<nbuf; ++i)
  183.         putc(buf[i]&0xFF, ffp);
  184.     putc('\n', ffp);
  185.     if (ferror(ffp) != FALSE) {
  186.         ewprintf("Write I/O error");
  187.         return (FIOERR);
  188.     }
  189.     return (FIOSUC);
  190. }
  191.  
  192. /*
  193.  * Read a line from a file, and store the bytes
  194.  * in the supplied buffer. Stop on end of file or end of
  195.  * line. Don't get upset by files that don't have an end of
  196.  * line on the last line; this seem to be common on CP/M-86 and
  197.  * MS-DOS (the suspected culprit is VAX/VMS kermit, but this
  198.  * has not been confirmed. If this is sufficiently researched
  199.  * it may be possible to pull this kludge). Delete any CR
  200.  * followed by an LF. This is mainly for runoff documents,
  201.  * both on VMS and on Ultrix (they get copied over from
  202.  * VMS systems with DECnet).
  203.  */
  204. ffgetline(buf, nbuf) register char buf[]; {
  205.     register int    c;
  206.     register int    i;
  207.  
  208.     i = 0;
  209.     for (;;) {
  210.         c = getc(ffp);
  211.         if (c == '\r') {        /* Delete any non-stray    */
  212.             c = getc(ffp);        /* carriage returns.    */
  213.             if (c != '\n') {
  214.                 if (i >= nbuf-1) {
  215.                     ewprintf("File has long line");
  216.                     return (FIOERR);
  217.                 }
  218.                 buf[i++] = '\r';
  219.             }
  220.         }
  221.         if (c==EOF || c=='\n')        /* End of line.        */
  222.             break;
  223.         if (i >= nbuf-1) {
  224.             ewprintf("File has long line");
  225.             return (FIOERR);
  226.         }
  227.         buf[i++] = c;
  228.     }
  229.     if (c == EOF) {                /* End of file.        */
  230.         if (ferror(ffp) != FALSE) {
  231.             ewprintf("File read error");
  232.             return (FIOERR);
  233.         }
  234.         if (i == 0)            /* Don't get upset if    */
  235.             return (FIOEOF);    /* no newline at EOF.    */
  236.     }
  237.     buf[i] = 0;
  238.     return (FIOSUC);
  239. }
  240.  
  241. #if    BACKUP
  242. /*
  243.  * Rename the file "fname" into a backup
  244.  * copy. On Unix the backup has the same name as the
  245.  * original file, with a "~" on the end; this seems to
  246.  * be newest of the new-speak. The error handling is
  247.  * all in "file.c". The "unlink" is perhaps not the
  248.  * right thing here; I don't care that much as
  249.  * I don't enable backups myself.
  250.  */
  251. fbackupfile(fn) char *fn; {
  252.     register char    *nname;
  253.     char        *malloc();
  254.     char        buf[NFILEN];
  255.  
  256.     fn = bsd(fn, buf, sizeof(buf));
  257.     if ((nname=malloc(strlen(fn)+1+1)) == NULL) {
  258.         ewprintf("Can't get %d bytes", strlen(fname) + 1);
  259.         return (ABORT);
  260.     }
  261.     (void) strcpy(nname, fn);
  262.     (void) strcat(nname, "~");
  263.     (void) unlink(nname);            /* Ignore errors.    */
  264.     if (rename(fname, nname) < 0) {
  265.         free(nname);
  266.         return (FALSE);
  267.     }
  268.     free(nname);
  269.     return (TRUE);
  270. }
  271. #endif
  272. /*
  273.  * The string "fn" is a file name.
  274.  * Perform any required case adjustments. All sustems
  275.  * we deal with so far have case insensitive file systems.
  276.  * We zap everything to lower case. The problem we are trying
  277.  * to solve is getting 2 buffers holding the same file if
  278.  * you visit one of them with the "caps lock" key down.
  279.  * On UNIX file names are dual case, so we leave
  280.  * everything alone.
  281.  */
  282. /*ARGSUSED*/
  283. adjustcase(fn) register char *fn; {
  284. #if    0
  285.     register int    c;
  286.  
  287.     while ((c = *fn) != 0) {
  288.         if (c>='A' && c<='Z')
  289.             *fn = c + 'a' - 'A';
  290.         ++fn;
  291.     }
  292. #endif
  293. }
  294.  
  295. #ifdef    STARTUP
  296. #include <sys/file.h>
  297. /*
  298.  * find the users startup file, and return it's name. Check for
  299.  * $HOME/.mg then for $HOME/.emacs, then give up.
  300.  */
  301.  
  302. char *
  303. startupfile() {
  304.     register char    *file;
  305.     static char    home[NFILEN];
  306.     char        *getenv();
  307.  
  308.     if ((file = getenv("HOME")) == NULL) return NULL;
  309.     if (strlen(file)+7 >= NFILEN - 1) return NULL;
  310.     (VOID) strcpy(home, file);
  311.     file = &(home[strlen(home)]);
  312.     *file++ = '/';
  313.  
  314.     (VOID) strcpy(file, ".mg");
  315.     if (access(home, F_OK ) == 0) return home;
  316.  
  317.     (VOID) strcpy(file, ".emacs");
  318.     if (access(home, F_OK) == 0) return home;
  319.  
  320.     return NULL;
  321. }
  322. #endif
  323. SHAR_EOF
  324. fi # end of overwriting check
  325. if test -f 'sys/eunice/readme'
  326. then
  327.     echo shar: will not over-write existing file "'sys/eunice/readme'"
  328. else
  329. cat << \SHAR_EOF > 'sys/eunice/readme'
  330. This directory contains sources that allow MicroEmacs to be compiled
  331. and linked using Eunice cc.  Although I am the de facto Eunice hacker
  332. at the site I work for, I don't have enough experience with it to
  333. understand why it crashes for me when I attempt to run it under the
  334. C shell.  If I give the command
  335.  
  336.     $ MG :== $dev:[dir]MG. MG
  337.  
  338. and invoke it from DCL, it works fine.  If you find out what's wrong
  339. (probably something simple), let me know.
  340.  
  341. If you have the VAX C compiler, you might be better off using the native
  342. VMS terminal/system modules, to avoid the overhead involved in running Eunice.
  343.  
  344. Mic Kaczmarczik
  345. ...!ihnp4!seismo!ut-sally!ut-ngp!mic
  346. ccep001@utadnx.bitnet
  347. mic@ngp.utexas.edu
  348. SHAR_EOF
  349. fi # end of overwriting check
  350. if test -f 'sys/eunice/spawn.c'
  351. then
  352.     echo shar: will not over-write existing file "'sys/eunice/spawn.c'"
  353. else
  354. cat << \SHAR_EOF > 'sys/eunice/spawn.c'
  355. /*
  356.  * Spawn. New version, which
  357.  * interracts with the job control stuff
  358.  * in the 4.X BSD C shell.
  359.  * Last edit:  Wed Aug 27 11:16:07 PDT 1986
  360.  * By:           rtech!daveb, to use stop for ksh.
  361.  */
  362. #include    "def.h"
  363.  
  364. #include    <sgtty.h>
  365. #include    <signal.h>
  366.  
  367. char    *shellp    = NULL;            /* Saved "SHELL" name.        */
  368.  
  369. extern    struct    sgttyb    oldtty;        /* There really should be a    */
  370. extern    struct    sgttyb    newtty;        /* nicer way of doing this, so    */
  371. extern    struct    sgttyb    oldtchars;    /* spawn does not need to know    */
  372. extern    struct    sgttyb    newtchars;    /* about the insides of the    */
  373. extern    struct    sgttyb    oldltchars;    /* terminal I/O code.        */
  374. extern    struct    sgttyb    newltchars;
  375.  
  376. extern    char    *getenv();
  377.  
  378. /*
  379.  * This code does a one of 2 different
  380.  * things, depending on what version of the shell
  381.  * you are using. If you are using the C shell, which
  382.  * implies that you are using job control, then MicroEMACS
  383.  * moves the cursor to a nice place and sends itself a
  384.  * stop signal. If you are using the Bourne shell it runs
  385.  * a subshell using fork/exec. Bound to "C-C", and used
  386.  * as a subcommand by "C-Z".
  387.  *
  388.  * Daveb -- changed sense of test so that we only spawn if you
  389.  *        are explicitly using /bin/sh.  This makes it stop
  390.  *        work with the ksh.
  391.  */
  392. /*ARGSUSED*/
  393. spawncli(f, n, k) {
  394.     register int    pid, wpid, (*oqsig)(), (*oisig)(), omask;
  395.     int        status;
  396.  
  397.     if (shellp == NULL) {
  398.         shellp = getenv("SHELL");
  399.         if (shellp == NULL)
  400.             shellp = getenv("shell");
  401.         if (shellp == NULL)
  402.             shellp = "/bin/sh";    /* Safer.        */
  403.     }
  404.     ttcolor(CTEXT);
  405.     ttnowindow();
  406.     if (strcmp(shellp, "/bin/csh") == 0) {
  407.         if (epresf != FALSE) {
  408.             ttmove(nrow-1, 0);
  409.             tteeol();
  410.             epresf = FALSE;
  411.         }                /* Csh types a "\n"    */
  412.         ttmove(nrow-2, 0);        /* before "Stopped".    */
  413.     } else {
  414.         ttmove(nrow-1, 0);
  415.         if (epresf != FALSE) {
  416.             tteeol();
  417.             epresf = FALSE;
  418.         }
  419.     }
  420.     ttflush();
  421.     if (ioctl(0, TIOCSLTC, (char *) &oldltchars) < 0
  422.     ||  ioctl(0, TIOCSETC, (char *) &oldtchars)  < 0
  423.     ||  ioctl(0, TIOCSETP, (char *) &oldtty)     < 0) {
  424.         ewprintf("IOCTL #1 to terminal failed");
  425.         return (FALSE);
  426.     }
  427.     if (strcmp(shellp, "/bin/sh") != 0) {    /* C shell, ksh        */
  428. #ifdef    BSD43
  429.         omask = sigsetmask(0);
  430. #endif
  431.         (void) kill(0, SIGTSTP);
  432.         setttysize() ;
  433. #ifdef    BSD43
  434.         (void) sigsetmask(omask);
  435. #endif
  436.     } else {                /* Bourne shell.    */
  437.         oqsig = signal(SIGQUIT, SIG_IGN);
  438.         oisig = signal(SIGINT,  SIG_IGN);
  439.         if ((pid=fork()) < 0) {
  440.             (void) signal(SIGQUIT, oqsig);
  441.             (void) signal(SIGINT,  oisig);
  442.             ewprintf("Failed to create process");
  443.             return (FALSE);
  444.         }
  445.         if (pid == 0) {
  446.             execl(shellp, "sh", "-i", NULL);
  447.             _exit(0);        /* Should do better!    */
  448.         }
  449.         while ((wpid=wait(&status))>=0 && wpid!=pid)
  450.                 ;
  451.         (void) signal(SIGQUIT, oqsig);
  452.         (void) signal(SIGINT,  oisig);
  453.     }
  454.     sgarbf = TRUE;                /* Force repaint.    */
  455.     if (ioctl(0, TIOCSETP, (char *) &newtty)     < 0
  456.     ||  ioctl(0, TIOCSETC, (char *) &newtchars)  < 0
  457.     ||  ioctl(0, TIOCSLTC, (char *) &newltchars) < 0) {
  458.         ewprintf("IOCTL #2 to terminal failed");
  459.         return (FALSE);
  460.     }
  461.     return (TRUE);
  462. }
  463. SHAR_EOF
  464. fi # end of overwriting check
  465. if test -f 'sys/eunice/sysdef.h'
  466. then
  467.     echo shar: will not over-write existing file "'sys/eunice/sysdef.h'"
  468. else
  469. cat << \SHAR_EOF > 'sys/eunice/sysdef.h'
  470. /*
  471.  *        Ultrix-32 system header file.
  472.  */
  473. #define    PCC    1            /* "[]" gets an error.        */
  474. #define    KBLOCK    8192            /* Kill grow.            */
  475. #define    GOOD    0            /* Good exit status.        */
  476.  
  477. typedef int    RSIZE;            /* Type for file/region sizes    */
  478. typedef short    KEY;            /* Type for internal keystrokes    */
  479.  
  480. /*
  481.  * Macros used by the buffer name making code.
  482.  * Start at the end of the file name, scan to the left
  483.  * until BDC1 (or BDC2, if defined) is reached. The buffer
  484.  * name starts just to the right of that location, and
  485.  * stops at end of string (or at the next BDC3 character,
  486.  * if defined). BDC2 and BDC3 are mainly for VMS.
  487.  */
  488. #define    BDC1    '/'            /* Buffer names.        */
  489. SHAR_EOF
  490. fi # end of overwriting check
  491. if test -f 'sys/eunice/ttyio.c'
  492. then
  493.     echo shar: will not over-write existing file "'sys/eunice/ttyio.c'"
  494. else
  495. cat << \SHAR_EOF > 'sys/eunice/ttyio.c'
  496. /*
  497.  *        Ultrix-32 and Unix terminal I/O.
  498.  * The functions in this file
  499.  * negotiate with the operating system for
  500.  * keyboard characters, and write characters to
  501.  * the display in a barely buffered fashion.
  502.  */
  503. #include    "def.h"
  504.  
  505. #include    <sgtty.h>
  506.  
  507. #define    NOBUF    512            /* Output buffer size.        */
  508.  
  509. char    obuf[NOBUF];            /* Output buffer.        */
  510. int    nobuf;
  511. struct    sgttyb    oldtty;            /* V6/V7 stty data.        */
  512. struct    sgttyb    newtty;
  513. struct    tchars    oldtchars;        /* V7 editing.            */
  514. struct    tchars    newtchars;
  515. struct    ltchars oldltchars;        /* 4.2 BSD editing.        */
  516. struct    ltchars    newltchars;
  517. #ifdef    TIOCGWINSZ
  518. struct    winsize    winsize;        /* 4.3 BSD window sizing    */
  519. #endif
  520. int    nrow;                /* Terminal size, rows.        */
  521. int    ncol;                /* Terminal size, columns.    */
  522.  
  523. /*
  524.  * This function gets called once, to set up
  525.  * the terminal channel. On Ultrix is's tricky, since
  526.  * we want flow control, but we don't want any characters
  527.  * stolen to send signals. Use CBREAK mode, and set all
  528.  * characters but start and stop to 0xFF.
  529.  */
  530. ttopen() {
  531.         register char *tv_stype;
  532.         char *getenv(), *tgetstr(), tcbuf[1024], err_str[72];
  533.  
  534.     if (ioctl(0, TIOCGETP, (char *) &oldtty) < 0)
  535.         panic("ttopen can't get sgtty");
  536.     newtty.sg_ospeed = oldtty.sg_ospeed;
  537.     newtty.sg_ispeed = oldtty.sg_ispeed;
  538.     newtty.sg_erase  = oldtty.sg_erase;
  539.     newtty.sg_kill   = oldtty.sg_kill;
  540.     newtty.sg_flags  = oldtty.sg_flags;
  541.     newtty.sg_flags &= ~(ECHO|CRMOD);    /* Kill echo, CR=>NL.    */
  542. #ifdef FLOWCONTROL
  543.     newtty.sg_flags |= CBREAK;        /* Half-cooked mode.    */
  544. #else
  545.     newtty.sg_flags |= RAW|ANYP;        /* raw mode for 8 bit path.*/
  546. #endif
  547.     if (ioctl(0, TIOCSETP, (char *) &newtty) < 0)
  548.         panic("ttopen can't set sgtty");
  549.     if (ioctl(0, TIOCGETC, (char *) &oldtchars) < 0)
  550.         panic("ttopen can't get chars");
  551.     newtchars.t_intrc  = 0xFF;        /* Interrupt.        */
  552.     newtchars.t_quitc  = 0xFF;        /* Quit.        */
  553. #if FLOWCONTROL
  554.     newtchars.t_startc = 0x11;        /* ^Q, for terminal.    */
  555.     newtchars.t_stopc  = 0x13;        /* ^S, for terminal.    */
  556. #else
  557.     newtchars.t_startc = 0xFF;        /* ^Q, for terminal.    */
  558.     newtchars.t_stopc  = 0xFF;        /* ^S, for terminal.    */
  559. #endif
  560.     newtchars.t_eofc   = 0xFF;
  561.     newtchars.t_brkc   = 0xFF;
  562.     if (ioctl(0, TIOCSETC, (char *) &newtchars) < 0)
  563.         panic("ttopen can't set chars");
  564.     if (ioctl(0, TIOCGLTC, (char *) &oldltchars) < 0)
  565.         panic("ttopen can't get ltchars");
  566.     newltchars.t_suspc  = 0xFF;        /* Suspend #1.        */
  567.     newltchars.t_dsuspc = 0xFF;        /* Suspend #2.        */
  568.     newltchars.t_rprntc = 0xFF;
  569.     newltchars.t_flushc = 0xFF;        /* Output flush.    */
  570.     newltchars.t_werasc = 0xFF;
  571.     newltchars.t_lnextc = 0xFF;        /* Literal next.    */
  572.     if (ioctl(0, TIOCSLTC, (char *) &newltchars) < 0)
  573.         panic("ttopen can't set ltchars");
  574.  
  575. /* do this the REAL way */
  576.         if ((tv_stype = getenv("TERM")) == NULL)
  577.         {
  578.                 puts("Environment variable TERM not defined!");
  579.                 exit(1);
  580.         }
  581.  
  582.         if((tgetent(tcbuf, tv_stype)) != 1)
  583.         {
  584.                 (void) sprintf(err_str, "Unknown terminal type %s!", tv_stype);
  585.                 puts(err_str);
  586.                 exit(1);
  587.         }
  588.  
  589.     setttysize() ;
  590. }
  591.  
  592. /*
  593.  * This function gets called just
  594.  * before we go back home to the shell. Put all of
  595.  * the terminal parameters back.
  596.  */
  597. ttclose() {
  598.     ttflush();
  599.     if (ioctl(0, TIOCSLTC, (char *) &oldltchars) < 0)
  600.         panic("ttclose can't set ltchars");
  601.     if (ioctl(0, TIOCSETC, (char *) &oldtchars) < 0)
  602.         panic("ttclose can't set chars");
  603.     if (ioctl(0, TIOCSETP, (char *) &oldtty) < 0)
  604.         panic("ttclose can't set sgtty");
  605. }
  606.  
  607. /*
  608.  * Write character to the display.
  609.  * Characters are buffered up, to make things
  610.  * a little bit more efficient.
  611.  */
  612. ttputc(c) {
  613.     if (nobuf >= NOBUF)
  614.         ttflush();
  615.     obuf[nobuf++] = c;
  616. }
  617.  
  618. /*
  619.  * Flush output.
  620.  */
  621. ttflush() {
  622.     if (nobuf != 0) {
  623.         if (write(1, obuf, nobuf) != nobuf)
  624.             panic("ttflush write failed");
  625.         nobuf = 0;
  626.     }
  627. }
  628.  
  629. /*
  630.  * Read character from terminal.
  631.  * All 8 bits are returned, so that you can use
  632.  * a multi-national terminal.
  633.  */
  634. ttgetc() {
  635.     char    buf[1];
  636.  
  637.     while (read(0, &buf[0], 1) != 1)
  638.         ;
  639.     return (buf[0] & 0xFF);
  640. }
  641. /*
  642.  * set the tty size. Functionized for 43BSD.
  643.  */
  644. setttysize() {
  645.  
  646. #ifdef    TIOCGWINSZ
  647.     if (ioctl(0, TIOCGWINSZ, (char *) &winsize) == 0) {
  648.         nrow = winsize . ws_row;
  649.         ncol = winsize . ws_col;
  650.     } else
  651. #endif
  652.     if ((nrow=tgetnum ("li")) <= 0
  653.     || (ncol=tgetnum ("co")) <= 0) {
  654.         nrow = 24;
  655.         ncol = 80;
  656.     }
  657.     if (nrow > NROW)            /* Don't crash if the    */
  658.         nrow = NROW;            /* termcap entry is    */
  659.     if (ncol > NCOL)            /* too big.        */
  660.         ncol = NCOL;
  661. }
  662.  
  663. /*
  664.  * typeahead returns TRUE if there are characters available to be read
  665.  * in.
  666.  */
  667. typeahead() {
  668.     int    x;
  669.  
  670.     return((ioctl(0, FIONREAD, (char *) &x) < 0) ? 0 : x);
  671. }
  672.  
  673. /*
  674.  * panic - just exit, as quickly as we can.
  675.  */
  676. panic(s) char *s; {
  677.     printf(stderr, "panic: %s\n", s);
  678.     abort();        /* To leave a core image. */
  679. }
  680. SHAR_EOF
  681. fi # end of overwriting check
  682. if test -f 'sys/vms/aaareadme.1st'
  683. then
  684.     echo shar: will not over-write existing file "'sys/vms/aaareadme.1st'"
  685. else
  686. cat << \SHAR_EOF > 'sys/vms/aaareadme.1st'
  687. This directory ([.SYS.VMS]) contains the VMS-specific files for MicroGnuEmacs.
  688.  
  689.             +-----------------------+
  690.             |      Construction    |
  691.             +-----------------------+
  692.  
  693. By this point you should have put the ``system-independent'' files into
  694. a directory of your choice, then put the VMS files into the subdirectory
  695. [.SYS.VMS].  You should also put the termcap terminal driver into the
  696. subdirectory [.TTY.TERMCAP]. 
  697.  
  698. The command file MAKE.COM is designed to compile and link the entire
  699. program, using the VMS system functions and the termcap terminal driver.
  700.  
  701. To invoke MAKE.COM, enter
  702.  
  703.     SET DEF dev:[emacs-dir]    ! location of system-independent files
  704.     @[.SYS.VMS]MAKE        ! go have some coffee...
  705.  
  706. This will create the termcap library, compile each of the necessary
  707. modules, and link the entire program into dev:[emacs-dir]MG.EXE.
  708.  
  709. NOTE: To keep the size of the executable program down,
  710. [.SYS.VMS]MGLINK.COM attempts to link in the VAX C shareable run-time
  711. library. If the command procedure finds the file SYS$SHARE:VAXCRTL.EXE,
  712. it attempts to link to it, else it defaults to SYS$LIBRARY:VAXCRTL.OLB
  713. for the runtime library.
  714.  
  715.     +-------------------------------------------------------+
  716.     |    Specifying Your Terminal With Termcap        |
  717.     +-------------------------------------------------------+
  718.  
  719. (CAVEAT AND CREDITS: The termcap library in [.SYS.VMS.TERMCAP] was
  720. written by Fred Fish (of Amiga Public Domain Library fame) and placed in
  721. the public domain. It is not guaranteed to be a complete implementation
  722. of the Unix termcap(5) library; the usual disclaimers (like "it works
  723. for me":-) apply here.  I have modified it to support the tc=
  724. capability, which lets you define terminals in terms (pardon the pun) of
  725. other terminals, so it should work reasonably well with the termcap
  726. provided in [.SYS.VMS.TERMCAP]TERMCAP.)
  727.  
  728. To use the termcap library, you need to tell it where to find a terminal
  729. definition (termcap) file. On Unix systems, this is found in a file
  730. called /etc/termcap. To emulate the same behavior on VMS, DEFINE/JOB the
  731. logical name ETC to point to a directory that contains a termcap file,
  732. with the name TERMCAP. (no extension). (The /JOB qualifier is needed
  733. when you run MicroGnuEmacs as a spawned supprocess.)
  734.  
  735. If your system has Eunice, there is a large termcap file already
  736. available via this exact mechanism, so you shouldn't need to define ETC
  737. at all.  If you don't have Eunice, never fear; a termcap resides in the
  738. file [.SYS.VMS.TERMCAP]TERMCAP., so all you have to do is
  739.  
  740.     DEFINE ETC [emacs-directory.SYS.VMS.TERMCAP]
  741.  
  742. to get started.  You get the idea.  Lastly, if your site uses the logical
  743. name ETC for another purpose, you can define the logical name TERMCAP
  744. to point to the MG termcap file.  You must specify the path in Unix format,
  745. with the root being the disk drive the file resides on.  For example,
  746. if the termcap file is in DUA0:[USER]TERMCAP., the command would be
  747.  
  748.     DEFINE TERMCAP "/dua0/user/termcap"
  749.  
  750. The VAX C run-time library can translate this into the appropriate
  751. VMS file specification for you (a rather nice feature...).
  752.  
  753. Once you've indicated where the termcap file is,
  754.     DEFINE/JOB TERM "termtype"
  755.  
  756. where "termtype" is in lower case and matches an entry in the termcap
  757. file. This tells MicroEmacs (even when it runs in another process) what
  758. your terminal type is. 
  759.  
  760. NOTE: One performance aspect of termcap files is that they are searched
  761. sequentially, so you may want to move the most frequently used terminals
  762. at your site to the beginning of the file to minimize startup overhead. 
  763.  
  764.         +---------------------------------------+
  765.         |        INVOKING MG        |
  766.         +---------------------------------------+
  767.  
  768. First of all, remember to set up the logical names for the terminal
  769. type and termcap file:
  770.     $ DEFINE/JOB    ETC    dev:[dir]    ! location of TERMCAP. file
  771.     (or)$ DEFINE/JOB    TERMCAP "/disk/dir1/dir2/termcapfile"
  772.  
  773.     $ DEFINE/JOB    TERM    "termtype"    ! termtype is lower case
  774.  
  775. (Obviously, this can be done just once, in your LOGIN.COM file.)
  776.  
  777. Then, to just run MicroGnuEmacs in your current process,
  778.     $ RUN [emacs-directory]MG
  779.  
  780. Or you can define a symbol to run it with command line arguments:
  781.     $ MG :== $dev:[emacs-directory]MG
  782.     $ MG [file]
  783.  
  784.         +---------------------------------------+
  785.         |              MG As a Kept Fork        |
  786.         +---------------------------------------+
  787.  
  788. You can use [.SYS.VMS]MG.COM to spawn a MicroEmacs subjob, which you
  789. can then attach to and pop out of as you please. Edit the line at the
  790. top of MG.COM that defines the path to the image MG.EXE, then define a
  791. global symbol called MG:
  792.  
  793.     $ MG :== @dev:[emacs-directory.SYS.VMS]MG
  794.  
  795. You can then use MG to edit files:
  796.  
  797.     $ MG [file]
  798.  
  799. When inside MicroGnuEmacs, use the command M-x suspend-emacs (bound to
  800. C-z by default) to suspend the MicroGnuEmacs process and attach your
  801. terminal to the process that spawned it. To re-attach to
  802. MicroGnuEmacs, just issue the MG command again:
  803.  
  804.     $ MG [file]
  805.  
  806. The command file will reattach you to your MicroGnuEmacs process,
  807. where you can continue editing where you left off. If you specify a
  808. new file to edit, the command file sets a logical name which
  809. MicroGnuEmacs then looks at when you reattach. 
  810.  
  811. Note that this functionality may not be identical to what happens in
  812. real GNU Emacs for VMS. However, it does provide a facility that you
  813. don't really want to do without.
  814.  
  815.         +---------------------------------------+
  816.         |     MicroGnuEmacs As a Mail Editor    |
  817.         +---------------------------------------+
  818.  
  819. As an added bonus, the file MGMAILEDIT.COM makes MicroGnuEmacs your
  820. mail editor when you use the SEND/EDIT command.  Just issue the
  821. command
  822.  
  823.     DEFINE/JOB MAIL$EDIT dev:[dir]MGMAILEDIT.COM
  824.  
  825. to inform the mail system you want to use MGMAILEDIT.COM, then whenever
  826. you issue SEND/EDIT inside mail, MG will be used as your mail editor.
  827. SHAR_EOF
  828. fi # end of overwriting check
  829. if test -f 'sys/vms/bcopy.mar'
  830. then
  831.     echo shar: will not over-write existing file "'sys/vms/bcopy.mar'"
  832. else
  833. cat << \SHAR_EOF > 'sys/vms/bcopy.mar'
  834.     .title    bcopy    MicroEmacs access to movc3
  835. ;
  836. ;    Mic Kaczmarczik
  837. ;    July 11, 1986
  838. ;
  839. ;    This code implements the bcopy() function for quick
  840. ;    memory copies in VAX C.
  841. ;
  842.     .entry    bcopy,^m<r2,r3,r4,r5>    ; MOVC3 side-effects r0-r5
  843.     subl2    #4,sp            ; Step over call frame
  844.     movc3    12(ap),@4(ap),@8(ap)    ; Copy them bytes
  845.     ret                ; Bye!
  846.     .end
  847. SHAR_EOF
  848. fi # end of overwriting check
  849. if test -f 'sys/vms/ccom.com'
  850. then
  851.     echo shar: will not over-write existing file "'sys/vms/ccom.com'"
  852. else
  853. cat << \SHAR_EOF > 'sys/vms/ccom.com'
  854. $    Verify = F$Verify(0)
  855. $!
  856. $! CCOM.COM
  857. $!
  858. $!    Run the C compiler on P1, but only if the .c file
  859. $!    is newer than the corresponding .obj file.
  860. $!
  861. $! Usage:
  862. $!    @CCOM [file [qualifiers]]
  863. $!
  864. $    If P1 .Eqs. "" Then -
  865.         Inquire P1 "C Source File"
  866. $    Name = P1 - ".C"
  867. $    Source = Name + ".C"
  868. $    Object = Name + ".OBJ"
  869. $!
  870. $! See if both files exist.  If both exist, only compile the
  871. $! source if the revision date is greater than or equal to
  872. $! that of the object file.
  873. $!
  874. $    If F$Search(Source) .Eqs. "" Then -
  875.         Goto NoSource
  876. $    If F$Search(Object) .Eqs. "" Then -
  877. $        Goto Compile
  878. $    SDate = F$File_Attributes(Source, "RDT")
  879. $    ODate = F$File_Attributes(Object, "RDT") 
  880. $    If SDate .Lts. ODate Then -
  881.         Goto Bye
  882. $!
  883. $! Compile the program
  884. $!
  885. $Compile:
  886. $    On Error Then Goto Fail
  887. $    Write Sys$Output "Compiling " + Source
  888. $    CC 'P2' 'Source
  889. $    If F$Search(Object) .Eqs. "" Then -
  890.         Goto Fail
  891. $!
  892. $! Done.
  893. $!
  894. $Bye:
  895. $    If Verify Then -
  896.         Set Verify
  897. $    Exit
  898. $!
  899. $NoSource:
  900. $    Write Sys$Output "%CCOM-F-NOTFOUND, file not found"
  901. $    Goto Bye
  902. $!
  903. $Fail:
  904. $    Write Sys$Output "%CCOM-F-FAIL, compile failed"
  905. $    Goto Bye
  906.  
  907. SHAR_EOF
  908. fi # end of overwriting check
  909. if test -f 'sys/vms/make.com'
  910. then
  911.     echo shar: will not over-write existing file "'sys/vms/make.com'"
  912. else
  913. cat << \SHAR_EOF > 'sys/vms/make.com'
  914. $    on error then goto trouble
  915. $    on severe_error then goto trouble
  916. $    default = f$trnlnm("SYS$DISK") + f$directory()
  917. $!
  918. $! Command procedure to build MicroGnuEmacs on VMS systems.
  919. $!
  920. $! Compile-time options you can set by appropriate assignments to
  921. $! "ccomflags" and "linkflags".  Defining these flags asks for
  922. $! a particular feature.
  923. $!
  924. $!    /DEFINE:"STARTUP"        -- look for SYS$LOGIN:.MG startup file
  925. $!    /DEFINE:"FLOWCONTROL"        -- use ^S, ^Q for flow control
  926. $!
  927. $! Set compilation and linking options.  The first commented-out-line is
  928. $! the set I use...
  929. $    ccomflags := "/define:""STARTUP"" "
  930. $!    ccomflags := "/define:(""STARTUP"",""XKEYS"",""PREFIXREGION"") "
  931. $!    ccomflags := "/debug"    ! if you want to debug the program
  932. $!
  933. $    linkflags := ""
  934. $!    linkflags := "/debug"    ! to debug the program
  935. $!
  936. $! To make MG,
  937. $!
  938. $! Set def to the top level MicroGnuEmacs directory and type
  939. $!
  940. $!    @[.SYS.VMS]MAKE
  941. $!
  942. $! to get things rolling.
  943. $!
  944. $!* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  945. $! Create the termcap library
  946. $!
  947. $    set def [.sys.vms.termcap]
  948. $    @createlib.com
  949. $    set def [---]
  950. $!* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  951. $! Define a search path for source files.  This is important
  952. $! because 
  953. $!    1) The search path lets us to keep these files in
  954. $!       separate directories
  955. $!    2) When searching for quoted #include files (e.g.
  956. $!       #include "def.h"), VAX C uses the default file
  957. $!       specification set up by the source file name.
  958. $!
  959. $!       If we use mgsrc:foo.c,  the search list becomes
  960. $!       part of the default file spec, and the compiler
  961. $!       can find the system- and terminal-specific
  962. $!       header files.  This acts as a substitute for the
  963. $!       -I flag found on most Unix C compilers.
  964. $!
  965. $! A side effect of the search list is that the object files get
  966. $! created in the top level directory, which I prefer.
  967. $!
  968. $    define mgsrc [],[.sys.vms],[.tty.termcap]
  969. $!
  970. $! Define alias for the compilation command.  By default, use a
  971. $! command file that checks revision dates and only compiles when
  972. $! it has to.  If you want to force a total recompile,  switch the
  973. $! comments around.
  974. $!
  975. $    ccom := @mgsrc:ccom
  976. $!    ccom := cc
  977. $!
  978. $! Compile all the basic files
  979. $!
  980. $    ccom mgsrc:basic    'ccomflags
  981. $    ccom mgsrc:buffer    'ccomflags
  982. $    ccom mgsrc:cinfo    'ccomflags
  983. $    ccom mgsrc:display    'ccomflags
  984. $    ccom mgsrc:echo        'ccomflags
  985. $    ccom mgsrc:extend    'ccomflags
  986. $    ccom mgsrc:file        'ccomflags
  987. $    ccom mgsrc:kbd        'ccomflags
  988. $    ccom mgsrc:line        'ccomflags
  989. $    ccom mgsrc:main        'ccomflags
  990. $    ccom mgsrc:match    'ccomflags
  991. $    ccom mgsrc:paragraph    'ccomflags
  992. $    ccom mgsrc:prefix    'ccomflags
  993. $    ccom mgsrc:random    'ccomflags
  994. $    ccom mgsrc:region    'ccomflags
  995. $    ccom mgsrc:search    'ccomflags
  996. $    ccom mgsrc:symbol    'ccomflags
  997. $    ccom mgsrc:version    'ccomflags
  998. $    ccom mgsrc:window    'ccomflags
  999. $    ccom mgsrc:word        'ccomflags
  1000. $!
  1001. $! Compile the terminal interface 
  1002. $!
  1003. $    ccom mgsrc:tty        'ccomflags
  1004. $    ccom mgsrc:ttykbd    'ccomflags
  1005. $!
  1006. $! Compile the VMS-specific files
  1007. $!
  1008. $    ccom mgsrc:fileio    'ccomflags
  1009. $    ccom mgsrc:spawn    'ccomflags
  1010. $    ccom mgsrc:trnlnm    'ccomflags
  1011. $    ccom mgsrc:ttyio    'ccomflags/define:"FLOWCONTROL=0"
  1012. $    macro mgsrc:bcopy
  1013. $!
  1014. $! Link the program
  1015. $!
  1016. $    @[.sys.vms]mglink    "''linkflags'"
  1017. $!
  1018. $! We're done!
  1019. $!
  1020. $    write sys$output "MicroEmacs build completed."
  1021. $    set default 'default
  1022. $    exit
  1023. $!
  1024. $! Trouble somewhere -- go 'way
  1025. $!
  1026. $trouble:
  1027. $    write sys$output "Problem building MicroEmacs!!!!!"
  1028. $    set default 'default
  1029. $    exit
  1030. SHAR_EOF
  1031. fi # end of overwriting check
  1032. if test -f 'sys/vms/mg.com'
  1033. then
  1034.     echo shar: will not over-write existing file "'sys/vms/mg.com'"
  1035. else
  1036. cat << \SHAR_EOF > 'sys/vms/mg.com'
  1037. $    Verify = 'F$Verify(0)
  1038. $!
  1039. $! MG.COM
  1040. $!
  1041. $! Usage:
  1042. $! @MG [file1 [file2 [...]]]        ! To start up MG
  1043. $! @MG [file]                ! To reattach to MG after ^Z
  1044. $!
  1045. $! MG.COM implements a "kept-fork" capability for MG, allowing you to pop
  1046. $! in and out of the editor without reloading it all the time.  If a
  1047. $! process called user_MG (where user is your username) exists, this
  1048. $! command file attempts to attach to it.  If not, it silently spawns a
  1049. $! subjob to run Emacs for you. 
  1050. $!
  1051. $! To `keep' MG around once you get into it, use "suspend-emacs" (bound
  1052. $! to C-z by default) to suspend MG and attach back to the process
  1053. $! pointed to by MG$AttachTo. 
  1054. $!
  1055. $! To get back into MG from DCL enter @MG again.  You may optionally
  1056. $! specify *one* new file name, in which case MG will attempt to
  1057. $! visit that file when you re-attach. 
  1058. $!
  1059. $!----------------------------------------------------------------
  1060. $!
  1061. $! Set things up.  Change the definition of MG_Name to whatever you like.
  1062. $! You'll *have* to redefine MG_PROG, of course...
  1063. $!
  1064. $    MG_Name = F$Edit(F$Getjpi("","USERNAME"),"TRIM") + "_MG"
  1065. $    MG_Prog = "Disk$Staff:[Ccep001.Proj.Mg3]MG.Exe"
  1066. $    MG_Base = MG_Name            ! Used for additions
  1067. $    If F$Length(MG_Base) .GT. 13 Then -    ! Truncate base for _1,_2...
  1068. $        MG_Base = F$Extract(0,13,MG_Base)
  1069. $    Proc = F$GetJpi("","PRCNAM")
  1070. $    Master_Pid = F$Getjpi("","MASTER_PID")
  1071. $!
  1072. $! Define logical names used for communicating with MG
  1073. $!
  1074. $    Define/Nolog/Job MG$AttachTo    "''Proc'"
  1075. $    Define/Nolog/Job MG$File    " "    ! No file by default
  1076. $    If P1 .Nes. "" Then -
  1077.         Define/Nolog/Job MG$File "''P1'"
  1078. $!
  1079. $! Attempt to find MG subprocess in current tree.  If found, attach
  1080. $! to it, else spawn a new MG process
  1081. $!
  1082. $    Save_Priv = F$SetPrv("NOWORLD,NOGROUP")    ! Only look in job tree
  1083. $    Try_Count = 1
  1084. $Search:
  1085. $    Context = ""            ! Set up process search context
  1086. $ProcLoop:
  1087. $    Pid = F$Pid(Context)        ! Get next PID
  1088. $    If Pid .Eqs. "" Then -
  1089.          Goto Spawn        ! No MG_Name found; spawn a process
  1090. $    If F$GetJpi(Pid,"PRCNAM") .Nes. MG_Name Then -
  1091.         Goto Procloop        ! Try next process
  1092. $! Process name matches; see if it's in our job
  1093. $    If F$GetJpi(Pid,"MASTER_PID") .Eqs. Master_Pid Then -
  1094.         Goto Attach        ! Found process in our job!
  1095. $! Process name matches, but isn't in our job.  Re-start search
  1096. $    MG_Name = MG_Base + "_" + F$String(Try_Count)
  1097. $    Try_Count = Try_Count + 1
  1098. $    Goto Search
  1099. $!
  1100. $! Here to attach to a process in our tree. Set message to
  1101. $! turn off the "Attaching to..." message
  1102. $!
  1103. $Attach:
  1104. $    Message = F$Environment("MESSAGE")
  1105. $    Set Proc/Priv=('Save_Priv')        ! Restore privileges
  1106. $    Set Message/NoFacility/NoIdentification/NoSeverity/NoText
  1107. $    Attach "''MG_Name'"
  1108. $    Set Message/Facility/Identification/Severity/Text
  1109. $    Goto Done
  1110. $!
  1111. $! Here if can't attach.  Spawn a new MG process
  1112. $!
  1113. $Spawn:
  1114. $    Set Process/Priv=('Save_Priv')        ! Restore privileges
  1115. $    MG$MG :== $'MG_Prog'            ! Avoid recursion
  1116. $    Spawn/NoLog/Proc="''MG_Name'" MG$MG 'P1' 'P2' 'P3' 'P4' 'P5' 'P6' 'P7' 'P8'
  1117. $    Delete/Symbol/Global MG$MG        ! Get rid of it 
  1118. $Done:
  1119. $!
  1120. $! Here once we reconnect from MG, whether we detached or exited.
  1121. $!
  1122. $    Deassign/Job MG$File
  1123. $    Deassign/Job MG$AttachTo
  1124. $    If Verify Then -
  1125.         Set Verify
  1126. SHAR_EOF
  1127. fi # end of overwriting check
  1128. if test -f 'sys/vms/mglink.com'
  1129. then
  1130.     echo shar: will not over-write existing file "'sys/vms/mglink.com'"
  1131. else
  1132. cat << \SHAR_EOF > 'sys/vms/mglink.com'
  1133. $!
  1134. $! Link MicroGnuEmacs object files into MG.EXE
  1135. $!
  1136. $! Note: This command procedure is designed to be executed
  1137. $! in the main microEmacs directory.
  1138. $!
  1139. $! Further note: If the VAX C shareable run-time library is
  1140. $! found in SYS$SHARE, the command procedure uses it.
  1141. $! If not found, it uses SYS$LIBRARY:VAXCRTL.
  1142. $
  1143. $ runtime_library := sys$library:vaxcrtl.olb/lib
  1144. $ if f$search("SYS$SHARE:VAXCRTL.EXE") .nes. "" then -
  1145.     runtime_library := [.sys.vms]emacs.opt/opt
  1146. $ link'p1'/exec=sys$disk:[]mg.exe basic.obj, buffer.obj, cinfo.obj, -
  1147.     display.obj, echo.obj, extend.obj, file.obj, kbd.obj, line.obj, -
  1148.     main.obj, match.obj, paragraph.obj, prefix.obj, random.obj, -
  1149.     region.obj, search.obj, symbol.obj, version.obj, window.obj, word.obj, -
  1150.     tty.obj, ttykbd.obj, -
  1151.     fileio.obj, spawn.obj, trnlnm.obj, ttyio.obj, bcopy.obj, -
  1152.     [.sys.vms.termcap]termcap.olb/lib,-
  1153.     'runtime_library'
  1154. SHAR_EOF
  1155. fi # end of overwriting check
  1156. if test -f 'sys/vms/mgmailedit.com'
  1157. then
  1158.     echo shar: will not over-write existing file "'sys/vms/mgmailedit.com'"
  1159. else
  1160. cat << \SHAR_EOF > 'sys/vms/mgmailedit.com'
  1161. $    Verify = 'F$Verify(0)
  1162. $ ! Command procedure to invoke MG from MAIL.  You should
  1163. $ ! have the symbol MG globally defined, either as
  1164. $ !
  1165. $ !    MG :== $dev:[dir]MG
  1166. $ !
  1167. $ ! Then
  1168. $ !    DEFINE MAIL$EDIT dev:[dir]MGMAILEDIT.COM
  1169. $ !
  1170. $ ! to make MAIL look for this file.
  1171. $ !
  1172. $ ! or, if using the kept-fork capability,
  1173. $ !
  1174. $ !    MG :== @dev:[dir]MG.COM
  1175. $ !
  1176. $ ! Inputs:
  1177. $ !
  1178. $ !    P1 = Input file name.
  1179. $ !    P2 = Output file name.
  1180. $ !
  1181. $ ! The default directory is the same as the parent process.
  1182. $ !
  1183. $ ! Copy the input file to the output file, then invoke MG on it.
  1184. $ !
  1185. $ Set Noon
  1186. $ Define/Job MG$AttachTo "''F$Process()'"
  1187. $ If P2 .Nes. "" .AND. P1 .Nes. "" Then Copy 'P1' 'P2'
  1188. $ Define/User Sys$Input Sys$Command
  1189. $ MG 'P2'
  1190. $ If F$Trnlnm("MG$AttachTo") .Nes. "" Then - ! MG.COM might have done it already
  1191.     Deassign/Job MG$AttachTo
  1192. $ If Verify Then -
  1193.     Set Verify
  1194. SHAR_EOF
  1195. fi # end of overwriting check
  1196. if test -f 'sys/vms/emacs.opt'
  1197. then
  1198.     echo shar: will not over-write existing file "'sys/vms/emacs.opt'"
  1199. else
  1200. cat << \SHAR_EOF > 'sys/vms/emacs.opt'
  1201. SYS$SHARE:VAXCRTL.EXE/SHARE
  1202. SHAR_EOF
  1203. fi # end of overwriting check
  1204. if test -f 'sys/vms/fileio.c'
  1205. then
  1206.     echo shar: will not over-write existing file "'sys/vms/fileio.c'"
  1207. else
  1208. cat << \SHAR_EOF > 'sys/vms/fileio.c'
  1209. /*
  1210.  * Name:    MicroEMACS
  1211.  * Version:    30
  1212.  *        VAX/VMS file I/O.
  1213.  * Last edit:    05-Feb-86
  1214.  * By:        rex::conroy
  1215.  *        decvax!decwrl!dec-rhea!dec-rex!conroy
  1216.  *
  1217.  * Read and write ASCII files. All
  1218.  * of the low level file I/O knowledge is here.
  1219.  * VAX/VMS.
  1220.  * Pretty much vanilla standard I/O, using
  1221.  * the (traditional) funny open.
  1222.  */
  1223. #include    "def.h"
  1224.  
  1225. static    FILE    *ffp;
  1226.  
  1227. /*
  1228.  * Open a file for reading.
  1229.  */
  1230. ffropen(fn)
  1231. char    *fn;
  1232. {
  1233.     if ((ffp=fopen(fn, "r")) == NULL)
  1234.         return (FIOFNF);
  1235.     return (FIOSUC);
  1236. }
  1237.  
  1238. /*
  1239.  * Open a file for writing.
  1240.  * Return TRUE if all is well, and
  1241.  * FALSE on error (cannot create).
  1242.  */
  1243. ffwopen(fn)
  1244. char    *fn;
  1245. {
  1246.     register int    fd;
  1247.  
  1248.     if ((fd=creat(fn, 0, "rfm=var", "rat=cr")) < 0
  1249.     || (ffp=fdopen(fd, "w")) == NULL) {
  1250.         ewprintf("Cannot open file for writing");
  1251.         return (FIOERR);
  1252.     }
  1253.     return (FIOSUC);
  1254. }
  1255.  
  1256. /*
  1257.  * Close a file.
  1258.  * Should look at the status.
  1259.  */
  1260. ffclose()
  1261. {
  1262.     fclose(ffp);
  1263.     return (FIOSUC);
  1264. }
  1265.  
  1266. /*
  1267.  * Write a line to the already
  1268.  * opened file. The "buf" points to the
  1269.  * buffer, and the "nbuf" is its length, less
  1270.  * the free newline. Return the status.
  1271.  * Check only at the newline.
  1272.  */
  1273. ffputline(buf, nbuf)
  1274. register char    buf[];
  1275. {
  1276.     register int    i;
  1277.  
  1278.     for (i=0; i<nbuf; ++i)
  1279.         putc(buf[i]&0xFF, ffp);
  1280.     putc('\n', ffp);
  1281.     if (ferror(ffp) != FALSE) {
  1282.         ewprintf("Write I/O error");
  1283.         return (FIOERR);
  1284.     }
  1285.     return (FIOSUC);
  1286. }
  1287.  
  1288. /*
  1289.  * Read a line from a file, and store the bytes
  1290.  * in the supplied buffer. Stop on end of file or end of
  1291.  * line. Don't get upset by files that don't have an end of
  1292.  * line on the last line; this seem to be common on CP/M-86 and
  1293.  * MS-DOS (the suspected culprit is VAX/VMS kermit, but this
  1294.  * has not been confirmed. If this is sufficiently researched
  1295.  * it may be possible to pull this kludge). Delete any CR
  1296.  * followed by an LF. This is mainly for runoff documents,
  1297.  * both on VMS and on Ultrix (they get copied over from
  1298.  * VMS systems with DECnet).
  1299.  * (17-Jul-1986 MPK) strip NULs too.
  1300.  */
  1301. ffgetline(buf, nbuf)
  1302. register char    buf[];
  1303. {
  1304.     register int    c;
  1305.     register int    i;
  1306.  
  1307.     i = 0;
  1308.     for (;;) {
  1309.         c = getc(ffp);
  1310.         if (c == '\r') {        /* Delete any non-stray    */
  1311.             c = getc(ffp);        /* carriage returns.    */
  1312.             if (c != '\n') {
  1313.                 if (i >= nbuf-1) {
  1314.                     ewprintf("File has long line");
  1315.                     return (FIOERR);
  1316.                 }
  1317.                 buf[i++] = '\r';
  1318.             }
  1319.         }
  1320.         if (c==EOF || c=='\n')        /* End of line.        */
  1321.             break;
  1322.         if (c == '\0')            /* strip NULs        */
  1323.             continue;
  1324.         if (i >= nbuf-1) {
  1325.             ewprintf("File has long line");
  1326.             return (FIOERR);
  1327.         }
  1328.         buf[i++] = c;
  1329.     }
  1330.     if (c == EOF) {                /* End of file.        */
  1331.         if (ferror(ffp) != FALSE) {
  1332.             ewprintf("File read error");
  1333.             return (FIOERR);
  1334.         }
  1335.         if (i == 0)            /* Don't get upset if    */
  1336.             return (FIOEOF);    /* no newline at EOF.    */
  1337.     }
  1338.     buf[i] = 0;
  1339.     return (FIOSUC);
  1340. }
  1341.  
  1342. /*
  1343.  * VMS has version numbers, so there is
  1344.  * no need for MicroEMACS to bother making its own
  1345.  * flavour of backup copy. Return TRUE so the
  1346.  * caller doesn't quit.
  1347.  */
  1348. fbackupfile(fname)
  1349. char    *fname;
  1350. {
  1351.     return (TRUE);
  1352. }
  1353.  
  1354. /*
  1355.  * The string "fn" is a file name.
  1356.  * Perform any required case adjustments. All sustems
  1357.  * we deal with so far have case insensitive file systems.
  1358.  * We zap everything to lower case. The problem we are trying
  1359.  * to solve is getting 2 buffers holding the same file if
  1360.  * you visit one of them with the "caps lock" key down.
  1361.  * On UNIX file names are dual case, so we leave
  1362.  * everything alone.
  1363.  */
  1364. adjustcase(fn)
  1365. register char    *fn;
  1366. {
  1367.     register int    c;
  1368.  
  1369.     while ((c = *fn) != 0) {
  1370.         if (c>='A' && c<='Z')
  1371.             *fn = c + 'a' - 'A';
  1372.         ++fn;
  1373.     }
  1374. }
  1375.  
  1376. #ifndef    MICRO
  1377. #include <file.h>
  1378. /*
  1379.  * Find the user's startup file, and return its name.
  1380.  * Use the VAX C getenv() function, which returns the VMS
  1381.  * directory spec for the user's home directory.
  1382.  * Check for ${HOME}.emacs, then for ${HOME}.mg, then give up.
  1383.  */
  1384. char *
  1385. startupfile() {
  1386.     register char    *file;
  1387.     static char    home[NFILEN];
  1388.     char        *getenv();
  1389.  
  1390.     if ((file = getenv("HOME")) == NULL) return NULL;
  1391.     if (strlen(file)+7 >= NFILEN - 1) return NULL;
  1392.     (VOID) strcpy(home, file);
  1393.     file = &(home[strlen(home)]);
  1394.  
  1395.     (VOID) strcpy(file, ".mg");
  1396.     if (access(home, O_RDONLY ) == 0) return home;
  1397.  
  1398.     (VOID) strcpy(file, ".emacs");
  1399.     if (access(home, O_RDONLY) == 0) return home;
  1400.  
  1401.     return NULL;
  1402. }
  1403. #endif
  1404. SHAR_EOF
  1405. fi # end of overwriting check
  1406. if test -f 'sys/vms/spawn.c'
  1407. then
  1408.     echo shar: will not over-write existing file "'sys/vms/spawn.c'"
  1409. else
  1410. cat << \SHAR_EOF > 'sys/vms/spawn.c'
  1411. /*
  1412.  * Name:    MicroEMACS
  1413.  *        VAX/VMS spawn and attach to a DCL subprocess.
  1414.  * Created:    rex::conroy
  1415.  *        decvax!decwrl!dec-rhea!dec-rex!conroy
  1416.  * Modified:
  1417.  *         19-May-86 ...!ihnp4!seismo!ut-sally!ut-ngp!mic
  1418.  *            Add att-to-parent command to attach to the parent
  1419.  *            process.  If we can't attach to parent somehow,
  1420.  *            spawn a DCL subjob.  This gives us the same
  1421.  *            suspend capability as Unix Emacses.
  1422.  *
  1423.  *            As an added hook, you can DEFINE/JOB
  1424.  *            MG$ATTACHTO to a process name, and
  1425.  *            the code will try to attach to that name.
  1426.  *
  1427.  *            Also, if the logical name MG$FILE is
  1428.  *            defined, attachtoparent() will visit that file
  1429.  *            when you re-attach to Emacs.  This is useful
  1430.  *            for a lot of applications, especially MAIL/EDIT...
  1431.  *        26-Jun-86 ...!ihnp4!seismo!ut-sally!ut-ngp!mic
  1432.  *            Specify process we're attaching to when we attempt
  1433.  *            to attach to it.
  1434.  *        03-Sep-86 ...!ihnp4!seismo!ut-sally!ut-ngp!mic
  1435.  *            Call savebuffers() before leaving the editor.
  1436.  *            Unlike csh, DCL has no problem with people
  1437.  *            logging out without completing subjobs...
  1438.  *            #define NOSAVEONZ if you don't want this behavior.
  1439.  *        13-Oct-86 ...!ihnp4!seismo!ut-sally!ut-ngp!mic
  1440.  *            Change MICROEMACS$... to MG$... for consistency.
  1441.  */
  1442. #include    "def.h"
  1443.  
  1444. #include    <ssdef.h>
  1445. #include    <stsdef.h>
  1446. #include    <descrip.h>
  1447. #include    <iodef.h>
  1448. #include    <jpidef.h>
  1449.  
  1450. #define    EFN    0                /* Event flag.        */
  1451.  
  1452. extern    int    oldmode[3];            /* In "ttyio.c".    */
  1453. extern    int    newmode[3];
  1454. extern    short    iochan;
  1455. extern    int    ckttysize();            /* Checks for new term size */
  1456. #ifndef    NOSAVEONZ
  1457. extern    int    savebuffers();            /* Save all buffers before  */
  1458. #endif
  1459.  
  1460. /*
  1461.  * Create a subjob with a copy
  1462.  * of the command intrepreter in it. When the
  1463.  * command interpreter exits, mark the screen as
  1464.  * garbage so that you do a full repaint. Bound
  1465.  * to "C-C" and called from "C-Z". The message at
  1466.  * the start in VMS puts out a newline. Under
  1467.  * some (unknown) condition, you don't get one
  1468.  * free when DCL starts up.
  1469.  */
  1470.  
  1471. spawncli(f, n, k)
  1472. {
  1473.     register int    s;
  1474.  
  1475. #ifndef    NOSAVEONZ
  1476.     if (savebuffers() == ABORT)        /* TRUE means all saved,*/
  1477.         return (ABORT);            /* FALSE means not.    */
  1478. #endif
  1479.     eerase();                /* Get rid of echo line    */
  1480.     ttcolor(CTEXT);                /* Normal color.    */
  1481.     ttnowindow();                /* Full screen scroll.    */
  1482.     ttmove(nrow-1, 0);            /* Last line.        */
  1483.     eputs("Starting DCL");
  1484.     ttputc('\r');
  1485.     ttputc('\n');
  1486.     ttflush();
  1487.     sgarbf = TRUE;
  1488.     s = sys(NULL);                /* NULL => DCL.        */
  1489.     return (s);
  1490. }
  1491.  
  1492. /*
  1493.  * Run a command. The "cmd" is a pointer
  1494.  * to a command string, or NULL if you want to run
  1495.  * a copy of DCL in the subjob (this is how the standard
  1496.  * routine LIB$SPAWN works. You have to do wierd stuff
  1497.  * with the terminal on the way in and the way out,
  1498.  * because DCL does not want the channel to be
  1499.  * in raw mode.
  1500.  */
  1501. sys(cmd)
  1502. register char    *cmd;
  1503. {
  1504.     struct    dsc$descriptor    cdsc;
  1505.     struct    dsc$descriptor    *cdscp;
  1506.     long    status;
  1507.     long    substatus;
  1508.     long    iosb[2];
  1509.  
  1510.     status = SYS$QIOW(EFN, iochan, IO$_SETMODE, iosb, 0, 0,
  1511.               oldmode, sizeof(oldmode), 0, 0, 0, 0);
  1512.     if (status!=SS$_NORMAL || (iosb[0]&0xFFFF)!=SS$_NORMAL)
  1513.         return (FALSE);
  1514.     cdscp = NULL;                /* Assume DCL.        */
  1515.     if (cmd != NULL) {            /* Build descriptor.    */
  1516.         cdsc.dsc$a_pointer = cmd;
  1517.         cdsc.dsc$w_length  = strlen(cmd);
  1518.         cdsc.dsc$b_dtype   = DSC$K_DTYPE_T;
  1519.         cdsc.dsc$b_class   = DSC$K_CLASS_S;
  1520.         cdscp = &cdsc;
  1521.     }
  1522.     status = LIB$SPAWN(cdscp, 0, 0, 0, 0, 0, &substatus, 0, 0, 0);
  1523.     if (status != SS$_NORMAL)
  1524.         substatus = status;
  1525.     ckttysize();            /* check for new terminal size */
  1526.     status = SYS$QIOW(EFN, iochan, IO$_SETMODE, iosb, 0, 0,
  1527.               newmode, sizeof(newmode), 0, 0, 0, 0);
  1528.     if (status!=SS$_NORMAL || (iosb[0]&0xFFFF)!=SS$_NORMAL)
  1529.         return (FALSE);
  1530.     if ((substatus&STS$M_SUCCESS) == 0)    /* Command failed.    */
  1531.         return (FALSE);
  1532.     return (TRUE);
  1533. }
  1534.  
  1535. /*
  1536.  * Front end for combined attach-to-parent and spawn-cli action
  1537.  */
  1538.  
  1539. attachtoparent(f, n, k)
  1540. {
  1541.     register int    s;
  1542.     s = attparent();
  1543.     if (s == ABORT)
  1544.         return (ABORT);
  1545.     else if (s == FALSE)
  1546.         return spawncli(f, n, k);    /* better than nothing */
  1547.     else
  1548.         return (TRUE);
  1549. }
  1550.  
  1551. /*
  1552.  * Attach to parent.  If the logical name MG$ATTACHTO
  1553.  * is present, attempt to attach to it.  If not, attempt to
  1554.  * attach to parent process.
  1555.  *
  1556.  * On return, see if the logical name MG$FILE contains
  1557.  * anything, and try to visit that file.
  1558.  */
  1559.  
  1560. static $DESCRIPTOR(nmdsc,"MG$ATTACHTO");
  1561.  
  1562. attparent()
  1563. {
  1564.     long        pid, jpi_code;    
  1565.     char        equiv[18], msgbuf[60];
  1566.     struct    dsc$descriptor_s eqdsc;
  1567.     short        eqlen;
  1568.     int        status, pos;
  1569.     register BUFFER    *bp;
  1570.     BUFFER        *findbuffer();
  1571.     int        s;
  1572.  
  1573.  
  1574.     /* Set up string descriptor */
  1575.     eqdsc.dsc$a_pointer = equiv;
  1576.     eqdsc.dsc$w_length  = sizeof(equiv);
  1577.     eqdsc.dsc$b_dtype   = DSC$K_DTYPE_T;
  1578.     eqdsc.dsc$b_class   = DSC$K_CLASS_S;
  1579.  
  1580.     /* Try to translate MG$ATTACH */
  1581.     status = lib$sys_trnlog(&nmdsc, &eqdsc.dsc$w_length, &eqdsc);
  1582.     if (status!=SS$_NORMAL && status!=SS$_NOTRAN) {
  1583.         ewprintf("Error translating %s",nmdsc.dsc$a_pointer);/* DEBUG */
  1584.         return (FALSE);
  1585.     }
  1586.  
  1587.     if (status == SS$_NORMAL) {
  1588.         /* Found a translation -- attempt to attach to it */
  1589.         jpi_code = JPI$_PID;
  1590.  
  1591.         status = lib$getjpi(&jpi_code,0,&eqdsc,&pid,0);
  1592.         equiv[eqdsc.dsc$w_length] = '\0';
  1593.         if (status != SS$_NORMAL) {
  1594.             ewprintf("Error getting JPI for \"%s\"",equiv);
  1595.             return (FALSE);
  1596.         }
  1597.  
  1598. #ifndef    NOSAVEONZ
  1599.         /* Attempt to attach to named process.  Save all buffers,  */
  1600.         /* set sgarbf because attach() always trashes the display  */
  1601.         if (savebuffers() == ABORT)
  1602.             return (ABORT);
  1603. #endif
  1604.         /* indicate process we're attaching to */
  1605.         strcpy(msgbuf,"Attaching to process \"");
  1606.         for (pos = strlen(equiv) - 1; pos >= 0; --pos)
  1607.             if (equiv[pos] != ' ') {
  1608.                 equiv[pos+1] = '\0';
  1609.                 break;
  1610.             }
  1611.         strcat(msgbuf,equiv);
  1612.         strcat(msgbuf,"\"");
  1613.  
  1614.         sgarbf = TRUE;
  1615.         if (attach(pid,msgbuf) == FALSE)    /* whups -- try spawn */
  1616.             return (FALSE);
  1617.     }
  1618.     else {    /* No translation -- attempt to find parent process */
  1619.         jpi_code = JPI$_OWNER;
  1620.         status = lib$getjpi(&jpi_code,0,0,&pid,0,0);
  1621.  
  1622.         if ((status != SS$_NORMAL) || (pid == 0))    /* not found! */
  1623.             return (FALSE);
  1624.  
  1625. #ifndef    NOSAVEONZ
  1626.         if (savebuffers() == ABORT)
  1627.             return (ABORT);
  1628. #endif
  1629.         sgarbf = TRUE;
  1630.         if (attach(pid,"Attaching to parent process") == FALSE)
  1631.             return (FALSE);
  1632.     }
  1633.  
  1634.     newfile();    /* attempt to find a new file, but don't care    */
  1635.             /* if we don't find one...            */
  1636.     refresh(FALSE, 0, KRANDOM);
  1637.     return (TRUE);
  1638. }
  1639.  
  1640. /*
  1641.  * If we find after re-attaching that there is
  1642.  * a new file to be edited, attempt to read it in,
  1643.  * using essentially the same code as findfile().
  1644.  */
  1645.  
  1646. static newfile()
  1647. {
  1648.     register BUFFER    *bp;
  1649.     register int    s;
  1650.     char        filename[NFILEN];
  1651.     BUFFER        *findbuffer();
  1652.  
  1653.     if ((s = cknewfile(filename, sizeof filename)) != TRUE)
  1654.         return (s);
  1655.     if ((bp = findbuffer(filename, &s)) == NULL)
  1656.         return (s);
  1657.     curbp = bp;
  1658.     if (showbuffer(bp, curwp, WFHARD) != TRUE)
  1659.         return (FALSE);
  1660.     if (bp->b_fname[0] == 0)
  1661.         return (readin(filename));    /* Read it in. */
  1662.     return (TRUE);
  1663. }
  1664.  
  1665. /*
  1666.  * Attach to a process by process number.  Restore the
  1667.  * terminal channel to the way it was when we started.
  1668.  * Also put out an optional message to the user.
  1669.  */ 
  1670.  
  1671. static attach(pid, msg)
  1672. long pid;
  1673. char *msg;
  1674. {
  1675.     long    status, attstatus;
  1676.     long    iosb[2];
  1677.  
  1678.     ttcolor(CTEXT);                /* Normal color.    */
  1679.     ttnowindow();                /* Full screen scroll.    */
  1680.     ttmove(nrow-1, 0);            /* Last line.        */
  1681.     if (msg) {                /* Display a message    */
  1682.         eputs(msg);
  1683.         ttputc('\r');
  1684.         ttputc('\n');
  1685.     }
  1686.     ttflush();
  1687.  
  1688.     /* Set terminal to old modes */
  1689.     status = SYS$QIOW(EFN, iochan, IO$_SETMODE, iosb, 0, 0,
  1690.               oldmode, sizeof(oldmode), 0, 0, 0, 0);
  1691.     if (status!=SS$_NORMAL || (iosb[0]&0xFFFF)!=SS$_NORMAL)
  1692.         return (FALSE);
  1693.  
  1694.     /* Attach to the process */
  1695.     attstatus = LIB$ATTACH(&pid);
  1696.  
  1697.     /* Return terminal to the modes MG needs */
  1698.     ckttysize();            /* check for new terminal size first */
  1699.     status = SYS$QIOW(EFN, iochan, IO$_SETMODE, iosb, 0, 0,
  1700.               newmode, sizeof(newmode), 0, 0, 0, 0);
  1701.     if (status!=SS$_NORMAL || (iosb[0]&0xFFFF)!=SS$_NORMAL)
  1702.         return (FALSE);
  1703.  
  1704.     return (attstatus == SS$_NORMAL ? TRUE : FALSE);
  1705. }
  1706.  
  1707.  
  1708. /*
  1709.  * Attempt to translate MG$FILE into fname.
  1710.  * If it's there and non-empty, return TRUE.
  1711.  */
  1712.  
  1713. static $DESCRIPTOR(filedsc,"MG$FILE");
  1714.  
  1715. static cknewfile(fname,fnsiz)
  1716. char *fname;
  1717. int fnsiz;
  1718. {
  1719.     char     equiv[NFILEN];
  1720.     struct dsc$descriptor_s eqdsc;
  1721.     short    len;
  1722.     register int    status;
  1723.  
  1724.     eqdsc.dsc$a_pointer = equiv;
  1725.     eqdsc.dsc$w_length  = sizeof(equiv);
  1726.     eqdsc.dsc$b_dtype   = DSC$K_DTYPE_T;
  1727.     eqdsc.dsc$b_class   = DSC$K_CLASS_S;
  1728.  
  1729.     status = lib$sys_trnlog(&filedsc, &len, &eqdsc);
  1730.     if (status!=SS$_NORMAL && status!=SS$_NOTRAN) {
  1731.         ewprintf("Error translating MG$FILE");
  1732.         return (FALSE);
  1733.     }
  1734.  
  1735.     if (status == SS$_NOTRAN)        /* No new file found    */
  1736.         return (FALSE);
  1737.  
  1738.     if (equiv[0] == ' ')
  1739.         return (FALSE);
  1740.  
  1741.     equiv[len] = '\0';
  1742.     strcpy(fname, equiv);
  1743.     return (TRUE);
  1744. }
  1745. SHAR_EOF
  1746. fi # end of overwriting check
  1747. if test -f 'sys/vms/trnlnm.c'
  1748. then
  1749.     echo shar: will not over-write existing file "'sys/vms/trnlnm.c'"
  1750. else
  1751. cat << \SHAR_EOF > 'sys/vms/trnlnm.c'
  1752. /*
  1753.  * Name:    MicroEmacs
  1754.  *        VAX/VMS translate logical name routine
  1755.  * Version:    Gnu30
  1756.  * Last Edit:    10-Jul-86
  1757.  * By:        ...!ihnp4!seismo!ut-sally!ut-ngp!mic
  1758.  *
  1759.  */
  1760.  
  1761. /*
  1762.  *
  1763.  * Trnlnm()
  1764.  *
  1765.  * Description:
  1766.  *    Attempt to translate the logical name logname into an equivalence
  1767.  *    string, using the standard VMS routine LIB$SYS_TRNLOG().
  1768.  *    If a translation exists, return a pointer to the static area
  1769.  *    that contains the null-terminated translation string.  If not,
  1770.  *    return 0.
  1771.  *
  1772.  *  Bugs:
  1773.  *    Returns a pointer to static data that is modified each time
  1774.  *    the routine successfully translates a logical name.
  1775.  */
  1776.  
  1777. #include <ssdef.h>
  1778. #include <descrip.h>
  1779. #include <stdio.h>
  1780.  
  1781. static char _equiv_buf[256];
  1782. static struct dsc$descriptor_s
  1783. _equiv = {
  1784.     sizeof(_equiv_buf), DSC$K_DTYPE_T, DSC$K_CLASS_S, _equiv_buf
  1785. },
  1786. _name = {
  1787.     0, DSC$K_DTYPE_T, DSC$K_CLASS_S, NULL
  1788. };
  1789.  
  1790. char *trnlnm(logname)
  1791. char *logname;
  1792. {
  1793.     short eqlen;
  1794.     int status;
  1795.  
  1796.     if (logname == NULL)
  1797.         return (NULL);
  1798.  
  1799.     _name.dsc$a_pointer = logname;
  1800.     _name.dsc$w_length = strlen(logname);
  1801.  
  1802.     status = lib$sys_trnlog(&_name, &eqlen, &_equiv);
  1803.     if (status != SS$_NORMAL)
  1804.         return (NULL);
  1805.  
  1806.     _equiv_buf[eqlen] = '\0';
  1807.     return (_equiv_buf);
  1808. }
  1809.  
  1810. SHAR_EOF
  1811. fi # end of overwriting check
  1812. if test -f 'sys/vms/ttyio.c'
  1813. then
  1814.     echo shar: will not over-write existing file "'sys/vms/ttyio.c'"
  1815. else
  1816. cat << \SHAR_EOF > 'sys/vms/ttyio.c'
  1817. /*
  1818.  * Name:    MicroGnuEmacs
  1819.  *        VAX/VMS terminal I/O.
  1820.  *        o 16-Apr-86 ...!ihnp4!seismo!ut-sally!ut-ngp!mic
  1821.  *          Turn off TTSYNC so ^S and ^Q are sent to program.
  1822.  *          To get this back, compile with -DFLOWCONTROL
  1823.  *        o 10-Jul-86 ...!ihnp4!seismo!ut-sally!ut-ngp!mic
  1824.  *          Add setttysize(), typeahead() and panic() for Gnu v30
  1825.  */
  1826. #include    "def.h"
  1827.  
  1828. #include    <stsdef.h>
  1829. #include    <ssdef.h>
  1830. #include    <descrip.h>
  1831. #include    <iodef.h>
  1832. #include    <ttdef.h>
  1833. #include    <tt2def.h>
  1834.  
  1835. #define    NIBUF    128            /* Probably excessive.        */
  1836. #define    NOBUF    512            /* Not too big for 750/730.    */
  1837. #define    EFN    0            /* Event flag            */
  1838.  
  1839. char    obuf[NOBUF];            /* Output buffer        */
  1840. int    nobuf;                /* # of bytes in above        */
  1841. char    ibuf[NIBUF];            /* Input buffer            */
  1842. int    nibuf;                /* # of bytes in above        */
  1843. int    ibufi;                /* Read index            */
  1844. int    oldmode[3];            /* Old TTY mode bits        */
  1845. int    newmode[3];            /* New TTY mode bits        */
  1846. short    iochan;                /* TTY I/O channel        */
  1847. int    nrow;                /* Terminal size, rows.        */
  1848. int    ncol;                /* Terminal size, columns.    */
  1849. short    ospeed;                /* Terminal output speed    */
  1850.                     /* for termcap library        */
  1851.  
  1852. /*
  1853.  * This routines gets called once, to set up the
  1854.  * terminal channel.
  1855.  * On VMS we find the translation of the SYS$COMMAND:
  1856.  * logical name, assign a channel to it, and set it raw.
  1857.  */
  1858.  
  1859. ttopen()
  1860. {
  1861.     struct    dsc$descriptor    idsc;
  1862.     struct    dsc$descriptor    odsc;
  1863.     char    oname[40];
  1864.     int    iosb[2];
  1865.     int    status;
  1866.  
  1867.     odsc.dsc$a_pointer = "SYS$COMMAND";
  1868.     odsc.dsc$w_length  = strlen(odsc.dsc$a_pointer);
  1869.     odsc.dsc$b_dtype   = DSC$K_DTYPE_T;
  1870.     odsc.dsc$b_class   = DSC$K_CLASS_S;
  1871.     idsc.dsc$b_dtype   = DSC$K_DTYPE_T;
  1872.     idsc.dsc$b_class   = DSC$K_CLASS_S;
  1873.     do {
  1874.         idsc.dsc$a_pointer = odsc.dsc$a_pointer;
  1875.         idsc.dsc$w_length  = odsc.dsc$w_length;
  1876.         odsc.dsc$a_pointer = &oname[0];
  1877.         odsc.dsc$w_length  = sizeof(oname);
  1878.         status = LIB$SYS_TRNLOG(&idsc, &odsc.dsc$w_length, &odsc);
  1879.         if (status!=SS$_NORMAL && status!=SS$_NOTRAN)
  1880.             exit(status);
  1881.         if (oname[0] == 0x1B) {
  1882.             odsc.dsc$a_pointer += 4;
  1883.             odsc.dsc$w_length  -= 4;
  1884.         }
  1885.     } while (status == SS$_NORMAL);
  1886.     status = SYS$ASSIGN(&odsc, &iochan, 0, 0);
  1887.     if (status != SS$_NORMAL)
  1888.         exit(status);
  1889.     status = SYS$QIOW(EFN, iochan, IO$_SENSEMODE, iosb, 0, 0,
  1890.               oldmode, sizeof(oldmode), 0, 0, 0, 0);
  1891.     if (status!=SS$_NORMAL || (iosb[0]&0xFFFF)!=SS$_NORMAL)
  1892.         exit(status);
  1893.  
  1894.     nrow = (oldmode[1]>>24) & 0xFF;        /* Terminal length.    */
  1895.     if (nrow > NROW)
  1896.         nrow = NROW;
  1897.     ncol = (oldmode[0]>>16) & 0xFFFF;    /* Width.        */
  1898.     if (ncol > NCOL)
  1899.         ncol = NCOL;
  1900.     ospeed = (iosb[0]>>24) & 0xFF;        /* Speed (for termcap)    */
  1901.     newmode[0] = oldmode[0];        /* Only in version 4.    */
  1902. #ifdef    FLOWCONTROL
  1903.     newmode[1] = oldmode[1] | TT$M_NOECHO | TT$M_TTSYNC;
  1904. #else
  1905.     newmode[1] = (oldmode[1] | TT$M_NOECHO) & ~TT$M_TTSYNC;
  1906. #endif
  1907.     newmode[2] = oldmode[2] | TT2$M_PASTHRU;
  1908.     status = SYS$QIOW(EFN, iochan, IO$_SETMODE, iosb, 0, 0,
  1909.               newmode, sizeof(newmode), 0, 0, 0, 0);
  1910.  
  1911.     if (status!=SS$_NORMAL || (iosb[0]&0xFFFF)!=SS$_NORMAL)
  1912.         exit(status);
  1913. }
  1914.  
  1915. /*
  1916.  * This function gets called just
  1917.  * before we go back home to the command interpreter.
  1918.  * On VMS it puts the terminal back in a reasonable state.
  1919.  */
  1920. ttclose()
  1921. {
  1922.     int    status;
  1923.     int    iosb[2];
  1924.  
  1925.     ttflush();
  1926.     status = SYS$QIOW(EFN, iochan, IO$_SETMODE, iosb, 0, 0,
  1927.              oldmode, sizeof(oldmode), 0, 0, 0, 0);
  1928.     if (status!=SS$_NORMAL || (iosb[0]&0xFFFF)!=SS$_NORMAL)
  1929.         exit(status);
  1930.     status = SYS$DASSGN(iochan);
  1931.     if (status != SS$_NORMAL)
  1932.         exit(status);
  1933. }
  1934.  
  1935. /*
  1936.  * Write a character to the display.
  1937.  * On VMS, terminal output is buffered, and
  1938.  * we just put the characters in the big array,
  1939.  * after checking for overflow.
  1940.  */
  1941. ttputc(c)
  1942. {
  1943.     if (nobuf >= NOBUF)
  1944.         ttflush();
  1945.     obuf[nobuf++] = c;
  1946. }
  1947.  
  1948. /*
  1949.  * This function does the real work of
  1950.  * flushing out buffered I/O on VMS. All
  1951.  * we do is blast out the block with a write call. No status
  1952.  * checking is done on the write, because there isn't anything
  1953.  * clever that can be done, and because you will see the
  1954.  * error as a messed up screen.
  1955.  */
  1956. ttflush()
  1957. {
  1958.     int    iosb[2];
  1959.  
  1960.     if (nobuf != 0) {
  1961.         SYS$QIOW(EFN, iochan, IO$_WRITELBLK|IO$M_NOFORMAT,
  1962.         iosb, 0, 0, obuf, nobuf, 0, 0, 0, 0);
  1963.         nobuf = 0;
  1964.     }
  1965. }
  1966.  
  1967. /*
  1968.  * Read a character from the terminal,
  1969.  * performing no editing and doing no echo at all.
  1970.  * More complex in VMS that almost anyplace else,
  1971.  * which figures.
  1972.  */
  1973. ttgetc()
  1974. {
  1975.     int    status;
  1976.     int    iosb[2];
  1977.     int    term[2];
  1978.  
  1979.     term[0] = 0;
  1980.     term[1] = 0;
  1981.     while (ibufi >= nibuf) {
  1982.         ibufi   = 0;
  1983.         status = SYS$QIOW(EFN, iochan, IO$_READLBLK|IO$M_TIMED,
  1984.              iosb, 0, 0, ibuf, NIBUF, 0, term, 0, 0);
  1985.         if (status != SS$_NORMAL)
  1986.             continue;
  1987.         status = iosb[0] & 0xFFFF;
  1988.         if (status!=SS$_NORMAL && status!=SS$_TIMEOUT)
  1989.             continue;
  1990.         nibuf = (iosb[0]>>16) + (iosb[1]>>16);
  1991.         if (nibuf == 0) {
  1992.             status = SYS$QIOW(EFN, iochan, IO$_READLBLK,
  1993.                 iosb, 0, 0, ibuf, 1, 0, term, 0, 0);
  1994.             if (status != SS$_NORMAL)
  1995.                 continue;
  1996.             if ((iosb[0]&0xFFFF) != SS$_NORMAL)
  1997.                 continue;
  1998.             nibuf = (iosb[0]>>16) + (iosb[1]>>16);
  1999.         }
  2000.     }
  2001.     return (ibuf[ibufi++] & 0xFF);
  2002. }
  2003.  
  2004. /*
  2005.  * Internal check for new terminal size.
  2006.  * Do this *before* setting terminal modes, so
  2007.  * the size changes are kept when.
  2008.  */
  2009. ckttysize()
  2010. {
  2011.     int status, mode[3], iosb[2], wid, len;
  2012.  
  2013.     status = SYS$QIOW(EFN, iochan, IO$_SENSEMODE, iosb, 0, 0,
  2014.               mode, sizeof(mode), 0, 0, 0, 0);
  2015.     if (status!=SS$_NORMAL || (iosb[0]&0xFFFF)!=SS$_NORMAL)
  2016.         panic("ckttsize: can't sense terminal modes!");
  2017.  
  2018.     /* save new page length */
  2019.     len = (mode[1] >> 24) & 0xFF;
  2020.     oldmode[1] = (oldmode[1] & 0x00FFFFFF) | (len << 24);
  2021.     newmode[1] = (newmode[1] & 0x00FFFFFF) | (len << 24);
  2022.  
  2023.     /* save new page width */
  2024.     wid = (mode[0] >> 16) & 0xFF;
  2025.     oldmode[0] = (oldmode[0] & 0x0000FFFF) | (wid << 16);
  2026.     newmode[0] = (newmode[0] & 0x0000FFFF) | (wid << 16);
  2027. }
  2028.  
  2029. /*
  2030.  * Tell Emacs how big the terminal is now,
  2031.  * making sure the page size is in the range
  2032.  * 1..NROW.
  2033.  */
  2034.  
  2035. setttysize()
  2036. {
  2037.     nrow = (newmode[1]>>24) & 0xFF;        /* Length.        */
  2038.     if (nrow > NROW)
  2039.         nrow = NROW;
  2040.  
  2041.     ncol = (newmode[0]>>16) & 0xFFFF;    /* Width.        */
  2042.     if (ncol > NCOL)
  2043.         ncol = NCOL;
  2044. }
  2045.  
  2046. /*
  2047.  * Return the number of characters in the
  2048.  * typeahead buffer.
  2049.  */
  2050.  
  2051. typeahead()
  2052. {
  2053.     int    status, SYS$QIOW(), iosb[2], mode[2];
  2054.  
  2055.     status = SYS$QIOW(EFN, iochan, IO$_SENSEMODE|IO$M_TYPEAHDCNT,
  2056.             iosb, 0, 0, mode, sizeof(mode), 0, 0, 0, 0);
  2057.     if (status!=SS$_NORMAL || (iosb[0]&0xFFFF)!=SS$_NORMAL)
  2058.         exit(status);
  2059.     return (mode[0] & 0xFFFF);    /* # characters in typeahead buf */
  2060. }
  2061.  
  2062. #ifdef    DPROMPT
  2063. /*
  2064.  * Attempt to read for one character.  Return TRUE if the
  2065.  * read times out after 2 seconds, return immediately with
  2066.  * FALSE if the user enters something.
  2067.  */
  2068. ttwait()
  2069. {
  2070.     int    status;
  2071.     int    iosb[2];
  2072.     int    term[2];
  2073.  
  2074.     term[0] = 0;            /* no termination characters for read */
  2075.     term[1] = 0;
  2076.     while (ibufi >= nibuf) {    /* anything in the buffer?    */
  2077.         ibufi   = 0;        /* nope, read 1 char w/timeout    */
  2078.         status = SYS$QIOW(EFN, iochan, IO$_READLBLK|IO$M_TIMED,
  2079.              iosb, 0, 0, ibuf, 1, 2, term, 0, 0);
  2080.         if (status != SS$_NORMAL)
  2081.             continue;        /* did read succeed ?         */
  2082.         status = iosb[0] & 0xFFFF;    /* yes, get secondary status */
  2083.         if (status!=SS$_NORMAL && status!=SS$_TIMEOUT)
  2084.             continue;        /* try again if bad         */
  2085.         nibuf = (iosb[0]>>16) + (iosb[1]>>16);/* store # chars read  */
  2086.         if (status == SS$_TIMEOUT)
  2087.             return (TRUE);        /* the read timed out         */
  2088.     }
  2089.     return (FALSE);                /* read did not time out     */
  2090. }
  2091. #endif    DPROMPT
  2092.  
  2093. /*
  2094.  * Just exit, as quickly as we can.
  2095.  */
  2096.  
  2097. panic(s)
  2098. char *s;
  2099. {
  2100.     fprintf(stderr,"panic: %s\n", s);
  2101.     ttclose();    /* set the terminal back to sane state... */
  2102.     abort();
  2103. }
  2104. SHAR_EOF
  2105. fi # end of overwriting check
  2106. if test -f 'sys/vms/sysdef.h'
  2107. then
  2108.     echo shar: will not over-write existing file "'sys/vms/sysdef.h'"
  2109. else
  2110. cat << \SHAR_EOF > 'sys/vms/sysdef.h'
  2111. /*
  2112.  * Name:    MicroEMACS
  2113.  *        VAX/VMS system header file.
  2114.  * Version:    29
  2115.  * Last edit:    05-Feb-86
  2116.  * By:        rex::conroy
  2117.  *        decvax!decwrl!dec-rhea!dec-rex!conroy
  2118.  */
  2119. #include    <ssdef.h>
  2120.  
  2121. #define    PCC    0            /* "[]" works.            */
  2122. #define    KBLOCK    8192            /* Kill grow.            */
  2123. #define    GOOD    (SS$_NORMAL)        /* Good exit status.        */
  2124.  
  2125. typedef int    RSIZE;            /* Type for file/region sizes    */
  2126. typedef short    KEY;            /* Type for internal keystrokes    */
  2127.  
  2128. /*
  2129.  * Macros used by the buffer name making code.
  2130.  * Start at the end of the file name, scan to the left
  2131.  * until BDC1 (or BDC2, if defined) is reached. The buffer
  2132.  * name starts just to the right of that location, and
  2133.  * stops at end of string (or at the next BDC3 character,
  2134.  * if defined). BDC2 and BDC3 are mainly for VMS.
  2135.  */
  2136. #define    BDC1    ':'            /* Buffer names.        */
  2137. #define    BDC2    ']'
  2138. #define    BDC3    ';'
  2139.  
  2140. #define    DPROMPT                /* use delayed prompts        */
  2141. SHAR_EOF
  2142. fi # end of overwriting check
  2143. #    End of shell archive
  2144. exit 0
  2145.  
  2146.