/*-------------------------------------------------* | tail.c - Unix-like utility. | | Syntax: tail [-N | +N] [file [file [ ... ] ] | | Prints on stdout the last N (default: N_DEFVAL) | | lines read from the given files, or from stdin. | | If +N is given, the first N lines of input will | | be skipped, and the remainder printed. | | v1.00 MLO 911224 | *-------------------------------------------------*/ #include #include #include #include "mlo.h" #define N_DEFVAL 10 #define LINE_LENGTH 128 Boolean skip = False; char *pBuffer, *pOver; void DoTheStuff(FILE *fp, int n); void Syntax(void); void main( int argc, char **argv ){ int nLines = N_DEFVAL; int bufferLength; while (--argc) { if ( ((*++argv)[0] == '-') ) { if (isdigit((*argv)[1])) { if ((nLines = atoi(*argv+1)) < 1) Syntax(); } else { Syntax(); } } else if ((*argv)[0] == '+') { skip = True; if (isdigit((*argv)[1])) { if ((nLines = atoi(*argv+1)) < 1) Syntax(); } else if ((*argv)[1] == '\0') { continue; } else { Syntax(); } } else if ((*argv)[0] == '?') { Syntax(); } else { break; } } if (skip) { if ((pBuffer = malloc(LINE_LENGTH)) == NULL) { puts("tail: no memory."); exit(SYS_ABORT_CODE); } } else { if ((pBuffer = malloc(bufferLength = (nLines+1)*LINE_LENGTH)) == NULL) { printf("tail: no memory for %d lines %d characters each.\n", nLines, LINE_LENGTH); exit(SYS_ABORT_CODE); } pOver = pBuffer + bufferLength; } if (argc) { while (argc--) { FILE *fp; if ((fp = fopen(*argv, "r")) == NULL) { printf("tail: couldn't open file \"%s\".\n", *argv); } else { DoTheStuff(fp, nLines); fclose(fp); } ++argv; } } else { DoTheStuff(stdin, nLines); } free(pBuffer); exit(SYS_NORMAL_CODE); } void DoTheStuff( FILE *fp, int n ){ if (skip) { while (n--) { if (fgets(pBuffer, LINE_LENGTH, fp) == NULL) { puts("END-OF-FILE"); return; } } while (fgets(pBuffer, LINE_LENGTH, fp)) fputs(pBuffer, stdout); } else { char *pDest = pBuffer; Boolean bufferFull = False; char *pc; while (fgets(pDest, LINE_LENGTH, fp)) { if ((pDest += LINE_LENGTH) == pOver) { pDest = pBuffer; bufferFull = True; } } if (bufferFull) { pc = pDest; do { if ((pc += LINE_LENGTH) == pOver) pc = pBuffer; fputs(pc, stdout); } while (pc != pDest); } else { puts("TOP-OF-FILE"); for (pc=pBuffer; pc