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