chiark / gitweb /
bus: add .busname unit type to implement kdbus-style bus activation
[elogind.git] / src / core / dbus-timer.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
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
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
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
16   Lesser General Public License for more details.
17
18   You should have received a copy of the GNU Lesser General Public License
19   along with systemd; If not, see <http://www.gnu.org/licenses/>.
20 ***/
21
22 #include "unit.h"
23 #include "timer.h"
24 #include "dbus-unit.h"
25 #include "dbus-timer.h"
26 #include "bus-util.h"
27
28 static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_result, timer_result, TimerResult);
29
30 static int property_get_monotonic_timers(
31                 sd_bus *bus,
32                 const char *path,
33                 const char *interface,
34                 const char *property,
35                 sd_bus_message *reply,
36                 void *userdata,
37                 sd_bus_error *error) {
38
39         Timer *t = userdata;
40         TimerValue *v;
41         int r;
42
43         assert(bus);
44         assert(reply);
45         assert(t);
46
47         r = sd_bus_message_open_container(reply, 'a', "(stt)");
48         if (r < 0)
49                 return r;
50
51         LIST_FOREACH(value, v, t->values) {
52                 _cleanup_free_ char *buf = NULL;
53                 const char *s;
54                 size_t l;
55
56                 if (v->base == TIMER_CALENDAR)
57                         continue;
58
59                 s = timer_base_to_string(v->base);
60                 assert(endswith(s, "Sec"));
61
62                 /* s/Sec/USec/ */
63                 l = strlen(s);
64                 buf = new(char, l+2);
65                 if (!buf)
66                         return -ENOMEM;
67
68                 memcpy(buf, s, l-3);
69                 memcpy(buf+l-3, "USec", 5);
70
71                 r = sd_bus_message_append(reply, "(stt)", buf, v->value, v->next_elapse);
72                 if (r < 0)
73                         return r;
74         }
75
76         return sd_bus_message_close_container(reply);
77 }
78
79 static int property_get_calendar_timers(
80                 sd_bus *bus,
81                 const char *path,
82                 const char *interface,
83                 const char *property,
84                 sd_bus_message *reply,
85                 void *userdata,
86                 sd_bus_error *error) {
87
88         Timer *t = userdata;
89         TimerValue *v;
90         int r;
91
92         assert(bus);
93         assert(reply);
94         assert(t);
95
96         r = sd_bus_message_open_container(reply, 'a', "(sst)");
97         if (r < 0)
98                 return r;
99
100         LIST_FOREACH(value, v, t->values) {
101                 _cleanup_free_ char *buf = NULL;
102
103                 if (v->base != TIMER_CALENDAR)
104                         continue;
105
106                 r = calendar_spec_to_string(v->calendar_spec, &buf);
107                 if (r < 0)
108                         return r;
109
110                 r = sd_bus_message_append(reply, "(sst)", timer_base_to_string(v->base), buf, v->next_elapse);
111                 if (r < 0)
112                         return r;
113         }
114
115         return sd_bus_message_close_container(reply);
116 }
117
118 static int property_get_unit(
119                 sd_bus *bus,
120                 const char *path,
121                 const char *interface,
122                 const char *property,
123                 sd_bus_message *reply,
124                 void *userdata,
125                 sd_bus_error *error) {
126
127         Unit *u = userdata, *trigger;
128
129         assert(bus);
130         assert(reply);
131         assert(u);
132
133         trigger = UNIT_TRIGGER(u);
134
135         return sd_bus_message_append(reply, "s", trigger ? trigger->id : "");
136 }
137
138 const sd_bus_vtable bus_timer_vtable[] = {
139         SD_BUS_VTABLE_START(0),
140         SD_BUS_PROPERTY("Unit", "s", property_get_unit, 0, 0),
141         SD_BUS_PROPERTY("TimersMonotonic", "a(stt)", property_get_monotonic_timers, 0, 0),
142         SD_BUS_PROPERTY("TimersCalendar", "a(sst)", property_get_calendar_timers, 0, 0),
143         SD_BUS_PROPERTY("NextElapseUSecRealtime", "t", bus_property_get_usec, offsetof(Timer, next_elapse_monotonic), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
144         SD_BUS_PROPERTY("NextElapseUSecMonotonic", "t", bus_property_get_usec, offsetof(Timer, next_elapse_realtime), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
145         SD_BUS_PROPERTY("Result", "s", property_get_result, offsetof(Timer, result), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
146         SD_BUS_PROPERTY("AccuracyUSec", "t", bus_property_get_usec, offsetof(Timer, accuracy_usec), 0),
147         SD_BUS_VTABLE_END
148 };
149
150 const char* const bus_timer_changing_properties[] = {
151         "NextElapseUSecRealtime",
152         "NextElapseUSecMonotonic",
153         "Result",
154         NULL
155 };