Files
oldlinux-files/study/linux-travel/MINIX-1.5/1.5/Source/commands/tail.c
2024-02-19 00:25:23 -05:00

146 lines
2.4 KiB
C

/* 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 */