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