1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
2 
3 #include "bus-error.h"
4 #include "bus-locator.h"
5 #include "pretty-print.h"
6 #include "syslog-util.h"
7 #include "systemctl-log-setting.h"
8 #include "systemctl-util.h"
9 #include "systemctl.h"
10 #include "verb-log-control.h"
11 
give_log_control1_hint(const char * name)12 static void give_log_control1_hint(const char *name) {
13         _cleanup_free_ char *link = NULL;
14 
15         if (arg_quiet)
16                 return;
17 
18         (void) terminal_urlify_man("org.freedesktop.LogControl1", "5", &link);
19 
20         log_notice("Hint: the service must declare BusName= and implement the appropriate D-Bus interface.\n"
21                    "      See the %s for details.", link ?: "org.freedesktop.LogControl1(5) man page");
22 }
23 
verb_log_setting(int argc,char * argv[],void * userdata)24 int verb_log_setting(int argc, char *argv[], void *userdata) {
25         sd_bus *bus;
26         int r;
27 
28         assert(argc >= 1 && argc <= 2);
29 
30         r = acquire_bus(BUS_MANAGER, &bus);
31         if (r < 0)
32                 return r;
33 
34         return verb_log_control_common(bus, "org.freedesktop.systemd1", argv[0], argv[1]);
35 }
36 
service_name_to_dbus(sd_bus * bus,const char * name,char ** ret_dbus_name)37 static int service_name_to_dbus(sd_bus *bus, const char *name, char **ret_dbus_name) {
38         _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
39         _cleanup_free_ char *bus_name = NULL;
40         int r;
41 
42         /* First, look for the BusName= property */
43         _cleanup_free_ char *dbus_path = unit_dbus_path_from_name(name);
44         if (!dbus_path)
45                 return log_oom();
46 
47         r = sd_bus_get_property_string(
48                                 bus,
49                                 "org.freedesktop.systemd1",
50                                 dbus_path,
51                                 "org.freedesktop.systemd1.Service",
52                                 "BusName",
53                                 &error,
54                                 &bus_name);
55         if (r < 0)
56                 return log_error_errno(r, "Failed to obtain BusName= property of %s: %s",
57                                        name, bus_error_message(&error, r));
58 
59         if (isempty(bus_name)) {
60                 log_error("Unit %s doesn't declare BusName=.", name);
61                 give_log_control1_hint(name);
62                 return -ENOLINK;
63         }
64 
65         *ret_dbus_name = TAKE_PTR(bus_name);
66         return 0;
67 }
68 
verb_service_log_setting(int argc,char * argv[],void * userdata)69 int verb_service_log_setting(int argc, char *argv[], void *userdata) {
70         sd_bus *bus;
71         _cleanup_free_ char *unit = NULL, *dbus_name = NULL;
72         int r;
73 
74         assert(argc >= 2 && argc <= 3);
75 
76         r = acquire_bus(BUS_FULL, &bus);
77         if (r < 0)
78                 return r;
79 
80         r = unit_name_mangle_with_suffix(argv[1], argv[0],
81                                          arg_quiet ? 0 : UNIT_NAME_MANGLE_WARN,
82                                          ".service", &unit);
83         if (r < 0)
84                 return log_error_errno(r, "Failed to mangle unit name: %m");
85 
86         r = service_name_to_dbus(bus, unit, &dbus_name);
87         if (r < 0)
88                 return r;
89 
90         r = verb_log_control_common(bus, dbus_name, argv[0], argv[2]);
91 
92         if (r == -EBADR)
93                 give_log_control1_hint(dbus_name);
94 
95         return r;
96 }
97