1d012387afef0ba02185ebe27bc6bb15551912e92Havoc Pennington/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ 2041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington/* dbus-transport-unix.c UNIX socket subclasses of DBusTransport 3041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * 4dbdea921b5967ed25b24a9e5af5d6a3db54c5ec7Havoc Pennington * Copyright (C) 2002, 2003, 2004 Red Hat Inc. 5041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * 643605a6f4e78a8c28afb4b1e924dff0301e0e95cHavoc Pennington * Licensed under the Academic Free License version 2.1 7041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * 8041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * This program is free software; you can redistribute it and/or modify 9041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * it under the terms of the GNU General Public License as published by 10041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * the Free Software Foundation; either version 2 of the License, or 11041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * (at your option) any later version. 12041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * 13041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * This program is distributed in the hope that it will be useful, 14041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * but WITHOUT ANY WARRANTY; without even the implied warranty of 15041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * GNU General Public License for more details. 17041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * 18041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * You should have received a copy of the GNU General Public License 19041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * along with this program; if not, write to the Free Software 205baf2f856a9c6625993234855b07680da1c8916fTobias Mueller * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 21041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * 22041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington */ 23041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington 24dbecdeabb20e0ce11121819c63373f0afba57c58Marcus Brinkmann#include <config.h> 254299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat 264299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat#include <stdio.h> 274299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat 28041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington#include "dbus-internals.h" 29041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington#include "dbus-connection-internal.h" 30041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington#include "dbus-transport-unix.h" 31fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington#include "dbus-transport-socket.h" 32041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington#include "dbus-transport-protected.h" 33041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington#include "dbus-watch.h" 348027efc97b4bec85f674570f878919cb72456745Havoc Pennington#include "dbus-sysdeps-unix.h" 354299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat#include "dbus-test.h" 36041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington 37041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington/** 38041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * @defgroup DBusTransportUnix DBusTransport implementations for UNIX 39041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * @ingroup DBusInternals 40041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * @brief Implementation details of DBusTransport on UNIX 41041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * 42041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * @{ 43041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington */ 44041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington 45041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington/** 46041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * Creates a new transport for the given Unix domain socket 4729c71168cd17b11eed65023c97aff401d5305b01Havoc Pennington * path. This creates a client-side of a transport. 48041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * 49a70b042f0dcebb10689975c65a2c45b52b7a4437Havoc Pennington * @todo once we add a way to escape paths in a dbus 50a70b042f0dcebb10689975c65a2c45b52b7a4437Havoc Pennington * address, this function needs to do escaping. 51a70b042f0dcebb10689975c65a2c45b52b7a4437Havoc Pennington * 52041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * @param path the path to the domain socket. 53a70b042f0dcebb10689975c65a2c45b52b7a4437Havoc Pennington * @param abstract #TRUE to use abstract socket namespace 544b13bb6d7f9a8e240cc41466dc70d9beb912a35eAnders Carlsson * @param error address where an error can be returned. 55041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * @returns a new transport, or #NULL on failure. 56041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington */ 57041b0767b284034aee09e9a0de2a3844b8cc546aHavoc PenningtonDBusTransport* 58041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington_dbus_transport_new_for_domain_socket (const char *path, 59a70b042f0dcebb10689975c65a2c45b52b7a4437Havoc Pennington dbus_bool_t abstract, 60ce4fd314c6be9bfee16a172d5ca34e5097d309fcHavoc Pennington DBusError *error) 61041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington{ 62041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington int fd; 63041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington DBusTransport *transport; 6429c71168cd17b11eed65023c97aff401d5305b01Havoc Pennington DBusString address; 6529c71168cd17b11eed65023c97aff401d5305b01Havoc Pennington 66ce4fd314c6be9bfee16a172d5ca34e5097d309fcHavoc Pennington _DBUS_ASSERT_ERROR_IS_CLEAR (error); 6729c71168cd17b11eed65023c97aff401d5305b01Havoc Pennington 68fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington if (!_dbus_string_init (&address)) 6929c71168cd17b11eed65023c97aff401d5305b01Havoc Pennington { 7029c71168cd17b11eed65023c97aff401d5305b01Havoc Pennington dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 7129c71168cd17b11eed65023c97aff401d5305b01Havoc Pennington return NULL; 7229c71168cd17b11eed65023c97aff401d5305b01Havoc Pennington } 736d54407dbb089dd0b0d8d79189b029c4d82bae81Havoc Pennington 746d54407dbb089dd0b0d8d79189b029c4d82bae81Havoc Pennington fd = -1; 75a70b042f0dcebb10689975c65a2c45b52b7a4437Havoc Pennington 76a70b042f0dcebb10689975c65a2c45b52b7a4437Havoc Pennington if ((abstract && 77a70b042f0dcebb10689975c65a2c45b52b7a4437Havoc Pennington !_dbus_string_append (&address, "unix:abstract=")) || 78a70b042f0dcebb10689975c65a2c45b52b7a4437Havoc Pennington (!abstract && 79a70b042f0dcebb10689975c65a2c45b52b7a4437Havoc Pennington !_dbus_string_append (&address, "unix:path=")) || 8029c71168cd17b11eed65023c97aff401d5305b01Havoc Pennington !_dbus_string_append (&address, path)) 8129c71168cd17b11eed65023c97aff401d5305b01Havoc Pennington { 8229c71168cd17b11eed65023c97aff401d5305b01Havoc Pennington dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 836d54407dbb089dd0b0d8d79189b029c4d82bae81Havoc Pennington goto failed_0; 8429c71168cd17b11eed65023c97aff401d5305b01Havoc Pennington } 85ce4fd314c6be9bfee16a172d5ca34e5097d309fcHavoc Pennington 86a70b042f0dcebb10689975c65a2c45b52b7a4437Havoc Pennington fd = _dbus_connect_unix_socket (path, abstract, error); 87041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington if (fd < 0) 88ce4fd314c6be9bfee16a172d5ca34e5097d309fcHavoc Pennington { 89ce4fd314c6be9bfee16a172d5ca34e5097d309fcHavoc Pennington _DBUS_ASSERT_ERROR_IS_SET (error); 906d54407dbb089dd0b0d8d79189b029c4d82bae81Havoc Pennington goto failed_0; 91ce4fd314c6be9bfee16a172d5ca34e5097d309fcHavoc Pennington } 92ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington 93ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington _dbus_verbose ("Successfully connected to unix socket %s\n", 94ff5283ab92c668453fd2f28c1715a1e0e9b949f5Havoc Pennington path); 9529c71168cd17b11eed65023c97aff401d5305b01Havoc Pennington 968027efc97b4bec85f674570f878919cb72456745Havoc Pennington transport = _dbus_transport_new_for_socket (fd, NULL, &address); 97041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington if (transport == NULL) 98041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington { 99ce4fd314c6be9bfee16a172d5ca34e5097d309fcHavoc Pennington dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 1006d54407dbb089dd0b0d8d79189b029c4d82bae81Havoc Pennington goto failed_1; 101041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington } 1026d54407dbb089dd0b0d8d79189b029c4d82bae81Havoc Pennington 10329c71168cd17b11eed65023c97aff401d5305b01Havoc Pennington _dbus_string_free (&address); 10401af5ff4101e540a6456bca01d56272e701bea78Havoc Pennington 105041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington return transport; 1066d54407dbb089dd0b0d8d79189b029c4d82bae81Havoc Pennington 1076d54407dbb089dd0b0d8d79189b029c4d82bae81Havoc Pennington failed_1: 10808079a5bdedd6ec91cda413983e4bd3b6ee0252dHavoc Pennington _dbus_close_socket (fd, NULL); 1096d54407dbb089dd0b0d8d79189b029c4d82bae81Havoc Pennington failed_0: 1106d54407dbb089dd0b0d8d79189b029c4d82bae81Havoc Pennington _dbus_string_free (&address); 1116d54407dbb089dd0b0d8d79189b029c4d82bae81Havoc Pennington return NULL; 112041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington} 113041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington 11415ef0ef6fbba7827453b7973e62b6c1853576601Havoc Pennington/** 1154299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat * Creates a new transport for the given binary and arguments. This 1164299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat * creates a client-side of a transport. The process will be forked 1174299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat * off and executed with stdin/stdout connected to a local AF_UNIX 1184299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat * socket. 1194299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat * 1204299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat * @param path the path to the domain socket. 1214299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat * @param argv Parameters list 1224299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat * @param error address where an error can be returned. 1234299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat * @returns a new transport, or #NULL on failure. 1244299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat */ 1254299eb3c0907100fe95d2986984b48d40cc52841Daniel Eratstatic DBusTransport* 1264299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat_dbus_transport_new_for_exec (const char *path, 1274299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat char *const argv[], 1284299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat DBusError *error) 1294299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat{ 1304299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat int fd; 1314299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat DBusTransport *transport; 1324299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat DBusString address; 1334299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat unsigned i; 1344299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat char *escaped; 1354299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat 1364299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat _DBUS_ASSERT_ERROR_IS_CLEAR (error); 1374299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat 1384299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat if (!_dbus_string_init (&address)) 1394299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat { 1404299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 1414299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat return NULL; 1424299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat } 1434299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat 1444299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat fd = -1; 1454299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat 1464299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat escaped = dbus_address_escape_value (path); 1474299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat if (!escaped) 1484299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat { 1494299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 1504299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat goto failed; 1514299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat } 1524299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat 1534299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat if (!_dbus_string_append (&address, "unixexec:path=") || 1544299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat !_dbus_string_append (&address, escaped)) 1554299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat { 1564299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 1574299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat dbus_free (escaped); 1584299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat goto failed; 1594299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat } 1604299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat 1614299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat dbus_free (escaped); 1624299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat 1634299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat if (argv) 1644299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat { 1654299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat for (i = 0; argv[i]; i++) 1664299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat { 1674299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat dbus_bool_t success; 1684299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat 1694299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat escaped = dbus_address_escape_value (argv[i]); 1704299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat if (!escaped) 1714299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat { 1724299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 1734299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat goto failed; 1744299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat } 1754299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat 1764299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat success = _dbus_string_append_printf (&address, ",argv%u=%s", i, escaped); 1774299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat dbus_free (escaped); 1784299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat 1794299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat if (!success) 1804299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat { 1814299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 1824299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat goto failed; 1834299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat } 1844299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat } 1854299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat } 1864299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat 1874299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat fd = _dbus_connect_exec (path, argv, error); 1884299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat if (fd < 0) 1894299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat { 1904299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat _DBUS_ASSERT_ERROR_IS_SET (error); 1914299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat goto failed; 1924299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat } 1934299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat 1944299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat _dbus_verbose ("Successfully connected to process %s\n", 1954299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat path); 1964299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat 1974299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat transport = _dbus_transport_new_for_socket (fd, NULL, &address); 1984299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat if (transport == NULL) 1994299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat { 2004299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 2014299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat goto failed; 2024299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat } 2034299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat 2044299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat _dbus_string_free (&address); 2054299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat 2064299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat return transport; 2074299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat 2084299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat failed: 2094299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat if (fd >= 0) 2104299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat _dbus_close_socket (fd, NULL); 2114299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat 2124299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat _dbus_string_free (&address); 2134299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat return NULL; 2144299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat} 2154299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat 2164299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat/** 21715ef0ef6fbba7827453b7973e62b6c1853576601Havoc Pennington * Opens platform specific transport types. 21815ef0ef6fbba7827453b7973e62b6c1853576601Havoc Pennington * 21915ef0ef6fbba7827453b7973e62b6c1853576601Havoc Pennington * @param entry the address entry to try opening 22015ef0ef6fbba7827453b7973e62b6c1853576601Havoc Pennington * @param transport_p return location for the opened transport 22115ef0ef6fbba7827453b7973e62b6c1853576601Havoc Pennington * @param error error to be set 22215ef0ef6fbba7827453b7973e62b6c1853576601Havoc Pennington * @returns result of the attempt 22315ef0ef6fbba7827453b7973e62b6c1853576601Havoc Pennington */ 224fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc PenningtonDBusTransportOpenResult 225fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington_dbus_transport_open_platform_specific (DBusAddressEntry *entry, 226fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington DBusTransport **transport_p, 227fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington DBusError *error) 228fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington{ 229fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington const char *method; 230fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington 231fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington method = dbus_address_entry_get_method (entry); 232fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington _dbus_assert (method != NULL); 233fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington 234fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington if (strcmp (method, "unix") == 0) 235fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington { 236fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington const char *path = dbus_address_entry_get_value (entry, "path"); 237fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington const char *tmpdir = dbus_address_entry_get_value (entry, "tmpdir"); 238fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington const char *abstract = dbus_address_entry_get_value (entry, "abstract"); 239fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington 240fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington if (tmpdir != NULL) 241fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington { 242fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington _dbus_set_bad_address (error, NULL, NULL, 243fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington "cannot use the \"tmpdir\" option for an address to connect to, only in an address to listen on"); 244fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington return DBUS_TRANSPORT_OPEN_BAD_ADDRESS; 245fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington } 246fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington 247fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington if (path == NULL && abstract == NULL) 248fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington { 249fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington _dbus_set_bad_address (error, "unix", 250fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington "path or abstract", 251fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington NULL); 252fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington return DBUS_TRANSPORT_OPEN_BAD_ADDRESS; 253fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington } 254fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington 255fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington if (path != NULL && abstract != NULL) 256fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington { 257fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington _dbus_set_bad_address (error, NULL, NULL, 258fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington "can't specify both \"path\" and \"abstract\" options in an address"); 259fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington return DBUS_TRANSPORT_OPEN_BAD_ADDRESS; 260fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington } 261fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington 262fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington if (path) 263fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington *transport_p = _dbus_transport_new_for_domain_socket (path, FALSE, 264fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington error); 265fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington else 266fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington *transport_p = _dbus_transport_new_for_domain_socket (abstract, TRUE, 267fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington error); 268fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington if (*transport_p == NULL) 269fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington { 270fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington _DBUS_ASSERT_ERROR_IS_SET (error); 271fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington return DBUS_TRANSPORT_OPEN_DID_NOT_CONNECT; 272fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington } 273fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington else 274fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington { 275fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington _DBUS_ASSERT_ERROR_IS_CLEAR (error); 276fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington return DBUS_TRANSPORT_OPEN_OK; 2774299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat } 2784299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat } 2794299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat else if (strcmp (method, "unixexec") == 0) 2804299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat { 2814299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat const char *path; 2824299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat unsigned i; 2834299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat char **argv; 2844299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat 2854299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat path = dbus_address_entry_get_value (entry, "path"); 2864299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat if (path == NULL) 2874299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat { 2884299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat _dbus_set_bad_address (error, NULL, NULL, 2894299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat "No process path specified"); 2904299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat return DBUS_TRANSPORT_OPEN_BAD_ADDRESS; 2914299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat } 2924299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat 2934299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat /* First count argv arguments */ 2944299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat for (i = 1; ; i++) 2954299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat { 2964299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat char t[4+20+1]; /* "argv" plus space for a formatted base 10 64bit integer, plus NUL */ 2974299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat 2984299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat snprintf (t, sizeof(t), "argv%u", i); 2994299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat 3004299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat if (!dbus_address_entry_get_value (entry, t)) 3014299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat break; 3024299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat } 3034299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat 3044299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat /* Allocate string array */ 3054299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat argv = dbus_new0 (char*, i+1); 3064299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat if (!argv) 3074299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat { 3084299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 3094299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat return DBUS_TRANSPORT_OPEN_DID_NOT_CONNECT; 3104299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat } 3114299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat 3124299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat /* Fill in string array */ 3134299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat for (i = 0; ; i++) 3144299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat { 3154299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat char t[4+20+1]; 3164299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat const char *p; 3174299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat 3184299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat snprintf (t, sizeof(t), "argv%u", i); 3194299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat 3204299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat p = dbus_address_entry_get_value (entry, t); 3214299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat if (!p) 3224299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat { 3234299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat if (i == 0) 3244299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat /* If argv0 isn't specified, fill in the path instead */ 3254299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat p = path; 3264299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat else 3274299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat break; 3284299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat } 3294299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat 3304299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat argv[i] = _dbus_strdup (p); 3314299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat if (!argv[i]) 3324299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat { 3334299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat dbus_free_string_array (argv); 3344299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 3354299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat return DBUS_TRANSPORT_OPEN_DID_NOT_CONNECT; 3364299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat } 3374299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat } 3384299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat 3394299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat *transport_p = _dbus_transport_new_for_exec (path, argv, error); 3404299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat dbus_free_string_array (argv); 3414299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat 3424299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat if (*transport_p == NULL) 3434299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat { 3444299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat _DBUS_ASSERT_ERROR_IS_SET (error); 3454299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat return DBUS_TRANSPORT_OPEN_DID_NOT_CONNECT; 3464299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat } 3474299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat else 3484299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat { 3494299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat _DBUS_ASSERT_ERROR_IS_CLEAR (error); 3504299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat return DBUS_TRANSPORT_OPEN_OK; 3514299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat } 352fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington } 3534299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat#ifdef DBUS_ENABLE_LAUNCHD 3544299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat else if (strcmp (method, "launchd") == 0) 3554299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat { 3564299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat DBusError tmp_error = DBUS_ERROR_INIT; 3574299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat const char *launchd_env_var = dbus_address_entry_get_value (entry, "env"); 3584299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat const char *launchd_socket; 3594299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat DBusString socket_path; 3604299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat dbus_bool_t valid_socket; 3614299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat 3624299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat if (!_dbus_string_init (&socket_path)) 3634299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat { 3644299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat _DBUS_SET_OOM (error); 3654299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat return FALSE; 3664299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat } 3674299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat 3684299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat if (launchd_env_var == NULL) 3694299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat { 3704299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat _dbus_set_bad_address (error, "launchd", "env", NULL); 3714299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat return DBUS_TRANSPORT_OPEN_BAD_ADDRESS; 3724299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat } 3734299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat 3744299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat valid_socket = _dbus_lookup_launchd_socket (&socket_path, launchd_env_var, error); 3754299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat 3764299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat if (dbus_error_is_set(error)) 3774299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat { 3784299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat _dbus_string_free(&socket_path); 3794299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat return DBUS_TRANSPORT_OPEN_DID_NOT_CONNECT; 3804299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat } 3814299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat 3824299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat if (!valid_socket) 3834299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat { 3844299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat dbus_set_error(&tmp_error, DBUS_ERROR_BAD_ADDRESS, 3854299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat "launchd's env var %s does not exist", launchd_env_var); 3864299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat dbus_error_free(error); 3874299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat dbus_move_error(&tmp_error, error); 3884299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat return DBUS_TRANSPORT_OPEN_DID_NOT_CONNECT; 3894299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat } 3904299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat 3914299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat launchd_socket = _dbus_string_get_const_data(&socket_path); 3924299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat *transport_p = _dbus_transport_new_for_domain_socket (launchd_socket, FALSE, error); 3934299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat 3944299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat if (*transport_p == NULL) 3954299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat { 3964299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat _DBUS_ASSERT_ERROR_IS_SET (error); 3974299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat return DBUS_TRANSPORT_OPEN_DID_NOT_CONNECT; 3984299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat } 3994299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat else 4004299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat { 4014299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat _DBUS_ASSERT_ERROR_IS_CLEAR (error); 4024299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat return DBUS_TRANSPORT_OPEN_OK; 4034299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat } 4044299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat } 4054299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat#endif 406fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington else 407fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington { 408fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington _DBUS_ASSERT_ERROR_IS_CLEAR (error); 409fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington return DBUS_TRANSPORT_OPEN_NOT_HANDLED; 410fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington } 411fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington} 412fe4715b656237b89767b5dc0cba4c107541b6e0dHavoc Pennington 413041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington/** @} */ 4144299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat 4154299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat#ifdef DBUS_BUILD_TESTS 4164299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat 4174299eb3c0907100fe95d2986984b48d40cc52841Daniel Eratdbus_bool_t 4184299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat_dbus_transport_unix_test (void) 4194299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat{ 4204299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat DBusConnection *c; 4214299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat DBusError error; 4224299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat dbus_bool_t ret; 4234299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat const char *address; 4244299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat 4254299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat dbus_error_init (&error); 4264299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat 4274299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat c = dbus_connection_open ("unixexec:argv0=false,argv1=foobar,path=/bin/false", &error); 4284299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat _dbus_assert (c != NULL); 4294299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat _dbus_assert (!dbus_error_is_set (&error)); 4304299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat 4314299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat address = _dbus_connection_get_address (c); 4324299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat _dbus_assert (address != NULL); 4334299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat 4344299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat /* Let's see if the address got parsed, reordered and formatted correctly */ 4354299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat ret = strcmp (address, "unixexec:path=/bin/false,argv0=false,argv1=foobar") == 0; 4364299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat 4374299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat dbus_connection_unref (c); 4384299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat 4394299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat return ret; 4404299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat} 4414299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat 4424299eb3c0907100fe95d2986984b48d40cc52841Daniel Erat#endif 443