1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
2
3 #include "format-util.h"
4 #include "memory-util.h"
5 #include "stdio-util.h"
6 #include "strxcpyx.h"
7
8 assert_cc(STRLEN("%") + DECIMAL_STR_MAX(int) <= IF_NAMESIZE);
format_ifname_full(int ifindex,FormatIfnameFlag flag,char buf[static IF_NAMESIZE])9 int format_ifname_full(int ifindex, FormatIfnameFlag flag, char buf[static IF_NAMESIZE]) {
10 if (ifindex <= 0)
11 return -EINVAL;
12
13 if (if_indextoname(ifindex, buf))
14 return 0;
15
16 if (!FLAGS_SET(flag, FORMAT_IFNAME_IFINDEX))
17 return -errno;
18
19 if (FLAGS_SET(flag, FORMAT_IFNAME_IFINDEX_WITH_PERCENT))
20 assert(snprintf_ok(buf, IF_NAMESIZE, "%%%d", ifindex));
21 else
22 assert(snprintf_ok(buf, IF_NAMESIZE, "%d", ifindex));
23
24 return 0;
25 }
26
format_ifname_full_alloc(int ifindex,FormatIfnameFlag flag,char ** ret)27 int format_ifname_full_alloc(int ifindex, FormatIfnameFlag flag, char **ret) {
28 char buf[IF_NAMESIZE], *copy;
29 int r;
30
31 assert(ret);
32
33 r = format_ifname_full(ifindex, flag, buf);
34 if (r < 0)
35 return r;
36
37 copy = strdup(buf);
38 if (!copy)
39 return -ENOMEM;
40
41 *ret = copy;
42 return 0;
43 }
44
format_bytes_full(char * buf,size_t l,uint64_t t,FormatBytesFlag flag)45 char *format_bytes_full(char *buf, size_t l, uint64_t t, FormatBytesFlag flag) {
46 typedef struct {
47 const char *suffix;
48 uint64_t factor;
49 } suffix_table;
50 static const suffix_table table_iec[] = {
51 { "E", UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024) },
52 { "P", UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024) },
53 { "T", UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024) },
54 { "G", UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024) },
55 { "M", UINT64_C(1024)*UINT64_C(1024) },
56 { "K", UINT64_C(1024) },
57 }, table_si[] = {
58 { "E", UINT64_C(1000)*UINT64_C(1000)*UINT64_C(1000)*UINT64_C(1000)*UINT64_C(1000)*UINT64_C(1000) },
59 { "P", UINT64_C(1000)*UINT64_C(1000)*UINT64_C(1000)*UINT64_C(1000)*UINT64_C(1000) },
60 { "T", UINT64_C(1000)*UINT64_C(1000)*UINT64_C(1000)*UINT64_C(1000) },
61 { "G", UINT64_C(1000)*UINT64_C(1000)*UINT64_C(1000) },
62 { "M", UINT64_C(1000)*UINT64_C(1000) },
63 { "K", UINT64_C(1000) },
64 };
65 const suffix_table *table;
66 size_t n;
67
68 assert_cc(ELEMENTSOF(table_iec) == ELEMENTSOF(table_si));
69
70 if (t == UINT64_MAX)
71 return NULL;
72
73 table = flag & FORMAT_BYTES_USE_IEC ? table_iec : table_si;
74 n = ELEMENTSOF(table_iec);
75
76 for (size_t i = 0; i < n; i++)
77 if (t >= table[i].factor) {
78 if (flag & FORMAT_BYTES_BELOW_POINT) {
79 (void) snprintf(buf, l,
80 "%" PRIu64 ".%" PRIu64 "%s",
81 t / table[i].factor,
82 i != n - 1 ?
83 (t / table[i + 1].factor * UINT64_C(10) / table[n - 1].factor) % UINT64_C(10):
84 (t * UINT64_C(10) / table[i].factor) % UINT64_C(10),
85 table[i].suffix);
86 } else
87 (void) snprintf(buf, l,
88 "%" PRIu64 "%s",
89 t / table[i].factor,
90 table[i].suffix);
91
92 goto finish;
93 }
94
95 (void) snprintf(buf, l, "%" PRIu64 "%s", t, flag & FORMAT_BYTES_TRAILING_B ? "B" : "");
96
97 finish:
98 buf[l-1] = 0;
99 return buf;
100
101 }
102