/* tail.c - print the last few lines in a file. If count is specified, * * that many lines are printed instead of the default value of * * ten lines. If no files are specified, head reads standard * * input. * * * * tail [-] [ ...] * * * * tail (C) 1988 by Gary L. Brant * * * * :ts=8 */ #include #define MAXLINE 1000 void fputs (); int default_lines = 10; /* default number of lines to list */ int headlin = 0; typedef struct list { struct list *nxt; char line[MAXLINE]; }; main (argc, argv) /* list 1st n lines of a file */ int argc; char *argv[]; { FILE *input, *fopen (); void fclose (); int i = 0, rval; long maxlines, convert (); char ch; maxlines = default_lines; while (++i < argc) { if (argv [i][0] == '-') { /* process line count argument */ maxlines = convert (argv[i]); default_lines = maxlines; } else if (argv [i][0] == '+') { maxlines = -convert (argv[i]); default_lines = maxlines; } else { ++headlin; if ((input = fopen (argv[i], "r")) == NULL) { fputs ("tail: can't open ", stderr); fputs (argv[i], stderr); putc ('\n', stderr); break; } else { rval = list (input, argv[i], maxlines); fclose (input); if (rval) quit (rval); } } } if (!headlin) quit (list (stdin, "", maxlines)); quit (0); } list (fp, fn, maxlines) /* list tail of a file */ FILE *fp; char *fn; register long maxlines; { int n; char line[MAXLINE]; char *c, *fgets (), *alloc (); if (maxlines < 0) { /* +n, head relative list */ while (maxlines++ < 0 && (c = fgets (line, MAXLINE, fp)) != NULL); if (c != NULL) { heading (fn); while ((fgets (line, MAXLINE, fp)) != NULL) fputs (line, stdout); } } else { /* -n, tail relative list */ register struct list *head = NULL, *curr, *next, *p; register long nlin = 0; while ((fgets (line, MAXLINE, fp)) != NULL) { n = strlen (line); if (++nlin > maxlines) { /* de-link 1st line */ p = head; head = head->nxt; freeit (p); } if ((next = (struct list *) alloc (n+5)) == NULL) { fputs ("not enough memory for list\n", stderr); while (head != NULL) { p = head; head = head->nxt; freeit (p); } return (20); } if (head == NULL) head = next; else curr->nxt = next; curr = next; strcpy (next->line, line); next->nxt = NULL; } heading (fn); /* now print the lines in the list, deallocating as we go */ while (head != NULL) { fputs (head->line, stdout); p = head; head = head->nxt; freeit (p); } } return (0); } heading (filename) char *filename; { if (headlin) { fputs ("==> ", stdout); fputs (filename, stdout); fputs (" <==\n", stdout); } } long convert (string) char string[]; { register long maxlines = 0; register int j; register char ch; for (j = 1; (ch = string[j]) != '\0'; j++) if (ch >= '0' && ch <= '9') { maxlines *= 10; maxlines += ch - '0'; } else { maxlines = default_lines; break; } return (maxlines); } void _wb_parse () { }