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