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