1: #include <X/mit-copyright.h>
   2: 
   3: /* Copyright    Massachusetts Institute of Technology    1984, 1985	*/
   4: 
   5: /* util.c */
   6: 
   7: #ifndef lint
   8: static char *rcsid_util_c = "$Header: util.c,v 10.11 86/04/28 15:05:29 jg Exp $";
   9: #endif	lint
  10: 
  11: #include <stdio.h>
  12: #include <X/Xlib.h>
  13: #include <errno.h>
  14: #include <signal.h>
  15: 
  16: #include "ptyx.h"
  17: 
  18: extern errno;
  19: extern debug;
  20: #ifdef JUMPSCROLL
  21: /*
  22:  * These routines are used for the jump scroll feature
  23:  */
  24: FlushScroll(screen)
  25: register Screen *screen;
  26: {
  27:     register int height = screen->bot_marg - screen->top_marg + 1;
  28:     register int samount = screen->scroll_amt;
  29:     register int ramount = screen->refresh_amt;
  30:     register int scrolled = samount * screen->f_height;
  31:     register int refreshed = ramount * screen->f_height;
  32:     register int top = screen->top_marg * screen->f_height + screen->border;
  33:     int rtop;
  34: 
  35:   if(samount > 0) {
  36:     rtop = screen->bot_marg - ramount + 1;
  37:   } else {
  38:     rtop = screen->top_marg;
  39:     top -= scrolled;
  40:     ramount = -ramount;
  41:     refreshed = -refreshed;
  42:   }
  43: 
  44:   if (ramount != height) {
  45: 
  46:       if (screen->multiscroll && samount == 1 &&
  47:       screen->top_marg == 0 && screen->bot_marg == screen->max_row) {
  48:           if (screen->incopy < 0 && screen->scrolls == 0)
  49:               CopyWait (screen);
  50:           screen->scrolls++;
  51:       } else {
  52:           if (screen->incopy)
  53:               CopyWait (screen);
  54:           screen->incopy = -1;
  55:       }
  56: 
  57:       XMoveArea (screen->window,
  58:          screen->border, top + scrolled, screen->border, top,
  59:          screen->width, height * screen->f_height - refreshed);
  60:   }
  61:   screen->scroll_amt = 0;
  62:   screen->refresh_amt = 0;
  63:   XTileSet (screen->window, screen->border,
  64:         rtop * screen->f_height + screen->border,
  65:         screen->width, refreshed, screen->bgndtile);
  66:   ScrnRefresh(screen, rtop, 0, ramount, screen->max_col + 1);
  67: }
  68: 
  69: AddToRefresh(screen)
  70: register Screen *screen;
  71: {
  72:     register int amount = screen->refresh_amt;
  73:     register int row = screen->cur_row;
  74: 
  75:     if(amount == 0)
  76:         return(0);
  77:     if(amount > 0) {
  78:         register int bottom;
  79: 
  80:         if(row == (bottom = screen->bot_marg) - amount) {
  81:             screen->refresh_amt++;
  82:             return(1);
  83:         }
  84:         return(row >= bottom - amount + 1 && row <= bottom);
  85:     } else {
  86:         register int top;
  87: 
  88:         amount = -amount;
  89:         if(row == (top = screen->top_marg) + amount) {
  90:             screen->refresh_amt--;
  91:             return(1);
  92:         }
  93:         return(row <= top + amount - 1 && row >= top);
  94:     }
  95: }
  96: #endif JUMPSCROLL
  97: 
  98: /*
  99:  * scrolls the screen by amount lines, erases bottom, doesn't alter
 100:  * cursor position (i.e. cursor moves down amount relative to text).
 101:  * All done within the scrolling region, of course.
 102:  * requires: amount > 0
 103:  */
 104: Scroll (screen, amount)
 105: register Screen *screen;
 106: register int amount;
 107: {
 108:     register int height = screen->bot_marg - screen->top_marg + 1;
 109:     register int covered;
 110:     register int border = screen->border;
 111:     register int top = screen->top_marg * screen->f_height + border;
 112: 
 113:     if (amount > height)
 114:         amount = height;
 115: #ifdef JUMPSCROLL
 116:     if(screen->jumpscroll) {
 117:     if(screen->scroll_amt > 0) {
 118:         if(screen->refresh_amt + amount > height)
 119:             FlushScroll(screen);
 120:         screen->scroll_amt += amount;
 121:         screen->refresh_amt += amount;
 122:     } else {
 123:         if(screen->scroll_amt < 0)
 124:             FlushScroll(screen);
 125:         screen->scroll_amt = amount;
 126:         screen->refresh_amt = amount;
 127:     }
 128:     } else {
 129: #endif JUMPSCROLL
 130: 
 131:     if (amount == height) {
 132:         ClearScreen(screen);
 133:         return;
 134:     }
 135: 
 136:     covered = amount * screen->f_height;
 137: 
 138:     if (screen->multiscroll
 139:     && amount==1
 140:     && screen->top_marg==0
 141:     && screen->bot_marg==screen->max_row) {
 142:         if (screen->incopy<0 && screen->scrolls==0)
 143:             CopyWait(screen);
 144:         screen->scrolls++;
 145:     } else {
 146:         if (screen->incopy)
 147:             CopyWait(screen);
 148:         screen->incopy = -1;
 149:     }
 150: 
 151:     XMoveArea(screen->window, border, top + covered, border, top,
 152:         screen->width, height * screen->f_height - covered);
 153:     XTileSet(screen->window, border,
 154:         (screen->bot_marg - amount + 1) * screen->f_height + border,
 155:         screen->width, covered, screen->bgndtile);
 156: #ifdef JUMPSCROLL
 157:     }
 158: #endif JUMPSCROLL
 159: 
 160:     ScrnDeleteLine(screen->buf, screen->bot_marg, screen->top_marg,
 161:             amount, screen->max_col + 1);
 162: }
 163: 
 164: 
 165: /*
 166:  * Reverse scrolls the screen by amount lines, erases top, doesn't alter
 167:  * cursor position (i.e. cursor moves up amount relative to text).
 168:  * All done within the scrolling region, of course.
 169:  * Requires: amount > 0
 170:  */
 171: RevScroll(screen, amount)
 172: register Screen *screen;
 173: register int amount;
 174: {
 175:     register int height = screen->bot_marg - screen->top_marg + 1;
 176:     register int border = screen->border;
 177:     register int top = screen->top_marg * screen->f_height + border;
 178:     register int covered;
 179: 
 180:     amount = (amount < height) ? amount : height;
 181: #ifdef JUMPSCROLL
 182:     if(screen->jumpscroll) {
 183:     if(screen->scroll_amt < 0) {
 184:         if(-screen->refresh_amt + amount > height)
 185:             FlushScroll(screen);
 186:         screen->scroll_amt -= amount;
 187:         screen->refresh_amt -= amount;
 188:     } else {
 189:         if(screen->scroll_amt > 0)
 190:             FlushScroll(screen);
 191:         screen->scroll_amt = -amount;
 192:         screen->refresh_amt = -amount;
 193:     }
 194:     } else {
 195: #endif JUMPSCROLL
 196:     covered = amount * screen->f_height;
 197: 
 198:     if (screen->incopy)
 199:         CopyWait (screen);
 200:     screen->incopy = -1;
 201: 
 202:     XMoveArea (screen->window,
 203:         border, top,
 204:         border, top + covered,
 205:         screen->width, height * screen->f_height - covered);
 206:     XTileSet (screen->window,
 207:         border, top,
 208:         screen->width, covered,
 209:         screen->bgndtile);
 210: 
 211: #ifdef JUMPSCROLL
 212:     }
 213: #endif JUMPSCROLL
 214:     ScrnInsertLine (screen->buf, screen->bot_marg, screen->top_marg,
 215:             amount, screen->max_col + 1);
 216: }
 217: 
 218: /*
 219:  * If cursor not in scrolling region, returns.  Else,
 220:  * inserts n blank lines at the cursor's position.  Lines above the
 221:  * bottom margin are lost.
 222:  */
 223: InsertLine (screen, n)
 224: register Screen *screen;
 225: register int n;
 226: {
 227:     register int height;
 228:     register int bottom = screen->bot_marg;
 229: 
 230:     if (screen->cur_row < screen->top_marg ||
 231:         screen->cur_row > screen->bot_marg) return;
 232: 
 233:     if (screen->cur_row + n - 1 > bottom) n = bottom - screen->cur_row + 1;
 234: #ifdef JUMPSCROLL
 235:     if(screen->jumpscroll) {
 236:     if(screen->scroll_amt <= 0&&screen->cur_row <= -screen->refresh_amt) {
 237:         if(-screen->refresh_amt + n > height)
 238:             FlushScroll(screen);
 239:         screen->scroll_amt -= n;
 240:         screen->refresh_amt -= n;
 241:     } else if(screen->scroll_amt)
 242:         FlushScroll(screen);
 243:     }
 244:     if(!screen->scroll_amt) {
 245: #endif JUMPSCROLL
 246: 
 247: 
 248:     height = n * screen->f_height;
 249: 
 250:     screen->do_wrap = 0;
 251: 
 252:     if (screen->incopy)
 253:         CopyWait (screen);
 254:     screen->incopy = -1;
 255: 
 256:     /*
 257: 	 * move stuff down.
 258: 	 * clear hole.
 259: 	 */
 260:     XMoveArea(screen->window,
 261:              screen->border, CursorY (screen),
 262:              screen->border, CursorY (screen) + height,
 263:              screen->width,
 264:              (bottom + 1 - screen->cur_row - n) * screen->f_height);
 265:     XTileSet(screen->window,
 266:         screen->border, CursorY (screen),
 267:         screen->width, height, screen->bgndtile);
 268: 
 269: #ifdef JUMPSCROLL
 270:     }
 271: #endif JUMPSCROLL
 272:     /* adjust screen->buf */
 273:     ScrnInsertLine(screen->buf, bottom, screen->cur_row, n,
 274:             screen->max_col + 1);
 275: }
 276: 
 277: /*
 278:  * If cursor not in scrolling region, returns.  Else, deletes n lines
 279:  * at the cursor's position, lines added at bottom margin are blank.
 280:  */
 281: DeleteLine(screen, n)
 282: register Screen *screen;
 283: register int n;
 284: {
 285:     register int height;
 286:     register int bottom = screen->bot_marg;
 287: 
 288:     if (screen->cur_row < screen->top_marg
 289:     || screen->cur_row > screen->bot_marg)
 290:         return;
 291: 
 292:     if (screen->cur_row + n - 1 > bottom)
 293:         n = bottom - screen->cur_row + 1;
 294: #ifdef JUMPSCROLL
 295:     if(screen->jumpscroll) {
 296:     if(screen->scroll_amt >= 0 && screen->cur_row == screen->top_marg) {
 297:         if(screen->refresh_amt + n > height)
 298:             FlushScroll(screen);
 299:         screen->scroll_amt += n;
 300:         screen->refresh_amt += n;
 301:     } else if(screen->scroll_amt)
 302:         FlushScroll(screen);
 303:     }
 304:     if(!screen->scroll_amt) {
 305: #endif JUMPSCROLL
 306: 
 307:     height = n * screen->f_height;
 308:     screen->do_wrap = 0;
 309: 
 310:     if (screen->incopy)
 311:         CopyWait(screen);
 312:     screen->incopy = -1;
 313: 
 314:     /*
 315: 	 * move stuff up.
 316: 	 * clear bottom.
 317: 	 */
 318:     XMoveArea(screen->window,
 319:              screen->border, CursorY (screen) + height,
 320:              screen->border, CursorY (screen),
 321:              screen->width,
 322:              (bottom + 1 - screen->cur_row - n) * screen->f_height);
 323:     XTileSet(screen->window,
 324:              screen->border,
 325:              (bottom + 1 - n) * screen->f_height + screen->border,
 326:              screen->width, height, screen->bgndtile);
 327: 
 328: #ifdef JUMPSCROLL
 329:     }
 330: #endif JUMPSCROLL
 331:     /* adjust screen->buf */
 332:     ScrnDeleteLine(screen->buf, bottom, screen->cur_row, n,
 333:             screen->max_col + 1);
 334: }
 335: 
 336: /*
 337:  * Insert n blanks at the cursor's position, no wraparound.
 338:  */
 339: InsertChar (screen, n)
 340: register Screen *screen;
 341: register int n;
 342: {
 343:     register int width = n * screen->f_width;
 344: 
 345: #ifdef JUMPSCROLL
 346:     if(!AddToRefresh(screen)) {
 347:     if(screen->scroll_amt)
 348:         FlushScroll(screen);
 349: #endif JUMPSCROLL
 350: 
 351:     screen->do_wrap = 0;
 352: 
 353:     if (screen->incopy)
 354:         CopyWait (screen);
 355:     screen->incopy = -1;
 356: 
 357:     XMoveArea(screen->window,
 358:              CursorX (screen), CursorY (screen),
 359:              CursorX (screen) + width, CursorY (screen),
 360:              screen->width - (screen->cur_col + n) * screen->f_width,
 361:              screen->f_height);
 362:     XTileSet(screen->window,
 363:              CursorX (screen), CursorY (screen),
 364:              width, screen->f_height, screen->bgndtile);
 365: 
 366: #ifdef JUMPSCROLL
 367:     }
 368: #endif JUMPSCROLL
 369:     /* adjust screen->buf */
 370:     ScrnInsertChar(screen->buf, screen->cur_row, screen->cur_col, n,
 371:             screen->max_col + 1);
 372: }
 373: 
 374: /*
 375:  * Deletes n chars at the cursor's position, no wraparound.
 376:  */
 377: DeleteChar (screen, n)
 378: register Screen *screen;
 379: register int    n;
 380: {
 381:     register int width;
 382: 
 383:     if (screen->cur_col + n > screen->max_col + 1)
 384:         n = screen->max_col + 1 - screen->cur_col;
 385: 
 386: #ifdef JUMPSCROLL
 387:     if(!AddToRefresh(screen)) {
 388:     if(screen->scroll_amt)
 389:         FlushScroll(screen);
 390: #endif JUMPSCROLL
 391: 
 392:     width = n * screen->f_width;
 393: 
 394:     screen->do_wrap = 0;
 395: 
 396:     if (screen->incopy)
 397:         CopyWait (screen);
 398:     screen->incopy = -1;
 399: 
 400:     XMoveArea(screen->window,
 401:              CursorX (screen) + width, CursorY (screen),
 402:              CursorX (screen), CursorY (screen),
 403:              screen->width - (screen->cur_col + n) * screen->f_width,
 404:              screen->f_height);
 405:     XTileSet (screen->window,
 406:              screen->border + screen->width - width, CursorY (screen),
 407:              width, screen->f_height, screen->bgndtile);
 408: 
 409: #ifdef JUMPSCROLL
 410:     }
 411: #endif JUMPSCROLL
 412:     /* adjust screen->buf */
 413:     ScrnDeleteChar (screen->buf, screen->cur_row, screen->cur_col, n,
 414:             screen->max_col + 1);
 415: 
 416: }
 417: 
 418: /*
 419:  * Clear from cursor position to beginning of display, inclusive.
 420:  */
 421: ClearAbove (screen)
 422: register Screen *screen;
 423: {
 424: #ifdef JUMPSCROLL
 425:     if(screen->scroll_amt)
 426:         FlushScroll(screen);
 427: #endif JUMPSCROLL
 428:     ClearLeft(screen);
 429: 
 430:     XTileSet(screen->window, screen->border, 0,
 431:         screen->width, CursorY (screen), screen->bgndtile);
 432:     ClearBufRows(screen, 0, screen->cur_row - 1);
 433: }
 434: 
 435: /*
 436:  * Clear from cursor position to end of display, inclusive.
 437:  */
 438: ClearBelow (screen)
 439: register Screen *screen;
 440: {
 441:     register int sy = CursorY (screen) + screen->f_height;
 442: 
 443: #ifdef JUMPSCROLL
 444:     if(screen->scroll_amt)
 445:         FlushScroll(screen);
 446: #endif JUMPSCROLL
 447:     ClearRight(screen);
 448:     XTileSet(screen->window, screen->border, sy,
 449:          screen->width, screen->height - sy + screen->border,
 450:          screen->bgndtile);
 451:     ClearBufRows(screen, screen->cur_row + 1, screen->max_row);
 452: }
 453: 
 454: /*
 455:  * Clear last part of cursor's line, inclusive.
 456:  */
 457: ClearRight (screen)
 458: register Screen *screen;
 459: {
 460:     screen->do_wrap = 0;
 461: 
 462: #ifdef JUMPSCROLL
 463:     if(!AddToRefresh(screen)) {
 464:     if(screen->scroll_amt)
 465:         FlushScroll(screen);
 466: #endif JUMPSCROLL
 467:     XTileSet(screen->window,
 468:          CursorX (screen), CursorY (screen),
 469:          screen->width-screen->cur_col * screen->f_width,screen->f_height,
 470:          screen->bgndtile);
 471: #ifdef JUMPSCROLL
 472:     }
 473: #endif JUMPSCROLL
 474:     bzero((char *)(screen->buf [screen->cur_row] + screen->cur_col),
 475:            sizeof (short) * (screen->max_col - screen->cur_col + 1));
 476: }
 477: 
 478: /*
 479:  * Clear first part of cursor's line, inclusive.
 480:  */
 481: ClearLeft (screen)
 482: register Screen *screen;
 483: {
 484:     screen->do_wrap = 0;
 485: 
 486: #ifdef JUMPSCROLL
 487:     if(!AddToRefresh(screen)) {
 488:     if(screen->scroll_amt)
 489:         FlushScroll(screen);
 490: #endif JUMPSCROLL
 491: 
 492:     XTileSet (screen->window,
 493:          screen->border, CursorY (screen),
 494:          (screen->cur_col + 1) * screen->f_width,
 495:          screen->f_height, screen->bgndtile);
 496: #ifdef JUMPSCROLL
 497:     }
 498: #endif JUMPSCROLL
 499:     bzero ((char *)screen->buf [screen->cur_row],
 500:         sizeof (short) * (screen->cur_col + 1));
 501: }
 502: 
 503: /*
 504:  * Erase the cursor's line.
 505:  */
 506: ClearLine(screen)
 507: register Screen *screen;
 508: {
 509:     screen->do_wrap = 0;
 510: 
 511: #ifdef JUMPSCROLL
 512:     if(!AddToRefresh(screen)) {
 513:     if(screen->scroll_amt)
 514:         FlushScroll(screen);
 515: #endif JUMPSCROLL
 516:     XTileSet (screen->window,
 517:          screen->border, CursorY (screen),
 518:          screen->width, screen->f_height, screen->bgndtile);
 519: #ifdef JUMPSCROLL
 520:     }
 521: #endif JUMPSCROLL
 522:     bzero ((char *)screen->buf [screen->cur_row],
 523:         sizeof (short) * (screen->max_col + 1));
 524: }
 525: 
 526: ClearScreen(screen)
 527: register Screen *screen;
 528: {
 529:     screen->do_wrap = 0;
 530: 
 531: #ifdef JUMPSCROLL
 532:     if(screen->scroll_amt)
 533:         FlushScroll(screen);
 534: #endif JUMPSCROLL
 535:     XClear(screen->window);
 536:     ClearBufRows (screen, 0, screen->max_row);
 537: }
 538: 
 539: CopyWait(screen)
 540: register Screen *screen;
 541: {
 542:     XEvent reply;
 543:     XEvent *rep = &reply;
 544: 
 545:     while (1) {
 546:         XWindowEvent (screen->window, ExposeRegion|ExposeCopy, &reply);
 547:         switch (reply.type) {
 548:         case ExposeRegion:
 549:             if (((XExposeEvent *)rep)->detail == ExposeCopy &&
 550:                 screen->incopy <= 0) {
 551:                 screen->incopy = 1;
 552:                 if (screen->scrolls > 0)
 553:                     screen->scrolls--;
 554:             }
 555:             HandleExposure (screen, &reply);
 556:             break;
 557:         case ExposeCopy:
 558:             if (screen->incopy <= 0 && screen->scrolls > 0)
 559:                 screen->scrolls--;
 560:             if (screen->scrolls == 0) {
 561:                 screen->incopy = 0;
 562:                 return;
 563:             }
 564:             screen->incopy = -1;
 565:             break;
 566:         }
 567:     }
 568: }
 569: /*
 570:  * This routine handles exposure events
 571:  */
 572: HandleExposure (screen, reply)
 573: register Screen *screen;
 574: register XExposeEvent *reply;
 575: {
 576:     int toprow, leftcol, nrows, ncols;
 577:     extern Terminal term;   /* kludge */
 578:     XExposeRegionEvent event;
 579: 
 580:     toprow = (reply->y - screen->border) / screen->f_height;
 581:     leftcol = (reply->x - screen->border) / screen->f_width;
 582:     nrows = (reply->y + reply->height - 1 - screen->border) /
 583:             screen->f_height - toprow + 1;
 584:     ncols = (reply->x + reply->width - 1 - screen->border) /
 585:             screen->f_width - leftcol + 1;
 586:     toprow -= screen->scrolls;
 587:     if (toprow < 0) {
 588:         nrows += toprow;
 589:         toprow = 0;
 590:     }
 591:     if (toprow + nrows - 1 > screen->max_row)
 592:         nrows = screen->max_row - toprow + 1;
 593:     if (leftcol + ncols - 1 > screen->max_col)
 594:         ncols = screen->max_col - leftcol + 1;
 595: 
 596:     if (nrows > 0 && ncols > 0) {
 597:         if (screen->TekEmu && reply->detail != ExposeCopy)
 598:             /* Clear to avoid possible dangling cursor */
 599:             XTileSet (screen->window,
 600:                  leftcol * screen->f_width + screen->border,
 601:                  toprow * screen->f_height + screen->border,
 602:                  ncols * screen->f_width,
 603:                  nrows * screen->f_height,
 604:                  screen->bgndtile);
 605:         ScrnRefresh (screen, toprow, leftcol, nrows, ncols);
 606:         /* only do the tek refresh on the last refresh event */
 607:         if (screen->TekEmu) {
 608:             XSync(0);   /* make sure they are all here */
 609:             if (XPending() != 0) {
 610:                 XPeekEvent(&event);
 611:                 if (event.type != ExposeRegion) {
 612:                     if (reply->detail != ExposeCopy)
 613:                         TekRefresh(&term);
 614:                 }
 615:             }
 616:             else {
 617:                 if (reply->detail != ExposeCopy)
 618:                     TekRefresh (&term);
 619:             }
 620:         }
 621:         if (screen->cur_row >= toprow &&
 622:             screen->cur_row < toprow + nrows &&
 623:             screen->cur_col >= leftcol &&
 624:             screen->cur_col < leftcol + ncols)
 625:             return (1);
 626:     }
 627:     return (0);
 628: }
 629: 
 630: Panic(s, a)
 631: char    *s;
 632: {
 633:     fprintf(stderr, "PANIC!	");
 634:     fprintf(stderr, s, a);
 635:     fprintf(stderr, "\r\n");
 636:     fflush(stderr);
 637: }
 638: 
 639: Error ()
 640: {
 641:     fprintf (stderr, "Error %d: ", errno);
 642:     perror ("");
 643:     Cleanup(66);
 644: }
 645: 
 646: /*
 647:  * cleanup by sending SIGHUP to client processes
 648:  */
 649: Cleanup (code)
 650: int code;
 651: {
 652:     extern Terminal term;
 653:     register Screen *screen;
 654:     register long pgrp;
 655:     screen = &term.screen;
 656:     if (screen->pid > 1) {
 657:         pgrp = getpgrp(screen->pid);
 658:         if (pgrp > 1) killpg(pgrp, SIGHUP);
 659:     }
 660:     exit(code);
 661: }
 662: 
 663: /*
 664:  * sets the value of var to be arg in the Unix 4.2 BSD environment env.
 665:  * Var should end with '=' (bindings are of the form "var=value").
 666:  * This procedure assumes the memory for the first level of environ
 667:  * was allocated using malloc.
 668:  */
 669: Setenv (var, value)
 670: register char *var, *value;
 671: {
 672:     extern char **environ;
 673:     register int index = 0;
 674: 
 675:     while (environ [index] != NULL) {
 676:         if (strncmp (environ [index], var, strlen (var)) == 0) {
 677:         /* found it */
 678:         environ [index] = (char *) malloc (strlen (var) + strlen (value));
 679:         strcpy (environ [index], var);
 680:         strcat (environ [index], value);
 681:         return;
 682:         }
 683:         index ++;
 684:     }
 685: 
 686:     if (debug) printf ("expanding env\n");
 687:     environ = (char **) realloc((char *)environ, sizeof(char *) * (index+2));
 688:     if (environ == NULL) {
 689:         fprintf (stderr, "Setenv: malloc out of memory\n");
 690:         exit (1);
 691:     }
 692: 
 693:     environ [index] = (char *) malloc (strlen (var) + strlen (value));
 694:     strcpy (environ [index], var);
 695:     strcat (environ [index], value);
 696:     environ [++index] = NULL;
 697: }
 698: 
 699: /*
 700:  * returns a pointer to the first occurrence of s2 in s1,
 701:  * or NULL if there are none.
 702:  */
 703: char *strindex (s1, s2)
 704: register char   *s1, *s2;
 705: {
 706:     register char   *s3;
 707:     char        *index();
 708: 
 709:     while ((s3=index(s1, *s2)) != NULL) {
 710:         if (strncmp(s3, s2, strlen(s2)) == 0)
 711:             return (s3);
 712:         s1 = ++s3;
 713:     }
 714:     return (NULL);
 715: }

Defined functions

AddToRefresh defined in line 69; used 6 times
Cleanup defined in line 649; used 3 times
ClearAbove defined in line 421; used 1 times
ClearBelow defined in line 438; used 1 times
ClearLeft defined in line 481; used 2 times
ClearLine defined in line 506; used 1 times
ClearRight defined in line 457; used 2 times
ClearScreen defined in line 526; used 4 times
CopyWait defined in line 539; used 10 times
DeleteChar defined in line 377; used 1 times
DeleteLine defined in line 281; used 1 times
HandleExposure defined in line 572; used 3 times
InsertChar defined in line 339; used 2 times
InsertLine defined in line 223; used 1 times
RevScroll defined in line 171; used 1 times
Scroll defined in line 104; used 1 times
Setenv defined in line 669; used 3 times
strindex defined in line 703; used 3 times

Defined variables

rcsid_util_c defined in line 8; never used
Last modified: 1986-05-16
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 2869
Valid CSS Valid XHTML 1.0 Strict