blob: 949776d843f37ec4512b63f7a58b58f12eab187f [file] [log] [blame]
/**
* Copyright © 2016 IBM Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <systemd/sd-bus.h>
#include <systemd/sd-event.h>
#include <mapper.h>
static void quit(int r, void *loop)
{
sd_event_exit((sd_event *)loop, r);
}
static int callback(sd_bus_message *m, void *user, sd_bus_error *error)
{
sd_event *loop = user;
int r;
char *property = NULL;
r = sd_bus_message_skip(m, "s");
if (r < 0) {
fprintf(stderr, "Error skipping message fields: %s\n",
strerror(-r));
quit(r, loop);
return r;
}
r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "{sv}");
if (r < 0) {
fprintf(stderr, "Error entering container: %s\n",
strerror(-r));
quit(r, loop);
return r;
}
while((r = sd_bus_message_enter_container(
m,
SD_BUS_TYPE_DICT_ENTRY,
"sv")) > 0) {
r = sd_bus_message_read(m, "s", &property);
if (r < 0) {
fprintf(stderr, "Error reading message: %s\n",
strerror(-r));
quit(r, loop);
return r;
}
if(strcmp(property, "pgood"))
continue;
quit(0, loop);
break;
}
return 0;
}
int main(int argc, char *argv[])
{
static const char *matchfmt =
"type='signal',"
"interface='org.freedesktop.DBus.Properties',"
"member='PropertiesChanged',"
"arg0='org.openbmc.control.Power',"
"path='%s',"
"sender='%s'";
static const char *usage =
"Usage: %s OBJECTPATH on|off\n";
static const size_t LEN = 256;
sd_bus *conn = NULL;
sd_event *loop = NULL;
sd_bus_slot *slot = NULL;
sd_bus_error error = SD_BUS_ERROR_NULL;
char *service = NULL;
int r, dest = -1, state;
char match[LEN];
if(argc < 3) {
fprintf(stderr, usage, argv[0]);
exit(EXIT_FAILURE);
}
if(!strcmp(argv[2], "on"))
dest = 1;
if(!strcmp(argv[2], "off"))
dest = 0;
if(dest != 0 && dest != 1) {
fprintf(stderr, usage, argv[0]);
exit(EXIT_FAILURE);
}
r = sd_bus_default_system(&conn);
if(r < 0) {
fprintf(stderr, "Error connecting to system bus: %s\n",
strerror(-r));
goto finish;
}
r = mapper_get_service(conn, argv[1], &service);
if (r < 0) {
fprintf(stderr, "Error obtaining host service: %s\n",
strerror(-r));
goto finish;
}
r = sd_event_default(&loop);
if (r < 0) {
fprintf(stderr, "Error obtaining event loop: %s\n",
strerror(-r));
goto finish;
}
r = sd_bus_attach_event(conn, loop, SD_EVENT_PRIORITY_NORMAL);
if (r < 0) {
fprintf(stderr, "Failed to attach system "
"bus to event loop: %s\n",
strerror(-r));
goto finish;
}
if(strlen(matchfmt) + strnlen(argv[1], LEN) > LEN) {
r = -E2BIG;
fprintf(stderr, "Error adding match rule: %s\n",
strerror(-r));
goto finish;
}
sprintf(match, matchfmt, argv[1], service);
r = sd_bus_add_match(conn,
&slot,
match,
callback,
loop);
if(r < 0) {
fprintf(stderr, "Error adding match rule: %s\n",
strerror(-r));
goto finish;
}
r = sd_bus_get_property_trivial(conn,
service,
argv[1],
"org.openbmc.control.Power",
"pgood",
&error,
'i',
&state);
if(r < 0) {
fprintf(stderr, "Error getting property: %s\n",
strerror(-r));
goto finish;
}
if(dest == state)
goto finish;
r = sd_event_loop(loop);
if(r < 0) {
fprintf(stderr, "Error starting event loop: %s\n",
strerror(-r));
goto finish;
}
finish:
exit(r < 0 ? EXIT_FAILURE : EXIT_SUCCESS);
}