]>
Commit | Line | Data |
---|---|---|
d6c9574f | 1 | /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ |
871d7de4 LP |
2 | |
3 | /*** | |
4 | This file is part of systemd. | |
5 | ||
6 | Copyright 2010 Lennart Poettering | |
7 | ||
8 | systemd is free software; you can redistribute it and/or modify it | |
5430f7f2 LP |
9 | under the terms of the GNU Lesser General Public License as published by |
10 | the Free Software Foundation; either version 2.1 of the License, or | |
871d7de4 LP |
11 | (at your option) any later version. |
12 | ||
13 | systemd is distributed in the hope that it will be useful, but | |
14 | WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
5430f7f2 | 16 | Lesser General Public License for more details. |
871d7de4 | 17 | |
5430f7f2 | 18 | You should have received a copy of the GNU Lesser General Public License |
871d7de4 LP |
19 | along with systemd; If not, see <http://www.gnu.org/licenses/>. |
20 | ***/ | |
21 | ||
22 | #include <errno.h> | |
23 | ||
24 | #include "dbus-unit.h" | |
25 | #include "dbus-timer.h" | |
26 | #include "dbus-execute.h" | |
bfebab7f | 27 | #include "dbus-common.h" |
cad45ba1 | 28 | #include "selinux-access.h" |
871d7de4 LP |
29 | |
30 | #define BUS_TIMER_INTERFACE \ | |
31 | " <interface name=\"org.freedesktop.systemd1.Timer\">\n" \ | |
707e5e52 | 32 | " <property name=\"Unit\" type=\"s\" access=\"read\"/>\n" \ |
b719810d LP |
33 | " <property name=\"TimersMonotonic\" type=\"a(stt)\" access=\"read\"/>\n" \ |
34 | " <property name=\"TimersCalendar\" type=\"a(sst)\" access=\"read\"/>\n" \ | |
35 | " <property name=\"NextElapseUSecRealtime\" type=\"t\" access=\"read\"/>\n" \ | |
36 | " <property name=\"NextElapseUSecMonotonic\" type=\"t\" access=\"read\"/>\n" \ | |
067d72c9 | 37 | " <property name=\"Result\" type=\"s\" access=\"read\"/>\n" \ |
707e5e52 | 38 | " </interface>\n" |
871d7de4 LP |
39 | |
40 | #define INTROSPECTION \ | |
41 | DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE \ | |
42 | "<node>\n" \ | |
43 | BUS_UNIT_INTERFACE \ | |
44 | BUS_TIMER_INTERFACE \ | |
45 | BUS_PROPERTIES_INTERFACE \ | |
c4e2ceae | 46 | BUS_PEER_INTERFACE \ |
871d7de4 LP |
47 | BUS_INTROSPECTABLE_INTERFACE \ |
48 | "</node>\n" | |
49 | ||
05feefe0 LP |
50 | #define INTERFACES_LIST \ |
51 | BUS_UNIT_INTERFACES_LIST \ | |
52 | "org.freedesktop.systemd1.Timer\0" | |
53 | ||
9a60da28 | 54 | const char bus_timer_interface[] _introspect_("Timer") = BUS_TIMER_INTERFACE; |
871d7de4 | 55 | |
c4e2ceae | 56 | const char bus_timer_invalidating_properties[] = |
b719810d LP |
57 | "TimersMonotonic\0" |
58 | "TimersRealtime\0" | |
59 | "NextElapseUSecRealtime\0" | |
60 | "NextElapseUSecMonotonic\0" | |
067d72c9 | 61 | "Result\0"; |
c4e2ceae | 62 | |
b719810d | 63 | static int bus_timer_append_monotonic_timers(DBusMessageIter *i, const char *property, void *data) { |
707e5e52 LP |
64 | Timer *p = data; |
65 | DBusMessageIter sub, sub2; | |
66 | TimerValue *k; | |
67 | ||
707e5e52 LP |
68 | assert(i); |
69 | assert(property); | |
70 | assert(p); | |
71 | ||
72 | if (!dbus_message_iter_open_container(i, DBUS_TYPE_ARRAY, "(stt)", &sub)) | |
73 | return -ENOMEM; | |
74 | ||
75 | LIST_FOREACH(value, k, p->values) { | |
3761902e | 76 | _cleanup_free_ char *buf = NULL; |
03fae018 LP |
77 | const char *t; |
78 | size_t l; | |
79 | bool b; | |
707e5e52 | 80 | |
b719810d LP |
81 | if (k->base == TIMER_CALENDAR) |
82 | continue; | |
03fae018 | 83 | |
b719810d LP |
84 | t = timer_base_to_string(k->base); |
85 | assert(endswith(t, "Sec")); | |
3761902e | 86 | |
b719810d LP |
87 | /* s/Sec/USec/ */ |
88 | l = strlen(t); | |
89 | buf = new(char, l+2); | |
90 | if (!buf) | |
91 | return -ENOMEM; | |
03fae018 | 92 | |
b719810d LP |
93 | memcpy(buf, t, l-3); |
94 | memcpy(buf+l-3, "USec", 5); | |
03fae018 LP |
95 | |
96 | b = dbus_message_iter_open_container(&sub, DBUS_TYPE_STRUCT, NULL, &sub2) && | |
97 | dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &buf) && | |
98 | dbus_message_iter_append_basic(&sub2, DBUS_TYPE_UINT64, &k->value) && | |
99 | dbus_message_iter_append_basic(&sub2, DBUS_TYPE_UINT64, &k->next_elapse) && | |
100 | dbus_message_iter_close_container(&sub, &sub2); | |
101 | ||
03fae018 | 102 | if (!b) |
707e5e52 LP |
103 | return -ENOMEM; |
104 | } | |
105 | ||
106 | if (!dbus_message_iter_close_container(i, &sub)) | |
107 | return -ENOMEM; | |
108 | ||
109 | return 0; | |
110 | } | |
111 | ||
b719810d LP |
112 | static int bus_timer_append_calendar_timers(DBusMessageIter *i, const char *property, void *data) { |
113 | Timer *p = data; | |
114 | DBusMessageIter sub, sub2; | |
115 | TimerValue *k; | |
116 | ||
117 | assert(i); | |
118 | assert(property); | |
119 | assert(p); | |
120 | ||
121 | if (!dbus_message_iter_open_container(i, DBUS_TYPE_ARRAY, "(sst)", &sub)) | |
122 | return -ENOMEM; | |
123 | ||
124 | LIST_FOREACH(value, k, p->values) { | |
125 | _cleanup_free_ char *buf = NULL; | |
126 | const char *t; | |
127 | bool b; | |
128 | int j; | |
129 | ||
130 | if (k->base != TIMER_CALENDAR) | |
131 | continue; | |
132 | ||
133 | t = timer_base_to_string(k->base); | |
134 | j = calendar_spec_to_string(k->calendar_spec, &buf); | |
135 | if (j < 0) | |
136 | return j; | |
137 | ||
138 | b = dbus_message_iter_open_container(&sub, DBUS_TYPE_STRUCT, NULL, &sub2) && | |
139 | dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &t) && | |
140 | dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &buf) && | |
141 | dbus_message_iter_append_basic(&sub2, DBUS_TYPE_UINT64, &k->next_elapse) && | |
142 | dbus_message_iter_close_container(&sub, &sub2); | |
143 | ||
144 | if (!b) | |
145 | return -ENOMEM; | |
146 | } | |
147 | ||
148 | if (!dbus_message_iter_close_container(i, &sub)) | |
149 | return -ENOMEM; | |
150 | ||
151 | return 0; | |
152 | } | |
153 | ||
bfebab7f | 154 | static int bus_timer_append_unit(DBusMessageIter *i, const char *property, void *data) { |
3ecaa09b | 155 | Unit *u = data, *trigger; |
b284eabd LP |
156 | const char *t; |
157 | ||
b284eabd LP |
158 | assert(i); |
159 | assert(property); | |
160 | assert(u); | |
161 | ||
3ecaa09b LP |
162 | trigger = UNIT_TRIGGER(u); |
163 | t = trigger ? trigger->id : ""; | |
b284eabd LP |
164 | |
165 | return dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, &t) ? 0 : -ENOMEM; | |
166 | } | |
167 | ||
067d72c9 LP |
168 | static DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_timer_append_timer_result, timer_result, TimerResult); |
169 | ||
d200735e | 170 | static const BusProperty bus_timer_properties[] = { |
b719810d LP |
171 | { "Unit", bus_timer_append_unit, "s", 0 }, |
172 | { "TimersMonotonic", bus_timer_append_monotonic_timers, "a(stt)", 0 }, | |
173 | { "TimersCalendar", bus_timer_append_calendar_timers, "a(sst)", 0 }, | |
174 | { "NextElapseUSecMonotonic", bus_property_append_usec, "t", offsetof(Timer, next_elapse_monotonic) }, | |
175 | { "NextElapseUSecRealtime", bus_property_append_usec, "t", offsetof(Timer, next_elapse_realtime) }, | |
176 | { "Result", bus_timer_append_timer_result, "s", offsetof(Timer, result) }, | |
d200735e MS |
177 | { NULL, } |
178 | }; | |
179 | ||
5e8d1c9a | 180 | DBusHandlerResult bus_timer_message_handler(Unit *u, DBusConnection *c, DBusMessage *message) { |
ac155bb8 | 181 | Timer *t = TIMER(u); |
d200735e MS |
182 | const BusBoundProperties bps[] = { |
183 | { "org.freedesktop.systemd1.Unit", bus_unit_properties, u }, | |
184 | { "org.freedesktop.systemd1.Timer", bus_timer_properties, t }, | |
185 | { NULL, } | |
871d7de4 LP |
186 | }; |
187 | ||
cad45ba1 LP |
188 | SELINUX_UNIT_ACCESS_CHECK(u, c, message, "status"); |
189 | ||
d200735e | 190 | return bus_default_message_handler(c, message, INTROSPECTION, INTERFACES_LIST, bps); |
871d7de4 | 191 | } |