xref: /openbmc/phosphor-objmgr/libmapper/app.c (revision a4555f60)
1 /**
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 "config.h"
17 #include <stdlib.h>
18 #include <stdio.h>
19 #include <systemd/sd-bus.h>
20 #include <systemd/sd-event.h>
21 #include "mapper.h"
22 
23 static 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) {
47 		fprintf(stderr, "Error finding '%s' service: %s\n",
48 				argv[2], strerror(-r));
49 		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 
78 finish:
79 	exit(r < 0 ? EXIT_FAILURE : EXIT_SUCCESS);
80 }
81 
82 static void quit(int r, void *loop)
83 {
84 	sd_event_exit((sd_event *)loop, r);
85 }
86 
87 static int wait_main(int argc, char *argv[])
88 {
89 	int r;
90 	sd_bus *conn = NULL;
91 	sd_event *loop = NULL;
92 	mapper_async_wait *wait = NULL;
93 
94 	if(argc < 3) {
95 		fprintf(stderr, "Usage: %s wait OBJECTPATH...\n", argv[0]);
96 		exit(EXIT_FAILURE);
97 	}
98 
99 	r = sd_bus_default_system(&conn);
100 	if(r < 0) {
101 		fprintf(stderr, "Error connecting to system bus: %s\n",
102 				strerror(-r));
103 		goto finish;
104 	}
105 
106 	r = sd_event_default(&loop);
107 	if (r < 0) {
108 		fprintf(stderr, "Error obtaining event loop: %s\n",
109 				strerror(-r));
110 
111 		goto finish;
112 	}
113 
114 	r = sd_bus_attach_event(conn, loop, SD_EVENT_PRIORITY_NORMAL);
115 	if (r < 0) {
116 		fprintf(stderr, "Failed to attach system "
117 				"bus to event loop: %s\n",
118 				strerror(-r));
119 		goto finish;
120 	}
121 
122 	if (!strcmp(argv[1], "wait"))
123 		r = mapper_wait_async(conn, loop, argv+2, quit, loop, &wait, true);
124 	else if (!strcmp(argv[1], "wait-until-removed"))
125 		r = mapper_wait_async(conn, loop, argv+2, quit, loop, &wait, false);
126 	if(r < 0) {
127 		fprintf(stderr, "Error configuring waitlist: %s\n",
128 				strerror(-r));
129 		goto finish;
130 	}
131 
132 	r = sd_event_loop(loop);
133 	if(r < 0) {
134 		fprintf(stderr, "Error starting event loop: %s\n",
135 				strerror(-r));
136 		goto finish;
137 	}
138 
139 finish:
140 	exit(r < 0 ? EXIT_FAILURE : EXIT_SUCCESS);
141 }
142 
143 /* print out the distinct dbus service name for the input dbus path */
144 static int get_service_main(int argc, char *argv[])
145 {
146 	int r;
147 	sd_bus *conn = NULL;
148 	char *service = NULL;
149 
150 	if(argc != 3) {
151 		fprintf(stderr, "Usage: %s get-service OBJECTPATH\n",
152 				argv[0]);
153 		exit(EXIT_FAILURE);
154 	}
155 
156 	r = sd_bus_default_system(&conn);
157 	if(r < 0) {
158 		fprintf(stderr, "Error connecting to system bus: %s\n",
159 				strerror(-r));
160 		goto finish;
161 	}
162 
163 	r = mapper_get_service(conn, argv[2], &service);
164 	if(r < 0) {
165 		fprintf(stderr, "Error finding '%s' service: %s\n",
166 				argv[2], strerror(-r));
167 		goto finish;
168 	}
169 
170 	printf("%s\n", service);
171 
172 
173 finish:
174 	exit(r < 0 ? EXIT_FAILURE : EXIT_SUCCESS);
175 }
176 
177 int main(int argc, char *argv[])
178 {
179 	static const char *usage =
180 		"Usage: %s {COMMAND} ...\n"
181 		"\nCOMMANDS:\n"
182 		"  call           invoke the specified method\n"
183 		"  wait           wait for the specified objects to appear on the DBus\n"
184 		"  wait-until-removed"
185 		"		wait until the specified objects are not present in the DBus\n"
186 		"  get-service    return the service identifier for input path\n";
187 
188 	if(argc < 2) {
189 		fprintf(stderr, usage, argv[0]);
190 		exit(EXIT_FAILURE);
191 	}
192 
193 	if(!strcmp(argv[1], "call"))
194 		call_main(argc, argv);
195 	if(!strcmp(argv[1], "wait") ||
196 	   !strcmp(argv[1], "wait-until-removed"))
197 		wait_main(argc, argv);
198 	if(!strcmp(argv[1], "get-service"))
199 		get_service_main(argc, argv);
200 
201 	fprintf(stderr, usage, argv[0]);
202 	exit(EXIT_FAILURE);
203 }
204