blob: 949776d843f37ec4512b63f7a58b58f12eab187f [file] [log] [blame]
Brad Bishop059cffb2016-08-23 10:47:19 -04001/**
2 * Copyright © 2016 IBM Corporation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16#include <stdlib.h>
17#include <stdio.h>
18#include <errno.h>
19#include <systemd/sd-bus.h>
20#include <systemd/sd-event.h>
21#include <mapper.h>
22
23static void quit(int r, void *loop)
24{
25 sd_event_exit((sd_event *)loop, r);
26}
27
28static int callback(sd_bus_message *m, void *user, sd_bus_error *error)
29{
30 sd_event *loop = user;
31 int r;
32 char *property = NULL;
33
34 r = sd_bus_message_skip(m, "s");
35 if (r < 0) {
36 fprintf(stderr, "Error skipping message fields: %s\n",
37 strerror(-r));
38 quit(r, loop);
39 return r;
40 }
41
42 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "{sv}");
43 if (r < 0) {
44 fprintf(stderr, "Error entering container: %s\n",
45 strerror(-r));
46 quit(r, loop);
47 return r;
48 }
49
50 while((r = sd_bus_message_enter_container(
51 m,
52 SD_BUS_TYPE_DICT_ENTRY,
53 "sv")) > 0) {
54 r = sd_bus_message_read(m, "s", &property);
55 if (r < 0) {
56 fprintf(stderr, "Error reading message: %s\n",
57 strerror(-r));
58 quit(r, loop);
59 return r;
60 }
61
62 if(strcmp(property, "pgood"))
63 continue;
64
65 quit(0, loop);
66 break;
67 }
68
69 return 0;
70}
71
72int main(int argc, char *argv[])
73{
74 static const char *matchfmt =
75 "type='signal',"
76 "interface='org.freedesktop.DBus.Properties',"
77 "member='PropertiesChanged',"
78 "arg0='org.openbmc.control.Power',"
79 "path='%s',"
80 "sender='%s'";
81 static const char *usage =
82 "Usage: %s OBJECTPATH on|off\n";
83 static const size_t LEN = 256;
84
85 sd_bus *conn = NULL;
86 sd_event *loop = NULL;
87 sd_bus_slot *slot = NULL;
88 sd_bus_error error = SD_BUS_ERROR_NULL;
89 char *service = NULL;
90 int r, dest = -1, state;
91 char match[LEN];
92
93 if(argc < 3) {
94 fprintf(stderr, usage, argv[0]);
95 exit(EXIT_FAILURE);
96 }
97
98 if(!strcmp(argv[2], "on"))
99 dest = 1;
100 if(!strcmp(argv[2], "off"))
101 dest = 0;
102
103 if(dest != 0 && dest != 1) {
104 fprintf(stderr, usage, argv[0]);
105 exit(EXIT_FAILURE);
106 }
107
108 r = sd_bus_default_system(&conn);
109 if(r < 0) {
110 fprintf(stderr, "Error connecting to system bus: %s\n",
111 strerror(-r));
112 goto finish;
113 }
114
115 r = mapper_get_service(conn, argv[1], &service);
116 if (r < 0) {
117 fprintf(stderr, "Error obtaining host service: %s\n",
118 strerror(-r));
119 goto finish;
120 }
121
122 r = sd_event_default(&loop);
123 if (r < 0) {
124 fprintf(stderr, "Error obtaining event loop: %s\n",
125 strerror(-r));
126 goto finish;
127 }
128
129 r = sd_bus_attach_event(conn, loop, SD_EVENT_PRIORITY_NORMAL);
130 if (r < 0) {
131 fprintf(stderr, "Failed to attach system "
132 "bus to event loop: %s\n",
133 strerror(-r));
134 goto finish;
135 }
136
137 if(strlen(matchfmt) + strnlen(argv[1], LEN) > LEN) {
138 r = -E2BIG;
139 fprintf(stderr, "Error adding match rule: %s\n",
140 strerror(-r));
141 goto finish;
142 }
143
144 sprintf(match, matchfmt, argv[1], service);
145
146 r = sd_bus_add_match(conn,
147 &slot,
148 match,
149 callback,
150 loop);
151 if(r < 0) {
152 fprintf(stderr, "Error adding match rule: %s\n",
153 strerror(-r));
154 goto finish;
155 }
156
157 r = sd_bus_get_property_trivial(conn,
158 service,
159 argv[1],
160 "org.openbmc.control.Power",
161 "pgood",
162 &error,
163 'i',
164 &state);
165 if(r < 0) {
166 fprintf(stderr, "Error getting property: %s\n",
167 strerror(-r));
168 goto finish;
169 }
170
171 if(dest == state)
172 goto finish;
173
174 r = sd_event_loop(loop);
175 if(r < 0) {
176 fprintf(stderr, "Error starting event loop: %s\n",
177 strerror(-r));
178 goto finish;
179 }
180
181finish:
182 exit(r < 0 ? EXIT_FAILURE : EXIT_SUCCESS);
183}