1d012387afef0ba02185ebe27bc6bb15551912e92Havoc Pennington/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ 2f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira/* dbus-launch.h dbus-launch utility 3f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira * 4f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira * Copyright (C) 2006 Thiago Macieira <thiago@kde.org> 5f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira * 6f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira * Licensed under the Academic Free License version 2.1 7f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira * 8f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira * This program is free software; you can redistribute it and/or modify 9f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira * it under the terms of the GNU General Public License as published by 10f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira * the Free Software Foundation; either version 2 of the License, or 11f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira * (at your option) any later version. 12f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira * 13f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira * This program is distributed in the hope that it will be useful, 14f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira * but WITHOUT ANY WARRANTY; without even the implied warranty of 15f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira * GNU General Public License for more details. 17f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira * 18f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira * You should have received a copy of the GNU General Public License 19f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira * 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 21f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira * 22f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira */ 23dbecdeabb20e0ce11121819c63373f0afba57c58Marcus Brinkmann 24dbecdeabb20e0ce11121819c63373f0afba57c58Marcus Brinkmann#include <config.h> 25f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira#include "dbus-launch.h" 26f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira 27f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira#ifdef DBUS_BUILD_X11 28f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira#include <stdlib.h> 2910fe37f58213d3895229208453c3e691e554ed72Havoc Pennington#include <sys/types.h> 3010fe37f58213d3895229208453c3e691e554ed72Havoc Pennington#include <sys/stat.h> 31f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira#include <unistd.h> 32f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira#include <fcntl.h> 33f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira#include <errno.h> 34f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira#include <stdio.h> 35f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira#include <string.h> 36f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira#include <pwd.h> 37f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira#include <X11/Xlib.h> 38f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira#include <X11/Xatom.h> 39f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira 40d8155bf51bf6484a94e734601526bf211053a5e1Havoc PenningtonDisplay *xdisplay = NULL; 41f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieirastatic Atom selection_atom; 42f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieirastatic Atom address_atom; 43f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieirastatic Atom pid_atom; 44f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira 45f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieirastatic int 46f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieirax_io_error_handler (Display *xdisplay) 47f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira{ 48f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira verbose ("X IO error\n"); 49f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira kill_bus_and_exit (0); 50f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira return 0; 51f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira} 52f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira 5310fe37f58213d3895229208453c3e691e554ed72Havoc Penningtonstatic void 5410fe37f58213d3895229208453c3e691e554ed72Havoc Penningtonremove_prefix (char *s, 5510fe37f58213d3895229208453c3e691e554ed72Havoc Pennington char *prefix) 56f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira{ 5710fe37f58213d3895229208453c3e691e554ed72Havoc Pennington int plen; 5810fe37f58213d3895229208453c3e691e554ed72Havoc Pennington 5910fe37f58213d3895229208453c3e691e554ed72Havoc Pennington plen = strlen (prefix); 60f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira 6110fe37f58213d3895229208453c3e691e554ed72Havoc Pennington if (strncmp (s, prefix, plen) == 0) 62f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira { 6310fe37f58213d3895229208453c3e691e554ed72Havoc Pennington memmove (s, s + plen, strlen (s) - plen + 1); 6410fe37f58213d3895229208453c3e691e554ed72Havoc Pennington } 6510fe37f58213d3895229208453c3e691e554ed72Havoc Pennington} 66f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira 6710fe37f58213d3895229208453c3e691e554ed72Havoc Penningtonstatic const char* 6810fe37f58213d3895229208453c3e691e554ed72Havoc Penningtonget_homedir (void) 6910fe37f58213d3895229208453c3e691e554ed72Havoc Pennington{ 7010fe37f58213d3895229208453c3e691e554ed72Havoc Pennington const char *home; 7110fe37f58213d3895229208453c3e691e554ed72Havoc Pennington 7210fe37f58213d3895229208453c3e691e554ed72Havoc Pennington home = getenv ("HOME"); 7310fe37f58213d3895229208453c3e691e554ed72Havoc Pennington if (home == NULL) 7410fe37f58213d3895229208453c3e691e554ed72Havoc Pennington { 7510fe37f58213d3895229208453c3e691e554ed72Havoc Pennington /* try from the user database */ 7610fe37f58213d3895229208453c3e691e554ed72Havoc Pennington struct passwd *user = getpwuid (getuid()); 7710fe37f58213d3895229208453c3e691e554ed72Havoc Pennington if (user != NULL) 7810fe37f58213d3895229208453c3e691e554ed72Havoc Pennington home = user->pw_dir; 7910fe37f58213d3895229208453c3e691e554ed72Havoc Pennington } 80f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira 8110fe37f58213d3895229208453c3e691e554ed72Havoc Pennington if (home == NULL) 8210fe37f58213d3895229208453c3e691e554ed72Havoc Pennington { 8310fe37f58213d3895229208453c3e691e554ed72Havoc Pennington fprintf (stderr, "Can't get user home directory\n"); 8410fe37f58213d3895229208453c3e691e554ed72Havoc Pennington exit (1); 85f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira } 86f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira 8710fe37f58213d3895229208453c3e691e554ed72Havoc Pennington return home; 88f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira} 89f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira 9010fe37f58213d3895229208453c3e691e554ed72Havoc Pennington#define DBUS_DIR ".dbus" 9110fe37f58213d3895229208453c3e691e554ed72Havoc Pennington#define DBUS_SESSION_BUS_DIR "session-bus" 9210fe37f58213d3895229208453c3e691e554ed72Havoc Pennington 93f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieirastatic char * 94f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieiraget_session_file (void) 95f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira{ 9610fe37f58213d3895229208453c3e691e554ed72Havoc Pennington static const char prefix[] = "/" DBUS_DIR "/" DBUS_SESSION_BUS_DIR "/"; 9710fe37f58213d3895229208453c3e691e554ed72Havoc Pennington const char *machine; 9810fe37f58213d3895229208453c3e691e554ed72Havoc Pennington const char *home; 99f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira char *display; 100f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira char *result; 101f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira char *p; 102f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira 10301b91ba121034f94c1e4d4511b9e61f622dde48cThiago Macieira machine = get_machine_uuid (); 10401b91ba121034f94c1e4d4511b9e61f622dde48cThiago Macieira if (machine == NULL) 10501b91ba121034f94c1e4d4511b9e61f622dde48cThiago Macieira return NULL; 10601b91ba121034f94c1e4d4511b9e61f622dde48cThiago Macieira 107f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira display = xstrdup (getenv ("DISPLAY")); 108f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira if (display == NULL) 109f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira { 110f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira verbose ("X11 integration disabled because X11 is not running\n"); 111f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira return NULL; 112f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira } 113f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira 114f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira /* remove the screen part of the display name */ 115f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira p = strrchr (display, ':'); 116f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira if (p != NULL) 11710fe37f58213d3895229208453c3e691e554ed72Havoc Pennington { 11810fe37f58213d3895229208453c3e691e554ed72Havoc Pennington for ( ; *p; ++p) 119f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira { 12010fe37f58213d3895229208453c3e691e554ed72Havoc Pennington if (*p == '.') 12110fe37f58213d3895229208453c3e691e554ed72Havoc Pennington { 12210fe37f58213d3895229208453c3e691e554ed72Havoc Pennington *p = '\0'; 12310fe37f58213d3895229208453c3e691e554ed72Havoc Pennington break; 12410fe37f58213d3895229208453c3e691e554ed72Havoc Pennington } 125f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira } 126f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira } 127f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira 12810fe37f58213d3895229208453c3e691e554ed72Havoc Pennington /* Note that we leave the hostname in the display most of the 12910fe37f58213d3895229208453c3e691e554ed72Havoc Pennington * time. The idea is that we want to be per-(machine,display,user) 13010fe37f58213d3895229208453c3e691e554ed72Havoc Pennington * triplet to be extra-sure we get a bus we can connect to. Ideally 13110fe37f58213d3895229208453c3e691e554ed72Havoc Pennington * we'd recognize when the hostname matches the machine we're on in 13210fe37f58213d3895229208453c3e691e554ed72Havoc Pennington * all cases; we do try to drop localhost and localhost.localdomain 13310fe37f58213d3895229208453c3e691e554ed72Havoc Pennington * as a special common case so that alternate spellings of DISPLAY 13410fe37f58213d3895229208453c3e691e554ed72Havoc Pennington * don't result in extra bus instances. 13510fe37f58213d3895229208453c3e691e554ed72Havoc Pennington * 13610fe37f58213d3895229208453c3e691e554ed72Havoc Pennington * We also kill the ":" if there's nothing in front of it. This 13710fe37f58213d3895229208453c3e691e554ed72Havoc Pennington * avoids an ugly double underscore in the filename. 13810fe37f58213d3895229208453c3e691e554ed72Havoc Pennington */ 13910fe37f58213d3895229208453c3e691e554ed72Havoc Pennington remove_prefix (display, "localhost.localdomain:"); 14010fe37f58213d3895229208453c3e691e554ed72Havoc Pennington remove_prefix (display, "localhost:"); 14110fe37f58213d3895229208453c3e691e554ed72Havoc Pennington remove_prefix (display, ":"); 14210fe37f58213d3895229208453c3e691e554ed72Havoc Pennington 14310fe37f58213d3895229208453c3e691e554ed72Havoc Pennington /* replace the : in the display with _ if the : is still there. 14410fe37f58213d3895229208453c3e691e554ed72Havoc Pennington * use _ instead of - since it can't be in hostnames. 14510fe37f58213d3895229208453c3e691e554ed72Havoc Pennington */ 14610fe37f58213d3895229208453c3e691e554ed72Havoc Pennington for (p = display; *p; ++p) 147f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira { 14810fe37f58213d3895229208453c3e691e554ed72Havoc Pennington if (*p == ':') 14910fe37f58213d3895229208453c3e691e554ed72Havoc Pennington *p = '_'; 150f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira } 15110fe37f58213d3895229208453c3e691e554ed72Havoc Pennington 15210fe37f58213d3895229208453c3e691e554ed72Havoc Pennington home = get_homedir (); 15310fe37f58213d3895229208453c3e691e554ed72Havoc Pennington 15410fe37f58213d3895229208453c3e691e554ed72Havoc Pennington result = malloc (strlen (home) + strlen (prefix) + strlen (machine) + 155f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira strlen (display) + 2); 156f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira if (result == NULL) 157f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira { 158f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira /* out of memory */ 159f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira free (display); 160f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira return NULL; 161f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira } 162f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira 163f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira strcpy (result, home); 164f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira strcat (result, prefix); 16510fe37f58213d3895229208453c3e691e554ed72Havoc Pennington strcat (result, machine); 16610fe37f58213d3895229208453c3e691e554ed72Havoc Pennington strcat (result, "-"); 167f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira strcat (result, display); 168f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira free (display); 169f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira 170f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira verbose ("session file: %s\n", result); 171f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira return result; 172f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira} 173f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira 17410fe37f58213d3895229208453c3e691e554ed72Havoc Penningtonstatic void 17510fe37f58213d3895229208453c3e691e554ed72Havoc Penningtonensure_session_directory (void) 17610fe37f58213d3895229208453c3e691e554ed72Havoc Pennington{ 17710fe37f58213d3895229208453c3e691e554ed72Havoc Pennington const char *home; 17810fe37f58213d3895229208453c3e691e554ed72Havoc Pennington char *dir; 17910fe37f58213d3895229208453c3e691e554ed72Havoc Pennington 18010fe37f58213d3895229208453c3e691e554ed72Havoc Pennington home = get_homedir (); 18110fe37f58213d3895229208453c3e691e554ed72Havoc Pennington 18210fe37f58213d3895229208453c3e691e554ed72Havoc Pennington /* be sure we have space for / and nul */ 18310fe37f58213d3895229208453c3e691e554ed72Havoc Pennington dir = malloc (strlen (home) + strlen (DBUS_DIR) + strlen (DBUS_SESSION_BUS_DIR) + 3); 18410fe37f58213d3895229208453c3e691e554ed72Havoc Pennington if (dir == NULL) 18510fe37f58213d3895229208453c3e691e554ed72Havoc Pennington { 18610fe37f58213d3895229208453c3e691e554ed72Havoc Pennington fprintf (stderr, "no memory\n"); 18710fe37f58213d3895229208453c3e691e554ed72Havoc Pennington exit (1); 18810fe37f58213d3895229208453c3e691e554ed72Havoc Pennington } 18910fe37f58213d3895229208453c3e691e554ed72Havoc Pennington 19010fe37f58213d3895229208453c3e691e554ed72Havoc Pennington strcpy (dir, home); 19110fe37f58213d3895229208453c3e691e554ed72Havoc Pennington strcat (dir, "/"); 19210fe37f58213d3895229208453c3e691e554ed72Havoc Pennington strcat (dir, DBUS_DIR); 19310fe37f58213d3895229208453c3e691e554ed72Havoc Pennington 19410fe37f58213d3895229208453c3e691e554ed72Havoc Pennington if (mkdir (dir, 0700) < 0) 19510fe37f58213d3895229208453c3e691e554ed72Havoc Pennington { 19610fe37f58213d3895229208453c3e691e554ed72Havoc Pennington /* only print a warning here, writing the session file itself will fail later */ 19710fe37f58213d3895229208453c3e691e554ed72Havoc Pennington if (errno != EEXIST) 19810fe37f58213d3895229208453c3e691e554ed72Havoc Pennington fprintf (stderr, "Unable to create %s\n", dir); 19910fe37f58213d3895229208453c3e691e554ed72Havoc Pennington } 20010fe37f58213d3895229208453c3e691e554ed72Havoc Pennington 20110fe37f58213d3895229208453c3e691e554ed72Havoc Pennington strcat (dir, "/"); 20210fe37f58213d3895229208453c3e691e554ed72Havoc Pennington strcat (dir, DBUS_SESSION_BUS_DIR); 20310fe37f58213d3895229208453c3e691e554ed72Havoc Pennington 20410fe37f58213d3895229208453c3e691e554ed72Havoc Pennington if (mkdir (dir, 0700) < 0) 20510fe37f58213d3895229208453c3e691e554ed72Havoc Pennington { 20610fe37f58213d3895229208453c3e691e554ed72Havoc Pennington /* only print a warning here, writing the session file itself will fail later */ 20710fe37f58213d3895229208453c3e691e554ed72Havoc Pennington if (errno != EEXIST) 20810fe37f58213d3895229208453c3e691e554ed72Havoc Pennington fprintf (stderr, "Unable to create %s\n", dir); 20910fe37f58213d3895229208453c3e691e554ed72Havoc Pennington } 21010fe37f58213d3895229208453c3e691e554ed72Havoc Pennington 21110fe37f58213d3895229208453c3e691e554ed72Havoc Pennington free (dir); 21210fe37f58213d3895229208453c3e691e554ed72Havoc Pennington} 21310fe37f58213d3895229208453c3e691e554ed72Havoc Pennington 214f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieirastatic Display * 215f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieiraopen_x11 (void) 216f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira{ 217f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira if (xdisplay != NULL) 218f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira return xdisplay; 219f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira 220f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira xdisplay = XOpenDisplay (NULL); 221f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira if (xdisplay != NULL) 222f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira { 223f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira verbose ("Connected to X11 display '%s'\n", DisplayString (xdisplay)); 224f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira XSetIOErrorHandler (x_io_error_handler); 225f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira } 226f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira return xdisplay; 227f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira} 228f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira 229f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieirastatic int 230f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieirainit_x_atoms (Display *display) 231f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira{ 23210fe37f58213d3895229208453c3e691e554ed72Havoc Pennington static const char selection_prefix[] = "_DBUS_SESSION_BUS_SELECTION_"; 23310fe37f58213d3895229208453c3e691e554ed72Havoc Pennington static const char address_prefix[] = "_DBUS_SESSION_BUS_ADDRESS"; 23410fe37f58213d3895229208453c3e691e554ed72Havoc Pennington static const char pid_prefix[] = "_DBUS_SESSION_BUS_PID"; 235f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira static int init = FALSE; 236f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira char *atom_name; 23710fe37f58213d3895229208453c3e691e554ed72Havoc Pennington const char *machine; 238f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira char *user_name; 239f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira struct passwd *user; 240f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira 241f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira if (init) 242f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira return TRUE; 243f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira 24401b91ba121034f94c1e4d4511b9e61f622dde48cThiago Macieira machine = get_machine_uuid (); 24501b91ba121034f94c1e4d4511b9e61f622dde48cThiago Macieira if (machine == NULL) 24601b91ba121034f94c1e4d4511b9e61f622dde48cThiago Macieira return FALSE; 24701b91ba121034f94c1e4d4511b9e61f622dde48cThiago Macieira 248f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira user = getpwuid (getuid ()); 249f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira if (user == NULL) 250f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira { 251f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira verbose ("Could not determine the user informations; aborting X11 integration.\n"); 252f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira return FALSE; 253f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira } 254f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira user_name = xstrdup(user->pw_name); 255f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira 25610fe37f58213d3895229208453c3e691e554ed72Havoc Pennington atom_name = malloc (strlen (machine) + strlen (user_name) + 2 + 257f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira MAX (strlen (selection_prefix), 258f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira MAX (strlen (address_prefix), 259f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira strlen (pid_prefix)))); 260f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira if (atom_name == NULL) 261f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira { 262f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira verbose ("Could not create X11 atoms; aborting X11 integration.\n"); 263f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira free (user_name); 264f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira return FALSE; 265f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira } 266f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira 267f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira /* create the selection atom */ 268f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira strcpy (atom_name, selection_prefix); 269f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira strcat (atom_name, user_name); 270f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira strcat (atom_name, "_"); 27110fe37f58213d3895229208453c3e691e554ed72Havoc Pennington strcat (atom_name, machine); 272f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira selection_atom = XInternAtom (display, atom_name, FALSE); 273f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira 274f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira /* create the address property atom */ 275f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira strcpy (atom_name, address_prefix); 276f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira address_atom = XInternAtom (display, atom_name, FALSE); 277f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira 278f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira /* create the PID property atom */ 279f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira strcpy (atom_name, pid_prefix); 280f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira pid_atom = XInternAtom (display, atom_name, FALSE); 281f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira 282f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira free (atom_name); 283f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira free (user_name); 284f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira init = TRUE; 285f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira return TRUE; 286f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira} 287f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira 288f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira/* 289f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira * Gets the daemon address from the X11 display. 290f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira * Returns FALSE if there was an error. Returning 291f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira * TRUE does not mean the address exists. 292f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira */ 293f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieiraint 294f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieirax11_get_address (char **paddress, pid_t *pid, long *wid) 295f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira{ 296f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira Atom type; 297f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira Window owner; 298f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira int format; 299f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira unsigned long items; 300f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira unsigned long after; 301f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira char *data; 302f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira 303f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira *paddress = NULL; 304f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira 305f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira /* locate the selection owner */ 306f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira owner = XGetSelectionOwner (xdisplay, selection_atom); 307f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira if (owner == None) 308f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira return TRUE; /* no owner */ 309f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira if (wid != NULL) 310f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira *wid = (long) owner; 311f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira 312f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira /* get the bus address */ 313f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira XGetWindowProperty (xdisplay, owner, address_atom, 0, 1024, False, 314f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira XA_STRING, &type, &format, &items, &after, 315f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira (unsigned char **) &data); 316f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira if (type == None || after != 0 || data == NULL || format != 8) 317f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira return FALSE; /* error */ 318f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira 319f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira *paddress = xstrdup (data); 320f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira XFree (data); 321f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira 322f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira /* get the PID */ 323f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira if (pid != NULL) 324f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira { 325f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira *pid = 0; 326f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira XGetWindowProperty (xdisplay, owner, pid_atom, 0, sizeof pid, False, 327f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira XA_CARDINAL, &type, &format, &items, &after, 328f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira (unsigned char **) &data); 329f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira if (type != None && after == 0 && data != NULL && format == 32) 330f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira *pid = (pid_t) *(long*) data; 331f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira XFree (data); 332f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira } 333f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira 334f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira return TRUE; /* success */ 335f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira} 336f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira 337f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira/* 338f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira * Saves the address in the X11 display. Returns 0 on success. 339f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira * If an error occurs, returns -1. If the selection already exists, 340f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira * returns 1. (i.e. another daemon is already running) 341f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira */ 342f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieirastatic Window 343f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieiraset_address_in_x11(char *address, pid_t pid) 344f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira{ 345f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira char *current_address; 346193ebb7083fb1e9dccff04fc0a9d805a0aa03ea2Colin Walters Window wid = None; 347163555c7ab56132ee27e3e7d9a26eb985682c1b5Havoc Pennington unsigned long pid32; /* Xlib property functions want _long_ not 32-bit for format "32" */ 34810fe37f58213d3895229208453c3e691e554ed72Havoc Pennington 349f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira /* lock the X11 display to make sure we're doing this atomically */ 350f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira XGrabServer (xdisplay); 351f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira 352f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira if (!x11_get_address (¤t_address, NULL, NULL)) 353f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira { 354f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira /* error! */ 355193ebb7083fb1e9dccff04fc0a9d805a0aa03ea2Colin Walters goto out; 356f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira } 357f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira 358f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira if (current_address != NULL) 359f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira { 360f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira /* someone saved the address in the meantime */ 361f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira free (current_address); 362193ebb7083fb1e9dccff04fc0a9d805a0aa03ea2Colin Walters goto out; 363f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira } 364f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira 365f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira /* Create our window */ 3668f5c3e3c25901b089bc3fb87d53c7a98df48121fEamon Walsh wid = XCreateWindow (xdisplay, RootWindow (xdisplay, 0), -20, -20, 10, 10, 3678f5c3e3c25901b089bc3fb87d53c7a98df48121fEamon Walsh 0, CopyFromParent, InputOnly, CopyFromParent, 3688f5c3e3c25901b089bc3fb87d53c7a98df48121fEamon Walsh 0, NULL); 369f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira verbose ("Created window %d\n", wid); 370f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira 371f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira /* Save the property in the window */ 372f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira XChangeProperty (xdisplay, wid, address_atom, XA_STRING, 8, PropModeReplace, 373f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira (unsigned char *)address, strlen (address)); 37410fe37f58213d3895229208453c3e691e554ed72Havoc Pennington pid32 = pid; 375f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira XChangeProperty (xdisplay, wid, pid_atom, XA_CARDINAL, 32, PropModeReplace, 37610fe37f58213d3895229208453c3e691e554ed72Havoc Pennington (unsigned char *)&pid32, 1); 377f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira 378f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira /* Now grab the selection */ 379f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira XSetSelectionOwner (xdisplay, selection_atom, wid, CurrentTime); 380f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira 381193ebb7083fb1e9dccff04fc0a9d805a0aa03ea2Colin Walters out: 382f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira /* Ungrab the server to let other people use it too */ 383f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira XUngrabServer (xdisplay); 384f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira 385193ebb7083fb1e9dccff04fc0a9d805a0aa03ea2Colin Walters /* And make sure that the ungrab gets sent to X11 */ 386f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira XFlush (xdisplay); 387f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira 388f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira return wid; 389f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira} 390f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira 391f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira/* 392f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira * Saves the session address in session file. Returns TRUE on 393f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira * success, FALSE if an error occurs. 394f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira */ 395f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieirastatic int 396f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieiraset_address_in_file (char *address, pid_t pid, Window wid) 397f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira{ 398f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira char *session_file; 399f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira FILE *f; 400f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira 40110fe37f58213d3895229208453c3e691e554ed72Havoc Pennington ensure_session_directory (); 402f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira session_file = get_session_file(); 403f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira if (session_file == NULL) 404f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira return FALSE; 405f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira 406f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira f = fopen (session_file, "w"); 407f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira if (f == NULL) 408f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira return FALSE; /* some kind of error */ 40910fe37f58213d3895229208453c3e691e554ed72Havoc Pennington fprintf (f, 41010fe37f58213d3895229208453c3e691e554ed72Havoc Pennington "# This file allows processes on the machine with id %s using \n" 41110fe37f58213d3895229208453c3e691e554ed72Havoc Pennington "# display %s to find the D-Bus session bus with the below address.\n" 41210fe37f58213d3895229208453c3e691e554ed72Havoc Pennington "# If the DBUS_SESSION_BUS_ADDRESS environment variable is set, it will\n" 41310fe37f58213d3895229208453c3e691e554ed72Havoc Pennington "# be used rather than this file.\n" 41410fe37f58213d3895229208453c3e691e554ed72Havoc Pennington "# See \"man dbus-launch\" for more details.\n" 41510fe37f58213d3895229208453c3e691e554ed72Havoc Pennington "DBUS_SESSION_BUS_ADDRESS=%s\n" 41610fe37f58213d3895229208453c3e691e554ed72Havoc Pennington "DBUS_SESSION_BUS_PID=%ld\n" 41710fe37f58213d3895229208453c3e691e554ed72Havoc Pennington "DBUS_SESSION_BUS_WINDOWID=%ld\n", 41810fe37f58213d3895229208453c3e691e554ed72Havoc Pennington get_machine_uuid (), 41910fe37f58213d3895229208453c3e691e554ed72Havoc Pennington getenv ("DISPLAY"), 42010fe37f58213d3895229208453c3e691e554ed72Havoc Pennington address, (long)pid, (long)wid); 421f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira 422f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira fclose (f); 423f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira free (session_file); 424f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira 425f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira return TRUE; 426f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira} 427f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira 428f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieiraint 429f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieirax11_save_address (char *address, pid_t pid, long *wid) 430f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira{ 431f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira Window id = set_address_in_x11 (address, pid); 432f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira if (id != None) 433f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira { 434f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira if (!set_address_in_file (address, pid, id)) 435f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira return FALSE; 436f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira 437f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira if (wid != NULL) 438f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira *wid = (long) id; 439f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira return TRUE; 440f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira } 441f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira return FALSE; 442f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira} 443f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira 444f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieiraint 445f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieirax11_init (void) 446f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira{ 447f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira return open_x11 () != NULL && init_x_atoms (xdisplay); 448f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira} 449f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira 450f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieiravoid 451f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieirax11_handle_event (void) 452f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira{ 453f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira if (xdisplay != NULL) 454f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira { 455f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira while (XPending (xdisplay)) 456f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira { 457f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira XEvent ignored; 458f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira XNextEvent (xdisplay, &ignored); 459f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira } 460f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira } 461f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira} 462f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira 463f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira#else 46446df8b52d970d7c4ec3a61b5c696a05d0cb55f5dRalf Habackervoid dummy_dbus_launch_x11 (void); 46546df8b52d970d7c4ec3a61b5c696a05d0cb55f5dRalf Habacker 466f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieiravoid dummy_dbus_launch_x11 (void) { } 467f6fa010403cb2badd88ce096ae91f664418508d1Thiago Macieira#endif 468