/* tail - print the end of a file */ #include "stdio.h" #define TRUE 1 #define FALSE 0 #define BLANK ' ' #define TAB '\t' #define NEWL '\n' int lines, chars ; char buff[BUFSIZ]; main(argc, argv) int argc ; char *argv[] ; { char *s ; FILE *input , *fopen(); int count ; setbuf(stdout, buff); argc-- ; argv++ ; lines = TRUE ; chars = FALSE ; count = -10 ; if (argc == 0 ) { tail(stdin, count); done(0) ; } s = *argv ; if (*s == '-' || *s == '+' ) { s++ ; if (*s >= '0' && *s <= '9' ) { count = stoi(*argv); s++ ; while (*s >= '0' && *s <= '9' ) s++ ; } if (*s == 'c' ) { chars = TRUE ; lines = FALSE ; } else if (*s != 'l' && *s != NULL ) { fprintf(stderr, "tail: unknown option %c\n", *s); argc = 0 ; } argc-- ; argv++ ; } if (argc < 0 ) { fprintf(stderr, "Usage: tail [+/-[number][lc]] [files]\n"); done(1) ; } if (argc == 0 ) tail(stdin, count); else if ((input=fopen(*argv,"r")) == NULL ) { fprintf(stderr, "tail: can't open %s\n", *argv) ; done(1) ; } else { tail(input, count); fclose(input); } done(0) ; } /* stoi - convert string to integer */ stoi(s) char *s ; { int n, sign ; while (*s == BLANK || *s == NEWL || *s == TAB ) s++ ; sign = 1 ; if (*s == '+' ) s++ ; else if (*s == '-' ) { sign = -1 ; s++ ; } for(n=0 ; *s >= '0' && *s <= '9' ; s++ ) n = 10 * n + *s - '0' ; return(sign * n); } /* tail - print 'count' lines/chars */ #define INCR(p) if (p >= end) p=cbuf ; else p++ #define BUF_SIZE 4098 char cbuf[ BUF_SIZE ] ; tail(in, goal ) FILE *in ; int goal ; { int c, count ; char *start, *finish, *end ; count = 0 ; if (goal > 0 ) { /* skip */ if (lines ) /* lines */ while ((c=getc(in)) != EOF ) { if (c == NEWL ) count++ ; if (count >= goal ) break ; } else /* chars */ while (getc(in) != EOF ) { count++ ; if (count >= goal ) break ; } if (count >= goal ) while ((c=getc(in)) != EOF ) putc(c, stdout); } else { /* tail */ goal = -goal ; start = finish = cbuf ; end = &cbuf[ BUF_SIZE - 1 ] ; while ((c=getc(in)) != EOF ) { *finish = c ; INCR(finish); if (start == finish ) INCR(start); if (!lines || c == NEWL ) count++ ; if (count > goal ) { count = goal ; if (lines ) while (*start != NEWL ) INCR(start); INCR(start); } } /* end while */ while (start != finish ) { putc(*start, stdout); INCR(start); } } /* end else */ } /* end tail */ done(n) int n; { _cleanup(); /* flush stdio's internal buffers */ exit(n); }