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