Annotation of 43BSD/ucb/tail.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (c) 1980 Regents of the University of California.
        !             3:  * All rights reserved.  The Berkeley software License Agreement
        !             4:  * specifies the terms and conditions for redistribution.
        !             5:  */
        !             6: 
        !             7: #ifndef lint
        !             8: char copyright[] =
        !             9: "@(#) Copyright (c) 1980 Regents of the University of California.\n\
        !            10:  All rights reserved.\n";
        !            11: #endif not lint
        !            12: 
        !            13: #ifndef lint
        !            14: static char sccsid[] = "@(#)tail.c     5.2 (Berkeley) 1/10/86";
        !            15: #endif not lint
        !            16: 
        !            17: /* tail command 
        !            18:  *
        !            19:  *     tail where [file]
        !            20:  *     where is +/-n[type]
        !            21:  *     - means n lines before end
        !            22:  *     + means nth line from beginning
        !            23:  *     type 'b' means tail n blocks, not lines
        !            24:  *     type 'c' means tail n characters
        !            25:  *     Type 'r' means in lines in reverse order from end
        !            26:  *      (for -r, default is entire buffer )
        !            27:  *     option 'f' means loop endlessly trying to read more
        !            28:  *             characters after the end of file, on the  assumption
        !            29:  *             that the file is growing
        !            30: */
        !            31: 
        !            32: #include       <stdio.h>
        !            33: #include       <ctype.h>
        !            34: #include       <sys/types.h>
        !            35: #include       <sys/stat.h>
        !            36: #include       <sys/file.h>
        !            37: #include       <errno.h>
        !            38: 
        !            39: #define LBIN 32769
        !            40: #undef BUFSIZ
        !            41: #define        BUFSIZ  8192
        !            42: struct stat    statb;
        !            43: int    follow;
        !            44: int    piped;
        !            45: char bin[LBIN];
        !            46: int errno;
        !            47: 
        !            48: main(argc,argv)
        !            49: char **argv;
        !            50: {
        !            51:        long n,di;
        !            52:        register i,j,k;
        !            53:        char    *arg;
        !            54:        int partial,bylines,bkwds,fromend,lastnl;
        !            55:        char *p;
        !            56: 
        !            57:        arg = argv[1];
        !            58:        if(argc<=1 || *arg!='-'&&*arg!='+') {
        !            59:                arg = "-10l";
        !            60:                argc++;
        !            61:                argv--;
        !            62:        }
        !            63:        fromend = *arg=='-';
        !            64:        arg++;
        !            65:        if (isdigit(*arg)) {
        !            66:                n = 0;
        !            67:                while(isdigit(*arg))
        !            68:                        n = n*10 + *arg++ - '0';
        !            69:        } else
        !            70:                n = -1;
        !            71:        if(!fromend&&n>0)
        !            72:                n--;
        !            73:        if(argc>2) {
        !            74:                (void)close(0);
        !            75:                if(open(argv[2],0)!=0) {
        !            76:                        perror(argv[2]);
        !            77:                        exit(1);
        !            78:                }
        !            79:        }
        !            80:        (void)lseek(0,(off_t)0,L_INCR);
        !            81:        piped = errno==ESPIPE;
        !            82:        bylines = -1; bkwds = 0;
        !            83:        while(*arg)
        !            84:        switch(*arg++) {
        !            85: 
        !            86:        case 'b':
        !            87:                if (n == -1) n = 1;
        !            88:                n <<= 9;
        !            89:                if(bylines!=-1) goto errcom;
        !            90:                bylines=0;
        !            91:                break;
        !            92:        case 'c':
        !            93:                if(bylines!=-1) goto errcom;
        !            94:                bylines=0;
        !            95:                break;
        !            96:        case 'f':
        !            97:                follow = 1;
        !            98:                break;
        !            99:        case 'r':
        !           100:                if(n==-1) n = LBIN;
        !           101:                bkwds = 1; fromend = 1; bylines = 1;
        !           102:                break;
        !           103:        case 'l':
        !           104:                if(bylines!=-1) goto errcom;
        !           105:                bylines = 1;
        !           106:                break;
        !           107:        default:
        !           108:                goto errcom;
        !           109:        }
        !           110:        if (n==-1) n = 10;
        !           111:        if(bylines==-1) bylines = 1;
        !           112:        if(bkwds) follow=0;
        !           113:        if(fromend)
        !           114:                goto keep;
        !           115: 
        !           116:                        /*seek from beginning */
        !           117: 
        !           118:        if(bylines) {
        !           119:                j = 0;
        !           120:                while(n-->0) {
        !           121:                        do {
        !           122:                                if(j--<=0) {
        !           123:                                        p = bin;
        !           124:                                        j = read(0,p,BUFSIZ);
        !           125:                                        if(j--<=0)
        !           126:                                                fexit();
        !           127:                                }
        !           128:                        } while(*p++ != '\n');
        !           129:                }
        !           130:                (void)write(1,p,j);
        !           131:        } else  if(n>0) {
        !           132:                if(!piped)
        !           133:                        (void)fstat(0,&statb);
        !           134:                if(piped||(statb.st_mode&S_IFMT)==S_IFCHR)
        !           135:                        while(n>0) {
        !           136:                                i = n>BUFSIZ?BUFSIZ:n;
        !           137:                                i = read(0,bin,i);
        !           138:                                if(i<=0)
        !           139:                                        fexit();
        !           140:                                n -= i;
        !           141:                        }
        !           142:                else
        !           143:                        (void)lseek(0,(off_t)n,L_SET);
        !           144:        }
        !           145: copy:
        !           146:        while((i=read(0,bin,BUFSIZ))>0)
        !           147:                (void)write(1,bin,i);
        !           148:        fexit();
        !           149: 
        !           150:                        /*seek from end*/
        !           151: 
        !           152: keep:
        !           153:        if(n <= 0)
        !           154:                fexit();
        !           155:        if(!piped) {
        !           156:                (void)fstat(0,&statb);
        !           157:                /* If by lines, back up 1 buffer: else back up as needed */
        !           158:                di = bylines?LBIN-1:n;
        !           159:                if(statb.st_size > di)
        !           160:                        (void)lseek(0,(off_t)-di,L_XTND);
        !           161:                if(!bylines)
        !           162:                        goto copy;
        !           163:        }
        !           164:        partial = 1;
        !           165:        for(;;) {
        !           166:                i = 0;
        !           167:                do {
        !           168:                        j = read(0,&bin[i],LBIN-i);
        !           169:                        if(j<=0)
        !           170:                                goto brka;
        !           171:                        i += j;
        !           172:                } while(i<LBIN);
        !           173:                partial = 0;
        !           174:        }
        !           175: brka:
        !           176:        if(!bylines) {
        !           177:                k =
        !           178:                    n<=i ? i-n:
        !           179:                    partial ? 0:
        !           180:                    n>=LBIN ? i+1:
        !           181:                    i-n+LBIN;
        !           182:                k--;
        !           183:        } else {
        !           184:                if(bkwds && bin[i==0?LBIN-1:i-1]!='\n'){        /* force trailing newline */
        !           185:                        bin[i]='\n';
        !           186:                        if(++i>=LBIN) {i = 0; partial = 0;}
        !           187:                }
        !           188:                k = i;
        !           189:                j = 0;
        !           190:                do {
        !           191:                        lastnl = k;
        !           192:                        do {
        !           193:                                if(--k<0) {
        !           194:                                        if(partial) {
        !           195:                                                if(bkwds) 
        !           196:                                                    (void)write(1,bin,lastnl+1);
        !           197:                                                goto brkb;
        !           198:                                        }
        !           199:                                        k = LBIN -1;
        !           200:                                }
        !           201:                        } while(bin[k]!='\n'&&k!=i);
        !           202:                        if(bkwds && j>0){
        !           203:                                if(k<lastnl) (void)write(1,&bin[k+1],lastnl-k);
        !           204:                                else {
        !           205:                                        (void)write(1,&bin[k+1],LBIN-k-1);
        !           206:                                        (void)write(1,bin,lastnl+1);
        !           207:                                }
        !           208:                        }
        !           209:                } while(j++<n&&k!=i);
        !           210: brkb:
        !           211:                if(bkwds) exit(0);
        !           212:                if(k==i) do {
        !           213:                        if(++k>=LBIN)
        !           214:                                k = 0;
        !           215:                } while(bin[k]!='\n'&&k!=i);
        !           216:        }
        !           217:        if(k<i)
        !           218:                (void)write(1,&bin[k+1],i-k-1);
        !           219:        else {
        !           220:                (void)write(1,&bin[k+1],LBIN-k-1);
        !           221:                (void)write(1,bin,i);
        !           222:        }
        !           223:        fexit();
        !           224: errcom:
        !           225:        fprintf(stderr, "usage: tail [+_[n][lbc][rf]] [file]\n");
        !           226:        exit(2);
        !           227: }
        !           228: 
        !           229: fexit()
        !           230: {      register int n;
        !           231:        if (!follow || piped) exit(0);
        !           232:        for (;;)
        !           233:        {       sleep(1);
        !           234:                while ((n = read (0, bin, BUFSIZ)) > 0)
        !           235:                        (void)write (1, bin, n);
        !           236:        }
        !           237: }

unix.superglobalmegacorp.com

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