|
|
1.1 ! root 1: /* EMACS_MODES: c !fill */ ! 2: #ifdef v8 ! 3: #include <sys/types.h> ! 4: #endif ! 5: #include "emacs_gb.h" ! 6: #include "emacs_io.h" ! 7: #ifndef PC ! 8: #include <signal.h> ! 9: #endif ! 10: #ifdef bsd ! 11: #include <sys/time.h> ! 12: #else ! 13: #include <time.h> ! 14: #endif ! 15: #include <errno.h> ! 16: #ifdef ux3 ! 17: #include <termio.h> ! 18: #else ! 19: #include <sgtty.h> ! 20: #endif ! 21: ! 22: #ifdef bsd ! 23: ! 24: /* The following defines turn on the use of the select system call ! 25: * and Cbreak mode for berkeley unix. If you are running a version ! 26: * of berkeley unix without these features, taken them out */ ! 27: ! 28: #define SELECT ! 29: #define CBRAKE ! 30: #define FLIM ! 31: #endif ! 32: #ifdef ux3 ! 33: #define FLIM ! 34: #endif ! 35: ! 36: ! 37: #ifdef COMPRESS ! 38: long coutc = 0; ! 39: int DOCOMP=0; ! 40: char *trtab[128] = { ! 41: ! 42: #include "compress.h" ! 43: }; ! 44: ! 45: #endif ! 46: ! 47: #ifdef NDLAY ! 48: #include <sys/types.h> ! 49: #ifdef ux3 ! 50: #include <fcntl.h> ! 51: #endif ux3 ! 52: ! 53: int ndfrn; /* file for ndelay I/O */ ! 54: #endif ! 55: ! 56: extern int SAVEMD; ! 57: extern int curbf; ! 58: extern char *getenv(); ! 59: ! 60: #ifdef PC ! 61: #define READM (0) ! 62: #define APPEM (1) ! 63: #define WRITEM (1) ! 64: #else ! 65: #define READM 0 ! 66: #define APPEM 1 ! 67: #define WRITEM 0666 ! 68: ! 69: int READ_WAIT = 255; ! 70: int read_miss; ! 71: #endif ! 72: /* TTY buffer */ ! 73: ! 74: /* if unix3.0 (or later) system with no wait raw-mode I/O, use a big tty */ ! 75: /* buffer to allow type ahead and avoid excessive re-display */ ! 76: ! 77: #if (defined(ux3) || defined(bsd) || defined(v8)) ! 78: #define TTLOOK 16 ! 79: #else ! 80: #define TTLOOK 1 ! 81: #endif ! 82: int ttcnt ; ! 83: char ttbuf[18]; /* Make large */ ! 84: char *ttptr; ! 85: int ungc = 0; ! 86: extern int ttywarp; ! 87: ! 88: /* Interrupted system command flag */ ! 89: int irupt = 0; ! 90: #define MAXIRUPT 100 ! 91: ! 92: /* controlification stuff */ ! 93: ! 94: int ctlify; ! 95: int CONCHAR = 036; /* ^^ */ ! 96: ioinit() ! 97: { ! 98: /* Keywords: internal-initialization standard-I/O files:20 */ ! 99: register char *ttname; ! 100: ! 101: xclose(3); /* close all files */ ! 102: _stdout._frn = 1; ! 103: _stdout._cnt = 0; ! 104: _stdout._flags = _OUTPUT; ! 105: incnt = inlev = infrn = 0; ! 106: infrn = NULL; ! 107: brkflg = 0; ! 108: inbuf = _inbuf[0]; ! 109: #ifdef NDLAY ! 110: #ifdef ux3 ! 111: ! 112: #ifdef pdp11 ! 113: #define PDPTEST (ttywarp<2) ! 114: #else ! 115: #define PDPTEST 0 ! 116: #endif ! 117: ! 118: /* IF we have NDELAY I/O, close standard error and open it with ndelay */ ! 119: ! 120: close(2); /* close standard error */ ! 121: ! 122: ! 123: if ((ttname=getenv("LOGTTY"))==NULL) ttname="/dev/tty"; ! 124: if (PDPTEST || (open(ttname,O_RDWR+O_NDELAY)<0)) { ! 125: dup(1); ! 126: ndfrn = 0; ! 127: } else ndfrn = 2; ! 128: ! 129: /* if we can't get tty, restore frn2 */ ! 130: #endif ux3 ! 131: #ifdef (defined(bsd) || defined(v8)) ! 132: /* ! 133: * we can see how many chars await us in bsd4.1, ! 134: * so set ndfrn if the tty is fast enough for us. - CRC ! 135: */ ! 136: ndfrn = 2; /* CRC */ ! 137: ! 138: #endif (bsd || v8) /* CRC */ ! 139: ! 140: #endif /* CRC */ ! 141: } ! 142: int FLOWMIN=0; /* Mode variable must be present */ ! 143: ! 144: #ifdef PC ! 145: ! 146: cook() ! 147: { ! 148: } ! 149: uncook() ! 150: { ! 151: } ! 152: #else ! 153: /* into raw mode */ ! 154: ! 155: ! 156: /* Terminal I/O modes, sgttyb for before unix 3.0, termio for later */ ! 157: ! 158: ! 159: int xon; ! 160: ! 161: #ifdef ux3 ! 162: struct termio ttyjunk; ! 163: struct termio nttyjunk; ! 164: #else ! 165: struct sgttyb ttyjunk; ! 166: struct sgttyb nttyjunk; ! 167: #endif ! 168: ! 169: #ifdef CBRAKE ! 170: /* Additional goodies for 4.2BSD */ ! 171: ! 172: int ldisc; /* Line discipline */ ! 173: struct tchars tchars; /* Basic characters */ ! 174: int locmode; /* Local mode */ ! 175: struct ltchars ltchars; /* And at last, local modes */ ! 176: struct ltchars zchars = { ! 177: -1,-1,-1,-1,-1,-1 }; /* Zero characters for ioctl */ ! 178: struct tchars fcoff = {0,-1,-1,-1,-1,-1}; ! 179: struct tchars fcon = {0,-1,021,023,-1,-1}; ! 180: int mylmode = LLITOUT|LDECCTQ; /* Literal output, ^Q starts ^S */ ! 181: #endif ! 182: ! 183: ! 184: #define NBAUD 16 /* number of baud rates */ ! 185: char charms[NBAUD] = { /* ms per char in various rates */ ! 186: 100, ! 187: 100, /* 50 */ ! 188: 100, /* 75 */ ! 189: 100, /* 110 */ ! 190: 70, /* 134 */ ! 191: 66, /* 150 */ ! 192: 50, /* 200 */ ! 193: 33, /* 300 */ ! 194: 16, /* 600 */ ! 195: 8, /* 1200 */ ! 196: 5, /* 1800 */ ! 197: 4, /* 2400 */ ! 198: 2, /* 4800 */ ! 199: 1, /* 9600 */ ! 200: 1, /* EXTA */ ! 201: 1, /* EXTB */ ! 202: }; ! 203: ! 204: uncook() ! 205: { ! 206: ! 207: /* UNIX 3 code thanks to J. Langer and M. Plotnick */ ! 208: ! 209: /* Keywords: the-terminal internal-initialization:40 terminal-initialization terminal-modes unix-interface:50 */ ! 210: #ifdef ux3 ! 211: ! 212: ! 213: ioctl(1, TCGETA, &ttyjunk); ! 214: nttyjunk=ttyjunk; ! 215: ! 216: #ifdef u370 ! 217: ! 218: nttyjunk.c_iflag |= (BRKINT|ISTRIP|IGNPAR); ! 219: nttyjunk.c_iflag &= ! 220: ~(IGNBRK|IGNPAR|PARMRK|IXON|INLCR|IGNCR|ICRNL|INPCK); ! 221: /* accept break, no crnl mapping, no ^S^Q */ ! 222: nttyjunk.c_oflag = 0; /* no delays, no crlf mapping */ ! 223: /* nttyjunk.c_cflag |= CS8 ;*/ ! 224: nttyjunk.c_lflag &= ~(ISIG|ECHO|ICANON); /* no echo, signals, ! 225: or erase/kill processing */ ! 226: #else ! 227: nttyjunk.c_iflag |= (BRKINT|ISTRIP); ! 228: nttyjunk.c_iflag &= ~(IGNBRK|PARMRK|INLCR|ICRNL|IGNCR|IXON|IXOFF); ! 229: /* accept break, no crnl mapping, no ^S^Q */ ! 230: nttyjunk.c_oflag = 0; /* no delays, no crlf mapping */ ! 231: nttyjunk.c_lflag &= ~(ISIG|ECHO|ICANON); /* no echo, signals, ! 232: or erase/kill processing */ ! 233: #endif ! 234: nttyjunk.c_cc[VMIN] = 0; /* return after every character read */ ! 235: ! 236: /* Setting VMIN to 0 causes emacs to time out input every 25.5 seconds, ! 237: * updating the display of time (if time mode is on) and received ! 238: * mail. Setting it to 1 will cause emacs to wait indefinetely for ! 239: * input. */ ! 240: ! 241: nttyjunk.c_cc[VTIME] = READ_WAIT; /* Or after 25.5 seconds */ ! 242: ttywarp = charms[ttyjunk.c_cflag&CBAUD]; /* milliseconds for character */ ! 243: ! 244: ioctl(1, TCSETAW, &nttyjunk); ! 245: ioctl(1, TCXONC,1); /* Force tty back on */ ! 246: xon = 0; /* Xon/XOff is now off */ ! 247: ! 248: #else ! 249: ! 250: ! 251: ioctl(1,TIOCGETP,&ttyjunk); ! 252: nttyjunk=ttyjunk; ! 253: #ifdef CBRAKE ! 254: nttyjunk.sg_flags = CBREAK; ! 255: ioctl(1,TIOCSETN,&nttyjunk); ! 256: ! 257: /* Now for the real fun, get all of the other 4.2BSD goodies */ ! 258: ! 259: ioctl(1,TIOCGETC,&tchars); ! 260: ioctl(1,TIOCSETC,&fcoff); ! 261: ioctl(1,TIOCLGET,&locmode); ! 262: ioctl(1,TIOCLBIS,&mylmode); ! 263: ioctl(1,TIOCGLTC,<chars); ! 264: ioctl(1,TIOCSLTC,&zchars); ! 265: xon = 0; ! 266: #else ! 267: nttyjunk.sg_flags &= (~ECHO); /* it was so SIMPLE in the old days */ ! 268: nttyjunk.sg_flags |= (RAW); ! 269: ioctl(1,TIOCSETP,&nttyjunk); ! 270: #endif ! 271: ttywarp = charms[ttyjunk.sg_ospeed]; /* milliseconds for char */ ! 272: #endif ! 273: ! 274: vinit(); ! 275: ! 276: /* Anything above 2500 baud may cause problems */ ! 277: /* If the user has not selected a limit we'll set one */ ! 278: /* Commented out, remove this line to enable it ! 279: if ((ttywarp < 4)&&(FLOWMIN==0)) FLOWMIN = 64; /* */ ! 280: ! 281: } ! 282: ! 283: cook() ! 284: { ! 285: /* Keywords: the-terminal terminal-modes exit-processing:50 unix-interface:50 */ ! 286: extern int osert,umode; ! 287: ! 288: /* First, return the terminal to a sane state */ ! 289: ! 290: if (no_io) return; ! 291: if (umode) unline(); ! 292: if (osert) unsert(); ! 293: vexit(); ! 294: mflush(stdout); /* force output */ ! 295: #ifdef ux3 ! 296: ioctl(1,TCSETAW, &ttyjunk); ! 297: ioctl(1, TCXONC,1); /* Force tty back on */ ! 298: xon = 1; /* XON/XOFF is now ON */ ! 299: #else ! 300: #ifdef CBRAKE ! 301: ioctl(1,TIOCSETN,&ttyjunk); ! 302: ioctl(1,TIOCSETC,&tchars); ! 303: ioctl(1,TIOCLSET,&locmode); ! 304: ioctl(1,TIOCLBIC,&mylmode); ! 305: ioctl(1,TIOCSLTC,<chars); ! 306: xon = 1; ! 307: #else ! 308: ioctl(1,TIOCSETP,&ttyjunk); ! 309: #endif ! 310: #endif ! 311: } ! 312: #endif ! 313: ! 314: /*VARARGS2*/ ! 315: ! 316: char * ! 317: nscan(stptr,ret) ! 318: ! 319: register char *stptr; ! 320: register int *ret; ! 321: ! 322: /* Keywords: standard-I/O:20 conversions parsing:20 reading:20 */ ! 323: { ! 324: register int c; ! 325: ! 326: *ret = 0; ! 327: while (((c = *stptr)>='0') && (c <= '9')) { ! 328: stptr++; ! 329: *ret = *ret*10+(c-'0'); ! 330: } ! 331: return(stptr); ! 332: } ! 333: ! 334: ! 335: seprintf(string,fmt,x) ! 336: char *string; ! 337: char *fmt; ! 338: unsigned x; ! 339: { ! 340: sxprintf(string,fmt,&x); /* Depends on arg list format */ ! 341: } ! 342: ! 343: /* Internal printf formatter */ ! 344: ! 345: sxprintf(string,fmt, adx) ! 346: register char *string; ! 347: register char *fmt; ! 348: register unsigned int *adx; ! 349: { ! 350: /* Keywords: standard-I/O:50 formatting writing:20 terminal-parameters:20 */ ! 351: int c; ! 352: int width; ! 353: ! 354: extern char *mstrcpy(); ! 355: ! 356: if (fmt == NULL) fmt = ""; ! 357: ! 358: loop: ! 359: while((c = *fmt++) != '%') { ! 360: *string++ = c; ! 361: if(c == '\0') { ! 362: return; ! 363: } ! 364: } ! 365: width = 0; ! 366: c = *fmt++; ! 367: if ((c >= '0') && (c <= '9')) { ! 368: fmt = nscan(fmt-1,&width); ! 369: c = *fmt++; ! 370: } ! 371: ! 372: switch(c) { ! 373: case 'd': ! 374: case 'D': ! 375: case 'o': ! 376: case 'O': ! 377: { ! 378: register int b; ! 379: long n; ! 380: long n1; ! 381: register int i; ! 382: char dstack[20]; ! 383: ! 384: b = (((c=='o') || (c == 'O'))? 8: 10); /* number base */ ! 385: if ((c == 'o') || (c == 'd')) { ! 386: n = (long) (*adx); ! 387: if (sizeof(n) != sizeof(i)) { ! 388: if (n > 32768L) n = n-65536L; /* sign correction */ ! 389: } ! 390: } else { ! 391: n = *((long *) adx); ! 392: adx += ((sizeof(n)-sizeof(i))/sizeof(i)); ! 393: } ! 394: i = 0; ! 395: if (n < 0) { ! 396: n = -n; ! 397: *string++ = '-'; ! 398: } ! 399: ! 400: do { ! 401: n1 = n/b; ! 402: dstack[i++] = (short) (n-(n1*b)); ! 403: n = n1; ! 404: } while (n != 0); /* figure number */ ! 405: if ((b == 8) && ((i !=1 ) || (dstack[0] != 0))) dstack[i++]=0; ! 406: while (i<width) dstack[i++] = 0; ! 407: while (i > 0) { ! 408: #ifdef PC ! 409: char cq; ! 410: cq = dstack[--i]; ! 411: cq += '0'; ! 412: *string++ = cq; ! 413: #else ! 414: *string++ = (dstack[--i] + '0'); /* print number */ ! 415: #endif ! 416: } ! 417: } ! 418: break; ! 419: case 'P': ! 420: width *= SREGION; ! 421: /* Fall through */ ! 422: case 'p': ! 423: while (width > 0) { ! 424: *string++ = *NOP; ! 425: width -= ttywarp; ! 426: } ! 427: adx--; ! 428: break; ! 429: case 's': ! 430: string = mstrcpy(string,(char *)*adx); ! 431: break; ! 432: case 'm': ! 433: case 'M': ! 434: { ! 435: char *cp; ! 436: if (c=='m') { ! 437: cp = &TMAP[width * (*adx)]; ! 438: } else { ! 439: cp = &SMAP[width * (*adx)]; ! 440: } ! 441: for (c = 0; c < width; c++) { ! 442: if (*cp) *string++ = *cp++; ! 443: } ! 444: } ! 445: break; ! 446: case 'c': ! 447: c = *adx + width; ! 448: if (c) { ! 449: *string++ = c; ! 450: } else { ! 451: *string++ = '^'; ! 452: *string++ = '@'; /* punt */ ! 453: } ! 454: break; ! 455: case '%': ! 456: *string++ ='%'; ! 457: adx--; ! 458: break; ! 459: default: ! 460: error(WARN,70); /* Bad character in printf */ ! 461: } ! 462: adx++; ! 463: goto loop; ! 464: } ! 465: char *inget() ! 466: { ! 467: /* Keywords: command-files:10 */ ! 468: if (infrn < 0)return(inptr); ! 469: else return(NULL); ! 470: } ! 471: inset(newptr) ! 472: char *newptr; ! 473: /* Keywords: command-files:10 */ ! 474: { ! 475: if (infrn < 0) inptr = newptr; ! 476: } ! 477: ! 478: #ifdef SELECT ! 479: int sreadfd = 1; ! 480: struct timeval stimeout = {30,0}; /* timeout interval */ ! 481: #endif ! 482: #ifdef v8 ! 483: fd_set sreadfd; ! 484: #endif ! 485: int ! 486: getchar() ! 487: { ! 488: /* Keywords: the-terminal standard-I/O terminal-modes:10 reading mail-processing:20 time-processing:20 prompting:30 conversions:10 PC-only:10 keyboard-macros:20 unix-interface:10 */ ! 489: ! 490: extern int timemd; ! 491: extern int newmail; ! 492: extern int mailcnt; ! 493: extern int kbdfile; ! 494: extern char ctype[]; ! 495: extern char cbuf[]; ! 496: register int c; ! 497: ! 498: ! 499: if (no_io) return(CTRLZ); /* Flush I/O */ ! 500: if (brkflg) brkit(); /* handle break interrupt */ ! 501: if (incnt == 0) { ! 502: while (1) { ! 503: errno = 0; ! 504: if (infrn) { ! 505: inptr = inbuf; ! 506: incnt = read(infrn,inbuf,INLOOK); ! 507: } else { ! 508: ! 509: /* The following code expects read from a raw mode tty port to ! 510: * return whenever at least one character has been received or a ! 511: * timeout expires. It assumes that if it gets 0 characters, the ! 512: * timer expired, unless it happens too many times in a row. */ ! 513: ! 514: reread: ttptr = ttbuf+2; ! 515: #ifdef PC ! 516: ttcnt = incnt = rawread(ttbuf+2); ! 517: #else ! 518: ! 519: read_miss = 0; ! 520: if (donttime) goto notime; /* Avoid time and mail */ ! 521: ! 522: /* First, update time and mail */ ! 523: ! 524: if (timemd) dtime(0); ! 525: if ((mailcnt>=0) && (--mailcnt<=0)) { ! 526: ckmail(); ! 527: } ! 528: ! 529: /* Display them if necessary */ ! 530: if (newmail) { ! 531: int x,y; ! 532: x = mline; ! 533: y = mcol; ! 534: prompt(ECHOL-1,"%s You have mail",cbuf); ! 535: if (newmail < 0) beep(); ! 536: mgo(x,y); ! 537: newmail = 1; ! 538: } else if (disptime) { ! 539: ! 540: int x,y; ! 541: x = mline; ! 542: y = mcol; ! 543: prompt(ECHOL-1,cbuf); ! 544: disptime=0; ! 545: mgo(x,y); ! 546: } ! 547: notime: ! 548: /* Now try to read some standard input */ ! 549: ! 550: mflush(stdout); ! 551: #ifdef FLIM ! 552: if (xon && (FLOWMIN>=0)) { /* If xon/xoff is on, turn it off */ ! 553: #ifdef CBRAKE ! 554: ! 555: quietout(); ! 556: ioctl(1,TIOCSETC,&fcoff); ! 557: #else ! 558: nttyjunk.c_iflag &= ~(IXON|IXANY); ! 559: ioctl(1,TCSETAW,&nttyjunk); ! 560: #endif ! 561: xon = 0; ! 562: } ! 563: #endif ! 564: #ifdef SELECT ! 565: if (inproc){ ! 566: sreadfd = 1+(1<<inproc); ! 567: ttcnt = select(inproc+1,&sreadfd,NULL,NULL,&stimeout); ! 568: if (sreadfd > 1) readproc(); ! 569: } else { ! 570: sreadfd = 1; /* must set up each time since select clobbers it */ ! 571: ttcnt = select(1,&sreadfd,NULL,NULL,&stimeout); ! 572: } ! 573: if ((sreadfd & 1) && (brkflg == 0)) ttcnt = incnt = read(0,ttbuf+2,TTLOOK); ! 574: else { ! 575: incnt = 0; ! 576: errno = EINTR; /* Make it look like the read timed out! */ ! 577: ! 578: } ! 579: #else ! 580: #ifdef v8 ! 581: if (inproc){ ! 582: FD_ZERO(sreadfd); ! 583: FD_SET(0, sreadfd); ! 584: FD_SET(inproc, sreadfd); ! 585: ttcnt = select(inproc+1,&sreadfd,NULL,30000); ! 586: if (FD_ISSET(inproc,sreadfd)) ! 587: readproc(); ! 588: } else { ! 589: FD_ZERO(sreadfd); ! 590: FD_SET(0, sreadfd); ! 591: ttcnt = select(1,&sreadfd,NULL,30000); ! 592: } ! 593: if (FD_ISSET(0,sreadfd) && (brkflg == 0)) ! 594: ttcnt = incnt = read(0,ttbuf+2,TTLOOK); ! 595: else { ! 596: incnt = 0; ! 597: errno = EINTR; /* Make it look like the read timed out! */ ! 598: ! 599: } ! 600: #else ! 601: ttcnt = incnt = read(0,ttbuf+2,TTLOOK); ! 602: if (inproc) readproc(); /* Process any input */ ! 603: #ifdef ux3 ! 604: if (ttcnt) ioset(10); ! 605: else ioset(READ_WAIT<<1); /* Back off read timeout next time */ ! 606: #endif ux3 ! 607: #endif v8 ! 608: #endif SELECT ! 609: if (brkflg) { ! 610: incnt=ttcnt=0; ! 611: brkit(); ! 612: disup(); ! 613: goto reread; /* Try again for a charactger */ ! 614: ! 615: } ! 616: ! 617: if (incnt == 0) { ! 618: mailcnt = 0; /* Expire mail timer */ ! 619: if (++read_miss < 1000) goto reread; ! 620: } ! 621: #endif PC ! 622: } ! 623: ninch+= incnt; /* count for stats */ ! 624: if (incnt >= 0) break; ! 625: if ((errno != EINTR)|| (++irupt > MAXIRUPT)) break; ! 626: } ! 627: ! 628: } ! 629: ! 630: if (infrn < 0) { /* if in macro */ ! 631: incnt++; ! 632: } ! 633: if (infrn) { ! 634: if (incnt-- >0) return(*inptr++ & 0377); ! 635: } else { ! 636: if ((incnt= --ttcnt) >= 0) { ! 637: if (ungc) { ! 638: ungc--; ! 639: return(*ttptr++ & 0377); ! 640: } ! 641: c = (*ttptr++ & 0177); ! 642: if (ctlify && (c == CONCHAR)) { ! 643: ctlify = 0; /* don't controlify again */ ! 644: ! 645: c = getchar(); ! 646: if ((c>= 'a') && (c <= 'z')) c -= 040; ! 647: if ((ctype[c] == PLAIN) ||(ctype[c] == UL)) c ^= 0100; ! 648: ctlify++; ! 649: } ! 650: if (kbdfile) { ! 651: char x; ! 652: x=c; ! 653: write(kbdfile,&x,1); ! 654: } ! 655: return(c); ! 656: } ! 657: } ! 658: return(CTRLZ); ! 659: } ! 660: #ifndef PC ! 661: #ifdef ux3 ! 662: ! 663: /* Set non-blocking terminal timeout appropriately */ ! 664: ! 665: /* Note -- this is a very imperfect simulation of the select system ! 666: * call in 4.2bsd for system V unix. What is done is that if no ! 667: * process is running, the timeout is set to 25.5 seconds. If a ! 668: * process is running, the timeout is decreased after every piece of ! 669: * input is sent, and rises as reads time out, returning eventually ! 670: * to 25.5 seconds. Thus quick processes get good results, but slow ! 671: * ones can get dismal response. Emacs polls the sub-process(s) ! 672: * each time it reads from the tty, so the timeout just dictates ! 673: * how often this happens if there is no tty input. */ ! 674: ! 675: ! 676: ioset(limit) ! 677: int limit; ! 678: { ! 679: /* Keywords: unix-interface reading shell-escape sub-processes look-ahead: 10*/ ! 680: ! 681: if (READ_WAIT == 0) return; /* No non-blocking I/O available */ ! 682: if (limit > 255) limit = 255; /* Clamp it */ ! 683: ! 684: if (READ_WAIT == limit) return; ! 685: READ_WAIT = limit; ! 686: nttyjunk.c_cc[VTIME] = READ_WAIT; ! 687: ioctl(1, TCSETA, &nttyjunk); ! 688: ! 689: } ! 690: #endif ! 691: ! 692: /* Process input from process in the window */ ! 693: ! 694: readproc () ! 695: { ! 696: /* Keywords: unix-interface reading shell-escape sub-processes buffers:50 */ ! 697: ! 698: ! 699: char buf[128]; ! 700: int nc,obuf; ! 701: int cnt; ! 702: ! 703: #ifdef v8 ! 704: ioctl(inproc, FIONREAD, &cnt); ! 705: if(cnt <= 0) ! 706: return; ! 707: #endif ! 708: nc = read(inproc,buf,127); ! 709: buf[nc]=0; ! 710: if (nc) { ! 711: if (curbf != procbuf) { ! 712: if (procbuf == windbuf()) { ! 713: owind(); ! 714: stuffproc(buf); ! 715: disup(); ! 716: owind(); ! 717: disup(); ! 718: } else { ! 719: obuf=curbf; ! 720: chbuf(procbuf); ! 721: stuffproc(buf); ! 722: chbuf(obuf); ! 723: } ! 724: } else { ! 725: stuffproc(buf); ! 726: disup(); /* Update display for user */ ! 727: } ! 728: } else { ! 729: } ! 730: } ! 731: ! 732: /* stuffproc -- stuff process input into the current buffer */ ! 733: ! 734: stuffproc(string) ! 735: char *string; ! 736: { ! 737: /* Keywords: unix-interface reading shell-escape sub-processes buffers:50 */ ! 738: ! 739: bot(); ! 740: putin(string); ! 741: mark(curbf); ! 742: } ! 743: ! 744: /* sendproc -- send current line to the process */ ! 745: ! 746: sendproc (ptr,count) ! 747: char * ptr; ! 748: int count; ! 749: { ! 750: /* Keywords: unix-interface shell-escape buffer-representation:10 buffers:50 writing sub-processes */ ! 751: if (write(outproc,ptr,count)<0) flushproc(); ! 752: #ifdef ux3 ! 753: ioset(1); /* Set back timeout appropriately */ ! 754: ! 755: #endif ! 756: } ! 757: ! 758: /* brkproc -- send an interrupt to the current sub-process */ ! 759: ! 760: brkproc(arg) ! 761: ! 762: /* Keywords: unix-interface shell-escape break-handling sub-processes */ ! 763: ! 764: ! 765: { ! 766: if (curbf == procbuf) { ! 767: if (arg== 1) arg = SIGINT; ! 768: kill(procpid,arg); ! 769: } ! 770: } ! 771: ! 772: /* flushproc -- rid ourselves of the current sub-process */ ! 773: ! 774: flushproc() ! 775: { ! 776: /* Keywords: unix-interface shell-escape closing sub-processes */ ! 777: ! 778: int status; ! 779: ! 780: if (procpid) { ! 781: kill (procpid,9); ! 782: status=wait(&status); ! 783: close(inproc); ! 784: close(outproc); ! 785: procpid=inproc=outproc=0; ! 786: procbuf= -1; ! 787: } ! 788: } ! 789: #else ! 790: /* Define some tombstones for this code. It's easier than ifdeffing out all the calls */ ! 791: brkproc() ! 792: { ! 793: } ! 794: #endif ! 795: /* Fill tty buffer if we have ndelay I/O */ ! 796: ! 797: ttfill() ! 798: /* Keywords: the-terminal terminal-modes lookahead reading unix-interface:50 */ ! 799: ! 800: { ! 801: #ifdef NDLAY ! 802: long i; ! 803: register char *addr; ! 804: ! 805: if (no_io || (ndfrn == 0)) return; ! 806: mflush(stdout); /* flush tty */ ! 807: ! 808: #if (defined(bsd) || defined(v8)) /* CRC */ ! 809: i = 0; /* CRC */ ! 810: ioctl(2,FIONREAD,&i); /* CRC */ ! 811: if( i <= 0) /* CRC */ ! 812: /* no input awaits us. - CRC */ ! 813: return; /* CRC */ ! 814: #endif (bsd || v8) ! 815: if (ttcnt) { ! 816: /* more input, append to it */ ! 817: addr = ttptr+ttcnt; ! 818: i = read(2,addr,ttbuf+2+TTLOOK-addr); ! 819: } else { ! 820: i = read(2,ttbuf+2,TTLOOK); ! 821: ttptr = ttbuf+2; ! 822: } ! 823: if (i < 0) i = 0; ! 824: ttcnt += i; /* more characters */ ! 825: if (infrn == 0) { /* reading from tty */ ! 826: incnt = ttcnt; ! 827: inptr = ttptr; ! 828: } ! 829: #endif ! 830: return; ! 831: } ! 832: pushin(fp) ! 833: /* Keywords: command-files:50 keyboard-macros:20 opening unix-interface:10 */ ! 834: register char *fp; ! 835: { ! 836: register int frn; ! 837: ! 838: if (fp != NULL) { ! 839: while((frn = open(fp,READM)) <= 0) { ! 840: if ((errno != EINTR) && (errno != 23))break; ! 841: } ! 842: } else frn = 0; ! 843: if (frn >= 0) { ! 844: _incnt[inlev] = incnt; ! 845: _infrn[inlev] = infrn; ! 846: _inptr[inlev++] = inptr; ! 847: infrn = frn; ! 848: if (frn) incnt = 0; ! 849: else incnt = ttcnt; ! 850: return(1); ! 851: } else return(0); ! 852: } ! 853: ! 854: pshmac(pos) ! 855: /* Keywords: macro-invocation */ ! 856: ! 857: short pos; ! 858: { ! 859: ! 860: if (inlev>= NINP) error(FATAL,64); ! 861: _incnt[inlev] = incnt; ! 862: _infrn[inlev] = infrn; ! 863: _inptr[inlev++] = inptr; ! 864: infrn = -1; ! 865: incnt = 100; /* will never decrease */ ! 866: inptr = &bbuf[0][pos]; /* macro buffer position */ ! 867: return(1); ! 868: } ! 869: ! 870: ! 871: ! 872: inpop() ! 873: /* Keywords: exit-processing:10 macro-invoction:20 command-files:20 */ ! 874: { ! 875: if (inlev > 0) { ! 876: --inlev; ! 877: if (infrn>0) close(infrn); ! 878: infrn = _infrn[inlev]; ! 879: inptr = _inptr[inlev]; ! 880: inbuf = _inbuf[inlev]; ! 881: if (infrn) incnt = _incnt[inlev]; ! 882: else incnt = ttcnt; ! 883: return(1); ! 884: } else return(0); ! 885: } ! 886: ! 887: #ifdef COMPRESS ! 888: ! 889: #define CRELOAD 0376 ! 890: ! 891: translate(buf,count) ! 892: /* Keywords: standard-I/O:10 compressed-output conversions writing */ ! 893: char *buf; ! 894: int count; ! 895: { ! 896: register char *bp; ! 897: char *be; ! 898: register char *bo; ! 899: register char *mp; ! 900: register char *tp; ! 901: bp=bo=buf; ! 902: be=buf+count; ! 903: ! 904: while (bp<be-1) { ! 905: if (*bp&0200) { ! 906: *bp = 0; /* PUNT all meta characters to 0 */ ! 907: goto stop; ! 908: } ! 909: mp=trtab[*bp]; ! 910: while (*mp) { ! 911: tp=bp+1; ! 912: while (*tp++ == *mp++); ! 913: if ((mp[-1]&0200)){ ! 914: if (tp > be+1) { ! 915: goto stop; ! 916: } ! 917: /* Matched a substring */ ! 918: *bo++ = mp[-1]; ! 919: bp = tp-1; ! 920: goto out; ! 921: } ! 922: while ((*mp++ & 0200) == 0); /* Skip rest of string */ ! 923: } ! 924: stop: *bo++ = *bp++; ! 925: out: continue; ! 926: } ! 927: if (bp < be) *bo++ = *bp++; ! 928: return(bo-buf); ! 929: } ! 930: ! 931: loadtbl() ! 932: /* Load compression table here and remote */ ! 933: /* Keywords: commands the-terminal:90 conversions compressed-output */ ! 934: { ! 935: extern int macptr; ! 936: char *nullp; ! 937: char c; ! 938: int nc; ! 939: FILE fbuf; ! 940: FILE *fp; ! 941: int i; ! 942: ! 943: if (DOCOMP==0) return; /* Can't do compression */ ! 944: nullp = &bbuf[0][macptr]; ! 945: pshchr(0); /* Store a null string for common cases */ ! 946: fp = xopen(&fbuf,expenv(getname("Compression file: ")),"r"); ! 947: if (fp == NULL) return; ! 948: DOCOMP=0; ! 949: mflush(stdout); /* Past the point of no return */ ! 950: i = 0; ! 951: while (getc(fp) != EOF) { ! 952: nc = 0; ! 953: while (getc(fp) == '\\') { ! 954: if (nc == 0) trtab[i] = &bbuf[0][macptr]; ! 955: nc++; ! 956: c = ((getc(fp)&07)<<6); ! 957: c += ((getc(fp)&07)<<3); ! 958: c += (getc(fp)&07); ! 959: pshchr(c); ! 960: } ! 961: c = getc(fp); /* Eat comma */ ! 962: c = getc(fp); /* Eat newline */ ! 963: if (nc) pshchr(0); /* Put in null */ ! 964: else trtab[i]=nullp; /* Null string */ ! 965: i++; ! 966: } ! 967: /* OK, host table loaded, now load the blit */ ! 968: mclose(fp); ! 969: fp = xopen(&fbuf,expenv(getname("Decompression file: ")),"r"); ! 970: if (fp == NULL) return; ! 971: putchar(CRELOAD); /* Tell blit it's time to reload */ ! 972: while ((c = getc(fp)) != EOF) putchar(c); ! 973: putchar(CRELOAD); /* Reload done (let's hope!) */ ! 974: mflush(stdout); /* Force output out before we turn on compression */ ! 975: DOCOMP=1; /* Here goes nothing */ ! 976: clear(); /* refresh screen */ ! 977: mclose(fp); ! 978: } ! 979: #endif ! 980: ungetch(c) ! 981: /* Keywords: the-terminal:90 standard-I/O parsing:10 reading:10 */ ! 982: { ! 983: if (incnt < 0) return; /* Can't unget an eof */ ! 984: ++incnt; ! 985: if (infrn==0) { ! 986: ++ungc; ! 987: *(--ttptr) = c; ! 988: ++ttcnt; ! 989: } else { ! 990: *(--inptr) = c; ! 991: } ! 992: } ! 993: ! 994: mflush(p) ! 995: ! 996: register FILE *p; ! 997: /* Keywords: writing the-terminal:10 standard-I/O PC-only:40 unix-interface:20 */ ! 998: { ! 999: register int bc; ! 1000: register int bo; ! 1001: ! 1002: if (p->_flags & _OUTPUT) { ! 1003: if (p->_flags & _ERROR) { ! 1004: p->_cnt = 0; ! 1005: return; ! 1006: } ! 1007: if (p == stdout) { ! 1008: if (no_io) { ! 1009: p->_cnt = 0; ! 1010: return; ! 1011: } ! 1012: ntwrite++; /* count for stats */ ! 1013: noutc += p->_cnt; ! 1014: #ifdef PC ! 1015: return; /* No output to stdout */ ! 1016: #endif PC ! 1017: #ifdef COMPRESS ! 1018: if (DOCOMP&& (p->_cnt > 10)) p->_cnt = translate(p->_buf,p->_cnt); ! 1019: coutc += p->_cnt; ! 1020: #endif ! 1021: #ifdef FLIM ! 1022: if (FLOWMIN && (p->_cnt > FLOWMIN) && (xon == 0)) { ! 1023: #ifdef CBRAKE ! 1024: quietout(); ! 1025: ioctl(1,TIOCSETC,&fcon); ! 1026: #else ! 1027: nttyjunk.c_iflag |= IXON+IXANY; ! 1028: ioctl(1,TCSETA,&nttyjunk); ! 1029: #endif ! 1030: xon = 1; ! 1031: } ! 1032: #endif ! 1033: } ! 1034: #ifdef PC ! 1035: if (p->_cnt) { ! 1036: if ((bc = write(p->_frn, p->_buf, p->_cnt)) < p->_cnt) { ! 1037: error (NORM,errno,"writing"); ! 1038: } ! 1039: } ! 1040: #else ! 1041: bo = 0; ! 1042: while((bc = write(p->_frn, p->_buf+bo, p->_cnt)) != p->_cnt) { ! 1043: if (bc >0) { ! 1044: p->_cnt -= bc; ! 1045: bo += bc; ! 1046: } ! 1047: if ((errno != EINTR)|| (++irupt > MAXIRUPT)) { ! 1048: if ((p == stdout) || (errno == EPIPE)) break; /* PUNT ! 1049: * errors on standard output */ ! 1050: p->_flags |= _ERROR; ! 1051: SAVEMD = 0; /* Give up on autosaving */ ! 1052: error (NORM,errno,"writing"); ! 1053: break; ! 1054: } ! 1055: } ! 1056: #endif PC ! 1057: p->_cnt = 0; ! 1058: } ! 1059: } ! 1060: ! 1061: #ifdef CBRAKE ! 1062: /* Wait for quiet output on berkely systems. This is very imperfect */ ! 1063: /* but it's all we can do. */ ! 1064: ! 1065: quietout() ! 1066: { ! 1067: int outqs; ! 1068: struct timeval outime; ! 1069: long timeout; ! 1070: ! 1071: ioctl(1,TIOCOUTQ,&outqs); ! 1072: while (outqs > 0) { ! 1073: ! 1074: timeout = outqs*1000 /ttywarp - 3000; /* Microseconds of timeout */ ! 1075: if (timeout > 0) { ! 1076: ! 1077: outime.tv_sec = timeout/1000000; ! 1078: outime.tv_usec = timeout%1000000; ! 1079: select(0,NULL,NULL,NULL,&outime); /* Wait for something to happen! */ ! 1080: } ! 1081: ioctl(1,TIOCOUTQ,&outqs); ! 1082: } ! 1083: } ! 1084: #endif ! 1085: filbuf(p) ! 1086: ! 1087: FILE *p; ! 1088: { ! 1089: /* Keywords: reading standard-I/O PC-only:40 unix-interface:10 */ ! 1090: #ifdef PC ! 1091: p->_cnt = read(p->_frn, p->_buf, BUFSIZ); ! 1092: #else ! 1093: mflush(stdout); /* Make output come out */ ! 1094: while ((p->_cnt = read(p->_frn, p->_buf, BUFSIZ)) < 0) { ! 1095: if ((errno != EINTR)|| (++irupt > MAXIRUPT)) break; ! 1096: } ! 1097: #endif PC ! 1098: p->_ptr = &(p->_buf[1]); ! 1099: if (p->_cnt > 0) { ! 1100: p->_cnt--; ! 1101: return(p->_buf[0]&0377); ! 1102: } ! 1103: else p->_cnt = 0; ! 1104: return(EOF); ! 1105: } ! 1106: ! 1107: /*VARARGS1*/ ! 1108: ! 1109: eprintf(string,a1) ! 1110: ! 1111: char *string; ! 1112: /* Keywords: formatting standard-I/O:50 terminal-parameters:50 */ ! 1113: { ! 1114: char pbuf[1024]; ! 1115: sxprintf(pbuf,string,&a1); ! 1116: puts(pbuf,stdout); ! 1117: } ! 1118: ! 1119: puts(cp,p) ! 1120: ! 1121: FILE *p; ! 1122: register char *cp; ! 1123: /* Keywords standard-I/O writing */ ! 1124: { ! 1125: while (*cp) { ! 1126: putc(*cp++,p); ! 1127: } ! 1128: } ! 1129: ! 1130: mclose(p) ! 1131: ! 1132: FILE *p; ! 1133: /* Keywords: standard-I/O closing files unix-interface */ ! 1134: { ! 1135: mflush(p); ! 1136: close(p->_frn); ! 1137: return(p->_flags & _ERROR); ! 1138: } ! 1139: ! 1140: FILE * ! 1141: ! 1142: xopen(p,np,mode) ! 1143: ! 1144: FILE *p; ! 1145: char *np; ! 1146: char *mode; ! 1147: /* Keywords: files opening standard-I/O unix-interface */ ! 1148: { ! 1149: int omode; ! 1150: ! 1151: omode = 0; ! 1152: if (*mode == 'b') { ! 1153: #ifdef PC ! 1154: omode = 4; ! 1155: #endif ! 1156: mode++; ! 1157: } ! 1158: switch(*mode) { ! 1159: case 'r': /* read file mode */ ! 1160: ! 1161: while ((p->_frn = open(np,omode+READM)) <0) { ! 1162: if ((errno != EINTR) && (errno != 23))return(NULL); ! 1163: } ! 1164: p->_flags = _INPUT; ! 1165: break; ! 1166: ! 1167: case 'a': ! 1168: while((p->_frn = open(np,omode+APPEM)) <0) { ! 1169: if ((errno != EINTR) && (errno != 23))return(NULL); ! 1170: } ! 1171: lseek (p->_frn,0L,2); /* at end */ ! 1172: p->_flags = _OUTPUT; ! 1173: break; ! 1174: case 'w': ! 1175: ! 1176: while((p->_frn = creat(np,omode+WRITEM)) <=0) { ! 1177: if ((errno != EINTR)&& (errno != 23)) return(NULL); ! 1178: } ! 1179: p->_flags = _OUTPUT; ! 1180: break; ! 1181: } ! 1182: p->_cnt = 0; ! 1183: p->_ptr = 0; ! 1184: return(p); ! 1185: } ! 1186: ! 1187: FILE * ! 1188: ! 1189: fdopen(p,frn,mode) ! 1190: ! 1191: FILE *p; ! 1192: int frn; ! 1193: char *mode; ! 1194: /* Keywords: standard-I/O opening unix-interface */ ! 1195: ! 1196: { ! 1197: p->_frn = frn; ! 1198: p->_cnt = 0; ! 1199: p->_ptr = &(p->_buf[0]); ! 1200: p->_flags = _DEAD; ! 1201: switch(*mode) { ! 1202: ! 1203: case 'r': ! 1204: p->_flags = _INPUT; ! 1205: break; ! 1206: case 'w': ! 1207: p->_flags = _OUTPUT; ! 1208: break; ! 1209: } ! 1210: return(p); ! 1211: } ! 1212: ! 1213: /* ascii to integer */ ! 1214: ! 1215: aint(string) ! 1216: ! 1217: register char *string; ! 1218: /* Keywords: standard-I/O:10 conversions string-handling:10 */ ! 1219: { ! 1220: register int result; ! 1221: register int base; ! 1222: ! 1223: base = ((*string == '0') ? 8 : 10); ! 1224: result = 0; ! 1225: while ((*string >= '0') && (*string <= '9')) { ! 1226: result = (result * base) + (*string++ - '0'); ! 1227: } ! 1228: if (*string == 0) return(result); ! 1229: else return(-1); ! 1230: } ! 1231: ! 1232: xclose(lowfile) ! 1233: ! 1234: register int lowfile; ! 1235: /* Keywords: unix-interface files closing */ ! 1236: { ! 1237: register int fileno; ! 1238: #ifndef PC ! 1239: for (fileno = lowfile; fileno < 20; fileno++) { ! 1240: close(fileno); ! 1241: } ! 1242: #endif PC ! 1243: } ! 1244: #ifdef PC ! 1245: /* All the nice? C routines you don't really need! */ ! 1246: signal() ! 1247: { ! 1248: return(0); ! 1249: } ! 1250: char * ! 1251: getenv() ! 1252: { ! 1253: return(0); ! 1254: } ! 1255: char cbuf[2]; /* Fake character buffer */ ! 1256: #else ! 1257: ! 1258: /* ctime stuff */ ! 1259: ! 1260: ! 1261: ! 1262: char cbuf[26]; ! 1263: char dmsize[12] = ! 1264: { ! 1265: 31, ! 1266: 28, ! 1267: 31, ! 1268: 30, ! 1269: 31, ! 1270: 30, ! 1271: 31, ! 1272: 31, ! 1273: 30, ! 1274: 31, ! 1275: 30, ! 1276: 31 ! 1277: }; ! 1278: ! 1279: long timez = 0; ! 1280: int daylite = 1; ! 1281: ! 1282: #define dysize(xyear) ((xyear&03) ? 365 : 366) ! 1283: ! 1284: ! 1285: struct tm *gmtime(); ! 1286: struct tm *localtime(); ! 1287: char *ctime(); ! 1288: char *asctime(); ! 1289: ! 1290: char * ! 1291: ctime(t) ! 1292: long *t; ! 1293: { ! 1294: /* Keywords: time-processing */ ! 1295: return(asctime(localtime(t))); ! 1296: } ! 1297: ! 1298: #ifdef ux3 ! 1299: void ! 1300: #endif ! 1301: tzset() ! 1302: { ! 1303: register char *p; ! 1304: register int n; ! 1305: int sign; ! 1306: /* Keywords: time-processing internal-initialization */ ! 1307: if ((p = getenv ("TZ")) && *p) { ! 1308: ! 1309: p += 3; ! 1310: if (sign = *p == '-') ! 1311: p++; ! 1312: n = 0; ! 1313: while (*p >= '0' && *p <= '9') ! 1314: n = (n * 10) + *p++ - '0'; ! 1315: if (sign) ! 1316: n = -n; ! 1317: timez = ((long) (n * 60)) * 60; ! 1318: if (*p) daylite = 1; ! 1319: else daylite = 0; ! 1320: } ! 1321: } ! 1322: ! 1323: struct tm * ! 1324: localtime(tim) ! 1325: long *tim; ! 1326: { ! 1327: /* Keywords: time-processing */ ! 1328: register int dayno; ! 1329: register struct tm *ct; ! 1330: register daylbegin, daylend; ! 1331: long copyt; ! 1332: ! 1333: if (timez == 0) tzset(); ! 1334: ! 1335: copyt = *tim - timez; ! 1336: ct = gmtime(©t); ! 1337: if (!daylite) return(ct); ! 1338: dayno = ct->tm_yday; ! 1339: daylbegin = 119; /* last Sun in Apr */ ! 1340: daylend = 303; /* Last Sun in Oct */ ! 1341: daylbegin = sunday(ct, daylbegin); ! 1342: daylend = sunday(ct, daylend); ! 1343: if ((dayno>daylbegin || (dayno==daylbegin && ct->tm_hour>=2)) && ! 1344: (dayno<daylend || (dayno==daylend && ct->tm_hour<1))) { ! 1345: copyt += 1*60*60; ! 1346: ct = gmtime(©t); ! 1347: } ! 1348: return(ct); ! 1349: } ! 1350: ! 1351: /* ! 1352: * The argument is a 0-origin day number. ! 1353: * The value is the day number of the first ! 1354: * Sunday on or after the day. ! 1355: */ ! 1356: sunday(t, d) ! 1357: register struct tm *t; ! 1358: register int d; ! 1359: { ! 1360: /* Keywords: time-processing */ ! 1361: if ((d >= 58) && ((t->tm_year & 03) == 0)) d+=1; /* leap year */ ! 1362: return(d - (d - t->tm_yday + t->tm_wday + 700) % 7); ! 1363: } ! 1364: ! 1365: struct tm * ! 1366: gmtime(tim) ! 1367: long *tim; ! 1368: { ! 1369: /* Keywords: time-processing */ ! 1370: register int d0, d1; ! 1371: int day; ! 1372: long hms; ! 1373: static struct tm xtime; ! 1374: ! 1375: /* ! 1376: * break initial number into days ! 1377: */ ! 1378: day = *tim / 86400; ! 1379: hms = *tim - (day*86400); ! 1380: ! 1381: /* ! 1382: * generate hours:minutes:seconds ! 1383: */ ! 1384: d1 = hms/60; ! 1385: xtime.tm_sec = hms - (((long)d1)*60L); ! 1386: xtime.tm_min = d1%60; ! 1387: d1 /= 60; ! 1388: xtime.tm_hour = d1; ! 1389: ! 1390: /* ! 1391: * day is the day number. ! 1392: * generate day of the week. ! 1393: * The addend is 4 mod 7 (1/1/1970 was Thursday) ! 1394: */ ! 1395: ! 1396: xtime.tm_wday = (day+4)%7; ! 1397: ! 1398: /* ! 1399: * year number ! 1400: */ ! 1401: for(d1=70; day >= dysize(d1); d1++) ! 1402: day -= dysize(d1); ! 1403: xtime.tm_year = d1; ! 1404: xtime.tm_yday = d0 = day; ! 1405: ! 1406: /* ! 1407: * generate month ! 1408: */ ! 1409: ! 1410: if ((d1&03) == 0)dmsize[1] = 29; ! 1411: else dmsize[1] = 28; ! 1412: for(d1=0; d0 >= dmsize[d1]; d1++) ! 1413: d0 -= dmsize[d1]; ! 1414: xtime.tm_mday= d0+1; ! 1415: xtime.tm_mon = d1; ! 1416: return(&xtime); ! 1417: } ! 1418: ! 1419: char * ! 1420: asctime(t) ! 1421: register struct tm *t; ! 1422: { ! 1423: /* Keywords: time-processing */ ! 1424: ! 1425: seprintf(cbuf,"%s %s %d %2d:%2d", ! 1426: &"Sun\0Mon\0Tue\0Wed\0Thu\0Fri\0Sat"[4*t->tm_wday], ! 1427: &"Jan\0Feb\0Mar\0Apr\0May\0Jun\0Jul\0Aug\0Sep\0Oct\0Nov\0Dec"[(t->tm_mon)*4], ! 1428: t->tm_mday, ! 1429: t->tm_hour, ! 1430: t->tm_min); ! 1431: return(cbuf); ! 1432: } ! 1433: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.