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:  *	Type 'r' means in lines in reverse order from end
  10:  *	 (for -r, default is entire buffer )
  11: */
  12: #include    <sys/types.h>
  13: #include    <sys/stat.h>
  14: #include    <errno.h>
  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:     register i,j,k;
  25:     char *p;
  26:     int partial,piped,bylines,bkwds,fromend,lastnl;
  27:     char *arg;
  28:     lseek(0,(long)0,1);
  29:     piped = errno==ESPIPE;
  30:     arg = argv[1];
  31:     if(argc<=1 || *arg!='-'&&*arg!='+') {
  32:         arg = "-10l";
  33:         argc++;
  34:         argv--;
  35:     }
  36:     fromend = *arg=='-';
  37:     arg++;
  38:     n = 0;
  39:     while(digit(*arg))
  40:         n = n*10 + *arg++ - '0';
  41:     if(!fromend&&n>0)
  42:         n--;
  43:     if(argc>2) {
  44:         close(0);
  45:         if(open(argv[2],0)!=0) {
  46:             write(2,"tail: can't open ",17);
  47:             write(2,argv[2],strlen(argv[2]));
  48:             write(2,"\n",1);
  49:             exit(1);
  50:         }
  51:     }
  52:     bylines = 0; bkwds = 0;
  53:     switch(*arg) {
  54:     case 'b':
  55:         n <<= 9;
  56:         break;
  57:     case 'c':
  58:         break;
  59:     case 'r':
  60:         if(n==0) n = LBIN;
  61:         bkwds = 1; fromend = 1; bylines = 1;
  62:         break;
  63:     case '\0':
  64:     case 'l':
  65:         bylines = 1;
  66:         break;
  67:     default:
  68:         goto errcom;
  69:     }
  70:     if(fromend)
  71:         goto keep;
  72: 
  73:             /*seek from beginning */
  74: 
  75:     if(bylines) {
  76:         j = 0;
  77:         while(n-->0) {
  78:             do {
  79:                 if(j--<=0) {
  80:                     p = bin;
  81:                     j = read(0,p,512);
  82:                     if(j--<=0) exit(0);
  83:                 }
  84:             } while(*p++ != '\n');
  85:         }
  86:         write(1,p,j);
  87:     } else  if(n>0) {
  88:         if(!piped)
  89:             fstat(0,&statb);
  90:         if(piped||(statb.st_mode&S_IFMT)==S_IFCHR)
  91:             while(n>0) {
  92:                 i = n>512?512:n;
  93:                 i = read(0,bin,i);
  94:                 if(i<=0) exit(0);
  95:                 n -= i;
  96:             }
  97:         else
  98:             lseek(0,n,0);
  99:     }
 100: copy:
 101:     while((i=read(0,bin,512))>0)
 102:         write(1,bin,i);
 103:     exit(0);
 104: 
 105:             /*seek from end*/
 106: 
 107: keep:
 108:     if(n<=0) exit(0);
 109:     if(!piped) {
 110:         fstat(0,&statb);
 111:         di = !bylines? n: LBIN-1;
 112:         if(statb.st_size > di)
 113:             lseek(0,-di,2);
 114:         if(!bylines)
 115:             goto copy;
 116:     }
 117:     partial = 1;
 118:     for(;;) {
 119:         i = 0;
 120:         do {
 121:             j = read(0,&bin[i],LBIN-i);
 122:             if(j<=0)
 123:                 goto brka;
 124:             i += j;
 125:         } while(i<LBIN);
 126:         partial = 0;
 127:     }
 128: brka:
 129:     if(!bylines) {
 130:         k =
 131:             n<=i ? i-n:
 132:             partial ? 0:
 133:             n>=LBIN ? i+1:
 134:             i-n+LBIN;
 135:         k--;
 136:     } else {
 137:         if(bkwds && bin[i==0?LBIN-1:i-1]!='\n'){    /* force trailing newline */
 138:             bin[i]='\n';
 139:             if(++i>=LBIN) {i = 0; partial = 0;}
 140:         }
 141:         k = i;
 142:         j = 0;
 143:         do {
 144:             lastnl = k;
 145:             do {
 146:                 if(--k<0) {
 147:                     if(partial) {
 148:                         if(bkwds) write(1,bin,lastnl+1);
 149:                         goto brkb;
 150:                     }
 151:                     k = LBIN -1;
 152:                 }
 153:             } while(bin[k]!='\n'&&k!=i);
 154:             if(bkwds && j>0){
 155:                 if(k<lastnl) write(1,&bin[k+1],lastnl-k);
 156:                 else {
 157:                     write(1,&bin[k+1],LBIN-k-1);
 158:                     write(1,bin,lastnl+1);
 159:                 }
 160:             }
 161:         } while(j++<n&&k!=i);
 162: brkb:
 163:         if(bkwds) exit(0);
 164:         if(k==i) do {
 165:             if(++k>=LBIN)
 166:                 k = 0;
 167:         } while(bin[k]!='\n'&&k!=i);
 168:     }
 169:     if(k<i)
 170:         write(1,&bin[k+1],i-k-1);
 171:     else {
 172:         write(1,&bin[k+1],LBIN-k-1);
 173:         write(1,bin,i);
 174:     }
 175:     exit(0);
 176: errcom:
 177:     write(2,"usage: tail +_n[lbcr] [file]\n",30);
 178:     exit(1);
 179: }
 180: 
 181: digit(c)
 182: {
 183:     return(c>='0'&&c<='9');
 184: }

Defined functions

digit defined in line 181; used 1 times
  • in line 39
main defined in line 20; never used

Defined variables

bin defined in line 17; used 16 times
errno defined in line 18; used 1 times
  • in line 29
statb defined in line 16; used 4 times

Defined macros

LBIN defined in line 15; used 13 times
Last modified: 1979-05-14
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 778
Valid CSS Valid XHTML 1.0 Strict