xref: /openbmc/phosphor-objmgr/libmapper/app.c (revision c7a7c45f)
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 	r = mapper_wait_async(conn, loop, argv+2, quit, loop, &wait);
123 	if(r < 0) {
124 		fprintf(stderr, "Error configuring waitlist: %s\n",
125 				strerror(-r));
126 		goto finish;
127 	}
128 
129 	r = sd_event_loop(loop);
130 	if(r < 0) {
131 		fprintf(stderr, "Error starting event loop: %s\n",
132 				strerror(-r));
133 		goto finish;
134 	}
135 
136 finish:
137 	exit(r < 0 ? EXIT_FAILURE : EXIT_SUCCESS);
138 }
139 
140 /* print out the distinct dbus service name for the input dbus path */
141 static int get_service_main(int argc, char *argv[])
142 {
143 	int r;
144 	sd_bus *conn = NULL;
145 	char *service = NULL;
146 
147 	if(argc != 3) {
148 		fprintf(stderr, "Usage: %s get-service OBJECTPATH\n",
149 				argv[0]);
150 		exit(EXIT_FAILURE);
151 	}
152 
153 	r = sd_bus_default_system(&conn);
154 	if(r < 0) {
155 		fprintf(stderr, "Error connecting to system bus: %s\n",
156 				strerror(-r));
157 		goto finish;
158 	}
159 
160 	r = mapper_get_service(conn, argv[2], &service);
161 	if(r < 0) {
162 		fprintf(stderr, "Error finding '%s' service: %s\n",
163 				argv[2], strerror(-r));
164 		goto finish;
165 	}
166 
167 	printf("%s\n", service);
168 
169 
170 finish:
171 	exit(r < 0 ? EXIT_FAILURE : EXIT_SUCCESS);
172 }
173 
174 int main(int argc, char *argv[])
175 {
176 	static const char *usage =
177 		"Usage: %s {COMMAND} ...\n"
178 		"\nCOMMANDS:\n"
179 		"  call           invoke the specified method\n"
180 		"  wait           wait for the specified objects to appear on the DBus\n"
181 		"  get-service    return the service identifier for input path\n";
182 
183 	if(argc < 2) {
184 		fprintf(stderr, usage, argv[0]);
185 		exit(EXIT_FAILURE);
186 	}
187 
188 	if(!strcmp(argv[1], "call"))
189 		call_main(argc, argv);
190 	if(!strcmp(argv[1], "wait"))
191 		wait_main(argc, argv);
192 	if(!strcmp(argv[1], "get-service"))
193 		get_service_main(argc, argv);
194 
195 	fprintf(stderr, usage, argv[0]);
196 	exit(EXIT_FAILURE);
197 }
198