blob: 917d983c6e93aa4154b0b49a33981f90a5b9e26c [file] [log] [blame]
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/* dbus-echo.c - a plain libdbus echo server
*
* Copyright © 2003 Philip Blundell <philb@gnu.org>
* Copyright © 2011 Nokia Corporation
* Copyright © 2014 Collabora Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <dbus/dbus.h>
#include "dbus/dbus-sysdeps.h"
#include "test-tool.h"
#include "tool-common.h"
static int sleep_ms = -1;
static dbus_bool_t noreply = FALSE;
static dbus_bool_t noread = FALSE;
static void usage_echo (int exit_with) _DBUS_GNUC_NORETURN;
static void
usage_echo (int exit_with)
{
fprintf (stderr,
"Usage: dbus-test-tool echo [OPTIONS]\n"
"\n"
"Respond to all method calls with an empty reply.\n"
"\n"
"Options:\n"
"\n"
" --name=NAME claim this well-known name first\n"
"\n"
" --sleep-ms=N sleep N milliseconds before sending each reply\n"
"\n"
" --session use the session bus (default)\n"
" --system use the system bus\n"
);
exit (exit_with);
}
static void usage_black_hole (int exit_with) _DBUS_GNUC_NORETURN;
static void
usage_black_hole (int exit_with)
{
fprintf (stderr,
"Usage: dbus-test-tool black-hole [OPTIONS]\n"
"\n"
"Receive method calls but do not reply.\n"
"\n"
"Options:\n"
"\n"
" --name=NAME claim this well-known name first\n"
"\n"
" --no-read don't read anything on the D-Bus socket\n"
"\n"
" --session use the session bus (default)\n"
" --system use the system bus\n"
);
exit (exit_with);
}
static DBusHandlerResult
filter (DBusConnection *connection,
DBusMessage *message,
void *user_data)
{
DBusMessage *reply;
if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_METHOD_CALL)
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
if (sleep_ms > 0)
{
_dbus_sleep_milliseconds (sleep_ms);
}
if (!noreply)
{
reply = dbus_message_new_method_return (message);
if (reply == NULL)
tool_oom ("allocating reply");
if (!dbus_connection_send (connection, reply, NULL))
tool_oom ("sending reply");
dbus_message_unref (reply);
}
return DBUS_HANDLER_RESULT_HANDLED;
}
static DBusConnection *
init_connection (DBusBusType type, const char *name)
{
DBusConnection *connection;
DBusError error = DBUS_ERROR_INIT;
connection = dbus_bus_get (type, &error);
if (connection == NULL)
{
fprintf (stderr, "Failed to connect to bus: %s: %s\n",
error.name, error.message);
dbus_error_free (&error);
exit (1);
}
if (name != NULL)
{
if (dbus_bus_request_name (connection, name, DBUS_NAME_FLAG_DO_NOT_QUEUE,
NULL) != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER)
{
fprintf (stderr, "failed to take bus name %s\n", name);
exit (1);
}
}
else
{
printf ("%s\n", dbus_bus_get_unique_name (connection));
}
if (!dbus_connection_add_filter (connection, filter, NULL, NULL))
tool_oom ("adding message filter");
return connection;
}
int
dbus_test_tool_echo (int argc, char **argv)
{
DBusConnection *connection;
DBusBusType type = DBUS_BUS_SESSION;
int i;
const char *name = NULL;
/* argv[1] is the tool name, so start from 2 */
for (i = 2; i < argc; i++)
{
const char *arg = argv[i];
if (strcmp (arg, "--system") == 0)
{
type = DBUS_BUS_SYSTEM;
}
else if (strcmp (arg, "--session") == 0)
{
type = DBUS_BUS_SESSION;
}
else if (strstr (arg, "--name=") == arg)
{
name = arg + strlen ("--name=");
}
else if (strstr (arg, "--sleep-ms=") == arg)
{
sleep_ms = atoi (arg + strlen ("--sleep-ms="));
}
else
{
usage_echo (2);
}
}
connection = init_connection (type, name);
while (dbus_connection_read_write_dispatch (connection, -1))
{}
dbus_connection_unref (connection);
return 0;
}
int
dbus_test_tool_black_hole (int argc, char **argv)
{
DBusConnection *connection;
DBusBusType type = DBUS_BUS_SESSION;
int i;
const char *name = NULL;
/* argv[1] is the tool name, so start from 2 */
for (i = 2; i < argc; i++)
{
const char *arg = argv[i];
if (strcmp (arg, "--system") == 0)
{
type = DBUS_BUS_SYSTEM;
}
else if (strcmp (arg, "--session") == 0)
{
type = DBUS_BUS_SESSION;
}
else if (strstr (arg, "--name=") == arg)
{
name = arg + strlen ("--name=");
}
else if (strcmp (arg, "--no-read") == 0)
{
noread = TRUE;
}
else
{
usage_black_hole (2);
}
}
connection = init_connection (type, name);
if (noread)
{
while (1)
_dbus_sleep_milliseconds (3600);
}
noreply = TRUE;
while (dbus_connection_read_write_dispatch (connection, -1))
{}
dbus_connection_unref (connection);
return 0;
}