blob: e4aea03f94f95dcecba4ace4e277d7d83ab38924 [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"
Brad Bishop2afe7182016-08-13 14:08:17 -040017#include <stdlib.h>
18#include <stdio.h>
19#include <systemd/sd-bus.h>
20#include <systemd/sd-event.h>
21#include "mapper.h"
22
23static int call_main(int argc, char *argv[])
24{
25 int r;
26 sd_bus *conn = NULL;
27 char *service = NULL;
28 sd_bus_message *m = NULL, *reply = NULL;
29 sd_bus_error error = SD_BUS_ERROR_NULL;
30
31 if(argc < 5) {
32 fprintf(stderr, "Usage: %s call OBJECTPATH INTERFACE "
33 "METHOD [SIGNATURE [ARGUMENT...]\n", argv[0]);
34 r = -1;
35 goto finish;
36 }
37
38 r = sd_bus_default_system(&conn);
39 if(r < 0) {
40 fprintf(stderr, "Error connecting to system bus: %s\n",
41 strerror(-r));
42 goto finish;
43 }
44
45 r = mapper_get_service(conn, argv[2], &service);
46 if(r < 0) {
Brad Bishope3bd2242016-11-02 11:04:27 -040047 fprintf(stderr, "Error finding '%s' service: %s\n",
48 argv[2], strerror(-r));
Brad Bishop2afe7182016-08-13 14:08:17 -040049 goto finish;
50 }
51
52 r = sd_bus_message_new_method_call(
53 conn, &m, service, argv[2], argv[3], argv[4]);
54 if(r < 0) {
55 fprintf(stderr, "Error populating message: %s\n",
56 strerror(-r));
57 goto finish;
58 }
59
60 if(argc > 5) {
61 char **p;
62 p = argv + 6;
63 r = sd_bus_message_append_cmdline(m, argv[5], &p);
64 if(r < 0) {
65 fprintf(stderr, "Error appending method arguments: %s\n",
66 strerror(-r));
67 goto finish;
68 }
69 }
70
71 r = sd_bus_call(conn, m, 0, &error, &reply);
72 if(r < 0) {
73 fprintf(stderr, "Error invoking method: %s\n",
74 strerror(-r));
75 goto finish;
76 }
77
78finish:
79 exit(r < 0 ? EXIT_FAILURE : EXIT_SUCCESS);
80}
81
82static void quit(int r, void *loop)
83{
84 sd_event_exit((sd_event *)loop, r);
85}
86
Adriana Kobylake4d6c792017-04-04 12:47:38 -050087static char** split_args(char* arg)
88{
89 int i = 0;
90 int count = 0;
91 char* p = arg;
92
93 while((p = strchr(p, ' ')) != NULL) {
94 count++;
95 p++;
96 }
97 if (count == 0)
98 return NULL;
99
100 /* Need to allocate space for count+1 number of arguments */
101 count++;
102 char** args = (char**)malloc(sizeof(*args) * count);
103 if (args != NULL) {
104 i = 0;
105 p = strtok(arg, " ");
106 while((p != NULL) && (i < count)) {
107 args[i++] = p;
108 p = strtok(NULL, " ");
109 }
110 }
111
112 return args;
113}
114
Brad Bishop2afe7182016-08-13 14:08:17 -0400115static int wait_main(int argc, char *argv[])
116{
117 int r;
Adriana Kobylake4d6c792017-04-04 12:47:38 -0500118 bool free_args = false;
119 char** args = argv + 2;
Brad Bishop2afe7182016-08-13 14:08:17 -0400120 sd_bus *conn = NULL;
121 sd_event *loop = NULL;
122 mapper_async_wait *wait = NULL;
123
Adriana Kobylake4d6c792017-04-04 12:47:38 -0500124 if((!strcmp(argv[1], "wait")) && argc < 3) {
Brad Bishop2afe7182016-08-13 14:08:17 -0400125 fprintf(stderr, "Usage: %s wait OBJECTPATH...\n", argv[0]);
126 exit(EXIT_FAILURE);
Adriana Kobylake4d6c792017-04-04 12:47:38 -0500127 } else if((!strcmp(argv[1], "wait-until-removed")) && argc < 4) {
128 /* The arguments can be passed by a single string, ex: "intf obj1..." */
129 /* Try to split the single into the multiple arguments */
130 args = split_args(argv[2]);
131 if (args != NULL)
132 free_args = true;
133 else {
134 fprintf(stderr, "Usage: %s wait-until-removed \
135 INTERFACE OBJECTPATH...\n", argv[0]);
136 exit(EXIT_FAILURE);
137 }
Brad Bishop2afe7182016-08-13 14:08:17 -0400138 }
139
140 r = sd_bus_default_system(&conn);
141 if(r < 0) {
142 fprintf(stderr, "Error connecting to system bus: %s\n",
143 strerror(-r));
144 goto finish;
145 }
146
147 r = sd_event_default(&loop);
148 if (r < 0) {
149 fprintf(stderr, "Error obtaining event loop: %s\n",
150 strerror(-r));
151
152 goto finish;
153 }
154
155 r = sd_bus_attach_event(conn, loop, SD_EVENT_PRIORITY_NORMAL);
156 if (r < 0) {
157 fprintf(stderr, "Failed to attach system "
158 "bus to event loop: %s\n",
159 strerror(-r));
160 goto finish;
161 }
162
Adriana Kobylak9f4c3c72017-03-28 09:02:20 -0500163 if (!strcmp(argv[1], "wait"))
Adriana Kobylake4d6c792017-04-04 12:47:38 -0500164 r = mapper_wait_async(conn, loop, NULL, args, quit, loop, &wait,
165 true);
Adriana Kobylak9f4c3c72017-03-28 09:02:20 -0500166 else if (!strcmp(argv[1], "wait-until-removed"))
Adriana Kobylake4d6c792017-04-04 12:47:38 -0500167 r = mapper_wait_async(conn, loop, args[0], args+1, quit, loop, &wait,
168 false);
Brad Bishop2afe7182016-08-13 14:08:17 -0400169 if(r < 0) {
170 fprintf(stderr, "Error configuring waitlist: %s\n",
171 strerror(-r));
172 goto finish;
173 }
174
175 r = sd_event_loop(loop);
176 if(r < 0) {
177 fprintf(stderr, "Error starting event loop: %s\n",
178 strerror(-r));
179 goto finish;
180 }
181
182finish:
Adriana Kobylake4d6c792017-04-04 12:47:38 -0500183 if (free_args)
184 free(args);
Brad Bishop2afe7182016-08-13 14:08:17 -0400185 exit(r < 0 ? EXIT_FAILURE : EXIT_SUCCESS);
186}
187
Andrew Geissler981f2662017-03-03 15:58:23 -0600188/* print out the distinct dbus service name for the input dbus path */
189static int get_service_main(int argc, char *argv[])
190{
191 int r;
192 sd_bus *conn = NULL;
193 char *service = NULL;
194
195 if(argc != 3) {
196 fprintf(stderr, "Usage: %s get-service OBJECTPATH\n",
197 argv[0]);
198 exit(EXIT_FAILURE);
199 }
200
201 r = sd_bus_default_system(&conn);
202 if(r < 0) {
203 fprintf(stderr, "Error connecting to system bus: %s\n",
204 strerror(-r));
205 goto finish;
206 }
207
208 r = mapper_get_service(conn, argv[2], &service);
209 if(r < 0) {
210 fprintf(stderr, "Error finding '%s' service: %s\n",
211 argv[2], strerror(-r));
212 goto finish;
213 }
214
215 printf("%s\n", service);
216
217
218finish:
219 exit(r < 0 ? EXIT_FAILURE : EXIT_SUCCESS);
220}
221
Brad Bishop2afe7182016-08-13 14:08:17 -0400222int main(int argc, char *argv[])
223{
224 static const char *usage =
225 "Usage: %s {COMMAND} ...\n"
226 "\nCOMMANDS:\n"
227 " call invoke the specified method\n"
Andrew Geissler981f2662017-03-03 15:58:23 -0600228 " wait wait for the specified objects to appear on the DBus\n"
Adriana Kobylak9f4c3c72017-03-28 09:02:20 -0500229 " wait-until-removed"
230 " wait until the specified objects are not present in the DBus\n"
Andrew Geissler981f2662017-03-03 15:58:23 -0600231 " get-service return the service identifier for input path\n";
Brad Bishop2afe7182016-08-13 14:08:17 -0400232
233 if(argc < 2) {
234 fprintf(stderr, usage, argv[0]);
235 exit(EXIT_FAILURE);
236 }
237
238 if(!strcmp(argv[1], "call"))
239 call_main(argc, argv);
Adriana Kobylak9f4c3c72017-03-28 09:02:20 -0500240 if(!strcmp(argv[1], "wait") ||
241 !strcmp(argv[1], "wait-until-removed"))
Brad Bishop2afe7182016-08-13 14:08:17 -0400242 wait_main(argc, argv);
Andrew Geissler981f2662017-03-03 15:58:23 -0600243 if(!strcmp(argv[1], "get-service"))
244 get_service_main(argc, argv);
Brad Bishop2afe7182016-08-13 14:08:17 -0400245
246 fprintf(stderr, usage, argv[0]);
247 exit(EXIT_FAILURE);
248}