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