1 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ 2 /* dbus-print-message.h Utility function to print out a message 3 * 4 * Copyright (C) 2003 Philip Blundell <philb (at) gnu.org> 5 * Copyright (C) 2003 Red Hat, Inc. 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation; either version 2 of the License, or 10 * (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 * 21 */ 22 23 #include <config.h> 24 #include "dbus-print-message.h" 25 26 #include <stdlib.h> 27 #include "config.h" 28 29 static const char* 30 type_to_name (int message_type) 31 { 32 switch (message_type) 33 { 34 case DBUS_MESSAGE_TYPE_SIGNAL: 35 return "signal"; 36 case DBUS_MESSAGE_TYPE_METHOD_CALL: 37 return "method call"; 38 case DBUS_MESSAGE_TYPE_METHOD_RETURN: 39 return "method return"; 40 case DBUS_MESSAGE_TYPE_ERROR: 41 return "error"; 42 default: 43 return "(unknown message type)"; 44 } 45 } 46 47 #define INDENT 3 48 49 static void 50 indent (int depth) 51 { 52 while (depth-- > 0) 53 printf (" "); /* INDENT spaces. */ 54 } 55 56 static void 57 print_hex (unsigned char *bytes, unsigned int len, int depth) 58 { 59 unsigned int i, columns; 60 61 printf ("array of bytes [\n"); 62 63 indent (depth + 1); 64 65 /* Each byte takes 3 cells (two hexits, and a space), except the last one. */ 66 columns = (80 - ((depth + 1) * INDENT)) / 3; 67 68 if (columns < 8) 69 columns = 8; 70 71 i = 0; 72 73 while (i < len) 74 { 75 printf ("%02x", bytes[i]); 76 i++; 77 78 if (i != len) 79 { 80 if (i % columns == 0) 81 { 82 printf ("\n"); 83 indent (depth + 1); 84 } 85 else 86 { 87 printf (" "); 88 } 89 } 90 } 91 92 printf ("\n"); 93 indent (depth); 94 printf ("]\n"); 95 } 96 97 #define DEFAULT_SIZE 100 98 99 static void 100 print_ay (DBusMessageIter *iter, int depth) 101 { 102 /* Not using DBusString because it's not public API. It's 2009, and I'm 103 * manually growing a string chunk by chunk. 104 */ 105 unsigned char *bytes = malloc (DEFAULT_SIZE + 1); 106 unsigned int len = 0; 107 unsigned int max = DEFAULT_SIZE; 108 dbus_bool_t all_ascii = TRUE; 109 int current_type; 110 111 while ((current_type = dbus_message_iter_get_arg_type (iter)) 112 != DBUS_TYPE_INVALID) 113 { 114 unsigned char val; 115 116 dbus_message_iter_get_basic (iter, &val); 117 bytes[len] = val; 118 len++; 119 120 if (val < 32 || val > 126) 121 all_ascii = FALSE; 122 123 if (len == max) 124 { 125 max *= 2; 126 bytes = realloc (bytes, max + 1); 127 } 128 129 dbus_message_iter_next (iter); 130 } 131 132 if (all_ascii) 133 { 134 bytes[len] = '\0'; 135 printf ("array of bytes \"%s\"\n", bytes); 136 } 137 else 138 { 139 print_hex (bytes, len, depth); 140 } 141 142 free (bytes); 143 } 144 145 static void 146 print_iter (DBusMessageIter *iter, dbus_bool_t literal, int depth) 147 { 148 do 149 { 150 int type = dbus_message_iter_get_arg_type (iter); 151 152 if (type == DBUS_TYPE_INVALID) 153 break; 154 155 indent(depth); 156 157 switch (type) 158 { 159 case DBUS_TYPE_STRING: 160 { 161 char *val; 162 dbus_message_iter_get_basic (iter, &val); 163 if (!literal) 164 printf ("string \""); 165 printf ("%s", val); 166 if (!literal) 167 printf ("\"\n"); 168 break; 169 } 170 171 case DBUS_TYPE_SIGNATURE: 172 { 173 char *val; 174 dbus_message_iter_get_basic (iter, &val); 175 if (!literal) 176 printf ("signature \""); 177 printf ("%s", val); 178 if (!literal) 179 printf ("\"\n"); 180 break; 181 } 182 183 case DBUS_TYPE_OBJECT_PATH: 184 { 185 char *val; 186 dbus_message_iter_get_basic (iter, &val); 187 if (!literal) 188 printf ("object path \""); 189 printf ("%s", val); 190 if (!literal) 191 printf ("\"\n"); 192 break; 193 } 194 195 case DBUS_TYPE_INT16: 196 { 197 dbus_int16_t val; 198 dbus_message_iter_get_basic (iter, &val); 199 printf ("int16 %d\n", val); 200 break; 201 } 202 203 case DBUS_TYPE_UINT16: 204 { 205 dbus_uint16_t val; 206 dbus_message_iter_get_basic (iter, &val); 207 printf ("uint16 %u\n", val); 208 break; 209 } 210 211 case DBUS_TYPE_INT32: 212 { 213 dbus_int32_t val; 214 dbus_message_iter_get_basic (iter, &val); 215 printf ("int32 %d\n", val); 216 break; 217 } 218 219 case DBUS_TYPE_UINT32: 220 { 221 dbus_uint32_t val; 222 dbus_message_iter_get_basic (iter, &val); 223 printf ("uint32 %u\n", val); 224 break; 225 } 226 227 case DBUS_TYPE_INT64: 228 { 229 dbus_int64_t val; 230 dbus_message_iter_get_basic (iter, &val); 231 #ifdef DBUS_INT64_PRINTF_MODIFIER 232 printf ("int64 %" DBUS_INT64_PRINTF_MODIFIER "d\n", val); 233 #else 234 printf ("int64 (omitted)\n"); 235 #endif 236 break; 237 } 238 239 case DBUS_TYPE_UINT64: 240 { 241 dbus_uint64_t val; 242 dbus_message_iter_get_basic (iter, &val); 243 #ifdef DBUS_INT64_PRINTF_MODIFIER 244 printf ("uint64 %" DBUS_INT64_PRINTF_MODIFIER "u\n", val); 245 #else 246 printf ("uint64 (omitted)\n"); 247 #endif 248 break; 249 } 250 251 case DBUS_TYPE_DOUBLE: 252 { 253 double val; 254 dbus_message_iter_get_basic (iter, &val); 255 printf ("double %g\n", val); 256 break; 257 } 258 259 case DBUS_TYPE_BYTE: 260 { 261 unsigned char val; 262 dbus_message_iter_get_basic (iter, &val); 263 printf ("byte %d\n", val); 264 break; 265 } 266 267 case DBUS_TYPE_BOOLEAN: 268 { 269 dbus_bool_t val; 270 dbus_message_iter_get_basic (iter, &val); 271 printf ("boolean %s\n", val ? "true" : "false"); 272 break; 273 } 274 275 case DBUS_TYPE_VARIANT: 276 { 277 DBusMessageIter subiter; 278 279 dbus_message_iter_recurse (iter, &subiter); 280 281 printf ("variant "); 282 print_iter (&subiter, literal, depth+1); 283 break; 284 } 285 case DBUS_TYPE_ARRAY: 286 { 287 int current_type; 288 DBusMessageIter subiter; 289 290 dbus_message_iter_recurse (iter, &subiter); 291 292 current_type = dbus_message_iter_get_arg_type (&subiter); 293 294 if (current_type == DBUS_TYPE_BYTE) 295 { 296 print_ay (&subiter, depth); 297 break; 298 } 299 300 printf("array [\n"); 301 while (current_type != DBUS_TYPE_INVALID) 302 { 303 print_iter (&subiter, literal, depth+1); 304 305 dbus_message_iter_next (&subiter); 306 current_type = dbus_message_iter_get_arg_type (&subiter); 307 308 if (current_type != DBUS_TYPE_INVALID) 309 printf (","); 310 } 311 indent(depth); 312 printf("]\n"); 313 break; 314 } 315 case DBUS_TYPE_DICT_ENTRY: 316 { 317 DBusMessageIter subiter; 318 319 dbus_message_iter_recurse (iter, &subiter); 320 321 printf("dict entry(\n"); 322 print_iter (&subiter, literal, depth+1); 323 dbus_message_iter_next (&subiter); 324 print_iter (&subiter, literal, depth+1); 325 indent(depth); 326 printf(")\n"); 327 break; 328 } 329 330 case DBUS_TYPE_STRUCT: 331 { 332 int current_type; 333 DBusMessageIter subiter; 334 335 dbus_message_iter_recurse (iter, &subiter); 336 337 printf("struct {\n"); 338 while ((current_type = dbus_message_iter_get_arg_type (&subiter)) != DBUS_TYPE_INVALID) 339 { 340 print_iter (&subiter, literal, depth+1); 341 dbus_message_iter_next (&subiter); 342 if (dbus_message_iter_get_arg_type (&subiter) != DBUS_TYPE_INVALID) 343 printf (","); 344 } 345 indent(depth); 346 printf("}\n"); 347 break; 348 } 349 350 default: 351 printf (" (dbus-monitor too dumb to decipher arg type '%c')\n", type); 352 break; 353 } 354 } while (dbus_message_iter_next (iter)); 355 } 356 357 void 358 print_message (DBusMessage *message, dbus_bool_t literal) 359 { 360 DBusMessageIter iter; 361 const char *sender; 362 const char *destination; 363 int message_type; 364 365 message_type = dbus_message_get_type (message); 366 sender = dbus_message_get_sender (message); 367 destination = dbus_message_get_destination (message); 368 369 if (!literal) 370 { 371 printf ("%s sender=%s -> dest=%s", 372 type_to_name (message_type), 373 sender ? sender : "(null sender)", 374 destination ? destination : "(null destination)"); 375 376 switch (message_type) 377 { 378 case DBUS_MESSAGE_TYPE_METHOD_CALL: 379 case DBUS_MESSAGE_TYPE_SIGNAL: 380 printf (" serial=%u path=%s; interface=%s; member=%s\n", 381 dbus_message_get_serial (message), 382 dbus_message_get_path (message), 383 dbus_message_get_interface (message), 384 dbus_message_get_member (message)); 385 break; 386 387 case DBUS_MESSAGE_TYPE_METHOD_RETURN: 388 printf (" reply_serial=%u\n", 389 dbus_message_get_reply_serial (message)); 390 break; 391 392 case DBUS_MESSAGE_TYPE_ERROR: 393 printf (" error_name=%s reply_serial=%u\n", 394 dbus_message_get_error_name (message), 395 dbus_message_get_reply_serial (message)); 396 break; 397 398 default: 399 printf ("\n"); 400 break; 401 } 402 } 403 404 dbus_message_iter_init (message, &iter); 405 print_iter (&iter, literal, 1); 406 fflush (stdout); 407 408 } 409 410