1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
2
3 #include "alloc-util.h"
4 #include "bus-get-properties.h"
5 #include "bus-log-control-api.h"
6 #include "bus-util.h"
7 #include "log.h"
8 #include "sd-bus.h"
9 #include "syslog-util.h"
10
bus_property_get_log_level(sd_bus * bus,const char * path,const char * interface,const char * property,sd_bus_message * reply,void * userdata,sd_bus_error * error)11 int bus_property_get_log_level(
12 sd_bus *bus,
13 const char *path,
14 const char *interface,
15 const char *property,
16 sd_bus_message *reply,
17 void *userdata,
18 sd_bus_error *error) {
19
20 _cleanup_free_ char *t = NULL;
21 int r;
22
23 assert(bus);
24 assert(reply);
25
26 r = log_level_to_string_alloc(log_get_max_level(), &t);
27 if (r < 0)
28 return r;
29
30 return sd_bus_message_append(reply, "s", t);
31 }
32
bus_property_set_log_level(sd_bus * bus,const char * path,const char * interface,const char * property,sd_bus_message * value,void * userdata,sd_bus_error * error)33 int bus_property_set_log_level(
34 sd_bus *bus,
35 const char *path,
36 const char *interface,
37 const char *property,
38 sd_bus_message *value,
39 void *userdata,
40 sd_bus_error *error) {
41
42 const char *t;
43 int r;
44
45 assert(bus);
46 assert(value);
47
48 r = sd_bus_message_read(value, "s", &t);
49 if (r < 0)
50 return r;
51
52 r = log_level_from_string(t);
53 if (r < 0)
54 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid log level '%s'", t);
55
56 log_info("Setting log level to %s.", t);
57 log_set_max_level(r);
58
59 return 0;
60 }
61
62 BUS_DEFINE_PROPERTY_GET_GLOBAL(bus_property_get_log_target, "s", log_target_to_string(log_get_target()));
63
bus_property_set_log_target(sd_bus * bus,const char * path,const char * interface,const char * property,sd_bus_message * value,void * userdata,sd_bus_error * error)64 int bus_property_set_log_target(
65 sd_bus *bus,
66 const char *path,
67 const char *interface,
68 const char *property,
69 sd_bus_message *value,
70 void *userdata,
71 sd_bus_error *error) {
72
73 LogTarget target;
74 const char *t;
75 int r;
76
77 assert(bus);
78 assert(value);
79
80 r = sd_bus_message_read(value, "s", &t);
81 if (r < 0)
82 return r;
83
84 target = log_target_from_string(t);
85 if (target < 0)
86 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid log target '%s'", t);
87
88 log_info("Setting log target to %s.", log_target_to_string(target));
89 log_set_target(target);
90 log_open();
91
92 return 0;
93 }
94
95 BUS_DEFINE_PROPERTY_GET_GLOBAL(bus_property_get_syslog_identifier, "s", program_invocation_short_name);
96
97 static const sd_bus_vtable log_control_vtable[] = {
98 SD_BUS_VTABLE_START(0),
99
100 SD_BUS_WRITABLE_PROPERTY("LogLevel", "s", bus_property_get_log_level, bus_property_set_log_level, 0, 0),
101 SD_BUS_WRITABLE_PROPERTY("LogTarget", "s", bus_property_get_log_target, bus_property_set_log_target, 0, 0),
102 SD_BUS_PROPERTY("SyslogIdentifier", "s", bus_property_get_syslog_identifier, 0, 0),
103
104 /* One of those days we might want to add a similar, second interface to cover common service
105 * operations such as Reload(), Reexecute(), Exit() … and maybe some properties exposing version
106 * number and other meta-data of the service. */
107
108 SD_BUS_VTABLE_END,
109 };
110
111 const BusObjectImplementation log_control_object = {
112 "/org/freedesktop/LogControl1",
113 "org.freedesktop.LogControl1",
114 .vtables = BUS_VTABLES(log_control_vtable),
115 };
116