summaryrefslogtreecommitdiff
path: root/src/commands/tail.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/commands/tail.c')
-rw-r--r--src/commands/tail.c238
1 files changed, 0 insertions, 238 deletions
diff --git a/src/commands/tail.c b/src/commands/tail.c
deleted file mode 100644
index 07b3d2b..0000000
--- a/src/commands/tail.c
+++ /dev/null
@@ -1,238 +0,0 @@
-#include "../command.h"
-
-static struct {
- bool lines;
- int count;
- bool print_headers;
- bool dont_print_headers;
- bool print_as_grow;
- int grow_wait;
-} flags;
-
-static size_t tail_file_lines(FILE* file, unsigned int count, size_t skip) {
-
- char** ring;
- int* ring_len;
- int index, read;
- unsigned int size, i;
- size_t len;
- char* line;
-
- ring = malloc(sizeof(char*) * count);
- memset(ring, 0, sizeof(char*) * count);
-
- ring_len = malloc(sizeof(int) * count);
-
- index = 0;
- size = 0;
-
- fseek(file, skip, SEEK_SET);
-
- len = skip;
- line = NULL;
-
- while ((read = getline(&line, &len, file)) != -1) {
-
- if (ring[index] != NULL) free(ring[index]);
- ring[index] = line;
- ring_len[index] = read;
-
- index++;
- index %= count;
- if (size < count) size++;
-
- line = NULL;
- }
-
- index += count - size;
- index %= count;
-
- for (i = 0; i < size; i++) {
- fwrite(ring[index], ring_len[index], 1, stdout);
- free(ring[index]);
- index += 1;
- index %= count;
- }
-
- free(line);
- fclose(file);
- free(ring);
- free(ring_len);
-
- return len;
-}
-
-static size_t tail_file_chars(FILE* file, unsigned int count, size_t skip) {
-
- char* ring;
- int index;
- unsigned int size, i;
- int read, c;
-
- ring = malloc(sizeof(char) * count);
- memset(ring, 0, count);
-
- index = 0;
- size = 0;
-
- fseek(file, skip, SEEK_SET);
- read = skip;
-
- while((c = getc(file)) != EOF) {
- ring[index] = c;
- index++;
- read++;
- index %= count;
- if (size < count) size++;
- }
-
- index += count - size;
- index %= count;
-
- for (i = 0; i < size; i++) {
- putchar(ring[index]);
- index += 1;
- index %= count;
- }
-
- fclose(file);
-
- return read;
-}
-
-static void help(void) {
- printf("Usage: tail [OPTIONS] [FILE]...\n\n");
- printf("Print last 10 lines of FILEs (or stdin) to.\n");
- printf("With more than one FILE, precede each with a filename header.\n\n");
- printf("\t-c [+]N[bkm]\tPrint last N bytes\n");
- printf("\t-n N[bkm]\tPrint last N lines\n");
- printf("\t\t\t(b:*512 k:*1024 m:*1024^2)\n");
- printf("\t-q\t\tNever print headers\n");
- printf("\t-v\t\tAlways print headers\n");
- printf("\t-f\t\tPrint data as file grows\n");
- printf("\t-s SECONDS\tWait SECONDS between reads with -f\n");
- exit(EXIT_SUCCESS);
-}
-
-static void print_header(char* path, bool many) {
- if (flags.dont_print_headers) return;
- if (!many && !flags.print_headers) return;
- if (streql("-", path)) {
- printf("\n==> standard input <==\n");
- } else {
- printf("\n=>> %s <==\n", path);
- }
-}
-
-static void tail_file(char* path, bool many) {
-
- FILE* file;
- size_t skip;
-
- file = get_file(path, "r");
- print_header(path, many);
-
- skip = 0;
- while (true) {
- if (flags.lines) {
- skip = tail_file_lines(file, flags.count, skip);
- } else {
- skip = tail_file_chars(file, flags.count, skip);
- }
- if (!flags.print_as_grow) break;
- sleep(flags.grow_wait);
- get_file(path, "r");
- };
-}
-
-static int short_arg(char c, char* next) {
- switch (c) {
- case 'c': {
- long int bkm;
-
- flags.lines = false;
-
- check_arg(next);
- bkm = get_blkm(next);
-
- if (bkm < 1) {
- error("bkm cannot be less than 1");
- }
-
- flags.count = bkm;
- return ARG_USED;
- }
- case 'n': {
- long int bkm;
-
- flags.lines = true;
-
- check_arg(next);
- bkm = get_blkm(next);
-
- if (bkm < 1) {
- error("bkm cannot be less than 1");
- }
-
- flags.count = bkm;
- return ARG_USED;
- }
- case 'q':
- flags.dont_print_headers = true;
- break;
- case 'v':
- flags.print_headers = true;
- break;
- case 'f':
- flags.print_as_grow = true;
- break;
- case 's': {
- long int sec;
-
- check_arg(next);
- sec = get_number(next);
-
- if (sec < 1) {
- error("wait seconds cannot be less than 1");
- }
-
- flags.grow_wait = sec;
- return ARG_USED;
- }
- default:
- return ARG_INVALID;
- }
- return ARG_UNUSED;
-}
-
-COMMAND(tail) {
-
- int start, count, i;
-
- flags.count = 10;
- flags.dont_print_headers = false;
- flags.print_headers = false;
- flags.lines = true;
- flags.print_as_grow = false;
- flags.grow_wait = 10;
-
- start = parse_args(argc, argv, help, short_arg, NULL);
-
- count = argc - start;
-
- if (count < 1) {
- tail_file_lines(stdin, 10, 0);
- return EXIT_SUCCESS;
- }
-
- if (count == 1) {
- tail_file(argv[start], false);
- return EXIT_SUCCESS;
- }
-
- for (i = 0; i < count; i++) {
- tail_file(argv[start + i], true);
- }
-
- return EXIT_SUCCESS;
-}