]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/core/dbus-timer.c
dbus: fix minor memory leak when sending job change signals
[thirdparty/systemd.git] / src / core / dbus-timer.c
CommitLineData
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 54const char bus_timer_interface[] _introspect_("Timer") = BUS_TIMER_INTERFACE;
871d7de4 55
c4e2ceae 56const 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 63static 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
112static 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 154static 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
168static DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_timer_append_timer_result, timer_result, TimerResult);
169
d200735e 170static 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 180DBusHandlerResult 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}