Minix1.5/commands/tail.c

Compare this file to the similar file:
Show the results in this format:

/* 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);
	exit(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 != '\0') {
		fprintf(stderr, "tail: unknown option %c\n", *s);
		argc = 0;
	}
	argc--;
	argv++;
  }
  if (argc < 0) {
	fprintf(stderr, "Usage: tail [+/-[number][lc]] [files]\n");
	exit(1);
  }
  if (argc == 0) tail(stdin, count);

  else if ((input = fopen(*argv, "r")) == NULL) {
	fprintf(stderr, "tail: can't open %s\n", *argv);
	exit(1);
  } else {
	tail(input, count);
	fclose(input);
  }

  exit(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 */
	count++;		/* start counting at 1 */
	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 */