summaryrefslogtreecommitdiff
path: root/src/commands/tail.c
blob: 04f7f424ce7cbdeff4f7d00719f7a07eec5da015 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
#include "../command.h"

#include <stdio.h>
#include <string.h>
#include <sys/stat.h>

static void tail_file(FILE* file) {
    char* ring[10];
    memset(ring, 0, sizeof(char*) * 10);

    int ring_len[10];
    
    int index = 0;
    int size = 0;

    int read;
    size_t len = 0;
    char* 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 %= 10;
        if (size < 10) size++;

        line = NULL;
    }

    index += 10 - size;
    index %= 10;
    
    for (int i = 0; i < size; i++) {
        fwrite(ring[index], ring_len[index], 1, stdout);
        free(ring[index]);
        index += 1;
        index %= 10;
    }

    free(line);
    fclose(file);
}

static void help() {
    printf("Usage: tail [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");
    exit(EXIT_SUCCESS);
}

COMMAND(tail) {
    if (argc < 1) {
        tail_file(stdin);
        return EXIT_SUCCESS;
    }

    if (streql(argv[0], "--help")) help();

    if (argc == 1) {
        FILE* file = get_file(argv[0], "r");
        tail_file(file);
        return EXIT_SUCCESS;
    }

    for (int i = 0; i < argc; i++) {
        FILE* file;
        if (streql("-", argv[i])) {
            file = stdin;
        } else {
            file = get_file_s(argv[i], "r");
            if (file == NULL) continue;
        }
        printf("\n==> %s <==\n", argv[i]);
        tail_file(file);
    }

    return EXIT_SUCCESS;
}