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