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

Defined functions

fexit defined in line 208; used 5 times
main defined in line 30; never used

Defined variables

bin defined in line 27; used 18 times
errno defined in line 28; used 1 times
  • in line 63
follow defined in line 25; used 3 times
piped defined in line 26; used 5 times
sccsid defined in line 1; never used
statb defined in line 24; used 4 times

Defined macros

LBIN defined in line 23; used 14 times
Last modified: 1983-09-07
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 872
Valid CSS Valid XHTML 1.0 Strict