|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.