aboutsummaryrefslogtreecommitdiff
path: root/src/output.c
blob: be0afb1b499463e37940d1c9025fdd330cc4f7f7 (plain) (blame)
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
81
82
83
84
85
86
87
88
89
/* SPDX-License-Identifier: Apache-2.0 */

/* Copyright 2025 Thorsten Töpper
 *
 * vim:ts=4:sw=4:expandtab
 */

#include <unistd.h>
#include <ctype.h>
#include <time.h>
#include <sys/ioctl.h>

#include "output.h"
#include "options.h"



inline int fputc_all_cols(char c, FILE *fdout) {
    struct winsize terminal;
    ioctl(STDOUT_FILENO, TIOCGWINSZ, &terminal);
    return fputc_width_x(c, ((terminal.ws_col == 0) ? 72 : terminal.ws_col), fdout);
}


/* Not the most performant way, but during output the time critical tasks are already done. */
inline int fputc_width_x(char c, size_t x, FILE *fdout) {
    size_t i=0;

    if (fdout == NULL) {
        LOGERR("ERROR: No output stream given.\n");
        return EOF;
    }

    if ( ! isprint(c) ) { c = '?'; }

    for (i=0; i<x; i++) {
        if (fputc(c, fdout) == EOF) {
            LOGERR("ERROR: Failed to write char 0x%02X to stream %d\n", c, fdout->_fileno);
            return EOF;
        }
    }

    return 1;
}


/* The most simple default output, formatted output is planned */
void print_list(struct list_head *list) {
    struct list_head *lh = list;
    struct list_node *ptr;
    struct tm *tm = NULL;
    char timestamp[128];
    size_t total_size = 0;

    if (list == NULL) return;
    if (option_sort_reverse_order) {
        lh = create_list_sort_reversed(list);
        /* be tolerant */
        if (lh == NULL) {
            lh = list;
        }
    }

    ptr = lh->first;
    while (ptr != NULL) {
        printf(" %8ld %2s ", ((ptr->fsize>=1024) ? (ptr->fsize/1024) : ptr->fsize),
                ((ptr->fsize >= 1024) ? "kB" : ""));

        tm = localtime(&ptr->ftime);
        if (option_timestamp_long) {
            strftime(timestamp, sizeof(timestamp), "%Y%m%d %H:%M:%S %Z", tm);
            printf(" %20s ", timestamp);
        } else {
            strftime(timestamp, sizeof(timestamp), "%H:%M:%S", tm);
            printf(" %8s ", timestamp);
        }
        printf(" %s\n", ptr->fname);
        /* Linux: Neither man stat(2) nor stat(3type) declare when struct stat field st_size
         * get's a negative value. */
        total_size += (ptr->fsize>0) ? (unsigned long int)ptr->fsize : 0;
        ptr = ptr->next;
    }
    fputc_all_cols('=', stdout);
    printf("\nTotal size: %lu %s\n", ((total_size>1024) ? total_size/1024 : total_size),
            ((total_size >= 1024) ? "kB" : ""));

    if (lh != list) destroy_list(lh);
}