1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
2
3 #include "bus-get-properties.h"
4 #include "rlimit-util.h"
5 #include "stdio-util.h"
6 #include "string-util.h"
7
bus_property_get_bool(sd_bus * bus,const char * path,const char * interface,const char * property,sd_bus_message * reply,void * userdata,sd_bus_error * error)8 int bus_property_get_bool(
9 sd_bus *bus,
10 const char *path,
11 const char *interface,
12 const char *property,
13 sd_bus_message *reply,
14 void *userdata,
15 sd_bus_error *error) {
16
17 int b = *(bool*) userdata;
18
19 return sd_bus_message_append_basic(reply, 'b', &b);
20 }
21
bus_property_set_bool(sd_bus * bus,const char * path,const char * interface,const char * property,sd_bus_message * value,void * userdata,sd_bus_error * error)22 int bus_property_set_bool(
23 sd_bus *bus,
24 const char *path,
25 const char *interface,
26 const char *property,
27 sd_bus_message *value,
28 void *userdata,
29 sd_bus_error *error) {
30
31 int b, r;
32
33 r = sd_bus_message_read(value, "b", &b);
34 if (r < 0)
35 return r;
36
37 *(bool*) userdata = b;
38 return 0;
39 }
40
bus_property_get_id128(sd_bus * bus,const char * path,const char * interface,const char * property,sd_bus_message * reply,void * userdata,sd_bus_error * error)41 int bus_property_get_id128(
42 sd_bus *bus,
43 const char *path,
44 const char *interface,
45 const char *property,
46 sd_bus_message *reply,
47 void *userdata,
48 sd_bus_error *error) {
49
50 sd_id128_t *id = userdata;
51
52 if (sd_id128_is_null(*id)) /* Add an empty array if the ID is zero */
53 return sd_bus_message_append(reply, "ay", 0);
54 else
55 return sd_bus_message_append_array(reply, 'y', id->bytes, 16);
56 }
57
58 #if __SIZEOF_SIZE_T__ != 8
bus_property_get_size(sd_bus * bus,const char * path,const char * interface,const char * property,sd_bus_message * reply,void * userdata,sd_bus_error * error)59 int bus_property_get_size(
60 sd_bus *bus,
61 const char *path,
62 const char *interface,
63 const char *property,
64 sd_bus_message *reply,
65 void *userdata,
66 sd_bus_error *error) {
67
68 uint64_t sz = *(size_t*) userdata;
69
70 return sd_bus_message_append_basic(reply, 't', &sz);
71 }
72 #endif
73
74 #if __SIZEOF_LONG__ != 8
bus_property_get_long(sd_bus * bus,const char * path,const char * interface,const char * property,sd_bus_message * reply,void * userdata,sd_bus_error * error)75 int bus_property_get_long(
76 sd_bus *bus,
77 const char *path,
78 const char *interface,
79 const char *property,
80 sd_bus_message *reply,
81 void *userdata,
82 sd_bus_error *error) {
83
84 int64_t l = *(long*) userdata;
85
86 return sd_bus_message_append_basic(reply, 'x', &l);
87 }
88
bus_property_get_ulong(sd_bus * bus,const char * path,const char * interface,const char * property,sd_bus_message * reply,void * userdata,sd_bus_error * error)89 int bus_property_get_ulong(
90 sd_bus *bus,
91 const char *path,
92 const char *interface,
93 const char *property,
94 sd_bus_message *reply,
95 void *userdata,
96 sd_bus_error *error) {
97
98 uint64_t ul = *(unsigned long*) userdata;
99
100 return sd_bus_message_append_basic(reply, 't', &ul);
101 }
102 #endif
103
bus_property_get_rlimit(sd_bus * bus,const char * path,const char * interface,const char * property,sd_bus_message * reply,void * userdata,sd_bus_error * error)104 int bus_property_get_rlimit(
105 sd_bus *bus,
106 const char *path,
107 const char *interface,
108 const char *property,
109 sd_bus_message *reply,
110 void *userdata,
111 sd_bus_error *error) {
112
113 const char *is_soft;
114 struct rlimit *rl;
115 uint64_t u;
116 rlim_t x;
117
118 assert(bus);
119 assert(reply);
120 assert(userdata);
121
122 is_soft = endswith(property, "Soft");
123
124 rl = *(struct rlimit**) userdata;
125 if (rl)
126 x = is_soft ? rl->rlim_cur : rl->rlim_max;
127 else {
128 struct rlimit buf = {};
129 const char *s, *p;
130 int z;
131
132 /* Chop off "Soft" suffix */
133 s = is_soft ? strndupa_safe(property, is_soft - property) : property;
134
135 /* Skip over any prefix, such as "Default" */
136 assert_se(p = strstr(s, "Limit"));
137
138 z = rlimit_from_string(p + 5);
139 assert(z >= 0);
140
141 (void) getrlimit(z, &buf);
142 x = is_soft ? buf.rlim_cur : buf.rlim_max;
143 }
144
145 /* rlim_t might have different sizes, let's map RLIMIT_INFINITY to UINT64_MAX, so that it is the same on all
146 * archs */
147 u = x == RLIM_INFINITY ? UINT64_MAX : (uint64_t) x;
148
149 return sd_bus_message_append(reply, "t", u);
150 }
151