blob: 9ead753a5f0436e90f9ded01150bf3907fa96822 [file] [log] [blame]
Brad Bishop2afe7182016-08-13 14:08:17 -04001/**
Andrew Geissler981f2662017-03-03 15:58:23 -06002 * Copyright 2016 IBM Corporation
Brad Bishop2afe7182016-08-13 14:08:17 -04003 *
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 */
Matthew Barthc6329c92016-11-15 11:13:37 -060016#include "config.h"
Matt Spinlercc6ee9c2018-09-19 13:23:13 -050017
Matt Spinler59cbf342018-09-24 09:46:00 -050018#include <errno.h>
Brad Bishop2afe7182016-08-13 14:08:17 -040019#include <stdio.h>
Matt Spinlercc6ee9c2018-09-19 13:23:13 -050020#include <stdlib.h>
Brad Bishop2afe7182016-08-13 14:08:17 -040021#include <systemd/sd-bus.h>
22#include <systemd/sd-event.h>
Matt Spinlercc6ee9c2018-09-19 13:23:13 -050023
Brad Bishop2afe7182016-08-13 14:08:17 -040024#include "mapper.h"
25
Matt Spinlercc6ee9c2018-09-19 13:23:13 -050026static void quit(int r, void* loop)
Brad Bishop2afe7182016-08-13 14:08:17 -040027{
Matt Spinlercc6ee9c2018-09-19 13:23:13 -050028 sd_event_exit((sd_event*)loop, r);
Brad Bishop2afe7182016-08-13 14:08:17 -040029}
30
Matt Spinlercc6ee9c2018-09-19 13:23:13 -050031static int wait_main(int argc, char* argv[])
Brad Bishop2afe7182016-08-13 14:08:17 -040032{
Ed Tanous167e2372018-05-07 11:59:10 -070033 int r;
Matt Spinlercc6ee9c2018-09-19 13:23:13 -050034 sd_bus* conn = NULL;
35 sd_event* loop = NULL;
36 mapper_async_wait* wait = NULL;
Brad Bishop2afe7182016-08-13 14:08:17 -040037
Ed Tanous167e2372018-05-07 11:59:10 -070038 if (argc < 3)
39 {
40 fprintf(stderr, "Usage: %s wait OBJECTPATH...\n", argv[0]);
41 exit(EXIT_FAILURE);
42 }
Brad Bishop2afe7182016-08-13 14:08:17 -040043
Ed Tanous167e2372018-05-07 11:59:10 -070044 r = sd_bus_default_system(&conn);
45 if (r < 0)
46 {
47 fprintf(stderr, "Error connecting to system bus: %s\n", strerror(-r));
48 goto finish;
49 }
Brad Bishop2afe7182016-08-13 14:08:17 -040050
Ed Tanous167e2372018-05-07 11:59:10 -070051 r = sd_event_default(&loop);
52 if (r < 0)
53 {
54 fprintf(stderr, "Error obtaining event loop: %s\n", strerror(-r));
Brad Bishop2afe7182016-08-13 14:08:17 -040055
Ed Tanous167e2372018-05-07 11:59:10 -070056 goto finish;
57 }
Brad Bishop2afe7182016-08-13 14:08:17 -040058
Ed Tanous167e2372018-05-07 11:59:10 -070059 r = sd_bus_attach_event(conn, loop, SD_EVENT_PRIORITY_NORMAL);
60 if (r < 0)
61 {
62 fprintf(stderr,
63 "Failed to attach system "
64 "bus to event loop: %s\n",
65 strerror(-r));
66 goto finish;
67 }
Brad Bishop2afe7182016-08-13 14:08:17 -040068
Ed Tanous167e2372018-05-07 11:59:10 -070069 r = mapper_wait_async(conn, loop, argv + 2, quit, loop, &wait);
70 if (r < 0)
71 {
72 fprintf(stderr, "Error configuring waitlist: %s\n", strerror(-r));
73 goto finish;
74 }
Brad Bishop2afe7182016-08-13 14:08:17 -040075
Ed Tanous167e2372018-05-07 11:59:10 -070076 r = sd_event_loop(loop);
77 if (r < 0)
78 {
79 fprintf(stderr, "Error starting event loop: %s\n", strerror(-r));
80 goto finish;
81 }
Brad Bishop2afe7182016-08-13 14:08:17 -040082
83finish:
Ed Tanous167e2372018-05-07 11:59:10 -070084 exit(r < 0 ? EXIT_FAILURE : EXIT_SUCCESS);
Brad Bishop2afe7182016-08-13 14:08:17 -040085}
86
Matt Spinlercc6ee9c2018-09-19 13:23:13 -050087static int subtree_main(int argc, char* argv[])
Adriana Kobylak04d7c7d2017-05-04 14:06:18 -050088{
Ed Tanous167e2372018-05-07 11:59:10 -070089 int r = 0;
90 int op = 0;
Matt Spinlercc6ee9c2018-09-19 13:23:13 -050091 static const char* token = ":";
92 char* tmp = NULL;
93 char* namespace = NULL;
94 char* interface = NULL;
95 sd_bus* conn = NULL;
96 sd_event* loop = NULL;
97 mapper_async_subtree* subtree = NULL;
Adriana Kobylak04d7c7d2017-05-04 14:06:18 -050098
Ed Tanous167e2372018-05-07 11:59:10 -070099 if (argc != 3)
100 {
101 fprintf(stderr,
102 "Usage: %s subtree-remove "
103 "NAMESPACE%sINTERFACE\n",
104 argv[0], token);
105 exit(EXIT_FAILURE);
106 }
Adriana Kobylak6a8688f2017-05-05 11:32:17 -0500107
Ed Tanous167e2372018-05-07 11:59:10 -0700108 op = MAPPER_OP_REMOVE;
Adriana Kobylak2a8bfc92017-05-11 09:16:02 -0500109
Ed Tanous167e2372018-05-07 11:59:10 -0700110 namespace = strtok_r(argv[2], token, &tmp);
111 interface = strtok_r(NULL, token, &tmp);
112 if ((namespace == NULL) || (interface == NULL))
113 {
114 fprintf(stderr, "Token '%s' was not found in '%s'\n", token, argv[2]);
115 exit(EXIT_FAILURE);
116 }
Adriana Kobylak04d7c7d2017-05-04 14:06:18 -0500117
Ed Tanous167e2372018-05-07 11:59:10 -0700118 r = sd_bus_default_system(&conn);
119 if (r < 0)
120 {
121 fprintf(stderr, "Error connecting to system bus: %s\n", strerror(-r));
122 goto finish;
123 }
Adriana Kobylak2a8bfc92017-05-11 09:16:02 -0500124
Ed Tanous167e2372018-05-07 11:59:10 -0700125 r = sd_event_default(&loop);
126 if (r < 0)
127 {
128 fprintf(stderr, "Error obtaining event loop: %s\n", strerror(-r));
129 goto finish;
130 }
Adriana Kobylak2a8bfc92017-05-11 09:16:02 -0500131
Ed Tanous167e2372018-05-07 11:59:10 -0700132 r = sd_bus_attach_event(conn, loop, SD_EVENT_PRIORITY_NORMAL);
133 if (r < 0)
134 {
135 fprintf(stderr, "Failed to attach system bus to event loop: %s\n",
136 strerror(-r));
137 goto finish;
138 }
Adriana Kobylak2a8bfc92017-05-11 09:16:02 -0500139
Ed Tanous167e2372018-05-07 11:59:10 -0700140 r = mapper_subtree_async(conn, loop, namespace, interface, quit, loop,
141 &subtree, op);
142 if (r < 0)
143 {
144 fprintf(stderr, "Error configuring subtree list: %s\n", strerror(-r));
145 goto finish;
146 }
Adriana Kobylak2a8bfc92017-05-11 09:16:02 -0500147
Ed Tanous167e2372018-05-07 11:59:10 -0700148 r = sd_event_loop(loop);
149 if (r < 0)
150 {
Matt Spinler59cbf342018-09-24 09:46:00 -0500151 /* If this function has been called after the interface in */
152 /* question has already been removed, then GetSubTree will */
153 /* fail and it will show up here. Treat as success instead. */
154 if (r == -ENXIO)
155 {
156 r = 0;
157 }
158 else
159 {
160 fprintf(stderr, "Error starting event loop: %d(%s)\n", r,
161 strerror(-r));
162 goto finish;
163 }
Ed Tanous167e2372018-05-07 11:59:10 -0700164 }
Adriana Kobylak2a8bfc92017-05-11 09:16:02 -0500165
166finish:
Ed Tanous167e2372018-05-07 11:59:10 -0700167 exit(r < 0 ? EXIT_FAILURE : EXIT_SUCCESS);
Adriana Kobylak04d7c7d2017-05-04 14:06:18 -0500168}
169
Andrew Geissler981f2662017-03-03 15:58:23 -0600170/* print out the distinct dbus service name for the input dbus path */
Matt Spinlercc6ee9c2018-09-19 13:23:13 -0500171static int get_service_main(int argc, char* argv[])
Andrew Geissler981f2662017-03-03 15:58:23 -0600172{
Ed Tanous167e2372018-05-07 11:59:10 -0700173 int r;
Matt Spinlercc6ee9c2018-09-19 13:23:13 -0500174 sd_bus* conn = NULL;
175 char* service = NULL;
Andrew Geissler981f2662017-03-03 15:58:23 -0600176
Ed Tanous167e2372018-05-07 11:59:10 -0700177 if (argc != 3)
178 {
179 fprintf(stderr, "Usage: %s get-service OBJECTPATH\n", argv[0]);
180 exit(EXIT_FAILURE);
181 }
Andrew Geissler981f2662017-03-03 15:58:23 -0600182
Ed Tanous167e2372018-05-07 11:59:10 -0700183 r = sd_bus_default_system(&conn);
184 if (r < 0)
185 {
186 fprintf(stderr, "Error connecting to system bus: %s\n", strerror(-r));
187 goto finish;
188 }
Andrew Geissler981f2662017-03-03 15:58:23 -0600189
Ed Tanous167e2372018-05-07 11:59:10 -0700190 r = mapper_get_service(conn, argv[2], &service);
191 if (r < 0)
192 {
193 fprintf(stderr, "Error finding '%s' service: %s\n", argv[2],
194 strerror(-r));
195 goto finish;
196 }
Andrew Geissler981f2662017-03-03 15:58:23 -0600197
Ed Tanous167e2372018-05-07 11:59:10 -0700198 printf("%s\n", service);
Andrew Geissler981f2662017-03-03 15:58:23 -0600199
200finish:
Ed Tanous167e2372018-05-07 11:59:10 -0700201 exit(r < 0 ? EXIT_FAILURE : EXIT_SUCCESS);
Andrew Geissler981f2662017-03-03 15:58:23 -0600202}
203
Matt Spinlercc6ee9c2018-09-19 13:23:13 -0500204int main(int argc, char* argv[])
Brad Bishop2afe7182016-08-13 14:08:17 -0400205{
Matt Spinlercc6ee9c2018-09-19 13:23:13 -0500206 static const char* usage =
Ed Tanous167e2372018-05-07 11:59:10 -0700207 "Usage: %s {COMMAND} ...\n"
208 "\nCOMMANDS:\n"
Ed Tanous167e2372018-05-07 11:59:10 -0700209 " wait wait for the specified objects to appear on the "
210 "DBus\n"
211 " subtree-remove\n"
212 " wait until the specified interface is not present\n"
213 " in any of the subtrees of the specified namespace\n"
214 " get-service return the service identifier for input path\n";
Brad Bishop2afe7182016-08-13 14:08:17 -0400215
Ed Tanous167e2372018-05-07 11:59:10 -0700216 if (argc < 2)
217 {
218 fprintf(stderr, usage, argv[0]);
219 exit(EXIT_FAILURE);
220 }
Brad Bishop2afe7182016-08-13 14:08:17 -0400221
Ed Tanous167e2372018-05-07 11:59:10 -0700222 if (!strcmp(argv[1], "wait"))
223 wait_main(argc, argv);
224 if (!strcmp(argv[1], "subtree-remove"))
225 subtree_main(argc, argv);
226 if (!strcmp(argv[1], "get-service"))
227 get_service_main(argc, argv);
Brad Bishop2afe7182016-08-13 14:08:17 -0400228
Ed Tanous167e2372018-05-07 11:59:10 -0700229 fprintf(stderr, usage, argv[0]);
230 exit(EXIT_FAILURE);
Brad Bishop2afe7182016-08-13 14:08:17 -0400231}