home *** CD-ROM | disk | FTP | other *** search
/ Atari FTP / ATARI_FTP_0693.zip / ATARI_FTP_0693 / Mint / Editors / mjovesrc.zoo / jove.c < prev    next >
C/C++ Source or Header  |  1992-09-16  |  30KB  |  1,588 lines

  1. /***************************************************************************
  2.  * This program is Copyright (C) 1986, 1987, 1988 by Jonathan Payne.  JOVE *
  3.  * is provided to you without charge, and with no warranty.  You may give  *
  4.  * away copies of JOVE, including sources, provided that this notice is    *
  5.  * included in all the files.                                              *
  6.  ***************************************************************************/
  7.  
  8. /* Contains the main loop initializations, and some system dependent
  9.    type things, e.g. putting terminal in CBREAK mode, etc. */
  10.  
  11. #include "jove.h"
  12. #include "fp.h"
  13. #include "termcap.h"
  14. #include "ctype.h"
  15. #include "chars.h"
  16. #include "disp.h"
  17. #include "re.h"    /* for find_tag() */
  18. #include "rec.h"
  19. #ifdef    IPROCS
  20. # include "iproc.h"
  21. #endif
  22.  
  23. #ifdef SCO
  24. #undef TIOCGWINSZ
  25.  
  26. #include <sys/stream.h>
  27. #include <sys/ptem.h>
  28. #endif
  29.  
  30. #ifdef    MAC
  31. # include "mac.h"
  32. #else
  33. # ifdef    STDARGS
  34. #  include <stdarg.h>
  35. # else
  36. #  include <varargs.h>
  37. # endif
  38. # include <stat.h>
  39. #endif
  40.  
  41. #include <signal.h>
  42. #include <errno.h>
  43.  
  44. #ifdef    MSDOS
  45. # include <process.h>
  46. #endif    /* MSDOS */
  47.  
  48. #ifndef    MAC
  49. # include <fcntl.h>
  50. #endif
  51.  
  52. #ifdef    MSDOS
  53. private    void    break_off proto((void)),
  54.         break_rst proto((void));
  55. #endif
  56.  
  57. #ifdef    MAC
  58. # define    WINRESIZE    1
  59. #else
  60. # ifdef    TIOCGWINSZ
  61. #   ifdef    SIGWINCH
  62. #     define    WINRESIZE    1
  63. #   endif
  64. # endif
  65. #endif
  66.  
  67. private void
  68.     DoKeys proto((bool firsttime));
  69.  
  70. #ifdef    MSDOS
  71. extern
  72. #else
  73. private
  74. #endif
  75.     void
  76.     UnsetTerm proto((char *)),
  77.     do_sgtty proto((void));
  78.  
  79. /* Various tty state structures.
  80.  * Each is an array, subscripted by one of "OFF" or "ON".
  81.  */
  82.  
  83. #ifdef    UNIX
  84.  
  85. #include "ttystate.h"
  86.  
  87. # ifdef    TIOCSLTC
  88. struct ltchars    ls[2];
  89. # endif    /* TIOCSLTC */
  90.  
  91. # ifdef    TIOCGETC
  92. struct tchars    tc[2];
  93. # endif
  94.  
  95. # ifdef    PASS8            /* use pass8 instead of raw for meta-key */
  96. private int    lmword[2];        /* local mode word */
  97. # endif
  98.  
  99. # ifdef    BRLUNIX
  100. struct sg_brl    sg[2];
  101. #endif
  102. #ifdef TERMIO
  103. struct termio    sg[2];
  104. #endif
  105. #ifdef TERMIOS
  106. struct termios    sg[2];
  107. #endif
  108. #ifdef SGTTY
  109. struct sgttyb    sg[2];
  110. #endif
  111.  
  112. # ifdef    BIFF
  113. private struct stat    tt_stat;    /* for biff */
  114. #  ifndef    BSD4_2
  115. private char    *tt_name = NULL;        /* name of the control tty */
  116. extern char    *ttyname();        /* for systems w/o fchmod ... */
  117. #  endif
  118. private bool    dw_biff = NO;        /* whether or not to fotz at all */
  119. # endif    /* BIFF */
  120. #endif    /* UNIX */
  121.  
  122. bool    errormsg;
  123. char    NullStr[] = "";
  124. jmp_buf    mainjmp;
  125.  
  126.  
  127. #ifdef    MSDOS
  128. # define SIGHUP    99
  129. #endif    /* MSDOS */
  130.  
  131. /* finish() does not return, so it is funny that it returns a non-void
  132.  * result.  This is because most systems claim that signal(2) deals
  133.  * with functions of type int ().  ANSI changes this: the function
  134.  * type must be void (int).  This bridge must soon be crossed.
  135.  */
  136. SIGRESULT
  137. finish(code)
  138. int    code;
  139. {
  140.     int save_errno = errno;    /* Subtle, but necessary! */
  141.     static int    Crashing = 0;    /* we are in the middle of crashing */
  142.     bool    CoreDump = (code != 0 && code != SIGHUP),
  143.         DelTmps = YES;        /* Usually we delete them. */
  144.  
  145.     if (code == SIGINT) {
  146.         char    c;
  147. #ifdef    PIPEPROCS
  148.         int    started;
  149. #endif
  150. #ifndef    MENLO_JCL
  151.         (void) signal(code, finish);
  152. #endif
  153.         f_mess("Abort (Type 'n' if you're not sure)? ");
  154. #ifndef    MSDOS
  155. # ifdef    PIPEPROCS
  156.         started = kbd_stop();
  157. # endif
  158. #ifdef    SYSV
  159.         if (read(0, (UnivPtr) &c, (size_t) 1) != 1)
  160. #endif
  161.             (void) read(0, (UnivPtr) &c, (size_t) 1);
  162. # ifdef    PIPEPROCS
  163.         if (started)
  164.             (void) kbd_strt();
  165. # endif
  166. #else    /* MSDOS */
  167.         c = getrawinchar();
  168. #endif    /* MSDOS */
  169.         message(NullStr);
  170.         if ((c & 0377) != 'y') {
  171.             redisplay();
  172.             errno = save_errno;
  173.             SIGRETURN;
  174.         }
  175.     }
  176.     DisabledRedisplay = YES;
  177. #ifndef    MAC
  178.     UnsetTerm(NullStr);
  179. #endif
  180. #ifdef    PIPEPROCS
  181.     kbd_kill();        /* kill the keyboard process */
  182. #endif
  183. #ifndef    MSDOS
  184.     if (code != 0) {
  185.         if (!Crashing) {
  186.             Crashing = YES;
  187.             lsave();
  188.             SyncRec();
  189.             writef("JOVE CRASH!! (code %d): %s\n", code,
  190.                    strerror(errno));
  191.             if (ModBufs(YES)) {
  192.                 writef("Your buffers have been saved.\n");
  193.                 writef("Use \"jove -r\" to have a look at them.\n");
  194.                 DelTmps = NO;    /* Don't delete anymore. */
  195.             } else
  196.                 writef("You didn't lose any work.\n");
  197.         } else
  198.             writef("\r\nYou may have lost your work!\n");
  199.     }
  200. #endif    /* MSDOS */
  201.     flushscreen();
  202.     if (DelTmps) {
  203. #ifdef    PTYPROCS
  204.         (void) signal(SIGCHLD, SIG_IGN);
  205. #endif
  206.         tmpremove();
  207. #ifndef    MSDOS
  208.         recremove();
  209. #endif    /* MSDOS */
  210.     }
  211. #ifdef    UNIX
  212.     if (CoreDump)
  213.         abort();
  214. #ifdef    PROFILING
  215.     exit(0);
  216. #else
  217.     _exit(0);
  218. #endif
  219. #else    /* !UNIX */
  220. #ifdef    MSDOS
  221.     break_rst();    /* restore previous ctrl-c handling */
  222. #endif
  223.     exit(0);
  224. #endif    /* !UNIX */
  225.     /*NOTREACHED*/
  226. }
  227. private char    smbuf[20],
  228.         *bp = smbuf;
  229.  
  230. private int    nchars = 0;
  231.  
  232. private char    peekbuf[10],
  233.         *peekp = peekbuf;
  234.  
  235. #if    defined(SYSV) || defined(M_XENIX)
  236.  
  237. #define    NONBLOCKINGREAD    1
  238.  
  239. private void
  240. setblock(fd, on)    /* turn blocking on or off */
  241. register int    fd;
  242. bool    on;
  243. {
  244.     static int blockf, nonblockf;
  245.     static bool    first = TRUE;
  246.  
  247.     if (first) {
  248.     int flags;
  249.  
  250.     first = FALSE;
  251.     if ((flags = fcntl(fd, F_GETFL, 0)) == -1)
  252.         finish(SIGHUP);
  253.     blockf = flags & ~O_NDELAY;    /* make sure O_NDELAY is off */
  254.     nonblockf = flags | O_NDELAY;    /* make sure O_NDELAY is on */
  255.     }
  256.     if (fcntl(fd, F_SETFL, on ? blockf : nonblockf) == -1)
  257.     finish(SIGHUP);
  258. }
  259.  
  260. #endif    /* defined(SYSV) || defined(M_XENIX) */
  261.  
  262. private int
  263. Peekc()
  264. {
  265.     return peekp == peekbuf? EOF : *--peekp & 0377;
  266. }
  267.  
  268. void
  269. Ungetc(c)
  270. int    c;
  271. {
  272.     if (peekp != &peekbuf[(sizeof peekbuf) - 1])
  273.         *peekp++ = c;
  274. }
  275.  
  276. bool    InputPending = NO;
  277.  
  278. char    *Inputp = NULL;
  279.  
  280. #ifdef    PTYPROCS
  281.  
  282. /* Warning! This code requires 32-bit ints.  A thoroughly obscure mess --
  283.    ffs() as a three-line "for" loop.   This is what you get for not
  284.    including ffs() in the libs.  -- Doug
  285. */
  286. #ifdef MiNT
  287. int
  288. ffs(int i)
  289. {
  290.     int z;
  291.  
  292.     for (z = 1; z <= (sizeof(int) * 8); z++)
  293.         if (i & ~(0xFFFFFFFF >> z))
  294.             return ((sizeof(int) * 8) - --z);
  295. }
  296. #endif
  297.  
  298. int
  299. jgetchar()
  300. {
  301.     long        reads;
  302.     register int    tmp,
  303.             nfds;
  304.     int        c;
  305.  
  306.     if (nchars <= 0) {
  307.         /* Get a character from the keyboard, first checking for
  308.            any input from a process.  Handle that first, and then
  309.            deal with the terminal input. */
  310.         do {
  311.             do {
  312.                 reads = global_fd;
  313.                 nfds = select(32, &reads, (long *)NULL, (long *)NULL, (struct timeval *)NULL);
  314.             } while (nfds < 0 && errno == EINTR);
  315.  
  316.             if (nfds == -1)
  317.                 complain("\rerror in select %ld: %s", global_fd, strerror(errno));
  318.             else {
  319.                 if (reads & 01) {
  320. /* This is where I replaced read() with my own command to get characters
  321.    from the BIOS.  This allowed me to implement all the Atari special keys.
  322.    Recent developments in MiNT have rendered all of this obsolete, and it
  323.    is one thing I will eventually replace.  If you, the reader, decide to
  324.    undertake this yourself, please email a copy of your code to:
  325.    dstailey@leidecker.gsfc.nasa.gov   -- Doug
  326. */
  327. #ifdef MiNT
  328.                     *smbuf = jgetkey();
  329.                     nchars = 1;
  330. #else
  331.                     nchars = read(0, (UnivPtr) smbuf, sizeof(smbuf));
  332. #endif MiNT
  333.                     reads &= ~01;
  334.                     nfds -= 1;
  335.                 }
  336.                 while (nfds--) {
  337.                     tmp = ffs(reads) - 1;
  338.                     read_proc(tmp);
  339.                     reads &= ~(1L << tmp);
  340.                 }
  341.             }
  342.         } while (nchars <= 0);
  343.  
  344.         if (nchars <= 0)
  345.             finish(SIGHUP);
  346.  
  347.         bp = smbuf;
  348.         InputPending = (nchars > 1);
  349.     }
  350.  
  351.     if (((c = *bp) & 0200) && MetaKey) {
  352.         *bp = (c & CHARMASK);
  353.         return '\033';
  354.     }
  355.     nchars -= 1;
  356.     return *bp++ & 0377;
  357. }
  358.  
  359. #else    /* !PTYPROCS */
  360.  
  361. int
  362. jgetchar()
  363. {
  364.     register int    c;
  365.     struct header {
  366.         int    pid;
  367.         int    nbytes;
  368.     } header;
  369.  
  370. normal:
  371.     if (nchars <= 0) {
  372.         bp = smbuf;
  373. #ifdef    MSDOS
  374.         *bp = getrawinchar();
  375.         nchars = 1;
  376. #else    /* !MSDOS */
  377. # ifdef    IPROCS
  378.         if (NumProcs > 0) {
  379.             for (;;) {
  380.                 size_t    n = f_readn(ProcInput, (char *) &header,
  381.                         sizeof(header));
  382.  
  383.                 if (n != sizeof(header)) {
  384.                     raw_complain("\r\nError reading kbd process, expected %d, got %d bytes\r\n", sizeof header, n);
  385.                     finish(SIGHUP);
  386.                 }
  387.                 /* data is from the keyboard process */
  388.                 if (header.pid == kbd_pid) {
  389.                     nchars = f_readn(ProcInput, smbuf, header.nbytes);
  390.                     if (nchars != header.nbytes) {
  391.                         raw_complain("\r\nError reading kbd process, expected %d, got %d bytes.\r\n", header.nbytes, nchars);
  392.                         finish(SIGHUP);
  393.                     }
  394.                     break;
  395.                 }
  396.                 read_proc(header.pid, header.nbytes);
  397.                 if (NumProcs == 0) {
  398.                     (void) kbd_stop();
  399.                     goto normal;
  400.                 }
  401.             }
  402.         } else /*...*/
  403. # endif
  404.         /*...*/ {
  405.             for (;;) {
  406.                 nchars = read(0, (UnivPtr) smbuf, sizeof smbuf);
  407.                 if (nchars > 0)
  408.                     break;
  409. # ifdef    SYSV
  410.                 /* System V seems to allow zero-length results */
  411.                 if (nchars == 0)
  412.                     continue;
  413. # endif    /* SYSV */
  414.                 /* retry on interrupt */
  415.                 if (!(nchars < 0 && errno == EINTR))
  416.                     finish(SIGHUP);
  417.             }
  418.         }
  419. #endif    /* !MSDOS */
  420.         InputPending = nchars > 0;
  421.     }
  422.     if (((c = *bp) & 0200) && MetaKey) {
  423.         *bp = (c & CHARMASK);
  424.         return '\033';
  425.     }
  426.     nchars -= 1;
  427.     return (*bp++ & CHARMASK);
  428. }
  429.  
  430. #endif    /* !PTYPROCS */
  431.  
  432. /* Returns non-zero if a character waiting */
  433.  
  434. bool
  435. charp()
  436. {
  437.     bool    some = NO;
  438.  
  439.     if (InJoverc != 0 || nchars > 0 || Inputp != NULL)
  440.         return YES;
  441. #ifdef    BRLUNIX
  442.     {
  443.         static struct sg_brl gttyBuf;
  444.  
  445.         gtty(0, (char *) >tyBuf);
  446.         if (gttyBuf.sg_xflags & INWAIT)
  447.             some = YES;
  448.     }
  449. #else
  450. #ifdef    FIONREAD
  451.     {
  452.         long c;
  453.  
  454.         if (ioctl(0, FIONREAD, (UnivPtr) &c) == -1)
  455.             c = 0;
  456.         some = (c > 0);
  457.     }
  458. #else
  459. #ifdef    NONBLOCKINGREAD
  460.     setblock(0, OFF);        /* turn blocking off */
  461.     nchars = read(0, (UnivPtr) smbuf, sizeof smbuf);    /* Is anything there? */
  462.     setblock(0, ON);        /* turn blocking on */
  463.     if (nchars > 0)        /* something was there */
  464.         bp = smbuf;        /* make sure bp points to it */
  465.     some = (nchars > 0);    /* just say we found something */
  466. #else
  467. #ifdef    c70
  468.     some = !empty(0);
  469. #else
  470. #ifdef    MSDOS
  471.     some = rawkey_ready();
  472. #else
  473. #ifdef    MAC
  474.     some = rawchkc();
  475. #endif
  476. #endif
  477. #endif
  478. #endif
  479. #endif
  480. #endif
  481.     return some;
  482. }
  483.  
  484. #ifdef    BIFF
  485. private void    biff_init proto((void));
  486. #endif
  487.  
  488. #ifdef    TERMCAP
  489.  
  490. private void
  491. ResetTerm()
  492. {
  493.     do_sgtty();        /* this is so if you change baudrate or stuff
  494.                    like that, JOVE will notice. */
  495.     ttyset(ON);
  496.     putpad(TI, 1);
  497.     putpad(VS, 1);
  498.     putpad(KS, 1);
  499. #ifdef    UNIX
  500.     (void) chkmail(YES);    /* force it to check to we can be accurate */
  501. #endif
  502. #ifdef    BIFF
  503.     if (BiffChk != dw_biff)
  504.         biff_init();
  505.     /* just in case we changed our minds about whether to deal with
  506.        biff */
  507. #endif
  508. }
  509.  
  510. private void
  511. UnsetTerm(mesg)
  512. char    *mesg;
  513. {
  514.     ttyset(OFF);
  515. #ifdef    ID_CHAR
  516.     INSmode(NO);
  517. #endif
  518.     putpad(KE, 1);
  519.     putpad(VE, 1);
  520.     Placur(ILI, 0);
  521.     putpad(CE, 1);
  522.     if (TE)
  523.         putpad(TE, 1);
  524.     if (mesg[0] != '\0')
  525.         writef("%s\n", mesg);
  526.     flushscreen();
  527. }
  528. #endif    /* TERMCAP */
  529.  
  530. #ifdef    JOB_CONTROL
  531. void
  532. PauseJove()
  533. {
  534.     UnsetTerm(ModBufs(NO) ? "[There are modified buffers]" : NullStr);
  535. #ifdef MiNT
  536.     (void) kill(getpid(), SIGTSTP);
  537. #else
  538.     (void) kill(0, SIGTSTP);
  539. #endif /* MiNT */
  540.     ResetTerm();
  541.     ClAndRedraw();
  542. }
  543. #endif
  544.  
  545.  
  546. #ifndef    MAC
  547. void
  548. jcloseall()
  549. {
  550.     tmpclose();
  551.     recclose();
  552. #ifdef    LOAD_AV
  553.     closekmem();
  554. #endif    /* LOAD_AV */
  555. }
  556.  
  557. void
  558. Push()
  559. {
  560. #ifndef    MSDOS
  561.     int    pid;
  562.     SIGRESULT    (*old_quit) ptrproto((int)) = signal(SIGQUIT, SIG_IGN);
  563. #endif    /* !MSDOS */
  564.     SIGRESULT    (*old_int) ptrproto((int)) = signal(SIGINT, SIG_IGN);
  565. # ifdef    PIPEPROCS
  566.     int    started;
  567. # endif
  568.  
  569. #ifndef    MSDOS
  570. #ifdef    IPROCS
  571.     SigHold(SIGCHLD);
  572. #endif
  573. #ifdef    WINRESIZE
  574.     SigHold(SIGWINCH);
  575. #endif
  576.     alarm((unsigned)0);
  577. # ifdef    PIPEPROCS
  578.     started = kbd_stop();
  579. # endif
  580.     switch (pid = fork()) {
  581.     case -1:
  582. # ifdef    PIPEPROCS
  583.         if (started)
  584.             (void) kbd_strt();
  585. # endif
  586.         complain("[Fork failed: %s]", strerror(errno));
  587.         /*NOTREACHED*/
  588.  
  589.     case 0:
  590.         UnsetTerm(ModBufs(NO) ? "[There are modified buffers]" : NullStr);
  591. #ifdef    WINRESIZE
  592.         SigRelse(SIGWINCH);
  593. #endif
  594. #ifdef    IPROCS
  595.         SigRelse(SIGCHLD);
  596. #endif
  597.         (void) signal(SIGTERM, SIG_DFL);
  598. #else    /* MSDOS */
  599.         UnsetTerm(ModBufs(NO) ? "[There are modified buffers]" : NullStr);
  600. #endif    /* MSDOS */
  601.         (void) signal(SIGINT, SIG_DFL);
  602. #ifdef    UNIX
  603.         (void) signal(SIGQUIT, SIG_DFL);
  604.         jcloseall();
  605.         /* note that curbuf->bfname may be NULL */
  606. #ifdef MiNT
  607.         execl(Shell, basename(Shell), "-s", pr_name(curbuf->b_fname, NO),
  608.             (char *)NULL);
  609. #else
  610.         execl(Shell, basename(Shell), "-is", pr_name(curbuf->b_fname, NO),
  611.             (char *)NULL);
  612. #endif /* MiNT */
  613.         raw_complain("[Execl failed: %s]", strerror(errno));
  614.         _exit(1);
  615.     }
  616. #ifdef    IPROCS
  617.     SigRelse(SIGCHLD);
  618. #endif
  619.     dowait(pid, (int *) NULL);
  620. #endif    /* UNIX */
  621. #ifdef    MSDOS
  622.     break_rst();
  623.     if (spawnl(0, Shell, basename(Shell), (char *)NULL) == -1)
  624.         message("[Spawn failed]");
  625. #endif    /* MSDOS */
  626. #ifndef    MAC
  627.     ResetTerm();
  628. #endif
  629. #ifdef    WINRESIZE
  630.     SigRelse(SIGWINCH);
  631. #endif
  632.     ClAndRedraw();
  633. #ifndef    MSDOS
  634.     (void) signal(SIGQUIT, old_quit);
  635. #else    /* MSDOS */
  636.     break_off();
  637.     getCWD();
  638. #endif    /* MSDOS */
  639.     (void) signal(SIGINT, old_int);
  640.     if (UpdFreq != 0)
  641.         (void) alarm((unsigned) (UpdFreq - (time((time_t *)NULL) % UpdFreq)));
  642. # ifdef    PIPEPROCS
  643.     if (started)
  644.         (void) kbd_strt();
  645. # endif
  646. }
  647. #endif    /* MAC */
  648.  
  649. bool    OKXonXoff = OFF;    /* ^S and ^Q initially DON'T work */
  650. int    IntChar = CTL(']');
  651.  
  652. private void
  653. ttsize()
  654. {
  655. #ifdef    UNIX
  656. #   ifdef    TIOCGWINSZ
  657.     struct winsize win;
  658.  
  659.     if (ioctl(0, TIOCGWINSZ, (UnivPtr) &win) == 0) {
  660.         if (win.ws_col)
  661.             CO = win.ws_col;
  662.         if (win.ws_row)
  663.             LI = win.ws_row;
  664.     }
  665. #   else    /* !TIOCGWINSZ */
  666. #    ifdef    BTL_BLIT
  667. #include <sys/jioctl.h>
  668.     struct jwinsize jwin;
  669.  
  670.     if (ioctl(0, JWINSIZE, &jwin) == 0) {
  671.         if (jwin.bytesx)
  672.             CO = jwin.bytesx;
  673.         if (jwin.bytesy)
  674.             LI = jwin.bytesy;
  675.     }
  676. #    endif    /* BTL_BLIT */
  677. #   endif    /* !TIOCGWINSZ */
  678. #endif    /* UNIX */
  679. #ifdef    MAC
  680.     CO = getCO();    /* see mac.c */
  681.     LI = getLI();
  682.     Windchange = YES;
  683.     clr_page();
  684. #endif
  685.     ILI = LI - 1;
  686. }
  687.  
  688. #ifdef    BIFF
  689. private void
  690. biff_init()
  691. {
  692.     dw_biff = ((BiffChk) &&
  693. #   ifndef    BSD4_2
  694.            ((tt_name != NULL) || (tt_name = ttyname(0))) &&
  695.            (stat(tt_name, &tt_stat) != -1) &&
  696. #   else
  697.            (fstat(0, &tt_stat) != -1) &&
  698. #   endif
  699.            (tt_stat.st_mode & S_IEXEC));    /* he's using biff */
  700.  
  701. }
  702.  
  703. private void
  704. biff(on)
  705. int    on;
  706. {
  707.     if (dw_biff == NO)
  708.         return;
  709. #   ifndef    BSD4_2
  710.     (void) chmod(tt_name, on ? tt_stat.st_mode :
  711.                    (tt_stat.st_mode & ~S_IEXEC));
  712. #   else
  713.     (void) fchmod(0, on ? tt_stat.st_mode :
  714.                   (tt_stat.st_mode & ~S_IEXEC));
  715. #   endif
  716. }
  717.  
  718. #endif    /* BIFF */
  719.  
  720. private void
  721. ttinit()
  722. {
  723. #ifdef    BIFF
  724.     biff_init();
  725. #endif
  726. #ifdef    TIOCSLTC
  727.     (void) ioctl(0, TIOCGLTC, (UnivPtr) &ls[OFF]);
  728.     ls[ON] = ls[OFF];
  729.     ls[ON].t_suspc = (char) -1;
  730.     ls[ON].t_dsuspc = (char) -1;
  731.     ls[ON].t_flushc = (char) -1;
  732.     ls[ON].t_lnextc = (char) -1;
  733. #endif
  734.  
  735. #ifdef    TIOCGETC
  736.     /* Change interupt and quit. */
  737.     (void) ioctl(0, TIOCGETC, (UnivPtr) &tc[OFF]);
  738.     tc[ON] = tc[OFF];
  739.     tc[ON].t_intrc = IntChar;
  740.     tc[ON].t_quitc = (char) -1;
  741.     if (OKXonXoff) {
  742.         tc[ON].t_stopc = (char) -1;
  743.         tc[ON].t_startc = (char) -1;
  744.     }
  745. #endif    /* TIOCGETC */
  746.     do_sgtty();
  747. }
  748.  
  749. private int    done_ttinit = NO;
  750.  
  751. #ifndef    MSDOS
  752. private
  753. #endif
  754. void
  755. do_sgtty()
  756. {
  757. #ifdef    UNIX
  758. # ifdef    TERMIO
  759.     (void) ioctl(0, TCGETA, (char *) &sg[OFF]);
  760. # endif
  761. # ifdef TERMIOS
  762.     (void) tcgetattr(0, &sg[OFF]);
  763. # endif
  764.  
  765. # ifdef SGTTY
  766.     (void) gtty(0, &sg[OFF]);
  767. # endif    /* SYSV */
  768.     sg[ON] = sg[OFF];
  769.  
  770. # ifdef    LPASS8
  771.     (void) ioctl(0, TIOCLGET, (UnivPtr) &lmword[OFF]);
  772.     lmword[ON] = lmword[OFF];
  773.     if (MetaKey)
  774.         lmword[ON] |= LPASS8;
  775. # endif
  776.  
  777. # ifdef LTILDE
  778.     if (Hazeltine)
  779.         lmword[ON] &= ~LTILDE;
  780. # endif
  781.  
  782. # if defined(TERMIO) || defined(TERMIOS)
  783.     TABS = !((sg[OFF].c_oflag & TAB3) == TAB3);
  784.     ospeed = sg[OFF].c_cflag & CBAUD;
  785.  
  786.     if (OKXonXoff)
  787.         sg[ON].c_iflag &= ~(IXON | IXOFF);
  788.     sg[ON].c_iflag &= ~(INLCR|ICRNL|IGNCR);
  789.     /* sg[ON].c_lflag &= ~(ICANON|ECHO); */
  790.     sg[ON].c_lflag &= ~(ISIG|ICANON|ECHO);
  791.     sg[ON].c_oflag &= ~(OCRNL|ONLCR);
  792. #  ifdef _POSIX_VDISABLE
  793.     /* The following characters cause signals in System Vr4.
  794.      * We should perhaps handle them; for now, we suppress them.
  795.      */
  796.     sg[ON].c_cc[VQUIT] = _POSIX_VDISABLE;
  797.     sg[ON].c_cc[VSWTCH] = _POSIX_VDISABLE;
  798.     sg[ON].c_cc[VSUSP] = _POSIX_VDISABLE;
  799.     sg[ON].c_cc[VDSUSP] = _POSIX_VDISABLE;
  800. #  else
  801.     sg[ON].c_cc[VINTR] = IntChar;
  802.     sg[ON].c_cc[VQUIT] = (char) -1;
  803. #  endif /* _POSIX_VDISABLE */
  804.     sg[ON].c_cc[VMIN] = 1;
  805.     sg[ON].c_cc[VTIME] = 1;
  806. # endif /* TERMIO || TERMIOS */
  807.  
  808. # if defined(SGTTY) || defined(BRLUNIX)
  809.     TABS = !(sg[OFF].sg_flags & XTABS);
  810.     sg[ON].sg_flags &= ~XTABS;
  811.     ospeed = sg[OFF].sg_ospeed;
  812. #  ifdef    BRLUNIX
  813.     sg[ON].sg_flags &= ~(ECHO | CRMOD);
  814.     sg[ON].sg_flags |= CBREAK;
  815.  
  816.     /* VT100 Kludge: leave STALL on for flow control if DC3DC1 (Yuck.) */
  817.     sg[ON].sg_xflags &= ~((sg[ON].sg_xflags&DC3DC1 ? 0 : STALL) | PAGE);
  818. #  else
  819.     sg[ON].sg_flags &= ~(ECHO | CRMOD);
  820. #  endif    /* BRLUNIX */
  821.  
  822. #  ifdef    LPASS8
  823.     sg[ON].sg_flags |= CBREAK;
  824. #  else
  825.     sg[ON].sg_flags |= (MetaKey ? RAW : CBREAK);
  826. #  endif
  827. # endif    /* SGTTY */
  828. #endif    /* UNIX */
  829.  
  830. #ifdef    MSDOS
  831. # ifndef    IBMPC
  832.     setmode(1, 0x8000);
  833. # endif    /* IBMPC */
  834.     TABS = NO;
  835. #endif    /* MSDOS */
  836. }
  837.  
  838. void
  839. tty_reset()
  840. {
  841.     if (!done_ttinit)
  842.         return;
  843.     ttyset(OFF);    /* go back to original modes */
  844.     ttinit();
  845.     ttyset(ON);
  846. }
  847.  
  848. /* If n is OFF reset to original modes */
  849.  
  850. void
  851. ttyset(n)
  852. bool    n;
  853. {
  854.     if (!done_ttinit && !n)    /* Try to reset before we've set! */
  855.         return;
  856. #ifdef    UNIX
  857. # ifdef    TERMIO
  858.     (void) ioctl(0, TCSETAW, (UnivPtr) &sg[n]);
  859. # endif    /* TERMIO */
  860.  
  861. # ifdef    TERMIOS
  862.     (void) tcsetattr(0, TCSADRAIN, &sg[n]);
  863. # endif /* TERMIOS */
  864.  
  865. # ifdef    SGTTY
  866. #  ifdef TIOCSETN
  867.     (void) ioctl(0, TIOCSETN, (UnivPtr) &sg[n]);
  868. #  else
  869.     (void) stty(0, &sg[n]);
  870. #  endif
  871. # endif
  872.  
  873. # ifdef    TIOCGETC
  874.     (void) ioctl(0, TIOCSETC, (UnivPtr) &tc[n]);
  875. # endif    /* TIOCSETC */
  876. # ifdef    TIOCSLTC
  877.     (void) ioctl(0, TIOCSLTC, (UnivPtr) &ls[n]);
  878. # endif    /* TIOCSLTC */
  879. # ifdef    LPASS8
  880.     (void) ioctl(0, TIOCLSET, (UnivPtr) &lmword[n]);
  881. # endif
  882. #endif    /* UNIX */
  883.  
  884. #ifdef    MSDOS
  885. # ifndef    IBMPC
  886.     setmode(1, n? 0x8000 : 0x4000);
  887. # endif
  888. #endif    /* MSDOS */
  889.     done_ttinit = YES;
  890. #ifdef    BIFF
  891.     biff(!n);
  892. #endif
  893. }
  894.  
  895. int    this_cmd,
  896.     last_cmd,
  897.     LastKeyStruck,
  898.     MetaKey = OFF;
  899.  
  900. int
  901. getch()
  902. {
  903.     register int    c,
  904.             peekc;
  905.  
  906.     if (Inputp) {
  907.         if ((c = *Inputp++) != '\0')
  908.             return LastKeyStruck = c;
  909.         Inputp = NULL;
  910.     }
  911.  
  912.     if (InJoverc)
  913.         return EOF;    /* somethings wrong if Inputp runs out while
  914.                    we're reading a .joverc file. */
  915.  
  916. #ifndef    MSDOS
  917.     if (ModCount >= SyncFreq) {
  918.         ModCount = 0;
  919.         SyncRec();
  920.     }
  921. #endif    /* MSDOS */
  922.  
  923.     /* If there are no ungetc'd characters,
  924.        AND we're interactive or we're not executing a macro,
  925.        we read from the terminal (i.e., jgetchar()).
  926.        Note: characters only get put in macros from inside this if. */
  927.     if (((peekc = c = Peekc()) == EOF) &&
  928.         (Interactive || ((c = mac_getc()) == EOF))) {
  929.         /* So messages that aren't error messages don't
  930.          * hang around forever.
  931.          * Note: this code is duplicated in SitFor()!
  932.          */
  933.         if (!UpdMesg && !Asking && mesgbuf[0] != '\0' && !errormsg)
  934.             message(NullStr);
  935.         redisplay();
  936. #ifdef    UNIX
  937.         inIOread = YES;
  938. #endif
  939.         if ((c = jgetchar()) == EOF)
  940.             finish(SIGHUP);
  941. #ifdef    UNIX
  942.         inIOread = NO;
  943. #endif
  944.  
  945.         if (!Interactive && InMacDefine)
  946.             mac_putc(c);
  947.     }
  948.     if (peekc == EOF)    /* don't add_stroke peekc's */
  949.         add_stroke(c);
  950.     return LastKeyStruck = c;
  951. }
  952.  
  953. #ifdef    UNIX
  954. private void
  955. dorecover()
  956. {
  957.     /* Since recover is a normal cooked mode program, reset the terminal */
  958.     UnsetTerm(NullStr);
  959. #ifdef    PIPEPROCS
  960.     kbd_kill();        /* kill the keyboard process */
  961. #endif
  962.     execl(Recover, "recover", "-d", TmpFilePath, (char *) NULL);
  963.     writef("%s: execl failed! %s\n", Recover, strerror(errno));
  964.     flushscreen();
  965.     _exit(-1);
  966.     /* NOTREACHED */
  967. }
  968. #endif    /* UNIX */
  969.  
  970. void
  971. ShowVersion()
  972. {
  973.     s_mess("Jonathan's Own Version of Emacs (%s)", version);
  974. }
  975.  
  976. private void
  977. UNIX_cmdline(argc, argv)
  978. int    argc;
  979. char    *argv[];
  980. {
  981.     int    lineno = 0,
  982.         nwinds = 1;
  983.     Buffer    *b;
  984.  
  985.     ShowVersion();
  986.     while (argc > 1) {
  987.         if (argv[1][0] != '-' && argv[1][0] != '+') {
  988.             bool    force = (nwinds > 0 || lineno != 0);
  989.  
  990. #ifdef    MSDOS
  991.             strlwr(argv[1]);
  992. #endif
  993.             minib_add(argv[1], force);
  994.             b = do_find(nwinds > 0 ? curwind : (Window *) NULL,
  995.                     argv[1], force);
  996.             if (force) {
  997.                 SetABuf(curbuf);
  998.                 SetBuf(b);
  999.                 if (lineno >= 0)
  1000.                     SetLine(next_line(curbuf->b_first, lineno));
  1001.                 else
  1002.                     SetLine(curbuf->b_last);
  1003.                 if (nwinds > 1)
  1004.                     NextWindow();
  1005.                 if (nwinds)
  1006.                     nwinds -= 1;
  1007.             }
  1008.             lineno = 0;
  1009.         } else    switch (argv[1][1]) {
  1010.             case 'd':
  1011.                 argv += 1;
  1012.                 argc -= 1;
  1013.                 break;
  1014.  
  1015.             case 'j':    /* Ignore .joverc in HOME */
  1016.                 break;
  1017. #ifndef    MAC
  1018.             case 'p':
  1019.                 argv += 1;
  1020.                 argc -= 1;
  1021.                 if (argv[1] != NULL) {
  1022.                     SetBuf(do_find(curwind, argv[1], NO));
  1023.                     ErrParse();
  1024.                     nwinds = 0;
  1025.                 }
  1026.                 break;
  1027. #endif
  1028.             case 't':
  1029.                 /* check if syntax is -tTag or -t Tag */
  1030.                 if (argv[1][2] != '\0') {
  1031.                     find_tag(&(argv[1][2]), YES);
  1032.                 } else {
  1033.                     argv += 1;
  1034.                     argc -= 1;
  1035.                     if (argv[1] != NULL)
  1036.                         find_tag(argv[1], YES);
  1037.                 }
  1038.                 break;
  1039.  
  1040.             case 'w':
  1041.                 if (argv[1][2] == '\0')
  1042.                     nwinds += 1;
  1043.                 else {
  1044.                     int    n;
  1045.  
  1046.                     (void) chr_to_int(&argv[1][2], 10, NO, &n);
  1047.                     nwinds += -1 + n;
  1048.                 }
  1049.                 (void) div_wind(curwind, nwinds - 1);
  1050.                 break;
  1051.  
  1052.             case '0':
  1053.             case '1':
  1054.             case '2':
  1055.             case '3':
  1056.             case '4':
  1057.             case '5':
  1058.             case '6':
  1059.             case '7':
  1060.             case '8':
  1061.             case '9':
  1062.                 (void) chr_to_int(&argv[1][1], 10, NO, &lineno);
  1063.                 lineno -= 1;
  1064.                 break;
  1065.             case '\0':
  1066.                 lineno = -1;    /* goto end of file ... */
  1067.                 break;        /* just like some people's */
  1068.         }                /* favourite editor */
  1069.         argv += 1;
  1070.         argc -= 1;
  1071.     }
  1072. }
  1073.  
  1074. void
  1075. raw_scream(m)
  1076. const char    *m;
  1077. {
  1078.     write(2, (UnivConstPtr)m, strlen(m));
  1079. }
  1080.  
  1081. #ifdef    STDARGS
  1082. void
  1083. error(const char *fmt, ...)
  1084. #else
  1085. /*VARARGS1*/ void
  1086. error(fmt, va_alist)
  1087.     const char    *fmt;
  1088.     va_dcl
  1089. #endif
  1090. {
  1091.     va_list    ap;
  1092.  
  1093.     if (fmt) {
  1094.         va_init(ap, fmt);
  1095.         format(mesgbuf, sizeof mesgbuf, fmt, ap);
  1096.         va_end(ap);
  1097.         UpdMesg = YES;
  1098.     }
  1099.     rbell();
  1100.     longjmp(mainjmp, ERROR);
  1101. }
  1102.  
  1103. #ifdef    STDARGS
  1104. void
  1105. complain(const char *fmt, ...)
  1106. #else
  1107. /*VARARGS1*/ void
  1108. complain(fmt, va_alist)
  1109.     const char    *fmt;
  1110.     va_dcl
  1111. #endif
  1112. {
  1113.     va_list    ap;
  1114.  
  1115.     if (fmt) {
  1116.         va_init(ap, fmt);
  1117.         format(mesgbuf, sizeof mesgbuf, fmt, ap);
  1118.         va_end(ap);
  1119.         UpdMesg = YES;
  1120.     }
  1121.     rbell();
  1122.     longjmp(mainjmp, COMPLAIN);
  1123. }
  1124.  
  1125. #ifdef    STDARGS
  1126. void
  1127. raw_complain(const char *fmt, ...)
  1128. #else
  1129. /*VARARGS1*/ void
  1130. raw_complain(fmt, va_alist)
  1131.     const char    *fmt;
  1132.     va_dcl
  1133. #endif
  1134. {
  1135.     va_list    ap;
  1136.  
  1137.     if (fmt) {
  1138.         va_init(ap, fmt);
  1139.         format(mesgbuf, sizeof mesgbuf, fmt, ap);
  1140.         va_end(ap);
  1141.         raw_scream(mesgbuf);
  1142.     }
  1143. }
  1144.  
  1145. #ifdef    STDARGS
  1146. void
  1147. confirm(const char *fmt, ...)
  1148. #else
  1149. /*VARARGS1*/ void
  1150. confirm(fmt, va_alist)
  1151.     const char    *fmt;
  1152.     va_dcl
  1153. #endif
  1154. {
  1155.     char    *yorn;
  1156.     va_list    ap;
  1157.  
  1158.     va_init(ap, fmt);
  1159.     format(mesgbuf, sizeof mesgbuf, fmt, ap);
  1160.     va_end(ap);
  1161.     yorn = ask((char *)NULL, mesgbuf);
  1162.     if (*yorn != 'Y' && *yorn != 'y')
  1163.         longjmp(mainjmp, COMPLAIN);
  1164. }
  1165.  
  1166. int    RecDepth = 0;
  1167.  
  1168. void
  1169. Recur()
  1170. {
  1171.     char    bname[128];
  1172.     Mark    *m;
  1173.  
  1174.     swritef(bname, sizeof(bname), "%s", curbuf->b_name);
  1175.     m = MakeMark(curline, curchar, M_FLOATER);
  1176.  
  1177.     RecDepth += 1;
  1178.     UpdModLine = YES;
  1179.     DoKeys(NO);    /* NO means not first time */
  1180.     UpdModLine = YES;
  1181.     RecDepth -= 1;
  1182.     SetBuf(do_select(curwind, bname));
  1183.     if (!is_an_arg())
  1184.         ToMark(m);
  1185.     DelMark(m);
  1186. }
  1187.  
  1188. #ifdef    MAC
  1189. jmp_buf auxjmp;
  1190. #endif
  1191.  
  1192. private int    iniargc;    /* main sets these for DoKeys() */
  1193. private char    **iniargv;
  1194.  
  1195. private void
  1196. DoKeys(firsttime)
  1197. bool    firsttime;
  1198. {
  1199.     int    c;
  1200.     jmp_buf    savejmp;
  1201.  
  1202.     push_env(savejmp);
  1203.  
  1204.     switch (setjmp(mainjmp)) {
  1205.     case 0:
  1206.         if (firsttime)
  1207.             UNIX_cmdline(iniargc, iniargv);
  1208.         break;
  1209.  
  1210.     case QUIT:
  1211.         if (RecDepth == 0) {
  1212.             if (ModMacs()) {
  1213.                 rbell();
  1214.                 if (CharUpcase(*ask("No",
  1215. "Some MACROS haven't been saved; leave anyway? ")) != 'Y')
  1216.                     break;
  1217.             }
  1218.             if (ModBufs(NO)) {
  1219.                 rbell();
  1220.                 if (CharUpcase(*ask("No",
  1221. "Some buffers haven't been saved; leave anyway? ")) != 'Y')
  1222.                     break;
  1223.             }
  1224. #ifdef    IPROCS
  1225.             KillProcs();
  1226. #endif
  1227.         }
  1228.         pop_env(savejmp);
  1229.         return;
  1230.  
  1231.     case ERROR:
  1232.         getDOT();    /* God knows what state linebuf was in */
  1233.         /*FALLTHROUGH*/
  1234.     case COMPLAIN:
  1235.         {
  1236.         gc_openfiles();        /* close any files we left open */
  1237.         errormsg = YES;
  1238.         unwind_macro_stack();
  1239.         Asking = NO;
  1240.         curwind->w_bufp = curbuf;
  1241.         DisabledRedisplay = NO;
  1242.         redisplay();
  1243.         break;
  1244.         }
  1245.     }
  1246.  
  1247.     this_cmd = last_cmd = 0;
  1248.  
  1249.     for (;;) {
  1250. #ifdef    MAC
  1251.         setjmp(auxjmp);
  1252. #endif
  1253.         if (this_cmd != ARG_CMD) {
  1254.             clr_arg_value();
  1255.             last_cmd = this_cmd;
  1256.             init_strokes();
  1257.         }
  1258. #ifdef    MAC
  1259.         HiliteMenu(0);
  1260.         EventCmd = NO;
  1261.         menus_on();
  1262. #endif
  1263.         c = getch();
  1264.         if (c == EOF)
  1265.             continue;
  1266.         dispatch(c);
  1267.     }
  1268. }
  1269.  
  1270. private char **
  1271. scanvec(args, str)
  1272. register char    **args,
  1273.         *str;
  1274. {
  1275.     while (*args) {
  1276.         if (strcmp(*args, str) == 0)
  1277.             return args;
  1278.         args += 1;
  1279.     }
  1280.     return NULL;
  1281. }
  1282.  
  1283. #ifdef    UNIX
  1284. int    UpdFreq = 30,
  1285.     inIOread = NO;
  1286.  
  1287. private SIGRESULT
  1288. updmode(junk)
  1289. int    junk;    /* passed in on signal; of no interest */
  1290. {
  1291.     int save_errno = errno;    /* Subtle, but necessary! */
  1292.  
  1293.     UpdModLine = YES;
  1294.     if (inIOread)
  1295.         redisplay();
  1296. #ifndef    BSD_SIGS
  1297.     (void) signal(SIGALRM, updmode);
  1298. #endif
  1299.     if (UpdFreq != 0)
  1300.         (void) alarm((unsigned) (UpdFreq - (time((time_t *)NULL) % UpdFreq)));
  1301.     errno = save_errno;
  1302.     SIGRETURN;
  1303. }
  1304. #endif    /* UNIX */
  1305.  
  1306. #ifdef    MSDOS
  1307. # ifndef    IBMPC
  1308. char    ttbuf[JBUFSIZ];
  1309. # endif    /* IBMPC */
  1310. #endif    /* MSDOS */
  1311.  
  1312. #ifdef    WINRESIZE
  1313. #ifndef    MAC
  1314. private
  1315. #endif
  1316. SIGRESULT
  1317. win_reshape(junk)
  1318. int    junk;    /* passed in when invoked by a signal; of no interest */
  1319. {
  1320.     int save_errno = errno;    /* Subtle, but necessary! */
  1321.     register int    oldLI;
  1322.     register int newsize, total;
  1323.     register Window *wp;
  1324.  
  1325. #ifdef    UNIX
  1326.     (void) SigHold(SIGWINCH);
  1327. #endif
  1328.     /*
  1329.      * Save old number of lines.
  1330.      */
  1331.     oldLI = LI;
  1332.  
  1333.     /*
  1334.      * Get new line/col info.
  1335.      */
  1336.     ttsize();
  1337.  
  1338.     /*
  1339.      * LI has changed, and now holds the
  1340.      * new value.
  1341.      */
  1342.     /*
  1343.      *  Go through the window list, changing each window size in
  1344.      *  proportion to the resize. If a window becomes too small,
  1345.      *  delete it. We keep track of all the excess lines (caused by
  1346.      *  roundoff!), and give them to the current window, as a sop -
  1347.      *  can't be more than one or two lines anyway. This seems fairer
  1348.      *  than just resizing the current window.
  1349.      */
  1350.     wp = fwind;
  1351.     total = 0;
  1352.     do {
  1353.         newsize = LI * wp->w_height / oldLI;
  1354.  
  1355.         if (newsize < 2) {
  1356.             total += wp->w_height;
  1357.             wp = wp->w_next;
  1358.             del_wind(wp->w_prev);
  1359.         } else {
  1360.             wp->w_height = newsize;
  1361.             total += newsize;
  1362.             wp = wp->w_next;
  1363.         }
  1364.     } while (wp != fwind);
  1365.  
  1366.     curwind->w_height += LI - total - 1;
  1367.  
  1368.     /* Make a new screen structure */
  1369.     make_scr();
  1370.     /* Do a 'hard' update on the screen - clear and redraw */
  1371.     cl_scr(YES);
  1372.     flushscreen();
  1373.     redisplay();
  1374.  
  1375. #ifdef    UNIX
  1376.     (void) SigRelse(SIGWINCH);
  1377.     (void) signal(SIGWINCH, win_reshape);
  1378. #endif
  1379.     errno = save_errno;
  1380.     SIGRETURN;
  1381. }
  1382. #endif
  1383.  
  1384. void
  1385.  
  1386. #ifdef    MAC    /* will get args from user, if option key held during launch */
  1387. main()
  1388. {
  1389.     int argc;
  1390.     char **argv;
  1391. #else
  1392. main(argc, argv)
  1393. int    argc;
  1394. char    *argv[];
  1395. {
  1396. #endif    /* MAC */
  1397.     char    *cp;
  1398.     char    ttbuf[MAXTTYBUF];
  1399. #ifdef    pdp11
  1400.     /* On the PDP-11, UNIX allocates at least 8K.
  1401.      * In order not to waste this space, we allocate
  1402.      * a bunch of buffers as autos.
  1403.      */
  1404.  
  1405.     char    s_iobuff[LBSIZE],
  1406.         s_genbuf[LBSIZE],
  1407.         s_linebuf[LBSIZE];
  1408.  
  1409.     iobuff = s_iobuff;
  1410.     genbuf = s_genbuf;
  1411.     linebuf = s_linebuf;
  1412. #endif
  1413.  
  1414. #ifdef    MAC
  1415.     MacInit();        /* initializes all */
  1416.     {
  1417.         extern bool    make_cache proto((void));
  1418.  
  1419.         if (!make_cache())
  1420.             exit(-1);
  1421.     }
  1422.     argc = getArgs(&argv);
  1423. #endif    /* MAC */
  1424.  
  1425.     iniargc = argc;
  1426.     iniargv = argv;
  1427.  
  1428.     if (setjmp(mainjmp)) {
  1429.         writef("\rAck! I can't deal with error \"%s\" now.\n\r", mesgbuf);
  1430.         finish(SIGIOT);    /* some bad signal (not SIGHUP) */
  1431.     }
  1432.  
  1433. #ifdef    MSDOS
  1434.     /* import the temporary file path from the environment and
  1435.        fix the string, so that we can append a slash safely    */
  1436.  
  1437.     if (((cp = getenv("TMP")) || (cp = getenv("TMPDIR"))) &&
  1438.         (*cp != '\0')) {
  1439.         strcpy(TmpFilePath, cp);
  1440.         cp = &TmpFilePath[strlen(TmpFilePath)-1];
  1441.         if ((*cp == '/') || (*cp == '\\'))
  1442.             *cp = '\0';
  1443.     }
  1444.     ShFlags[0] = switchar();
  1445. #endif    /* MSDOS */
  1446.  
  1447.     getTERM();    /* Get terminal. */
  1448.     if (getenv("METAKEY"))
  1449.         MetaKey = ON;
  1450.     ttsize();
  1451. #ifdef    MAC
  1452.     InitEvents();
  1453. #else
  1454.     InitCM();
  1455. #endif
  1456.  
  1457.     d_cache_init();        /* initialize the disk buffer cache */
  1458. #ifdef    MSDOS
  1459.     if ((cp = getenv("COMSPEC")) && (*cp != '\0')) {
  1460.         strcpy(Shell, cp);
  1461.     }
  1462.     if ((cp = getenv("DESCRIBE")) && (*cp != '\0'))
  1463.        strcpy(CmdDb, cp);
  1464. #else    /* !MSDOS */
  1465. #ifndef    MAC
  1466.     if ((cp = getenv("SHELL"))!=NULL && (*cp != '\0')) {
  1467.         strcpy(Shell, cp);
  1468.     }
  1469. #endif
  1470. #endif    /* !MSDOS */
  1471.  
  1472.     make_scr();
  1473.     mac_init();    /* Initialize Macros */
  1474.     winit();    /* Initialize Window */
  1475. #ifdef    IPROCS
  1476.     pinit();    /* Pipes/process initialization */
  1477. #endif
  1478.     buf_init();
  1479.  
  1480.     {
  1481.         char    **argp;
  1482.  
  1483.         if ((argp = scanvec(argv, "-d"))!=NULL
  1484. #ifdef    UNIX
  1485.             && chkCWD(argp[1])
  1486. #endif
  1487.             )
  1488.             setCWD(argp[1]);
  1489.         else
  1490.             getCWD();    /* After we setup curbuf in case we have to getwd() */
  1491.     }
  1492.  
  1493.     HomeDir = getenv("HOME");
  1494.     if (HomeDir == NULL)
  1495.         HomeDir = "/";
  1496.     HomeLen = strlen(HomeDir);
  1497.  
  1498. #ifdef    UNIX
  1499.     if ((cp = getenv("MAIL")) != NULL) {
  1500.         strcpy(Mailbox, cp);
  1501.     } else {
  1502.         swritef(Mailbox, sizeof(Mailbox), "%s/%s",
  1503.             MAILSPOOL, getenv("LOGNAME"));
  1504.     }
  1505. #endif
  1506.  
  1507.     InitKeymaps();
  1508.  
  1509.     ttinit();    /* initialize terminal (before ~/.joverc) */
  1510.     settout(ttbuf);    /* not until we know baudrate */
  1511. #ifndef    MAC
  1512.     ResetTerm();
  1513. #endif
  1514.  
  1515.     (void) joverc(Joverc);            /* system wide .joverc */
  1516.     cp = NULL;
  1517. #ifndef    MAC
  1518.     /* If a JOVERC environment variable is set, then use that instead */
  1519.     if ((cp = getenv("JOVERC"))!=NULL && (*cp != '\0'))
  1520.        (void) joverc(cp);
  1521. #endif    /* !MAC */
  1522.     if (!scanvec(argv, "-j") && (!cp || *cp == '\0')) {
  1523.         char    tmpbuf[100];
  1524.  
  1525.         swritef(tmpbuf, sizeof(tmpbuf), "%s/.joverc", HomeDir);
  1526.         (void) joverc(tmpbuf);        /* .joverc in home directory */
  1527.     }
  1528.  
  1529. #ifndef    MSDOS
  1530.     if (scanvec(argv, "-r"))
  1531.         dorecover();
  1532.     if (scanvec(argv, "-rc"))
  1533.         FullRecover();
  1534. #endif    /* MSDOS */
  1535.  
  1536. #ifdef    MSDOS
  1537.     (void) signal(SIGINT, SIG_IGN);
  1538.     break_off();    /* disable ctrl-c checking */
  1539. #endif    /* MSDOS */
  1540. #ifdef    UNIX
  1541.     (void) signal(SIGHUP, finish);
  1542.     (void) signal(SIGINT, finish);
  1543.     (void) signal(SIGBUS, finish);
  1544.     (void) signal(SIGSEGV, finish);
  1545.     (void) signal(SIGPIPE, finish);
  1546.     (void) signal(SIGTERM, SIG_IGN);
  1547. # ifdef    WINRESIZE
  1548.     (void) signal(SIGWINCH, win_reshape);
  1549. # endif
  1550.     /* set things up to update the modeline every UpdFreq seconds */
  1551.     (void) signal(SIGALRM, updmode);
  1552.     if (UpdFreq != 0)
  1553.         (void) alarm((unsigned) (UpdFreq - (time((time_t *)NULL) % UpdFreq)));
  1554. #endif    /* UNIX */
  1555.     cl_scr(YES);
  1556.     flushscreen();
  1557.     RedrawDisplay();    /* start the redisplay process. */
  1558.     DoKeys(YES);
  1559.     finish(0);
  1560. }
  1561.  
  1562. #ifdef    MSDOS
  1563.  
  1564. #include <dos.h>
  1565.  
  1566. private    char break_state;
  1567.  
  1568. /* set the break state to off */
  1569. private void
  1570. break_off()
  1571. {
  1572.     union REGS regs;
  1573.  
  1574.     regs.h.ah = 0x33;        /* break status */
  1575.     regs.h.al = 0x00;        /* request current state */
  1576.     intdos(®s, ®s);
  1577.     break_state = regs.h.dl;
  1578.     bdos(0x33, 0, 1);    /* turn off break */
  1579. }
  1580.  
  1581. /* reset the break state */
  1582. private void
  1583. break_rst()
  1584. {
  1585.     bdos(0x33, break_state, 1);
  1586. }
  1587. #endif
  1588.