BSD 4 release
[unix-history] / usr / src / cmd / tail.c
index 9ef7b41..e298f84 100644 (file)
@@ -1,3 +1,4 @@
+static char *sccsid = "@(#)tail.c      4.1 (Berkeley) 10/6/80";
 /* tail command 
  *
  *     tail where [file]
 /* tail command 
  *
  *     tail where [file]
@@ -6,14 +7,23 @@
  *     + means nth line from beginning
  *     type 'b' means tail n blocks, not lines
  *     type 'c' means tail n characters
  *     + means nth line from beginning
  *     type 'b' means tail n blocks, not lines
  *     type 'c' means tail n characters
+ *     Type 'r' means in lines in reverse order from end
+ *      (for -r, default is entire buffer )
+ *     option 'f' means loop endlessly trying to read more
+ *             characters after the end of file, on the  assumption
+ *             that the file is growing
 */
 */
+
+#include       <stdio.h>
+#include       <ctype.h>
 #include       <sys/types.h>
 #include       <sys/stat.h>
 #include       <errno.h>
 #include       <sys/types.h>
 #include       <sys/stat.h>
 #include       <errno.h>
-#include       <pagsiz.h>
-#define        BUFSIZ  BSIZE
+
 #define LBIN 4097
 struct stat    statb;
 #define LBIN 4097
 struct stat    statb;
+int    follow;
+int    piped;
 char bin[LBIN];
 int errno;
 
 char bin[LBIN];
 int errno;
 
@@ -21,11 +31,11 @@ main(argc,argv)
 char **argv;
 {
        long n,di;
 char **argv;
 {
        long n,di;
-       int fromend;
        register i,j,k;
        register i,j,k;
+       char    *arg;
+       int partial,bylines,bkwds,fromend,lastnl;
        char *p;
        char *p;
-       int partial,piped,bylines;
-       char *arg;
+
        lseek(0,(long)0,1);
        piped = errno==ESPIPE;
        arg = argv[1];
        lseek(0,(long)0,1);
        piped = errno==ESPIPE;
        arg = argv[1];
@@ -36,36 +46,48 @@ char **argv;
        }
        fromend = *arg=='-';
        arg++;
        }
        fromend = *arg=='-';
        arg++;
-       if(!digit(*arg))
-               goto errcom;
        n = 0;
        n = 0;
-       while(digit(*arg))
+       while(isdigit(*arg))
                n = n*10 + *arg++ - '0';
        if(!fromend&&n>0)
                n--;
        if(argc>2) {
                close(0);
                if(open(argv[2],0)!=0) {
                n = n*10 + *arg++ - '0';
        if(!fromend&&n>0)
                n--;
        if(argc>2) {
                close(0);
                if(open(argv[2],0)!=0) {
-                       write(2,"tail: can't open ",17);
-                       write(2,argv[2],strlen(argv[2]));
-                       write(2,"\n",1);
+                       perror(argv[2]);
                        exit(1);
                }
        }
                        exit(1);
                }
        }
-       bylines = 0;
-       switch(*arg) {
+       bylines = -1; bkwds = 0;
+       while(*arg)
+       switch(*arg++) {
+
        case 'b':
                n <<= 9;
        case 'b':
                n <<= 9;
+               if(bylines!=-1) goto errcom;
+               bylines=0;
                break;
        case 'c':
                break;
        case 'c':
+               if(bylines!=-1) goto errcom;
+               bylines=0;
+               break;
+       case 'f':
+               follow = 1;
+               break;
+       case 'r':
+               if(n==0) n = LBIN;
+               bkwds = 1; fromend = 1; bylines = 1;
                break;
                break;
-       case '\0':
        case 'l':
        case 'l':
+               if(bylines!=-1) goto errcom;
                bylines = 1;
                break;
        default:
                goto errcom;
        }
                bylines = 1;
                break;
        default:
                goto errcom;
        }
+       if (n==0) n = 10;
+       if(bylines==-1) bylines = 1;
+       if(bkwds) follow=0;
        if(fromend)
                goto keep;
 
        if(fromend)
                goto keep;
 
@@ -78,7 +100,8 @@ char **argv;
                                if(j--<=0) {
                                        p = bin;
                                        j = read(0,p,BUFSIZ);
                                if(j--<=0) {
                                        p = bin;
                                        j = read(0,p,BUFSIZ);
-                                       if(j--<=0) exit(0);
+                                       if(j--<=0)
+                                               fexit();
                                }
                        } while(*p++ != '\n');
                }
                                }
                        } while(*p++ != '\n');
                }
@@ -90,25 +113,30 @@ char **argv;
                        while(n>0) {
                                i = n>BUFSIZ?BUFSIZ:n;
                                i = read(0,bin,i);
                        while(n>0) {
                                i = n>BUFSIZ?BUFSIZ:n;
                                i = read(0,bin,i);
-                               if(i<=0) exit(0);
+                               if(i<=0)
+                                       fexit();
                                n -= i;
                        }
                else
                        lseek(0,n,0);
        }
                                n -= i;
                        }
                else
                        lseek(0,n,0);
        }
+copy:
        while((i=read(0,bin,BUFSIZ))>0)
                write(1,bin,i);
        while((i=read(0,bin,BUFSIZ))>0)
                write(1,bin,i);
-       exit(0);
+       fexit();
 
                        /*seek from end*/
 
 keep:
 
                        /*seek from end*/
 
 keep:
-       if(n<=0) exit(0);
+       if(n <= 0)
+               fexit();
        if(!piped) {
                fstat(0,&statb);
                di = !bylines&&n<LBIN?n:LBIN-1;
                if(statb.st_size > di)
                        lseek(0,-di,2);
        if(!piped) {
                fstat(0,&statb);
                di = !bylines&&n<LBIN?n:LBIN-1;
                if(statb.st_size > di)
                        lseek(0,-di,2);
+               if(!bylines)
+                       goto copy;
        }
        partial = 1;
        for(;;) {
        }
        partial = 1;
        for(;;) {
@@ -130,18 +158,33 @@ brka:
                    i-n+LBIN;
                k--;
        } else {
                    i-n+LBIN;
                k--;
        } else {
+               if(bkwds && bin[i==0?LBIN-1:i-1]!='\n'){        /* force trailing newline */
+                       bin[i]='\n';
+                       if(++i>=LBIN) {i = 0; partial = 0;}
+               }
                k = i;
                j = 0;
                do {
                k = i;
                j = 0;
                do {
+                       lastnl = k;
                        do {
                                if(--k<0) {
                        do {
                                if(--k<0) {
-                                       if(partial)
+                                       if(partial) {
+                                               if(bkwds) write(1,bin,lastnl+1);
                                                goto brkb;
                                                goto brkb;
+                                       }
                                        k = LBIN -1;
                                }
                        } while(bin[k]!='\n'&&k!=i);
                                        k = LBIN -1;
                                }
                        } while(bin[k]!='\n'&&k!=i);
+                       if(bkwds && j>0){
+                               if(k<lastnl) write(1,&bin[k+1],lastnl-k);
+                               else {
+                                       write(1,&bin[k+1],LBIN-k-1);
+                                       write(1,bin,lastnl+1);
+                               }
+                       }
                } while(j++<n&&k!=i);
 brkb:
                } while(j++<n&&k!=i);
 brkb:
+               if(bkwds) exit(0);
                if(k==i) do {
                        if(++k>=LBIN)
                                k = 0;
                if(k==i) do {
                        if(++k>=LBIN)
                                k = 0;
@@ -153,13 +196,18 @@ brkb:
                write(1,&bin[k+1],LBIN-k-1);
                write(1,bin,i);
        }
                write(1,&bin[k+1],LBIN-k-1);
                write(1,bin,i);
        }
-       exit(0);
+       fexit();
 errcom:
 errcom:
-       write(2,"usage: tail +\b_n[lbc] [file]\n",29);
-       exit(1);
+       fprintf(stderr, "usage: tail [+\b_[n][lbc][rf]] [file]\n");
+       exit(2);
 }
 
 }
 
-digit(c)
-{
-       return(c>='0'&&c<='9');
+fexit()
+{      register int n;
+       if (!follow || piped) exit(0);
+       for (;;)
+       {       sleep(1);
+               while ((n = read (0, bin, BUFSIZ)) > 0)
+                       write (1, bin, n);
+       }
 }
 }