Annotation of researchv9/cmd/emacs/emacs_io.c, revision 1.1.1.1

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,&ltchars);
                    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,&ltchars);
                    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(&copyt);
                   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(&copyt);
                   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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.