Annotation of 3BSD/cmd/tail.c, revision 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.