Annotation of 3BSD/cmd/tail.c, revision 1.1.1.1

1.1       root        1: /* tail command 
                      2:  *
                      3:  *     tail where [file]
                      4:  *     where is +_n[type]
                      5:  *     - means n lines before end
                      6:  *     + means nth line from beginning
                      7:  *     type 'b' means tail n blocks, not lines
                      8:  *     type 'c' means tail n characters
                      9: */
                     10: #include       <sys/types.h>
                     11: #include       <sys/stat.h>
                     12: #include       <errno.h>
                     13: #include       <pagsiz.h>
                     14: #define        BUFSIZ  BSIZE
                     15: #define LBIN 4097
                     16: struct stat    statb;
                     17: char bin[LBIN];
                     18: int errno;
                     19: 
                     20: main(argc,argv)
                     21: char **argv;
                     22: {
                     23:        long n,di;
                     24:        int fromend;
                     25:        register i,j,k;
                     26:        char *p;
                     27:        int partial,piped,bylines;
                     28:        char *arg;
                     29:        lseek(0,(long)0,1);
                     30:        piped = errno==ESPIPE;
                     31:        arg = argv[1];
                     32:        if(argc<=1 || *arg!='-'&&*arg!='+') {
                     33:                arg = "-10l";
                     34:                argc++;
                     35:                argv--;
                     36:        }
                     37:        fromend = *arg=='-';
                     38:        arg++;
                     39:        if(!digit(*arg))
                     40:                goto errcom;
                     41:        n = 0;
                     42:        while(digit(*arg))
                     43:                n = n*10 + *arg++ - '0';
                     44:        if(!fromend&&n>0)
                     45:                n--;
                     46:        if(argc>2) {
                     47:                close(0);
                     48:                if(open(argv[2],0)!=0) {
                     49:                        write(2,"tail: can't open ",17);
                     50:                        write(2,argv[2],strlen(argv[2]));
                     51:                        write(2,"\n",1);
                     52:                        exit(1);
                     53:                }
                     54:        }
                     55:        bylines = 0;
                     56:        switch(*arg) {
                     57:        case 'b':
                     58:                n <<= 9;
                     59:                break;
                     60:        case 'c':
                     61:                break;
                     62:        case '\0':
                     63:        case 'l':
                     64:                bylines = 1;
                     65:                break;
                     66:        default:
                     67:                goto errcom;
                     68:        }
                     69:        if(fromend)
                     70:                goto keep;
                     71: 
                     72:                        /*seek from beginning */
                     73: 
                     74:        if(bylines) {
                     75:                j = 0;
                     76:                while(n-->0) {
                     77:                        do {
                     78:                                if(j--<=0) {
                     79:                                        p = bin;
                     80:                                        j = read(0,p,BUFSIZ);
                     81:                                        if(j--<=0) exit(0);
                     82:                                }
                     83:                        } while(*p++ != '\n');
                     84:                }
                     85:                write(1,p,j);
                     86:        } else  if(n>0) {
                     87:                if(!piped)
                     88:                        fstat(0,&statb);
                     89:                if(piped||(statb.st_mode&S_IFMT)==S_IFCHR)
                     90:                        while(n>0) {
                     91:                                i = n>BUFSIZ?BUFSIZ:n;
                     92:                                i = read(0,bin,i);
                     93:                                if(i<=0) exit(0);
                     94:                                n -= i;
                     95:                        }
                     96:                else
                     97:                        lseek(0,n,0);
                     98:        }
                     99:        while((i=read(0,bin,BUFSIZ))>0)
                    100:                write(1,bin,i);
                    101:        exit(0);
                    102: 
                    103:                        /*seek from end*/
                    104: 
                    105: keep:
                    106:        if(n<=0) exit(0);
                    107:        if(!piped) {
                    108:                fstat(0,&statb);
                    109:                di = !bylines&&n<LBIN?n:LBIN-1;
                    110:                if(statb.st_size > di)
                    111:                        lseek(0,-di,2);
                    112:        }
                    113:        partial = 1;
                    114:        for(;;) {
                    115:                i = 0;
                    116:                do {
                    117:                        j = read(0,&bin[i],LBIN-i);
                    118:                        if(j<=0)
                    119:                                goto brka;
                    120:                        i += j;
                    121:                } while(i<LBIN);
                    122:                partial = 0;
                    123:        }
                    124: brka:
                    125:        if(!bylines) {
                    126:                k =
                    127:                    n<=i ? i-n:
                    128:                    partial ? 0:
                    129:                    n>=LBIN ? i+1:
                    130:                    i-n+LBIN;
                    131:                k--;
                    132:        } else {
                    133:                k = i;
                    134:                j = 0;
                    135:                do {
                    136:                        do {
                    137:                                if(--k<0) {
                    138:                                        if(partial)
                    139:                                                goto brkb;
                    140:                                        k = LBIN -1;
                    141:                                }
                    142:                        } while(bin[k]!='\n'&&k!=i);
                    143:                } while(j++<n&&k!=i);
                    144: brkb:
                    145:                if(k==i) do {
                    146:                        if(++k>=LBIN)
                    147:                                k = 0;
                    148:                } while(bin[k]!='\n'&&k!=i);
                    149:        }
                    150:        if(k<i)
                    151:                write(1,&bin[k+1],i-k-1);
                    152:        else {
                    153:                write(1,&bin[k+1],LBIN-k-1);
                    154:                write(1,bin,i);
                    155:        }
                    156:        exit(0);
                    157: errcom:
                    158:        write(2,"usage: tail +_n[lbc] [file]\n",29);
                    159:        exit(1);
                    160: }
                    161: 
                    162: digit(c)
                    163: {
                    164:        return(c>='0'&&c<='9');
                    165: }

unix.superglobalmegacorp.com

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