Changeset 43791 in vbox for trunk/src/VBox/Additions/common/VBoxService/VBoxServiceVMInfo.cpp
- Timestamp:
- Nov 1, 2012 1:25:57 PM (12 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/common/VBoxService/VBoxServiceVMInfo.cpp
r43363 r43791 39 39 # include <sys/socket.h> 40 40 # include <net/if.h> 41 # include <pwd.h> /* getpwuid */ 41 42 # include <unistd.h> 42 43 # if !defined(RT_OS_OS2) && !defined(RT_OS_FREEBSD) && !defined(RT_OS_HAIKU) … … 51 52 # include <net/if_dl.h> /* LLADDR */ 52 53 # include <netdb.h> /* getnameinfo */ 54 # endif 55 # ifdef VBOX_WITH_DBUS 56 # include <VBox/dbus.h> 53 57 # endif 54 58 #endif … … 85 89 86 90 91 /******************************************************************************* 92 * Defines * 93 *******************************************************************************/ 94 #ifdef VBOX_WITH_DBUS 95 /** ConsoleKit defines (taken from 0.4.5). */ 96 #define CK_NAME "org.freedesktop.ConsoleKit" 97 #define CK_PATH "/org/freedesktop/ConsoleKit" 98 #define CK_INTERFACE "org.freedesktop.ConsoleKit" 99 100 #define CK_MANAGER_PATH "/org/freedesktop/ConsoleKit/Manager" 101 #define CK_MANAGER_INTERFACE "org.freedesktop.ConsoleKit.Manager" 102 #define CK_SEAT_INTERFACE "org.freedesktop.ConsoleKit.Seat" 103 #define CK_SESSION_INTERFACE "org.freedesktop.ConsoleKit.Session" 104 #endif 105 106 87 107 88 108 /** … … 241 261 } 242 262 263 # if defined(VBOX_WITH_DBUS) && defined(RT_OS_LINUX) /* Not yet for Solaris/FreeBSB. */ 264 /* 265 * Simple wrapper to work around compiler-specific va_list madness. 266 */ 267 static dbus_bool_t vboxService_dbus_message_get_args(DBusMessage *message, 268 DBusError *error, 269 int first_arg_type, 270 ...) 271 { 272 va_list va; 273 va_start(va, first_arg_type); 274 dbus_bool_t ret = dbus_message_get_args_valist(message, error, 275 first_arg_type, va); 276 va_end(va); 277 return ret; 278 } 279 #endif 243 280 244 281 /** … … 282 319 rc = VERR_NO_MEMORY; 283 320 284 /* Process all entries in the utmp file. */ 321 /* Process all entries in the utmp file. 322 * Note: This only handles */ 285 323 while ( (ut_user = getutxent()) 286 324 && RT_SUCCESS(rc)) 287 325 { 288 VBoxServiceVerbose(4, "Found logged in user \"%s\" (type: %d)\n",289 ut_user->ut_user, ut_user->ut_type );326 VBoxServiceVerbose(4, "Found entry \"%s\" (type: %d, PID: %RU32, session: %RU32)\n", 327 ut_user->ut_user, ut_user->ut_type, ut_user->ut_pid, ut_user->ut_session); 290 328 if (cUsersInList > cListSize) 291 329 { … … 297 335 298 336 /* Make sure we don't add user names which are not 299 * part of type USER_PROCES S. */300 if (ut_user->ut_type == USER_PROCESS) 337 * part of type USER_PROCES. */ 338 if (ut_user->ut_type == USER_PROCESS) /* Regular user process. */ 301 339 { 302 340 bool fFound = false; … … 317 355 } 318 356 357 #ifdef VBOX_WITH_DBUS 358 # if defined(RT_OS_LINUX) /* Not yet for Solaris/FreeBSB. */ 359 /* Handle desktop sessions using ConsoleKit. */ 360 VBoxServiceVerbose(4, "Checking ConsoleKit sessions ...\n"); 361 362 DBusError dbErr; 363 dbus_error_init(&dbErr); 364 365 DBusConnection *pConnection = dbus_bus_get(DBUS_BUS_SYSTEM, &dbErr); 366 if ( pConnection 367 && !dbus_error_is_set(&dbErr)) 368 { 369 /* Get all available sessions. */ 370 DBusMessage *pMsgSessions = dbus_message_new_method_call("org.freedesktop.ConsoleKit", 371 "/org/freedesktop/ConsoleKit/Manager", 372 "org.freedesktop.ConsoleKit.Manager", 373 "GetSessions"); 374 if ( pMsgSessions 375 && (dbus_message_get_type(pMsgSessions) == DBUS_MESSAGE_TYPE_METHOD_CALL)) 376 { 377 DBusMessage *pReplySessions = dbus_connection_send_with_reply_and_block(pConnection, 378 pMsgSessions, 30 * 1000 /* 30s timeout */, 379 &dbErr); 380 if ( pReplySessions 381 && !dbus_error_is_set(&dbErr)) 382 { 383 char **ppszSessions; int cSessions; 384 if ( (dbus_message_get_type(pMsgSessions) == DBUS_MESSAGE_TYPE_METHOD_CALL) 385 && vboxService_dbus_message_get_args(pReplySessions, &dbErr, DBUS_TYPE_ARRAY, 386 DBUS_TYPE_OBJECT_PATH, &ppszSessions, &cSessions, 387 DBUS_TYPE_INVALID /* Termination */)) 388 { 389 VBoxServiceVerbose(4, "ConsoleKit: retrieved %RU16 session(s)\n", cSessions); 390 AssertPtr(*ppszSessions); 391 392 char **ppszCurSession = ppszSessions; 393 for (ppszCurSession; *ppszCurSession; ppszCurSession++) 394 { 395 VBoxServiceVerbose(4, "ConsoleKit: processing session '%s' ...\n", *ppszCurSession); 396 397 /* *ppszCurSession now contains the object path 398 * (e.g. "/org/freedesktop/ConsoleKit/Session1"). */ 399 DBusMessage *pMsgUnixUser = dbus_message_new_method_call("org.freedesktop.ConsoleKit", 400 *ppszCurSession, 401 "org.freedesktop.ConsoleKit.Session", 402 "GetUnixUser"); 403 if ( pMsgUnixUser 404 && dbus_message_get_type(pMsgUnixUser) == DBUS_MESSAGE_TYPE_METHOD_CALL) 405 { 406 DBusMessage *pReplyUnixUser = dbus_connection_send_with_reply_and_block(pConnection, 407 pMsgUnixUser, 30 * 1000 /* 30s timeout */, 408 &dbErr); 409 if ( pReplyUnixUser 410 && !dbus_error_is_set(&dbErr)) 411 { 412 DBusMessageIter itMsg; 413 if ( dbus_message_iter_init(pReplyUnixUser, &itMsg) 414 && dbus_message_iter_get_arg_type(&itMsg) == DBUS_TYPE_UINT32) 415 { 416 /* Get uid from message. */ 417 uint32_t uid; 418 dbus_message_iter_get_basic(&itMsg, &uid); 419 420 /* Look up user name (realname) from uid. */ 421 setpwent(); 422 struct passwd *ppwEntry = getpwuid(uid); 423 if ( ppwEntry 424 && ppwEntry->pw_name) 425 { 426 VBoxServiceVerbose(4, "ConsoleKit: session '%s' -> %s (uid: %RU32)\n", 427 *ppszCurSession, ppwEntry->pw_name, uid); 428 429 bool fFound = false; 430 for (uint32_t i = 0; i < cUsersInList && !fFound; i++) 431 fFound = strcmp(papszUsers[i], ppwEntry->pw_name) == 0; 432 433 if (!fFound) 434 { 435 VBoxServiceVerbose(4, "ConsoleKit: adding user \"%s\" to list\n", 436 ppwEntry->pw_name); 437 438 rc = RTStrDupEx(&papszUsers[cUsersInList], (const char *)ppwEntry->pw_name); 439 if (RT_FAILURE(rc)) 440 break; 441 cUsersInList++; 442 } 443 } 444 else 445 VBoxServiceError("ConsoleKit: unable to lookup user name for uid=%RU32\n", uid); 446 } 447 else 448 AssertMsgFailed(("ConsoleKit: GetUnixUser returned a wrong argument type\n")); 449 } 450 451 if (pReplyUnixUser) 452 dbus_message_unref(pReplyUnixUser); 453 } 454 else 455 VBoxServiceError("ConsoleKit: unable to retrieve user for session '%s' (msg type=%d): %s", 456 *ppszCurSession, dbus_message_get_type(pMsgUnixUser), 457 dbus_error_is_set(&dbErr) ? dbErr.message : "No error information available\n"); 458 459 if (pMsgUnixUser) 460 dbus_message_unref(pMsgUnixUser); 461 } 462 463 dbus_free_string_array(ppszSessions); 464 } 465 else 466 { 467 VBoxServiceError("ConsoleKit: unable to retrieve session parameters (msg type=%d): %s", 468 dbus_message_get_type(pMsgSessions), 469 dbus_error_is_set(&dbErr) ? dbErr.message : "No error information available\n"); 470 } 471 dbus_message_unref(pReplySessions); 472 } 473 474 if (pMsgSessions) 475 { 476 dbus_message_unref(pMsgSessions); 477 pMsgSessions = NULL; 478 } 479 } 480 else 481 { 482 static int s_iBitchedAboutConsoleKit = 0; 483 if (s_iBitchedAboutConsoleKit++ < 3) 484 VBoxServiceError("Unable to invoke ConsoleKit (%d/3) -- maybe not installed / used? Error: %s\n", 485 s_iBitchedAboutConsoleKit, 486 dbus_error_is_set(&dbErr) ? dbErr.message : "No error information available\n"); 487 } 488 489 if (pMsgSessions) 490 dbus_message_unref(pMsgSessions); 491 } 492 else 493 { 494 static int s_iBitchedAboutDBus = 0; 495 if (s_iBitchedAboutDBus++ < 3) 496 VBoxServiceError("Unable to connect to system D-Bus (%d/3)\n", s_iBitchedAboutDBus); 497 } 498 499 if (dbus_error_is_set(&dbErr)) 500 dbus_error_free(&dbErr); 501 # endif /* RT_OS_LINUX */ 502 #endif /* VBOX_WITH_DBUS */ 503 504 /** @todo Fedora/others: Handle systemd-loginctl. */ 505 319 506 /* Calc the string length. */ 320 507 size_t cchUserList = 0; 321 for (uint32_t i = 0; i < cUsersInList; i++) 322 cchUserList += (i != 0) + strlen(papszUsers[i]); 508 if (RT_SUCCESS(rc)) 509 { 510 for (uint32_t i = 0; i < cUsersInList; i++) 511 cchUserList += (i != 0) + strlen(papszUsers[i]); 512 } 323 513 324 514 /* Build the user list. */ 325 rc = RTStrAllocEx(&pszUserList, cchUserList + 1); 515 if (RT_SUCCESS(rc)) 516 rc = RTStrAllocEx(&pszUserList, cchUserList + 1); 326 517 if (RT_SUCCESS(rc)) 327 518 { … … 368 559 cUsersInList, pszUserList ? pszUserList : "<NULL>", rc); 369 560 561 #if 0 370 562 if (pszUserList && cUsersInList > 0) 371 563 VBoxServicePropCacheUpdate(&g_VMInfoPropCache, "/VirtualBox/GuestInfo/OS/LoggedInUsersList", "%s", pszUserList); … … 379 571 g_cVMInfoLoggedInUsers = cUsersInList; 380 572 } 573 #endif 381 574 if (RT_SUCCESS(rc) && pszUserList) 382 575 RTStrFree(pszUserList); … … 795 988 #endif /* RT_OS_WINDOWS */ 796 989 990 int rc2; 991 #ifdef VBOX_WITH_DBUS 992 rc2 = RTDBusLoadLib(); 993 if (RT_FAILURE(rc2)) 994 VBoxServiceVerbose(0, "VMInfo: D-Bus seems not to be installed; no ConsoleKit session handling available\n"); 995 #endif /* VBOX_WITH_DBUS */ 996 797 997 /* 798 998 * Write the fixed properties first. … … 834 1034 if (*pfShutdown) 835 1035 break; 836 intrc2 = RTSemEventMultiWait(g_hVMInfoEvent, g_cMsVMInfoInterval);1036 rc2 = RTSemEventMultiWait(g_hVMInfoEvent, g_cMsVMInfoInterval); 837 1037 if (*pfShutdown) 838 1038 break;
Note:
See TracChangeset
for help on using the changeset viewer.