summary refs log tree commit diff stats
path: root/src/common/dbus/dbus-client.c
blob: cc2fd08713c91e4bf8847bba786b1fe2f29b2b08 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
/* dbus-client.c - HexChat command-line options for D-Bus
 * Copyright (C) 2006 Claessens Xavier
 *
 * 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 St, Fifth Floor, Boston, MA 02110-1301, USA
 *
 * Claessens Xavier
 * xclaesse@gmail.com
 */

#include <dbus/dbus-glib.h>
#include "dbus-client.h"
#include "../hexchat.h"
#include "../hexchatc.h"

#define DBUS_SERVICE "org.hexchat.service"
#define DBUS_REMOTE "/org/hexchat/Remote"
#define DBUS_REMOTE_INTERFACE "org.hexchat.plugin"

static void
write_error (char *message,
	     GError **error)
{
	if (error == NULL || *error == NULL) {
		return;
	}
	g_printerr ("%s: %s\n", message, (*error)->message);
	g_clear_error (error);
}

void
hexchat_remote (void)
/* TODO: dbus_g_connection_unref (connection) are commented because it makes
 * dbus to crash. Fixed in dbus >=0.70 ?!?
 * https://launchpad.net/distros/ubuntu/+source/dbus/+bug/54375
 */
{
	DBusGConnection *connection;
	DBusGProxy *dbus = NULL;
	DBusGProxy *remote_object = NULL;
	gboolean hexchat_running;
	GError *error = NULL;
	char *command = NULL;

	/* GnomeVFS >=2.15 uses D-Bus and threads, so threads should be
	 * initialised before opening for the first time a D-Bus connection */
	if (!g_thread_supported ()) {
		g_thread_init (NULL);
	}
	dbus_g_thread_init ();

	/* if there is nothing to do, return now. */
	if (!arg_existing || !(arg_url || arg_command)) {
		return;
	}

	arg_dont_autoconnect = TRUE;

	connection = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
	if (!connection) {
		write_error (_("Couldn't connect to session bus"), &error);
		return;
	}

	/* Checks if HexChat is already running */
	dbus = dbus_g_proxy_new_for_name (connection,
					  DBUS_SERVICE_DBUS,
					  DBUS_PATH_DBUS,
					  DBUS_INTERFACE_DBUS);
	if (!dbus_g_proxy_call (dbus, "NameHasOwner", &error,
				G_TYPE_STRING, DBUS_SERVICE,
				G_TYPE_INVALID,
				G_TYPE_BOOLEAN, &hexchat_running,
				G_TYPE_INVALID)) {
		write_error (_("Failed to complete NameHasOwner"), &error);
		hexchat_running = FALSE;
	}
	g_object_unref (dbus);

	if (!hexchat_running) {
		//dbus_g_connection_unref (connection);
		return;
	}

	remote_object = dbus_g_proxy_new_for_name (connection,
						   DBUS_SERVICE,
						   DBUS_REMOTE,
						   DBUS_REMOTE_INTERFACE);

	if (arg_url) {
		command = g_strdup_printf ("url %s", arg_url);
	} else if (arg_command) {
		command = g_strdup (arg_command);
	}

	if (command) {
		if (!dbus_g_proxy_call (remote_object, "Command",
					&error,
					G_TYPE_STRING, command,
					G_TYPE_INVALID,G_TYPE_INVALID)) {
			write_error (_("Failed to complete Command"), &error);
		}
		g_free (command);
	}

	exit (0);
}
HAVE_SYS_MMAN_H #include <sys/mman.h> #endif ], [ int i; /* glibc defines this for functions which it implements * to always fail with ENOSYS. Some functions are actually * named something starting with __ and the normal name * is an alias. */ #if defined (__stub_mlock) || defined (__stub___mlock) choke me #else mlock(&i, 4); #endif ; return 0; ], gnupg_cv_mlock_is_in_sys_mman=yes, gnupg_cv_mlock_is_in_sys_mman=no)]) if test "$gnupg_cv_mlock_is_in_sys_mman" = "yes"; then AC_DEFINE(HAVE_MLOCK,1, [Defined if the system supports an mlock() call]) fi fi fi if test "$ac_cv_func_mlock" = "yes"; then AC_CHECK_FUNCS(sysconf getpagesize) AC_MSG_CHECKING(whether mlock is broken) AC_CACHE_VAL(gnupg_cv_have_broken_mlock, AC_TRY_RUN([ #include <stdlib.h> #include <unistd.h> #include <errno.h> #include <sys/mman.h> #include <sys/types.h> #include <fcntl.h> int main() { char *pool; int err; long int pgsize; #if defined(HAVE_SYSCONF) && defined(_SC_PAGESIZE) pgsize = sysconf (_SC_PAGESIZE); #elif defined (HAVE_GETPAGESIZE) pgsize = getpagesize(); #else pgsize = -1; #endif if (pgsize == -1) pgsize = 4096; pool = malloc( 4096 + pgsize ); if( !pool ) return 2; pool += (pgsize - ((long int)pool % pgsize)); err = mlock( pool, 4096 ); if( !err || errno == EPERM || errno == EAGAIN) return 0; /* okay */ return 1; /* hmmm */ } ], gnupg_cv_have_broken_mlock="no", gnupg_cv_have_broken_mlock="yes", gnupg_cv_have_broken_mlock="assume-no" ) ) if test "$gnupg_cv_have_broken_mlock" = "yes"; then AC_DEFINE(HAVE_BROKEN_MLOCK,1, [Defined if the mlock() call does not work]) AC_MSG_RESULT(yes) else if test "$gnupg_cv_have_broken_mlock" = "no"; then AC_MSG_RESULT(no) else AC_MSG_RESULT(assuming no) fi fi fi ]) # GNUPG_SYS_LIBTOOL_CYGWIN32 - find tools needed on cygwin32 AC_DEFUN([GNUPG_SYS_LIBTOOL_CYGWIN32], [AC_CHECK_TOOL(DLLTOOL, dlltool, false) AC_CHECK_TOOL(AS, as, false) ]) dnl LIST_MEMBER() dnl Check whether an element ist contained in a list. Set `found' to dnl `1' if the element is found in the list, to `0' otherwise. AC_DEFUN([LIST_MEMBER], [ name=$1 list=$2 found=0 for n in $list; do if test "x$name" = "x$n"; then found=1 fi done ]) dnl Check for socklen_t: historically on BSD it is an int, and in dnl POSIX 1g it is a type of its own, but some platforms use different dnl types for the argument to getsockopt, getpeername, etc. So we dnl have to test to find something that will work. AC_DEFUN([TYPE_SOCKLEN_T], [ AC_CHECK_TYPE([socklen_t], ,[ AC_MSG_CHECKING([for socklen_t equivalent]) AC_CACHE_VAL([socklen_t_equiv], [ # Systems have either "struct sockaddr *" or # "void *" as the second argument to getpeername socklen_t_equiv= for arg2 in "struct sockaddr" void; do for t in int size_t unsigned long "unsigned long"; do AC_TRY_COMPILE([ #include <sys/types.h> #include <sys/socket.h> int getpeername (int, $arg2 *, $t *); ],[ $t len; getpeername(0,0,&len); ],[ socklen_t_equiv="$t" break ]) done done if test "x$socklen_t_equiv" = x; then AC_MSG_ERROR([Cannot find a type to use in place of socklen_t]) fi ]) AC_MSG_RESULT($socklen_t_equiv) AC_DEFINE_UNQUOTED(socklen_t, $socklen_t_equiv, [type to use in place of socklen_t if not defined])], [#include <sys/types.h> #include <sys/socket.h>]) ]) # GNUPG_PTH_VERSION_CHECK(REQUIRED) # # If the version is sufficient, HAVE_PTH will be set to yes. # # Taken form the m4 macros which come with Pth AC_DEFUN([GNUPG_PTH_VERSION_CHECK], [ _pth_version=`$PTH_CONFIG --version | awk 'NR==1 {print [$]3}'` _req_version="ifelse([$1],,1.2.0,$1)" AC_MSG_CHECKING(for PTH - version >= $_req_version) for _var in _pth_version _req_version; do eval "_val=\"\$${_var}\"" _major=`echo $_val | sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\([[ab.]]\)\([[0-9]]*\)/\1/'` _minor=`echo $_val | sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\([[ab.]]\)\([[0-9]]*\)/\2/'` _rtype=`echo $_val | sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\([[ab.]]\)\([[0-9]]*\)/\3/'` _micro=`echo $_val | sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\([[ab.]]\)\([[0-9]]*\)/\4/'` case $_rtype in "a" ) _rtype=0 ;; "b" ) _rtype=1 ;; "." ) _rtype=2 ;; esac _hex=`echo dummy | awk '{ printf("%d%02d%1d%02d", major, minor, rtype, micro); }' \ "major=$_major" "minor=$_minor" "rtype=$_rtype" "micro=$_micro"` eval "${_var}_hex=\"\$_hex\"" done have_pth=no if test ".$_pth_version_hex" != .; then if test ".$_req_version_hex" != .; then if test $_pth_version_hex -ge $_req_version_hex; then have_pth=yes fi fi fi if test $have_pth = yes; then AC_MSG_RESULT(yes) AC_MSG_CHECKING([whether PTH installation is sane]) AC_CACHE_VAL(gnupg_cv_pth_is_sane,[ _gnupg_pth_save_cflags=$CFLAGS _gnupg_pth_save_ldflags=$LDFLAGS _gnupg_pth_save_libs=$LIBS CFLAGS="$CFLAGS `$PTH_CONFIG --cflags`" LDFLAGS="$LDFLAGS `$PTH_CONFIG --ldflags`" LIBS="$LIBS `$PTH_CONFIG --libs`" AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <pth.h> ], [[ pth_init ();]])], gnupg_cv_pth_is_sane=yes, gnupg_cv_pth_is_sane=no) CFLAGS=$_gnupg_pth_save_cflags LDFLAGS=$_gnupg_pth_save_ldflags LIBS=$_gnupg_pth_save_libs ]) if test $gnupg_cv_pth_is_sane != yes; then have_pth=no fi AC_MSG_RESULT($gnupg_cv_pth_is_sane) else AC_MSG_RESULT(no) fi ])