Annotation of 43BSDReno/usr.bin/tail/tail.c, revision 1.1.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.3 (Berkeley) 11/13/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:                        if (write (1, bin, n) < 0)
                    236:                                exit(1);
                    237:        }
                    238: }

unix.superglobalmegacorp.com

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