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 <stdlib.h> 17 #include <stdio.h> 18 #include <systemd/sd-bus.h> 19 #include <systemd/sd-event.h> 20 #include "mapper.h" 21 22 static int call_main(int argc, char *argv[]) 23 { 24 int r; 25 sd_bus *conn = NULL; 26 char *service = NULL; 27 sd_bus_message *m = NULL, *reply = NULL; 28 sd_bus_error error = SD_BUS_ERROR_NULL; 29 30 if(argc < 5) { 31 fprintf(stderr, "Usage: %s call OBJECTPATH INTERFACE " 32 "METHOD [SIGNATURE [ARGUMENT...]\n", argv[0]); 33 r = -1; 34 goto finish; 35 } 36 37 r = sd_bus_default_system(&conn); 38 if(r < 0) { 39 fprintf(stderr, "Error connecting to system bus: %s\n", 40 strerror(-r)); 41 goto finish; 42 } 43 44 r = mapper_get_service(conn, argv[2], &service); 45 if(r < 0) { 46 fprintf(stderr, "Error finding '%s' service: %s\n", 47 argv[2], strerror(-r)); 48 goto finish; 49 } 50 51 r = sd_bus_message_new_method_call( 52 conn, &m, service, argv[2], argv[3], argv[4]); 53 if(r < 0) { 54 fprintf(stderr, "Error populating message: %s\n", 55 strerror(-r)); 56 goto finish; 57 } 58 59 if(argc > 5) { 60 char **p; 61 p = argv + 6; 62 r = sd_bus_message_append_cmdline(m, argv[5], &p); 63 if(r < 0) { 64 fprintf(stderr, "Error appending method arguments: %s\n", 65 strerror(-r)); 66 goto finish; 67 } 68 } 69 70 r = sd_bus_call(conn, m, 0, &error, &reply); 71 if(r < 0) { 72 fprintf(stderr, "Error invoking method: %s\n", 73 strerror(-r)); 74 goto finish; 75 } 76 77 finish: 78 exit(r < 0 ? EXIT_FAILURE : EXIT_SUCCESS); 79 } 80 81 static void quit(int r, void *loop) 82 { 83 sd_event_exit((sd_event *)loop, r); 84 } 85 86 static int wait_main(int argc, char *argv[]) 87 { 88 int r; 89 sd_bus *conn = NULL; 90 sd_event *loop = NULL; 91 mapper_async_wait *wait = NULL; 92 93 if(argc < 3) { 94 fprintf(stderr, "Usage: %s wait OBJECTPATH...\n", argv[0]); 95 exit(EXIT_FAILURE); 96 } 97 98 r = sd_bus_default_system(&conn); 99 if(r < 0) { 100 fprintf(stderr, "Error connecting to system bus: %s\n", 101 strerror(-r)); 102 goto finish; 103 } 104 105 r = sd_event_default(&loop); 106 if (r < 0) { 107 fprintf(stderr, "Error obtaining event loop: %s\n", 108 strerror(-r)); 109 110 goto finish; 111 } 112 113 r = sd_bus_attach_event(conn, loop, SD_EVENT_PRIORITY_NORMAL); 114 if (r < 0) { 115 fprintf(stderr, "Failed to attach system " 116 "bus to event loop: %s\n", 117 strerror(-r)); 118 goto finish; 119 } 120 121 r = mapper_wait_async(conn, loop, argv+2, quit, loop, &wait); 122 if(r < 0) { 123 fprintf(stderr, "Error configuring waitlist: %s\n", 124 strerror(-r)); 125 goto finish; 126 } 127 128 r = sd_event_loop(loop); 129 if(r < 0) { 130 fprintf(stderr, "Error starting event loop: %s\n", 131 strerror(-r)); 132 goto finish; 133 } 134 135 finish: 136 exit(r < 0 ? EXIT_FAILURE : EXIT_SUCCESS); 137 } 138 139 int main(int argc, char *argv[]) 140 { 141 static const char *usage = 142 "Usage: %s {COMMAND} ...\n" 143 "\nCOMMANDS:\n" 144 " call invoke the specified method\n" 145 " wait wait for the specified objects to appear on the DBus\n"; 146 147 if(argc < 2) { 148 fprintf(stderr, usage, argv[0]); 149 exit(EXIT_FAILURE); 150 } 151 152 if(!strcmp(argv[1], "call")) 153 call_main(argc, argv); 154 if(!strcmp(argv[1], "wait")) 155 wait_main(argc, argv); 156 157 fprintf(stderr, usage, argv[0]); 158 exit(EXIT_FAILURE); 159 } 160