From 7e0f021a9aec35fd8e6725e87e3313b101d26f5e Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Sun, 27 Jan 2008 11:37:44 +0100 Subject: Initial import (2.0.2-6) --- reference/C/CONTRIB/SNIP/tail.c | 181 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 181 insertions(+) create mode 100755 reference/C/CONTRIB/SNIP/tail.c (limited to 'reference/C/CONTRIB/SNIP/tail.c') diff --git a/reference/C/CONTRIB/SNIP/tail.c b/reference/C/CONTRIB/SNIP/tail.c new file mode 100755 index 0000000..a932a58 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/tail.c @@ -0,0 +1,181 @@ +/* +** TAIL.C +** ---------------------------------------------------------------------- +** Display the last n lines of a file (20 lines by default). +** +** Revision history +** ================ +** Modified 19930604 by Ruurd Pels: +** - Increased default line numbers from 5 to 20 +** - Made ANSI C conformant (I hope) +** - Added '-' support for commandline +** - Outputs header to stderr instead of stdout to leave it out when +** redirecting files +** - Fixed \r\r\n bug for MSDOS machines +** +** Modified 19861005 by Joe Huffman: +** - Utilize prototyping, fixed a bug, added (a few) comments and help. +** +** Written 19860204 by Joe Huffman. +** +** Not copyrighted. +*/ + +#include +#include + +char head1[] = {"\n------- \""}; +char head2[] = {" -------\n"}; +FILE * fp; +int filenum; +int cc; +unsigned int linenum = 20; +unsigned int indx; +long int * tail; + +/* +** Get the number of lines to display at the "tail" of each file from +** the command line. +*/ + +void getlinenum(int n, char * str[]) +{ + for (--n; n; --n) + { + ++str; + if ((**str == '/') || (**str == '-')) + { + linenum = atoi(*(str) + 1); + if (linenum <= 0) + linenum = 20; + } + } + + /* Because we save a pointer to the end of the PREVIOUS line */ + linenum++; +} + +/* +** Set the file pointer "fp" to "linenum - 1" lines before the end of +** the file. +*/ + +void gettail(void) +{ + unsigned char outstr[15]; + unsigned long int currline = 0L; + + tail = (long int *)malloc(sizeof(*tail) * linenum); + if (!tail) + { + fputs("Insufficient memory.", stderr); + exit(1); + } + tail[0] = ftell(fp); + indx = 0; + + for (cc = getc(fp); cc != EOF; cc = getc(fp)) + { + if (cc == '\r') + { + ++currline; + cc = getc(fp); + if (cc != '\n') + ungetc(cc, fp); + ++indx; + indx %= linenum; + tail[indx] = ftell(fp); + } + else + { + if (cc == '\n') + { + ++currline; + cc = getc(fp); + if (cc != '\r') + ungetc(cc, fp); + ++indx; + indx %= linenum; + tail[indx] = ftell(fp); + } + } + } + fputs("\" ", stderr); + ltoa(currline, outstr, 10); + fputs(outstr, stderr); + fputs(" lines", stderr); + if (currline >= linenum - 1) + { + indx++; + indx %= linenum; + } + else indx = 0; + + if (fseek(fp, tail[indx], 0) == -1) + { + fputs("\nFile seek error.", stderr); + exit(1); + } + free(tail); +} + +/* +** Tell the user what the program is and how to use it. +*/ + +void help(void) +{ + char *ptr; + static char help_str[] = "Usage:\n\nTAIL [filename] " + "[/n]\n\n - The name of a valid file, wildcards " + "accepted.\nn - Number of lines to print out, 20 " + "by default."; + + for (ptr = &help_str[0]; *ptr; ptr++) + fputc(*ptr, stdout); +} + +int main(int argc, char **argv) +{ + if (argc <= 1) + { + help(); + exit(1); + } + + getlinenum(argc, argv); + + for (filenum = 1; filenum < argc; ++filenum) + { + if (*argv[filenum] == '/') + continue; + fp = fopen(argv[filenum], "rb"); + if (!fp) + { + fputs(head1, stderr); + fputs(argv[filenum], stderr); + fputs("\" not found.", stderr); + fputs(head2, stderr); + } + else + { + fputs(head1, stderr); + fputs(argv[filenum], stderr); + gettail(); + fputs(head2, stderr); + for (cc = getc(fp); cc != EOF; cc = getc(fp)) + { +#ifdef __MSDOS__ + if (cc != '\r') + { + fputc(cc, stdout); + } +#else + fputc(cc, stdout); +#endif + } + fclose(fp); + } + } + return EXIT_SUCCESS; +} -- cgit v1.2.3-54-g00ecf