/* tail.c - prints last lines of file					*/
/*	    Usage:  tail [-<number> -n] file				*/
/*	    Options: -<number>: print last <number> lines (default=10)	*/
/*		     -n:	print lines numbered 			*/
/*	    Note: file can be an ambiguous file name			*/

/* 16 Dec 1987	Andreas Herrmann					*/


#include "stdio.h"

#define TRUE	1
#define FALSE	0
#define MAXNR	128
#define MAXLINE 256
#define	NR_DEF	10


main(argc,argv)
int argc;
char *argv[];
{
	FILE	*fp;		/* file pointer				*/
	char	*fname;		/* file name				*/
	char	*s;		/* string pointer			*/
	char	*line[MAXNR];	/* lines buffer				*/
	int	ind;		/* line index				*/
	int	nr = NR_DEF;	/* number of lines to print		*/
	int	linenr;		/* total number of lines in file	*/
	int	ambig = FALSE;	/* TRUE iff file name is ambiguous	*/
	int	number = FALSE;	/* TRUE iff numbered line output	*/
	int	i;		/* index				*/

	char	*alloc();	/* allocates memory			*/
	char	*getffn(), *getnfn();	/* get first, next file name	*/


	while (--argc > 0 && (*++argv)[0] == '-')
	    for (s=argv[0]+1; *s != '\0'; s++)
		switch (*s) {
		case 'N':	
			number=TRUE;
			break;
		default:
		    if (isdigit(*s)) {
			nr = atoi(s);
			if (nr<=0) {
				printf("No lines???\n");
				exit(0);
			}
			if (nr>MAXNR) {
			    printf("Too many lines. Maximum is %d\n", MAXNR);
			    exit(0);
			}
			while (*++s);
			s--;
		    } else {
			printf("Illegal option %c\n", *s);
			argc = 0;
		    }
		    break;
		}
	if (argc != 1) {
		printf("Usage: tail [-<number> -n] file\n");
		exit(1);
	}

	fname = *(argv);
	for (i=0; i<nr; i++) {
		if ((line[i] = alloc(MAXLINE)) == NULL) {
			nr=i-1;
			printf("Only memory for %d line buffers\n",nr);
			break;
		}
	}
	if ((ambig = index(fname,'*') || index(fname,'?'))) {
		fname = getffn(fname);
	}
	do {
		if ((fp = fopen(fname, "r")) == NULL)
			printf("Can't open file %s\n", fname);
		else {
			if (ambig) printf("\n***  %s  ***\n",fname);
			linenr = ind = 0;
			while (getline(line[ind],MAXLINE,fp) > 0) {
				if (++ind>=nr) ind=0;
				linenr++;
			}
			if (linenr<nr) {
 				i=0; 
				linenr=1;
			} else {
				i=ind;
				linenr -= (nr-1);
			}
			do {
				if (number)
					printf("%d: %s", linenr, line[i]); 
				else
					printf("%s", line[i]);
				if (++i>=nr) i=0;
				linenr++;
			} while (i!=ind);
			fclose(fp);
		}
	} while ( ambig && (fname=getnfn()) != NULL);
}


int getline(s, lim, fp)		/* get line from file to s, return length */
char *s;
int lim;
FILE *fp;
{
	int c, i;

	for (i=0; i<lim-1 && (c=getc(fp))!=EOF && c!='\n'; ++i)
		*s++ = c;
	if (c == '\n') {
		*s++ = c;
		++i;
	}
	if (i>0) *s = '\0';
	return(i);
}
