# 2.11BSD#431 - /usr/src/ucb/tail.c

##### Functions

    fexit             X
    main              X

##### Variables

    bin               X
    copyright         X
    errno             X
    follow            X
    piped             X
    statb             X

##### Macros

    BUFSIZ            X
    LBIN              X

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

#### Defined functions

fexit defined in line 231; used 5 times

- in line 128, 141, 150, 156, 225

main defined in line 50; never used

#### Defined variables

bin defined in line 47; used 18 times

- in line 125, 139, 148-149(2), 170, 186-187(2), 198-208(5), 217-223(4), 236-237(2)

copyright defined in line 8; never used
errno defined in line 48; used 1 times

- in line 83

follow defined in line 45; used 3 times

- in line 99, 114, 233

piped defined in line 46; used 5 times

- in line 83, 134-136(2), 157, 233

sccsid defined in line 12; never used
statb defined in line 44; used 4 times

- in line 135-136(2), 158-161(2)

#### Defined macros

BUFSIZ defined in line 43; used 6 times

- in line 42, 126, 138(2), 148, 236

LBIN defined in line 40; used 13 times

- in line 47, 102, 160, 170-174(2), 182-188(4), 201, 207, 215, 222

Last modified: 1994-01-11 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 747 |