xref: /openbmc/phosphor-objmgr/libmapper/app.c (revision cc6ee9cb)
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 
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <systemd/sd-bus.h>
21 #include <systemd/sd-event.h>
22 
23 #include "mapper.h"
24 
25 static void quit(int r, void* loop)
26 {
27     sd_event_exit((sd_event*)loop, r);
28 }
29 
30 static int wait_main(int argc, char* argv[])
31 {
32     int r;
33     sd_bus* conn = NULL;
34     sd_event* loop = NULL;
35     mapper_async_wait* wait = NULL;
36 
37     if (argc < 3)
38     {
39         fprintf(stderr, "Usage: %s wait OBJECTPATH...\n", argv[0]);
40         exit(EXIT_FAILURE);
41     }
42 
43     r = sd_bus_default_system(&conn);
44     if (r < 0)
45     {
46         fprintf(stderr, "Error connecting to system bus: %s\n", strerror(-r));
47         goto finish;
48     }
49 
50     r = sd_event_default(&loop);
51     if (r < 0)
52     {
53         fprintf(stderr, "Error obtaining event loop: %s\n", strerror(-r));
54 
55         goto finish;
56     }
57 
58     r = sd_bus_attach_event(conn, loop, SD_EVENT_PRIORITY_NORMAL);
59     if (r < 0)
60     {
61         fprintf(stderr,
62                 "Failed to attach system "
63                 "bus to event loop: %s\n",
64                 strerror(-r));
65         goto finish;
66     }
67 
68     r = mapper_wait_async(conn, loop, argv + 2, quit, loop, &wait);
69     if (r < 0)
70     {
71         fprintf(stderr, "Error configuring waitlist: %s\n", strerror(-r));
72         goto finish;
73     }
74 
75     r = sd_event_loop(loop);
76     if (r < 0)
77     {
78         fprintf(stderr, "Error starting event loop: %s\n", strerror(-r));
79         goto finish;
80     }
81 
82 finish:
83     exit(r < 0 ? EXIT_FAILURE : EXIT_SUCCESS);
84 }
85 
86 static int subtree_main(int argc, char* argv[])
87 {
88     int r = 0;
89     int op = 0;
90     static const char* token = ":";
91     char* tmp = NULL;
92     char* namespace = NULL;
93     char* interface = NULL;
94     sd_bus* conn = NULL;
95     sd_event* loop = NULL;
96     mapper_async_subtree* subtree = NULL;
97 
98     if (argc != 3)
99     {
100         fprintf(stderr,
101                 "Usage: %s subtree-remove "
102                 "NAMESPACE%sINTERFACE\n",
103                 argv[0], token);
104         exit(EXIT_FAILURE);
105     }
106 
107     op = MAPPER_OP_REMOVE;
108 
109     namespace = strtok_r(argv[2], token, &tmp);
110     interface = strtok_r(NULL, token, &tmp);
111     if ((namespace == NULL) || (interface == NULL))
112     {
113         fprintf(stderr, "Token '%s' was not found in '%s'\n", token, argv[2]);
114         exit(EXIT_FAILURE);
115     }
116 
117     r = sd_bus_default_system(&conn);
118     if (r < 0)
119     {
120         fprintf(stderr, "Error connecting to system bus: %s\n", strerror(-r));
121         goto finish;
122     }
123 
124     r = sd_event_default(&loop);
125     if (r < 0)
126     {
127         fprintf(stderr, "Error obtaining event loop: %s\n", strerror(-r));
128         goto finish;
129     }
130 
131     r = sd_bus_attach_event(conn, loop, SD_EVENT_PRIORITY_NORMAL);
132     if (r < 0)
133     {
134         fprintf(stderr, "Failed to attach system bus to event loop: %s\n",
135                 strerror(-r));
136         goto finish;
137     }
138 
139     r = mapper_subtree_async(conn, loop, namespace, interface, quit, loop,
140                              &subtree, op);
141     if (r < 0)
142     {
143         fprintf(stderr, "Error configuring subtree list: %s\n", strerror(-r));
144         goto finish;
145     }
146 
147     r = sd_event_loop(loop);
148     if (r < 0)
149     {
150         fprintf(stderr, "Error starting event loop: %s\n", strerror(-r));
151         goto finish;
152     }
153 
154 finish:
155     exit(r < 0 ? EXIT_FAILURE : EXIT_SUCCESS);
156 }
157 
158 /* print out the distinct dbus service name for the input dbus path */
159 static int get_service_main(int argc, char* argv[])
160 {
161     int r;
162     sd_bus* conn = NULL;
163     char* service = NULL;
164 
165     if (argc != 3)
166     {
167         fprintf(stderr, "Usage: %s get-service OBJECTPATH\n", argv[0]);
168         exit(EXIT_FAILURE);
169     }
170 
171     r = sd_bus_default_system(&conn);
172     if (r < 0)
173     {
174         fprintf(stderr, "Error connecting to system bus: %s\n", strerror(-r));
175         goto finish;
176     }
177 
178     r = mapper_get_service(conn, argv[2], &service);
179     if (r < 0)
180     {
181         fprintf(stderr, "Error finding '%s' service: %s\n", argv[2],
182                 strerror(-r));
183         goto finish;
184     }
185 
186     printf("%s\n", service);
187 
188 finish:
189     exit(r < 0 ? EXIT_FAILURE : EXIT_SUCCESS);
190 }
191 
192 int main(int argc, char* argv[])
193 {
194     static const char* usage =
195         "Usage: %s {COMMAND} ...\n"
196         "\nCOMMANDS:\n"
197         "  wait           wait for the specified objects to appear on the "
198         "DBus\n"
199         "  subtree-remove\n"
200         "                 wait until the specified interface is not present\n"
201         "                 in any of the subtrees of the specified namespace\n"
202         "  get-service    return the service identifier for input path\n";
203 
204     if (argc < 2)
205     {
206         fprintf(stderr, usage, argv[0]);
207         exit(EXIT_FAILURE);
208     }
209 
210     if (!strcmp(argv[1], "wait"))
211         wait_main(argc, argv);
212     if (!strcmp(argv[1], "subtree-remove"))
213         subtree_main(argc, argv);
214     if (!strcmp(argv[1], "get-service"))
215         get_service_main(argc, argv);
216 
217     fprintf(stderr, usage, argv[0]);
218     exit(EXIT_FAILURE);
219 }
220