dbus-server-unix.c revision fa05de9230d62e7c427b5313796fc6ccd4d0ff60
1041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington/* -*- mode: C; c-file-style: "gnu" -*- */
2041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington/* dbus-server-unix.c Server implementation for Unix network protocols.
3041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington *
4041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * Copyright (C) 2002  Red Hat Inc.
5041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington *
6041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * Licensed under the Academic Free License version 1.2
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
20041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington *
22041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington */
23041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington
24041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington#include "dbus-internals.h"
25041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington#include "dbus-server-unix.h"
26041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington#include "dbus-transport-unix.h"
27041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington#include "dbus-connection-internal.h"
28041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington#include <sys/types.h>
29041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington#include <unistd.h>
30041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington
31041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington/**
32041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * @defgroup DBusServerUnix DBusServer implementations for UNIX
33041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * @ingroup  DBusInternals
34041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * @brief Implementation details of DBusServer on UNIX
35041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington *
36041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * @{
37041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington */
38041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington/**
39041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington *
40041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * Opaque object representing a Unix server implementation.
41041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington */
42041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Penningtontypedef struct DBusServerUnix DBusServerUnix;
43041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington
44041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington/**
45041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * Implementation details of DBusServerUnix. All members
46041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * are private.
47041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington */
48041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Penningtonstruct DBusServerUnix
49041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington{
50041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington  DBusServer base;  /**< Parent class members. */
51041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington  int fd;           /**< File descriptor or -1 if disconnected. */
52041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington  DBusWatch *watch; /**< File descriptor watch. */
53041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington};
54041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington
55041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Penningtonstatic void
56041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Penningtonunix_finalize (DBusServer *server)
57041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington{
58041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington  DBusServerUnix *unix_server = (DBusServerUnix*) server;
59041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington
60041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington  _dbus_server_finalize_base (server);
61041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington
62041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington  if (unix_server->watch)
63041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington    _dbus_watch_unref (unix_server->watch);
64041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington
65041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington  dbus_free (server);
66041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington}
67041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington
6889e6dfd29cfbdb92f15e8fb2bde76d94a4c5a7b3Alexander Larsson/**
6989e6dfd29cfbdb92f15e8fb2bde76d94a4c5a7b3Alexander Larsson * @todo unreffing the connection at the end may cause
7089e6dfd29cfbdb92f15e8fb2bde76d94a4c5a7b3Alexander Larsson * us to drop the last ref to the connection before
7189e6dfd29cfbdb92f15e8fb2bde76d94a4c5a7b3Alexander Larsson * disconnecting it. That is invalid.
7289e6dfd29cfbdb92f15e8fb2bde76d94a4c5a7b3Alexander Larsson */
73b4a1100f4f81534e2aac0141afda750f318223d4Havoc Pennington/* Return value is just for memory, not other failures. */
74b4a1100f4f81534e2aac0141afda750f318223d4Havoc Penningtonstatic dbus_bool_t
75041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Penningtonhandle_new_client_fd (DBusServer *server,
76041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington                      int         client_fd)
77041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington{
78041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington  DBusConnection *connection;
79041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington  DBusTransport *transport;
80041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington
81041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington  _dbus_verbose ("Creating new client connection with fd %d\n", client_fd);
82041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington
83041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington  if (!_dbus_set_fd_nonblocking (client_fd, NULL))
84b4a1100f4f81534e2aac0141afda750f318223d4Havoc Pennington    return TRUE;
85041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington
8629c71168cd17b11eed65023c97aff401d5305b01Havoc Pennington  transport = _dbus_transport_new_for_fd (client_fd, TRUE, NULL);
87041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington  if (transport == NULL)
88041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington    {
89041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington      close (client_fd);
90b4a1100f4f81534e2aac0141afda750f318223d4Havoc Pennington      return FALSE;
91041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington    }
92041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington
93041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington  /* note that client_fd is now owned by the transport, and will be
94041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington   * closed on transport disconnection/finalization
95041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington   */
96041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington
97041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington  connection = _dbus_connection_new_for_transport (transport);
98041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington  _dbus_transport_unref (transport);
99041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington
100041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington  if (connection == NULL)
101b4a1100f4f81534e2aac0141afda750f318223d4Havoc Pennington    return FALSE;
102041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington
10314cc2707a0318381b5cc68588efc36f61d617b78Havoc Pennington  _dbus_connection_set_connection_counter (connection,
10414cc2707a0318381b5cc68588efc36f61d617b78Havoc Pennington                                           server->connection_counter);
10514cc2707a0318381b5cc68588efc36f61d617b78Havoc Pennington
106041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington  /* See if someone wants to handle this new connection,
107041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington   * self-referencing for paranoia
108041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington   */
109041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington  if (server->new_connection_function)
110041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington    {
111041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington      dbus_server_ref (server);
112041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington
113041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington      (* server->new_connection_function) (server, connection,
114041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington                                           server->new_connection_data);
115041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington      dbus_server_unref (server);
116041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington    }
117041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington
118041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington  /* If no one grabbed a reference, the connection will die. */
119041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington  dbus_connection_unref (connection);
120b4a1100f4f81534e2aac0141afda750f318223d4Havoc Pennington
121b4a1100f4f81534e2aac0141afda750f318223d4Havoc Pennington  return TRUE;
122041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington}
123041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington
124b4a1100f4f81534e2aac0141afda750f318223d4Havoc Penningtonstatic dbus_bool_t
125041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Penningtonunix_handle_watch (DBusServer  *server,
126041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington                   DBusWatch   *watch,
127041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington                   unsigned int flags)
128041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington{
129041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington  DBusServerUnix *unix_server = (DBusServerUnix*) server;
130041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington
131041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington  _dbus_assert (watch == unix_server->watch);
132041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington
133041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington  _dbus_verbose ("Handling client connection, flags 0x%x\n", flags);
134041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington
135041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington  if (flags & DBUS_WATCH_READABLE)
136041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington    {
137041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington      int client_fd;
138041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington      int listen_fd;
139041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington
140041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington      listen_fd = dbus_watch_get_fd (watch);
141041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington
14201af5ff4101e540a6456bca01d56272e701bea78Havoc Pennington      client_fd = _dbus_accept (listen_fd);
143041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington
144041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington      if (client_fd < 0)
145041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington        {
146271fa7fc335f332bb2be3beeef735334546c4957Havoc Pennington          /* EINTR handled for us */
147271fa7fc335f332bb2be3beeef735334546c4957Havoc Pennington
148271fa7fc335f332bb2be3beeef735334546c4957Havoc Pennington          if (errno == EAGAIN || errno == EWOULDBLOCK)
149041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington            _dbus_verbose ("No client available to accept after all\n");
150041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington          else
151041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington            _dbus_verbose ("Failed to accept a client connection: %s\n",
152041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington                           _dbus_strerror (errno));
153041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington        }
154041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington      else
155041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington        {
156f116b1282f8482dff6dc797f64270d95f79b53a3Anders Carlsson	  _dbus_fd_set_close_on_exec (client_fd);
157b4a1100f4f81534e2aac0141afda750f318223d4Havoc Pennington
158b4a1100f4f81534e2aac0141afda750f318223d4Havoc Pennington          if (!handle_new_client_fd (server, client_fd))
159b4a1100f4f81534e2aac0141afda750f318223d4Havoc Pennington            _dbus_verbose ("Rejected client connection due to lack of memory\n");
160041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington        }
161041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington    }
162041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington
163041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington  if (flags & DBUS_WATCH_ERROR)
164041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington    _dbus_verbose ("Error on server listening socket\n");
165041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington
166041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington  if (flags & DBUS_WATCH_HANGUP)
167041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington    _dbus_verbose ("Hangup on server listening socket\n");
168b4a1100f4f81534e2aac0141afda750f318223d4Havoc Pennington
169b4a1100f4f81534e2aac0141afda750f318223d4Havoc Pennington  return TRUE;
170041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington}
171041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington
172041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Penningtonstatic void
173041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Penningtonunix_disconnect (DBusServer *server)
174041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington{
175041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington  DBusServerUnix *unix_server = (DBusServerUnix*) server;
176041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington
177041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington  if (unix_server->watch)
178041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington    {
179041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington      _dbus_server_remove_watch (server,
180041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington                                 unix_server->watch);
181041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington      _dbus_watch_unref (unix_server->watch);
182041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington      unix_server->watch = NULL;
183041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington    }
184041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington
185041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington  close (unix_server->fd);
186041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington  unix_server->fd = -1;
187041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington}
188041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington
189041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Penningtonstatic DBusServerVTable unix_vtable = {
190041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington  unix_finalize,
191041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington  unix_handle_watch,
192041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington  unix_disconnect
193041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington};
194041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington
195041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington/**
196041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * Creates a new server listening on the given file descriptor.  The
197041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * file descriptor should be nonblocking (use
198041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * _dbus_set_fd_nonblocking() to make it so). The file descriptor
199041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * should be listening for connections, that is, listen() should have
200041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * been successfully invoked on it. The server will use accept() to
201041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * accept new client connections.
202041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington *
203041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * @param fd the file descriptor.
20429c71168cd17b11eed65023c97aff401d5305b01Havoc Pennington * @param address the server's address
205041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * @returns the new server, or #NULL if no memory.
206041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington *
207041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington */
208041b0767b284034aee09e9a0de2a3844b8cc546aHavoc PenningtonDBusServer*
20929c71168cd17b11eed65023c97aff401d5305b01Havoc Pennington_dbus_server_new_for_fd (int               fd,
21029c71168cd17b11eed65023c97aff401d5305b01Havoc Pennington                         const DBusString *address)
211041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington{
212041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington  DBusServerUnix *unix_server;
213041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington  DBusWatch *watch;
214041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington
215041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington  watch = _dbus_watch_new (fd,
216f587ce7845edb0eb01451368d01b5bc86b5904cdHavoc Pennington                           DBUS_WATCH_READABLE,
217f587ce7845edb0eb01451368d01b5bc86b5904cdHavoc Pennington                           TRUE);
218041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington  if (watch == NULL)
219041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington    return NULL;
220041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington
221041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington  unix_server = dbus_new0 (DBusServerUnix, 1);
222041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington  if (unix_server == NULL)
223041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington    {
224041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington      _dbus_watch_unref (watch);
225041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington      return NULL;
226041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington    }
227041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington
228041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington  if (!_dbus_server_init_base (&unix_server->base,
22929c71168cd17b11eed65023c97aff401d5305b01Havoc Pennington                               &unix_vtable, address))
230041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington    {
231041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington      _dbus_watch_unref (watch);
232041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington      dbus_free (unix_server);
233041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington      return NULL;
234041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington    }
235041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington
236041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington  if (!_dbus_server_add_watch (&unix_server->base,
237041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington                               watch))
238041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington    {
239041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington      _dbus_server_finalize_base (&unix_server->base);
240041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington      _dbus_watch_unref (watch);
241041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington      dbus_free (unix_server);
242041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington      return NULL;
243041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington    }
244041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington
245041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington  unix_server->fd = fd;
246041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington  unix_server->watch = watch;
247041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington
248041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington  return (DBusServer*) unix_server;
249041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington}
250041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington
251041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington/**
252041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * Creates a new server listening on the given Unix domain socket.
253041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington *
254041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * @param path the path for the domain socket.
255ce4fd314c6be9bfee16a172d5ca34e5097d309fcHavoc Pennington * @param error location to store reason for failure.
256041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington * @returns the new server, or #NULL on failure.
257041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington */
258041b0767b284034aee09e9a0de2a3844b8cc546aHavoc PenningtonDBusServer*
259041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington_dbus_server_new_for_domain_socket (const char     *path,
260ce4fd314c6be9bfee16a172d5ca34e5097d309fcHavoc Pennington                                    DBusError      *error)
261041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington{
262041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington  DBusServer *server;
263041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington  int listen_fd;
26429c71168cd17b11eed65023c97aff401d5305b01Havoc Pennington  DBusString address;
26529c71168cd17b11eed65023c97aff401d5305b01Havoc Pennington
266ce4fd314c6be9bfee16a172d5ca34e5097d309fcHavoc Pennington  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
26729c71168cd17b11eed65023c97aff401d5305b01Havoc Pennington
268fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington  if (!_dbus_string_init (&address))
26929c71168cd17b11eed65023c97aff401d5305b01Havoc Pennington    {
27029c71168cd17b11eed65023c97aff401d5305b01Havoc Pennington      dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
27129c71168cd17b11eed65023c97aff401d5305b01Havoc Pennington      return NULL;
27229c71168cd17b11eed65023c97aff401d5305b01Havoc Pennington    }
27329c71168cd17b11eed65023c97aff401d5305b01Havoc Pennington
27429c71168cd17b11eed65023c97aff401d5305b01Havoc Pennington  if (!_dbus_string_append (&address, "unix:path=") ||
27529c71168cd17b11eed65023c97aff401d5305b01Havoc Pennington      !_dbus_string_append (&address, path))
27629c71168cd17b11eed65023c97aff401d5305b01Havoc Pennington    {
27729c71168cd17b11eed65023c97aff401d5305b01Havoc Pennington      _dbus_string_free (&address);
27829c71168cd17b11eed65023c97aff401d5305b01Havoc Pennington      dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
27929c71168cd17b11eed65023c97aff401d5305b01Havoc Pennington      return NULL;
28029c71168cd17b11eed65023c97aff401d5305b01Havoc Pennington    }
281ce4fd314c6be9bfee16a172d5ca34e5097d309fcHavoc Pennington
282ce4fd314c6be9bfee16a172d5ca34e5097d309fcHavoc Pennington  listen_fd = _dbus_listen_unix_socket (path, error);
283f116b1282f8482dff6dc797f64270d95f79b53a3Anders Carlsson  _dbus_fd_set_close_on_exec (listen_fd);
284f116b1282f8482dff6dc797f64270d95f79b53a3Anders Carlsson
285041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington  if (listen_fd < 0)
28629c71168cd17b11eed65023c97aff401d5305b01Havoc Pennington    {
28729c71168cd17b11eed65023c97aff401d5305b01Havoc Pennington      _dbus_string_free (&address);
28829c71168cd17b11eed65023c97aff401d5305b01Havoc Pennington      return NULL;
28929c71168cd17b11eed65023c97aff401d5305b01Havoc Pennington    }
290041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington
29129c71168cd17b11eed65023c97aff401d5305b01Havoc Pennington  server = _dbus_server_new_for_fd (listen_fd, &address);
292041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington  if (server == NULL)
293041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington    {
294ce4fd314c6be9bfee16a172d5ca34e5097d309fcHavoc Pennington      dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
295041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington      close (listen_fd);
29629c71168cd17b11eed65023c97aff401d5305b01Havoc Pennington      _dbus_string_free (&address);
297041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington      return NULL;
298041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington    }
299041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington
30029c71168cd17b11eed65023c97aff401d5305b01Havoc Pennington  _dbus_string_free (&address);
30129c71168cd17b11eed65023c97aff401d5305b01Havoc Pennington
302041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington  return server;
303041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington}
304041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington
3056180d6954c41a2412c166e5a9e8a2851cf39c6d1Mikael Hallendal/**
306ce4fd314c6be9bfee16a172d5ca34e5097d309fcHavoc Pennington * Creates a new server listening on the given hostname and port.
307ce4fd314c6be9bfee16a172d5ca34e5097d309fcHavoc Pennington * If the hostname is NULL, listens on localhost.
3086180d6954c41a2412c166e5a9e8a2851cf39c6d1Mikael Hallendal *
3096180d6954c41a2412c166e5a9e8a2851cf39c6d1Mikael Hallendal * @param host the hostname to listen on.
3106180d6954c41a2412c166e5a9e8a2851cf39c6d1Mikael Hallendal * @param port the port to listen on.
311ce4fd314c6be9bfee16a172d5ca34e5097d309fcHavoc Pennington * @param error location to store reason for failure.
3126180d6954c41a2412c166e5a9e8a2851cf39c6d1Mikael Hallendal * @returns the new server, or #NULL on failure.
3136180d6954c41a2412c166e5a9e8a2851cf39c6d1Mikael Hallendal */
3146180d6954c41a2412c166e5a9e8a2851cf39c6d1Mikael HallendalDBusServer*
3156180d6954c41a2412c166e5a9e8a2851cf39c6d1Mikael Hallendal_dbus_server_new_for_tcp_socket (const char     *host,
3166180d6954c41a2412c166e5a9e8a2851cf39c6d1Mikael Hallendal                                 dbus_uint32_t   port,
317ce4fd314c6be9bfee16a172d5ca34e5097d309fcHavoc Pennington                                 DBusError      *error)
3186180d6954c41a2412c166e5a9e8a2851cf39c6d1Mikael Hallendal{
3196180d6954c41a2412c166e5a9e8a2851cf39c6d1Mikael Hallendal  DBusServer *server;
3206180d6954c41a2412c166e5a9e8a2851cf39c6d1Mikael Hallendal  int listen_fd;
32129c71168cd17b11eed65023c97aff401d5305b01Havoc Pennington  DBusString address;
32229c71168cd17b11eed65023c97aff401d5305b01Havoc Pennington
323ce4fd314c6be9bfee16a172d5ca34e5097d309fcHavoc Pennington  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
32429c71168cd17b11eed65023c97aff401d5305b01Havoc Pennington
325fa05de9230d62e7c427b5313796fc6ccd4d0ff60Havoc Pennington  if (!_dbus_string_init (&address))
32629c71168cd17b11eed65023c97aff401d5305b01Havoc Pennington    {
32729c71168cd17b11eed65023c97aff401d5305b01Havoc Pennington      dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
32829c71168cd17b11eed65023c97aff401d5305b01Havoc Pennington      return NULL;
32929c71168cd17b11eed65023c97aff401d5305b01Havoc Pennington    }
33029c71168cd17b11eed65023c97aff401d5305b01Havoc Pennington
33129c71168cd17b11eed65023c97aff401d5305b01Havoc Pennington  if (!_dbus_string_append (&address, "tcp:host=") ||
33229c71168cd17b11eed65023c97aff401d5305b01Havoc Pennington      !_dbus_string_append (&address, host) ||
33329c71168cd17b11eed65023c97aff401d5305b01Havoc Pennington      !_dbus_string_append (&address, ",port=") ||
33429c71168cd17b11eed65023c97aff401d5305b01Havoc Pennington      !_dbus_string_append_int (&address, port))
33529c71168cd17b11eed65023c97aff401d5305b01Havoc Pennington    {
33629c71168cd17b11eed65023c97aff401d5305b01Havoc Pennington      _dbus_string_free (&address);
33729c71168cd17b11eed65023c97aff401d5305b01Havoc Pennington      dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
33829c71168cd17b11eed65023c97aff401d5305b01Havoc Pennington      return NULL;
33929c71168cd17b11eed65023c97aff401d5305b01Havoc Pennington    }
3406180d6954c41a2412c166e5a9e8a2851cf39c6d1Mikael Hallendal
341ce4fd314c6be9bfee16a172d5ca34e5097d309fcHavoc Pennington  listen_fd = _dbus_listen_tcp_socket (host, port, error);
3426180d6954c41a2412c166e5a9e8a2851cf39c6d1Mikael Hallendal  _dbus_fd_set_close_on_exec (listen_fd);
3436180d6954c41a2412c166e5a9e8a2851cf39c6d1Mikael Hallendal
3446180d6954c41a2412c166e5a9e8a2851cf39c6d1Mikael Hallendal  if (listen_fd < 0)
34529c71168cd17b11eed65023c97aff401d5305b01Havoc Pennington    {
34629c71168cd17b11eed65023c97aff401d5305b01Havoc Pennington      _dbus_string_free (&address);
34729c71168cd17b11eed65023c97aff401d5305b01Havoc Pennington      return NULL;
34829c71168cd17b11eed65023c97aff401d5305b01Havoc Pennington    }
3496180d6954c41a2412c166e5a9e8a2851cf39c6d1Mikael Hallendal
35029c71168cd17b11eed65023c97aff401d5305b01Havoc Pennington  server = _dbus_server_new_for_fd (listen_fd, &address);
3516180d6954c41a2412c166e5a9e8a2851cf39c6d1Mikael Hallendal  if (server == NULL)
3526180d6954c41a2412c166e5a9e8a2851cf39c6d1Mikael Hallendal    {
353ce4fd314c6be9bfee16a172d5ca34e5097d309fcHavoc Pennington      dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
3546180d6954c41a2412c166e5a9e8a2851cf39c6d1Mikael Hallendal      close (listen_fd);
35529c71168cd17b11eed65023c97aff401d5305b01Havoc Pennington      _dbus_string_free (&address);
3566180d6954c41a2412c166e5a9e8a2851cf39c6d1Mikael Hallendal      return NULL;
3576180d6954c41a2412c166e5a9e8a2851cf39c6d1Mikael Hallendal    }
3586180d6954c41a2412c166e5a9e8a2851cf39c6d1Mikael Hallendal
35929c71168cd17b11eed65023c97aff401d5305b01Havoc Pennington  _dbus_string_free (&address);
36029c71168cd17b11eed65023c97aff401d5305b01Havoc Pennington
3616180d6954c41a2412c166e5a9e8a2851cf39c6d1Mikael Hallendal  return server;
3626180d6954c41a2412c166e5a9e8a2851cf39c6d1Mikael Hallendal
3636180d6954c41a2412c166e5a9e8a2851cf39c6d1Mikael Hallendal
3646180d6954c41a2412c166e5a9e8a2851cf39c6d1Mikael Hallendal}
3656180d6954c41a2412c166e5a9e8a2851cf39c6d1Mikael Hallendal
366041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington/** @} */
367041b0767b284034aee09e9a0de2a3844b8cc546aHavoc Pennington
368