1: /*************************************************************************
   2:  * This program is copyright (C) 1985, 1986 by Jonathan Payne.  It is    *
   3:  * provided to you without charge for use only on a licensed Unix        *
   4:  * system.  You may copy JOVE provided that this notice is included with *
   5:  * the copy.  You may not sell copies of this program or versions        *
   6:  * modified for use on microcomputer systems, unless the copies are      *
   7:  * included with a Unix system distribution and the source is provided.  *
   8:  *************************************************************************/
   9: 
  10: /* Contains the main loop initializations, and some system dependent
  11:    type things, e.g. putting terminal in CBREAK mode, etc. */
  12: 
  13: #include "jove.h"
  14: #include "io.h"
  15: #include "termcap.h"
  16: 
  17: #include <varargs.h>
  18: #include <sys/stat.h>
  19: #include <signal.h>
  20: #include <errno.h>
  21: #ifndef SYSV
  22: #include <sgtty.h>
  23: #include <fcntl.h>
  24: #else
  25: #include <termio.h>
  26: #endif SYSV
  27: 
  28: #ifdef TIOCSLTC
  29: struct ltchars  ls1,
  30:         ls2;
  31: #endif TIOCSLTC
  32: 
  33: #ifdef TIOCGETC
  34: struct tchars   tc1,
  35:         tc2;
  36: #endif
  37: 
  38: #ifdef BRLUNIX
  39: struct sg_brl   sg1, sg2;
  40: #else
  41: #ifdef SYSV
  42: struct termio   sg1, sg2;
  43: #else SYSV
  44: struct sgttyb   sg1, sg2;
  45: #endif SYSV
  46: #endif BRLUNIX
  47: 
  48: #ifdef BIFF
  49: private struct stat tt_stat;    /* for biff */
  50: #ifndef BSD4_2
  51: private char    *tt_name = 0;       /* name of the control tty */
  52: extern char *ttyname();     /* for systems w/o fchmod ... */
  53: #endif
  54: private int dw_biff = NO;       /* whether or not to fotz at all */
  55: #endif
  56: 
  57: time_t  time0;          /* when jove started up */
  58: int errormsg;
  59: extern char *tfname;
  60: char    NullStr[] = "";
  61: 
  62: finish(code)
  63: {
  64:     int CoreDump = (code != 0 && code != SIGHUP),
  65:         DelTmps = 1;        /* Usually we delete them. */
  66: 
  67: #ifdef LSRHS
  68:     if (CoreDump)
  69:         setdump(1);
  70: #endif
  71:     if (code == SIGINT) {
  72:         char    c;
  73: 
  74: #ifndef MENLO_JCL
  75:         (void) signal(code, finish);
  76: #endif
  77:         f_mess("Abort (Type 'n' if you're not sure)? ");
  78:         (void) read(0, &c, 1);
  79:         message(NullStr);
  80:         if ((c & 0377) != 'y') {
  81:             redisplay();
  82:             return;
  83:         }
  84:     }
  85:     ttyset(OFF);
  86:     UnsetTerm(NullStr);
  87:     if (code != 0) {
  88:         if (!Crashing) {
  89:             Crashing++;
  90:             lsave();
  91:             SyncRec();
  92:             printf("JOVE CRASH!! (code %d)\n", code);
  93:             if (ModBufs(1)) {
  94:                 printf("Your buffers have been saved.\n");
  95:                 printf("Use \"jove_recover\" or \"jove -r\"\n");
  96:                 printf("to have a look at them.\n");
  97:                 DelTmps = 0;    /* Don't delete anymore. */
  98:             } else
  99:                 printf("You didn't lose any work.\n");
 100:         } else
 101:             printf("\r\nYou may have lost your work!\n");
 102:     }
 103:     flusho();
 104:     if (DelTmps) {
 105:         tmpclose();
 106:         recclose();
 107:     }
 108:     if (CoreDump)
 109:         abort();
 110: #ifdef PROFILING
 111:     exit(exp_p);
 112: #else
 113:     _exit(exp_p);
 114: #endif
 115: }
 116: 
 117: private char    smbuf[20],
 118:         *bp = smbuf;
 119: private int nchars = 0;
 120: 
 121: private char    peekbuf[10],
 122:         *peekp = peekbuf;
 123: 
 124: #ifdef SYSV
 125: void
 126: setblock(fd, on)    /* turn blocking on or off */
 127: register int    fd, on;
 128: {
 129:     static int blockf, nonblockf;
 130:     static int first = 1;
 131:     int flags;
 132: 
 133:     if (first) {
 134:     first = 0;
 135:     if ((flags = fcntl(fd, F_GETFL, 0)) == -1)
 136:         finish(SIGHUP);
 137:     blockf = flags & ~O_NDELAY; /* make sure O_NDELAY is off */
 138:     nonblockf = flags | O_NDELAY;   /* make sure O_NDELAY is on */
 139:     }
 140:     if (fcntl(fd, F_SETFL, on ? blockf : nonblockf) == -1)
 141:     finish(SIGHUP);
 142:     return;
 143: }
 144: #endif SYSV
 145: 
 146: Peekc()
 147: {
 148:     int c;
 149: 
 150:     if (peekp == peekbuf)
 151:         c = -1;
 152:     else
 153:         c = *--peekp & 0377;
 154:     return c;
 155: }
 156: 
 157: Ungetc(c)
 158: {
 159:     if (peekp == &peekbuf[(sizeof peekbuf) - 1])
 160:         return;     /* Sorry, can't oblige you ... */
 161:     *peekp++ = c;
 162: }
 163: 
 164: char    *Inputp = 0;
 165: 
 166: #ifdef IPROCS
 167: #ifdef PIPEPROCS
 168: getchar()
 169: {
 170:     extern int  errno;
 171:     register int    c;
 172: 
 173:     if (nchars <= 0) {
 174:         do
 175:             nchars = read(0, smbuf, sizeof smbuf);
 176: #ifdef SYSV
 177:         while (nchars == 0 || (nchars < 0 && errno == EINTR));
 178:         if (nchars < 0)
 179: #else
 180:         while (nchars < 0 && errno == EINTR);
 181:         if (nchars <= 0)
 182: #endif SYSV
 183:             finish(SIGHUP);
 184:         bp = smbuf;
 185:         InputPending = nchars > 1;
 186:     }
 187:     if (((c = *bp) & 0200) && MetaKey != 0) {
 188:         *bp = (c & 0177);
 189:         return '\033';
 190:     }
 191:     nchars--;
 192:     return (*bp++ & 0177);
 193: }
 194: #else PIPEPROCS
 195: getchar()
 196: {
 197:     extern int  global_fd,
 198:             NumProcs,
 199:             errno;
 200:     register int    tmp,
 201:             nfds;
 202:     int reads,
 203:         c;
 204: 
 205:     if (nchars <= 0) {
 206:         /* Get a character from the keyboard, first checking for
 207: 		   any input from a process.  Handle that first, and then
 208: 		   deal with the terminal input. */
 209:         if (NumProcs > 0) {
 210:             do {
 211:                 do {
 212:                     reads = global_fd;
 213:                     nfds = select(32, &reads, (int *) 0, (int *) 0, (struct timeval *) 0);
 214:                 } while (nfds < 0 && errno == EINTR);
 215: 
 216:                 switch (nfds) {
 217:                 case -1:
 218:                     printf("\rerror %d in select %d", errno, global_fd);
 219:                     global_fd = 1;
 220:                     break;
 221:                 default:
 222:                     if (reads & 01) {
 223:                         nchars = read(0, smbuf, sizeof(smbuf));
 224:                         reads &= ~01;
 225:                         --nfds;
 226:                     }
 227: 
 228:                     while (nfds--) {
 229:                         tmp = ffs(reads) - 1;
 230:                         read_proc(tmp);
 231:                         reads &= ~tmp;
 232:                     }
 233: 
 234:                     break;
 235:                 }
 236:             } while (nchars <= 0);
 237:         } else {
 238:             do
 239:                 nchars = read(0, smbuf, sizeof(smbuf));
 240:             while (nchars < 0 && errno == EINTR);
 241:         }
 242: 
 243:         if (nchars <= 0)
 244:             finish(SIGHUP);
 245: 
 246:         bp = smbuf;
 247:         InputPending = (nchars > 1);
 248:     }
 249: 
 250:     if (((c = *bp) & 0200) && MetaKey != 0) {
 251:         *bp = (c & 0177);
 252:         return '\033';
 253:     }
 254:     nchars--;
 255:     return *bp++ & 0377;
 256: }
 257: #endif PIPEPROCS
 258: #else IPROCS
 259: getchar()
 260: {
 261:     extern int  errno;
 262:     register int    c;
 263: 
 264:     if (nchars <= 0) {
 265:         do
 266:             nchars = read(0, smbuf, sizeof smbuf);
 267:         while (nchars < 0 && errno == EINTR);
 268: 
 269:         if (nchars <= 0)
 270:             finish(SIGHUP);
 271:         bp = smbuf;
 272:         InputPending = nchars > 1;
 273:     }
 274:     if (((c = *bp) & 0200) && MetaKey != 0) {
 275:         *bp = (c & 0177);
 276:         return '\033';
 277:     }
 278:     nchars--;
 279:     return *bp++ & 0377;
 280: }
 281: #endif IPROCS
 282: 
 283: int InputPending = 0;
 284: 
 285: /* Returns non-zero if a character waiting */
 286: 
 287: charp()
 288: {
 289:     int some = 0;
 290: 
 291:     if (InJoverc != 0 || nchars > 0 || Inputp != 0)
 292:         return 1;
 293: #ifdef BRLUNIX
 294:     {
 295:         static struct sg_brl gttyBuf;
 296: 
 297:         gtty(0, (char *) &gttyBuf);
 298:         if (gttyBuf.sg_xflags & INWAIT)
 299:             some++;
 300:     }
 301: #endif
 302: #ifdef FIONREAD
 303:     {
 304:         long c;
 305: 
 306:         if (ioctl(0, FIONREAD, (struct sgttyb *) &c) == -1)
 307:             c = 0;
 308:         some = (c > 0);
 309:     }
 310: #endif FIONREAD
 311: #ifdef SYSV
 312:     setblock(0, 0);     /* turn blocking off */
 313:     nchars = read(0, smbuf, sizeof smbuf);  /* Is anything there? */
 314:     setblock(0, 1);     /* turn blocking on */
 315:     if (nchars > 0)     /* something was there */
 316:         bp = smbuf;     /* make sure bp points to it */
 317:     some = (nchars > 0);    /* just say we found something */
 318: #endif SYSV
 319: #ifdef c70
 320:     some = !empty(0);
 321: #endif
 322:     return some;
 323: }
 324: 
 325: ResetTerm()
 326: {
 327:     putpad(TI, 1);
 328:     putpad(VS, 1);
 329:     putpad(KS, 1);
 330: #ifdef BIFF
 331:     if (BiffChk != dw_biff)
 332:         biff_init();
 333:     /* just in case we changed our minds about whether to deal with
 334: 	   biff */
 335: #endif
 336:     chkmail(YES);   /* force it to check to we can be accurate */
 337:     do_sgtty(); /* this is so if you change baudrate or stuff
 338: 			   like that, JOVE will notice. */
 339:     ttyset(ON);
 340: }
 341: 
 342: UnsetTerm(mesg)
 343: char    *mesg;
 344: {
 345:     ttyset(OFF);
 346:     putpad(KE, 1);
 347:     putpad(VE, 1);
 348:     putpad(TE, 1);
 349: #ifdef ID_CHAR
 350:     INSmode(0);
 351: #endif
 352:     Placur(ILI, 0);
 353:     printf("%s", mesg);
 354:     putpad(CE, 1);
 355:     flusho();
 356: }
 357: 
 358: #ifdef JOB_CONTROL
 359: PauseJove()
 360: {
 361:     UnsetTerm(ModBufs(0) ? "[There are modified buffers]" : NullStr);
 362:     (void) kill(0, SIGTSTP);
 363:     ResetTerm();
 364:     ClAndRedraw();
 365: }
 366: #endif
 367: 
 368: Push()
 369: {
 370:     int pid;
 371: 
 372:     switch (pid = fork()) {
 373:     case -1:
 374:         complain("[Fork failed]");
 375: 
 376:     case 0:
 377:         UnsetTerm(NullStr);
 378:         (void) signal(SIGTERM, SIG_DFL);
 379:         (void) signal(SIGINT, SIG_DFL);
 380:         execl(Shell, basename(Shell), 0);
 381:         message("[Execl failed]");
 382:         _exit(1);
 383: 
 384:     default:
 385:         {
 386:             int (*old_int)() = signal(SIGINT, SIG_IGN);
 387:         int (*old_quit)() = signal(SIGQUIT, SIG_IGN);
 388: 
 389: #ifdef IPROCS
 390:         sighold(SIGCHLD);
 391: #endif
 392:             dowait(pid, (int *) 0);
 393: #ifdef IPROCS
 394:         sigrelse(SIGCHLD);
 395: #endif
 396:             ResetTerm();
 397:             ClAndRedraw();
 398:             (void) signal(SIGINT, old_int);
 399:         (void) signal(SIGQUIT, old_quit);
 400:         }
 401:     }
 402: }
 403: 
 404: int OKXonXoff = 0;      /* ^S and ^Q initially DON'T work */
 405: 
 406: ttsize()
 407: {
 408: #ifdef TIOCGWINSZ
 409:     struct winsize win;
 410: 
 411:     if (ioctl (0, TIOCGWINSZ, &win) == 0) {
 412:         if (win.ws_col)
 413:             CO = win.ws_col;
 414:         if (win.ws_row)
 415:             LI = win.ws_row;
 416:     }
 417: #else TIOCGWINSZ
 418: #ifdef BTL_BLIT
 419: #include <sys/jioctl.h>
 420:     struct jwinsize jwin;
 421: 
 422:     if (ioctl(0, JWINSIZE, &jwin) == 0) {
 423:         if (jwin.bytesx)
 424:             CO = jwin.bytesx;
 425:         if (jwin.bytesy)
 426:             LI = jwin.bytesy;
 427:     }
 428: #endif BTL_BLIT
 429: #endif TIOCGWINSZ
 430:     ILI = LI - 1;
 431: }
 432: 
 433: #ifdef BIFF
 434: biff_init()
 435: {
 436:     dw_biff = ((BiffChk) &&
 437: #ifndef BSD4_2
 438:            ((tt_name != 0) || (tt_name = ttyname(0))) &&
 439:            (stat(tt_name, &tt_stat) != -1) &&
 440: #else
 441:            (fstat(0, &tt_stat) != -1) &&
 442: #endif
 443:            (tt_stat.st_mode & S_IEXEC));    /* he's using biff */
 444: 
 445: }
 446: 
 447: biff(on)
 448: {
 449:     if (dw_biff == NO)
 450:         return;
 451: #ifndef BSD4_2
 452:     (void) chmod(tt_name, on ? tt_stat.st_mode :
 453:                    (tt_stat.st_mode & ~S_IEXEC));
 454: #else
 455:     (void) fchmod(0, on ? tt_stat.st_mode :
 456:                   (tt_stat.st_mode & ~S_IEXEC));
 457: #endif
 458: }
 459: 
 460: #endif
 461: 
 462: ttinit()
 463: {
 464: #ifdef BIFF
 465:     biff_init();
 466: #endif
 467: #ifdef TIOCSLTC
 468:     (void) ioctl(0, TIOCGLTC, (struct sgttyb *) &ls1);
 469:     ls2 = ls1;
 470:     ls2.t_suspc = (char) -1;
 471:     ls2.t_dsuspc = (char) -1;
 472:     ls2.t_flushc = (char) -1;
 473:     ls2.t_lnextc = (char) -1;
 474: #endif
 475: 
 476: #ifdef TIOCGETC
 477:     /* Change interupt and quit. */
 478:     (void) ioctl(0, TIOCGETC, (struct sgttyb *) &tc1);
 479:     tc2 = tc1;
 480:     tc2.t_intrc = CTL(]);
 481:     tc2.t_quitc = (char) -1;
 482:     if (OKXonXoff) {
 483:         tc2.t_stopc = (char) -1;
 484:         tc2.t_startc = (char) -1;
 485:     }
 486: #endif TIOCGETC
 487:     do_sgtty();
 488: }
 489: 
 490: private int done_ttinit = 0;
 491: 
 492: do_sgtty()
 493: {
 494: #ifdef SYSV
 495:     (void) ioctl(0, TCGETA, (char *) &sg1);
 496: #else
 497:     (void) gtty(0, &sg1);
 498: #endif SYSV
 499:     sg2 = sg1;
 500: 
 501: #ifdef SYSV
 502:     TABS = !((sg1.c_oflag & TAB3) == TAB3);
 503:     ospeed = sg1.c_cflag & CBAUD;
 504: 
 505:     sg2.c_iflag &= ~(INLCR|ICRNL|IGNCR);
 506:     sg2.c_lflag &= ~(ISIG|ICANON|ECHO);
 507:     sg2.c_oflag &= ~(OCRNL|ONLCR);
 508:     sg2.c_cc[VMIN] = sizeof smbuf;
 509:     sg2.c_cc[VTIME] = 1;
 510: #else
 511:     TABS = !(sg1.sg_flags & XTABS);
 512:     ospeed = sg1.sg_ospeed;
 513: #ifdef BRLUNIX
 514:     sg2.sg_flags &= ~(ECHO | CRMOD);
 515:     sg2.sg_flags |= CBREAK;
 516: 
 517:     /* VT100 Kludge: leave STALL on for flow control if DC3DC1 (Yuck.) */
 518:     sg2.sg_xflags &= ~((sg2.sg_xflags&DC3DC1 ? 0 : STALL) | PAGE);
 519: #else
 520:     sg2.sg_flags &= ~(ECHO | CRMOD);
 521: #endif BRLUNIX
 522: 
 523: #ifdef EUNICE
 524:     sg2.sg_flags |= RAW;    /* Eunice needs RAW mode last I heard. */
 525: #else
 526: #ifdef PURDUE_EE
 527: #   ifdef pdp11
 528:     sg2.sg_flags |= RAW;
 529: #   else
 530:     sg2.sg_flags |= (MetaKey ? RAW : CBREAK);
 531: #   endif
 532: #else
 533:     sg2.sg_flags |= (MetaKey ? RAW : CBREAK);
 534: #endif PURDUE_EE
 535: #endif EUNICE
 536: #endif SYSV
 537: }
 538: 
 539: tty_reset()
 540: {
 541:     if (!done_ttinit)
 542:         return;
 543:     ttyset(OFF);    /* go back to original modes */
 544:     ttinit();
 545:     ttyset(ON);
 546: }
 547: 
 548: /* If n is OFF reset to original modes */
 549: 
 550: ttyset(n)
 551: {
 552:     if (!done_ttinit && n == 0) /* Try to reset before we've set! */
 553:         return;
 554: #ifdef SYSV
 555:     (void) ioctl(0, TCSETAW, n == 0 ? (struct sgttyb *) &sg1 : (struct sgttyb *) &sg2);
 556: #else
 557: #ifdef BRLUNIX
 558:     (void) stty(0, n == 0 ? (struct sgttyb *) &sg1 : (struct sgttyb *) &sg2);
 559: #else
 560:     (void) ioctl(0, TIOCSETN, n == 0 ? (struct sgttyb *) &sg1 : (struct sgttyb *) &sg2);
 561: #endif BRLUNIX
 562: #endif SYSV
 563: 
 564: #ifdef TIOCSETC
 565:     (void) ioctl(0, TIOCSETC, n == 0 ? (struct sgttyb *) &tc1 : (struct sgttyb *) &tc2);
 566: #endif TIOCSETC
 567: #ifdef TIOCSLTC
 568:     (void) ioctl(0, TIOCSLTC, n == 0 ? (struct sgttyb *) &ls1 : (struct sgttyb *) &ls2);
 569: #endif TIOCSLTC
 570:     done_ttinit = 1;
 571: #ifdef BIFF
 572:     biff(!n);
 573: #endif
 574: }
 575: 
 576: int this_cmd,
 577:     last_cmd;
 578: 
 579: dispatch(c)
 580: register int    c;
 581: {
 582:     data_obj    *cp;
 583: 
 584:     this_cmd = 0;
 585:     cp = mainmap[c & 0177];
 586: 
 587:     if (cp == 0) {
 588:         rbell();
 589:         exp = 1;
 590:         exp_p = errormsg = 0;
 591:         message(NullStr);
 592:         return;
 593:     }
 594:     ExecCmd(cp);
 595: }
 596: 
 597: int LastKeyStruck,
 598:     MetaKey = 0;
 599: 
 600: getch()
 601: {
 602:     register int    c,
 603:             peekc;
 604: #ifdef IPROCS
 605:     extern int  NumProcs;
 606: #endif
 607:     extern int  ModCount,
 608:             Interactive;
 609: 
 610:     if (Inputp) {
 611:         if ((c = *Inputp++) != 0)
 612:             return LastKeyStruck = c;
 613:         Inputp = 0;
 614:     }
 615: 
 616:     if (InJoverc)
 617:         return EOF; /* somethings wrong if Inputp runs out while
 618: 				   we're reading a .joverc file. */
 619: 
 620:     if (ModCount >= SyncFreq) {
 621:         ModCount = 0;
 622:         SyncRec();
 623:     }
 624: 
 625:     /* If we're not interactive and we're not executing a macro,
 626: 	   AND there are no ungetc'd characters, we read from the
 627: 	   terminal (i.e., getch()).  And characters only get put
 628: 	   in macros from inside this if. */
 629:     if (((peekc = c = Peekc()) == -1) && (Interactive || ((c = mac_getc()) == -1))) {
 630:         /* So messages that aren't error messages don't
 631: 		   hang around forever. */
 632:         if (!UpdMesg && !Asking) {  /* Don't erase if we are asking */
 633:             if (mesgbuf[0] && !errormsg)
 634:                 message(NullStr);
 635:         }
 636:         redisplay();
 637: #ifdef IPROCS
 638: #  ifdef PIPEPROCS
 639:         if (NumProcs > 0) {
 640:             sigrelse(INPUT_SIG);
 641:             sigrelse(SIGCHLD);
 642:         }
 643: #  endif
 644: #endif
 645:         inIOread = 1;
 646:         if ((c = getchar()) == EOF)
 647:             finish(SIGHUP);
 648:         inIOread = 0;
 649: 
 650: #ifdef IPROCS
 651: #  ifdef PIPEPROCS
 652:         if (NumProcs > 0) {
 653:             sighold(INPUT_SIG);
 654:             sighold(SIGCHLD);
 655:         }
 656: #  endif
 657: #endif
 658:         if (!Interactive && (KeyMacro.m_flags & DEFINE))
 659:             mac_putc(c);
 660:     }
 661:     if (peekc == -1)    /* Don't add_stroke peekc's */
 662:         add_stroke(c);
 663:     return LastKeyStruck = c;
 664: }
 665: 
 666: dorecover()
 667: {
 668:     execl(RECOVER, "jove_recover", 0);
 669:     printf("%s: execl failed!\n", RECOVER);
 670:     flusho();
 671:     _exit(-1);
 672: }
 673: 
 674: 
 675: ShowVersion()
 676: {
 677:     extern char *version;
 678: 
 679:     s_mess("Jonathan's Own Version of Emacs (%s)", version);
 680: }
 681: 
 682: UNIX_cmdline(argc, argv)
 683: char    *argv[];
 684: {
 685:     int lineno = 0,
 686:         nwinds = 1;
 687:     Buffer  *b;
 688: 
 689:     ShowVersion();
 690:     while (argc > 1) {
 691:         if (argv[1][0] != '-' && argv[1][0] != '+') {
 692:             int force = (nwinds > 0 || lineno != 0);
 693: 
 694:             minib_add(argv[1], force ? YES : NO);
 695:             b = do_find(nwinds > 0 ? curwind : (Window *) 0,
 696:                     argv[1], force);
 697:             if (force) {
 698:                 SetABuf(curbuf);
 699:                 SetBuf(b);
 700:                 SetLine(next_line(curbuf->b_first, lineno));
 701:                 if (nwinds > 1)
 702:                     NextWindow();
 703:                 if (nwinds)
 704:                     nwinds--;
 705:             }
 706:             lineno = 0;
 707:         } else  switch (argv[1][1]) {
 708:             case 'd':
 709:                 ++argv;
 710:                 --argc;
 711:                 break;
 712: 
 713:             case 'j':   /* Ignore .joverc in HOME */
 714:                 break;
 715: 
 716:             case 'p':
 717:                 ++argv;
 718:                 --argc;
 719:                 SetBuf(do_find(curwind, argv[1], 0));
 720:                 ParseAll();
 721:                 nwinds = 0;
 722:                 break;
 723: 
 724:             case 't':
 725:                 ++argv;
 726:                 --argc;
 727:                 exp_p = 1;
 728:                 find_tag(argv[1], YES);
 729:                 break;
 730: 
 731:             case 'w':
 732:                 if (argv[1][2] == '\0')
 733:                     nwinds++;
 734:                 else
 735:                     nwinds += -1 + chr_to_int(&argv[1][2], 10, NIL);
 736:                 (void) div_wind(curwind, nwinds - 1);
 737:                 break;
 738: 
 739:             case '0':
 740:             case '1':
 741:             case '2':
 742:             case '3':
 743:             case '4':
 744:             case '5':
 745:             case '6':
 746:             case '7':
 747:             case '8':
 748:             case '9':
 749:                 lineno = chr_to_int(&argv[1][1], 10, 0) - 1;
 750:                 break;
 751:         }
 752:         ++argv;
 753:         --argc;
 754:     }
 755: }
 756: 
 757: #ifdef lint
 758: Ignore(a)
 759:     char *a;
 760: {
 761: 
 762:     a = a;
 763: }
 764: 
 765: Ignorf(a)
 766:     int (*a)();
 767: {
 768: 
 769:     a = a;
 770: }
 771: 
 772: Ignorl(a)
 773: long    a;
 774: {
 775:     a = a;
 776: }
 777: #endif
 778: 
 779: /* VARARGS1 */
 780: 
 781: error(fmt, va_alist)
 782: char    *fmt;
 783: va_dcl
 784: {
 785:     va_list ap;
 786: 
 787:     if (fmt) {
 788:         va_start(ap);
 789:         format(mesgbuf, sizeof mesgbuf, fmt, ap);
 790:         va_end(ap);
 791:         UpdMesg++;
 792:     }
 793:     rbell();
 794:     (void) longjmp(mainjmp, ERROR);
 795: }
 796: 
 797: /* VARARGS1 */
 798: 
 799: complain(fmt, va_alist)
 800: char    *fmt;
 801: va_dcl
 802: {
 803:     va_list ap;
 804: 
 805:     if (fmt) {
 806:         va_start(ap);
 807:         format(mesgbuf, sizeof mesgbuf, fmt, ap);
 808:         va_end(ap);
 809:         UpdMesg++;
 810:     }
 811:     rbell();
 812:     (void) longjmp(mainjmp, COMPLAIN);
 813: }
 814: 
 815: /* VARARGS1 */
 816: 
 817: confirm(fmt, va_alist)
 818: char    *fmt;
 819: va_dcl
 820: {
 821:     char    *yorn;
 822:     va_list ap;
 823: 
 824:     va_start(ap);
 825:     format(mesgbuf, sizeof mesgbuf, fmt, ap);
 826:     va_end(ap);
 827:     yorn = ask((char *) 0, mesgbuf);
 828:     if (*yorn != 'Y' && *yorn != 'y')
 829:         (void) longjmp(mainjmp, COMPLAIN);
 830: }
 831: 
 832: int RecDepth = 0;
 833: 
 834: Recur()
 835: {
 836:     char    bname[128];
 837:     Mark    *m;
 838: 
 839:     sprintf(bname, "%s", curbuf->b_name);
 840:     m = MakeMark(curline, curchar, FLOATER);
 841: 
 842:     RecDepth++;
 843:     UpdModLine++;
 844:     DoKeys(1);  /* 1 means not first time */
 845:     UpdModLine++;
 846:     RecDepth--;
 847:     SetBuf(do_select(curwind, bname));
 848:     if (!exp_p)
 849:         ToMark(m);
 850:     DelMark(m);
 851: }
 852: 
 853: jmp_buf mainjmp;
 854: int iniargc;    /* main sets these for DoKeys() */
 855: char    **iniargv;
 856: 
 857: DoKeys(nocmdline)
 858: {
 859:     int c;
 860:     jmp_buf savejmp;
 861: 
 862:     push_env(savejmp);
 863: 
 864:     switch (setjmp(mainjmp)) {
 865:     case 0:
 866:         if (!nocmdline)
 867:             UNIX_cmdline(iniargc, iniargv);
 868:         break;
 869: 
 870:     case QUIT:
 871:         if (RecDepth == 0) {
 872:             if (ModMacs()) {
 873:                 rbell();
 874:                 if (Upper(*ask("No",
 875: "Some MACROS haven't been saved; leave anyway? ")) != 'Y')
 876:                     break;
 877:             }
 878:             if (ModBufs(0)) {
 879:                 rbell();
 880:                 if (Upper(*ask("No",
 881: "Some buffers haven't been saved; leave anyway? ")) != 'Y')
 882:                     break;
 883:             }
 884: #ifdef IPROCS
 885:             KillProcs();
 886: #endif
 887:         }
 888:         pop_env(savejmp);
 889:         return;
 890: 
 891:     case ERROR:
 892:         getDOT();   /* God knows what state linebuf was in */
 893: 
 894:     case COMPLAIN:
 895:         gc_openfiles(); /* close any files we left open */
 896:         errormsg++;
 897:         fix_macros();
 898:         Asking = 0;
 899:         curwind->w_bufp = curbuf;
 900:         redisplay();
 901:         break;
 902:     }
 903: 
 904:     this_cmd = last_cmd = 0;
 905: 
 906:     for (;;) {
 907:         if (this_cmd != ARG_CMD) {
 908:             exp = 1;
 909:             exp_p = 0;
 910:             last_cmd = this_cmd;
 911:             init_strokes();
 912:         }
 913:         c = getch();
 914:         if (c == -1)
 915:             continue;
 916:         dispatch(c);
 917:     }
 918: }
 919: 
 920: int Crashing = 0;
 921: 
 922: char **
 923: scanvec(args, str)
 924: register char   **args,
 925:         *str;
 926: {
 927:     while (*args) {
 928:         if (strcmp(*args, str) == 0)
 929:             return args;
 930:         args++;
 931:     }
 932:     return 0;
 933: }
 934: 
 935: int UpdFreq = 30,
 936:     inIOread = 0;
 937: 
 938: updmode()
 939: {
 940:     UpdModLine++;
 941:     if (inIOread)
 942:         redisplay();
 943: #ifndef JOB_CONTROL
 944:     (void) signal(SIGALRM, updmode);
 945: #endif
 946:     (void) alarm((unsigned) UpdFreq);
 947: }
 948: 
 949: #ifdef TIOCGWINSZ
 950: #ifdef SIGWINCH
 951: extern win_reshape();
 952: #endif
 953: #endif
 954: 
 955: #ifdef TIOCGWINSZ
 956: #ifdef SIGWINCH
 957: win_reshape()
 958: {
 959:     register int diff;
 960: 
 961:     (void) signal(SIGWINCH, SIG_IGN);
 962: 
 963:     /*
 964: 	 * Save old number of lines.
 965: 	 */
 966:     diff = LI;
 967: 
 968:     /*
 969: 	 * Get new line/col info.
 970: 	 */
 971:     ttsize();
 972: 
 973:     /*
 974: 	 * LI has changed, and now holds the
 975: 	 * new value.  See how much the size
 976: 	 * changed.
 977: 	 */
 978:     diff = LI - diff;
 979: 
 980:     /*
 981: 	 * Change the size of the current window
 982: 	 * only.  If they shrank by more than
 983: 	 * the window size, tough.
 984: 	 */
 985:     if ((curwind->w_height + diff) < 2)
 986:         curwind->w_height = 2;
 987:     else
 988:         curwind->w_height += diff;
 989: 
 990:     make_scr();
 991:     redisplay();
 992: 
 993:     (void) signal(SIGWINCH, win_reshape);
 994: }
 995: #endif
 996: #endif
 997: 
 998: main(argc, argv)
 999: char    *argv[];
1000: {
1001:     char    ttbuf[512],
1002: #ifndef VMUNIX
1003:         s_iobuff[LBSIZE],
1004:         s_genbuf[LBSIZE],
1005:         s_linebuf[LBSIZE],
1006: #endif
1007:         *cp;
1008: 
1009: 
1010: #ifndef VMUNIX
1011:     /* The way I look at it, there ain't no way I is gonna run
1012: 	   out of stack space UNLESS I have some kind of infinite
1013: 	   recursive bug.  So why use up some valuable memory, when
1014: 	   there is plenty of space on the stack?  (This only matters
1015: 	   on wimpy pdp11's, of course.) */
1016: 
1017:     iobuff = s_iobuff;
1018:     genbuf = s_genbuf;
1019:     linebuf = s_linebuf;
1020: #endif
1021: 
1022:     errormsg = 0;
1023: 
1024:     iniargc = argc;
1025:     iniargv = argv;
1026: 
1027:     if (setjmp(mainjmp)) {
1028:         printf("\rAck! I can't deal with error \"%s\" now.\n\r", mesgbuf);
1029:         finish(0);
1030:     }
1031: 
1032:     if (scanvec(argv, "-r"))
1033:         dorecover();
1034: 
1035:     getTERM();  /* Get terminal. */
1036:     if (getenv("METAKEY"))
1037:         MetaKey = 1;
1038:     ttsize();
1039:     InitCM();
1040: 
1041:     tmpinit();  /* Init temp file. */
1042: 
1043:     if (cp = getenv("SHELL"))
1044:         strcpy(Shell, cp);
1045: 
1046:     make_scr();
1047:     mac_init(); /* Initialize Macros */
1048:     winit();    /* Initialize Window */
1049: #ifdef IPROCS
1050:     pinit();    /* Pipes/process initialization */
1051: #endif
1052:     SetBuf(do_select(curwind, Mainbuf));
1053: 
1054: #ifdef CHDIR
1055:     {
1056:         char    **argp;
1057: 
1058:         if ((argp = scanvec(argv, "-d")) && (argp[1][0] == '/'))
1059:             setCWD(argp[1]);
1060:         else
1061:             getCWD();   /* After we setup curbuf in case we have to getwd() */
1062:     }
1063: #endif
1064:     HomeDir = getenv("HOME");
1065:     if (HomeDir == 0)
1066:         HomeDir = "/";
1067:     HomeLen = strlen(HomeDir);
1068:     (void) joverc(JOVERC);
1069:     if (!scanvec(argv, "-j")) {
1070:         char    tmpbuf[100];
1071: 
1072:         sprintf(tmpbuf, "%s/.joverc", HomeDir);
1073:         (void) joverc(tmpbuf);
1074:     }
1075: #ifdef SYSV
1076:     sprintf(MailBox, "/usr/mail/%s", getenv("LOGNAME"));
1077: #else
1078:     sprintf(Mailbox, "/usr/spool/mail/%s", getenv("USER"));
1079: #endif SYSV
1080:     (void) time(&time0);
1081:     ttinit();   /* initialize terminal (after ~/.joverc) */
1082:     settout(ttbuf); /* not until we know baudrate */
1083:     ResetTerm();
1084: 
1085:     (void) signal(SIGHUP, finish);
1086:     (void) signal(SIGINT, finish);
1087:     (void) signal(SIGQUIT, SIG_IGN);
1088:     (void) signal(SIGBUS, finish);
1089:     (void) signal(SIGSEGV, finish);
1090:     (void) signal(SIGPIPE, finish);
1091:     (void) signal(SIGTERM, SIG_IGN);
1092: #ifdef TIOCGWINSZ
1093: #ifdef SIGWINCH
1094:     (void) signal(SIGWINCH, win_reshape);
1095: #endif
1096: #endif
1097: 
1098:     /* set things up to update the modeline every UpdFreq seconds */
1099:     (void) signal(SIGALRM, updmode);
1100:     (void) alarm((unsigned) UpdFreq);
1101: 
1102:     cl_scr(1);
1103:     flusho();
1104:     RedrawDisplay();    /* start the redisplay process. */
1105:     DoKeys(0);
1106:     finish(0);
1107: }

Defined functions

DoKeys defined in line 857; used 2 times
Ignore defined in line 758; never used
Ignorf defined in line 765; never used
Ignorl defined in line 772; never used
PauseJove defined in line 359; used 3 times
Peekc defined in line 146; used 1 times
Push defined in line 368; used 3 times
ResetTerm defined in line 325; used 3 times
ShowVersion defined in line 675; used 3 times
UNIX_cmdline defined in line 682; used 1 times
Ungetc defined in line 157; used 5 times
UnsetTerm defined in line 342; used 3 times
biff defined in line 447; used 1 times
biff_init defined in line 434; used 2 times
complain defined in line 799; used 128 times
dispatch defined in line 579; used 2 times
do_sgtty defined in line 492; used 2 times
dorecover defined in line 666; used 1 times
error defined in line 781; never used
finish defined in line 62; used 20 times
getchar defined in line 259; used 5 times
main defined in line 998; never used
scanvec defined in line 922; used 3 times
setblock defined in line 125; used 2 times
ttinit defined in line 462; used 2 times
ttsize defined in line 406; used 2 times
tty_reset defined in line 539; used 1 times
ttyset defined in line 550; used 5 times
updmode defined in line 938; used 2 times
win_reshape defined in line 957; used 3 times

Defined variables

Crashing defined in line 920; used 2 times
InputPending defined in line 283; used 8 times
Inputp defined in line 164; used 6 times
LastKeyStruck defined in line 597; used 4 times
MetaKey defined in line 598; used 7 times
OKXonXoff defined in line 404; used 2 times
RecDepth defined in line 832; used 3 times
UpdFreq defined in line 935; used 4 times
bp defined in line 118; used 13 times
done_ttinit defined in line 490; used 3 times
dw_biff defined in line 54; used 3 times
errormsg defined in line 58; used 5 times
iniargc defined in line 854; used 2 times
iniargv defined in line 855; used 2 times
last_cmd defined in line 577; used 4 times
ls1 defined in line 29; used 6 times
ls2 defined in line 30; used 6 times
mainjmp defined in line 853; used 5 times
nchars defined in line 119; used 27 times
peekbuf defined in line 121; used 4 times
peekp defined in line 122; used 4 times
sg1 defined in line 44; used 11 times
sg2 defined in line 44; used 18 times
smbuf defined in line 117; used 16 times
tc1 defined in line 34; used 7 times
tc2 defined in line 35; used 6 times
this_cmd defined in line 576; used 11 times
tt_name defined in line 51; used 4 times
tt_stat defined in line 49; used 7 times
Last modified: 1986-03-28
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 3337
Valid CSS Valid XHTML 1.0 Strict