|
Carlos Lopez |
a09598 |
/* bundle-main.c -- X server launcher
|
|
Carlos Lopez |
a09598 |
$Id: bundle-main.c,v 1.17 2003/09/11 00:17:10 jharper Exp $
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
Copyright (c) 2002 Apple Computer, Inc. All rights reserved.
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
Permission is hereby granted, free of charge, to any person
|
|
Carlos Lopez |
a09598 |
obtaining a copy of this software and associated documentation files
|
|
Carlos Lopez |
a09598 |
(the "Software"), to deal in the Software without restriction,
|
|
Carlos Lopez |
a09598 |
including without limitation the rights to use, copy, modify, merge,
|
|
Carlos Lopez |
a09598 |
publish, distribute, sublicense, and/or sell copies of the Software,
|
|
Carlos Lopez |
a09598 |
and to permit persons to whom the Software is furnished to do so,
|
|
Carlos Lopez |
a09598 |
subject to the following conditions:
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
The above copyright notice and this permission notice shall be
|
|
Carlos Lopez |
a09598 |
included in all copies or substantial portions of the Software.
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
Carlos Lopez |
a09598 |
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
Carlos Lopez |
a09598 |
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
Carlos Lopez |
a09598 |
NONINFRINGEMENT. IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT
|
|
Carlos Lopez |
a09598 |
HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|
Carlos Lopez |
a09598 |
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
Carlos Lopez |
a09598 |
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
Carlos Lopez |
a09598 |
DEALINGS IN THE SOFTWARE.
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
Except as contained in this notice, the name(s) of the above
|
|
Carlos Lopez |
a09598 |
copyright holders shall not be used in advertising or otherwise to
|
|
Carlos Lopez |
a09598 |
promote the sale, use or other dealings in this Software without
|
|
Carlos Lopez |
a09598 |
prior written authorization.
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
Parts of this file are derived from xdm, which has this copyright:
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
Copyright 1988, 1998 The Open Group
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
Permission to use, copy, modify, distribute, and sell this software
|
|
Carlos Lopez |
a09598 |
and its documentation for any purpose is hereby granted without fee,
|
|
Carlos Lopez |
a09598 |
provided that the above copyright notice appear in all copies and
|
|
Carlos Lopez |
a09598 |
that both that copyright notice and this permission notice appear in
|
|
Carlos Lopez |
a09598 |
supporting documentation.
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
The above copyright notice and this permission notice shall be
|
|
Carlos Lopez |
a09598 |
included in all copies or substantial portions of the Software.
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
Carlos Lopez |
a09598 |
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
Carlos Lopez |
a09598 |
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
Carlos Lopez |
a09598 |
NONINFRINGEMENT. IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY
|
|
Carlos Lopez |
a09598 |
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
Carlos Lopez |
a09598 |
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
Carlos Lopez |
a09598 |
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
Except as contained in this notice, the name of The Open Group shall
|
|
Carlos Lopez |
a09598 |
not be used in advertising or otherwise to promote the sale, use or
|
|
Carlos Lopez |
a09598 |
other dealings in this Software without prior written authorization
|
|
Carlos Lopez |
a09598 |
from The Open Group. */
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
#include <stdio.h></stdio.h>
|
|
Carlos Lopez |
a09598 |
#include <unistd.h></unistd.h>
|
|
Carlos Lopez |
a09598 |
#include <stdlib.h></stdlib.h>
|
|
Carlos Lopez |
a09598 |
#include <fcntl.h></fcntl.h>
|
|
Carlos Lopez |
a09598 |
#include <errno.h></errno.h>
|
|
Carlos Lopez |
a09598 |
#include <sys socket.h=""></sys>
|
|
Carlos Lopez |
a09598 |
#include <sys utsname.h=""></sys>
|
|
Carlos Lopez |
a09598 |
#include <ifaddrs.h></ifaddrs.h>
|
|
Carlos Lopez |
a09598 |
#include <netdb.h></netdb.h>
|
|
Carlos Lopez |
a09598 |
#include <netinet in.h=""></netinet>
|
|
Carlos Lopez |
a09598 |
#include <time.h></time.h>
|
|
Carlos Lopez |
a09598 |
#include <sys wait.h=""></sys>
|
|
Carlos Lopez |
a09598 |
#include <setjmp.h></setjmp.h>
|
|
Carlos Lopez |
a09598 |
#include <sys ioctl.h=""></sys>
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
#include <x11 xlib.h=""></x11>
|
|
Carlos Lopez |
a09598 |
#include <x11 xauth.h=""></x11>
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
#include <corefoundation corefoundation.h=""></corefoundation>
|
|
Carlos Lopez |
a09598 |
#include <systemconfiguration systemconfiguration.h=""></systemconfiguration>
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
#define X_SERVER "/usr/X11R6/bin/Xquartz"
|
|
Carlos Lopez |
a09598 |
#define XTERM_PATH "/usr/X11R6/bin/xterm"
|
|
Carlos Lopez |
a09598 |
#define WM_PATH "/usr/X11R6/bin/quartz-wm"
|
|
Carlos Lopez |
a09598 |
#define DEFAULT_XINITRC "/usr/X11R6/lib/X11/xinit/xinitrc"
|
|
Carlos Lopez |
a09598 |
#include <mach-o dyld.h=""></mach-o>
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
/* what xinit does */
|
|
Carlos Lopez |
a09598 |
#ifndef SHELL
|
|
Carlos Lopez |
a09598 |
# define SHELL "sh"
|
|
Carlos Lopez |
a09598 |
#endif
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
#undef FALSE
|
|
Carlos Lopez |
a09598 |
#define FALSE 0
|
|
Carlos Lopez |
a09598 |
#undef TRUE
|
|
Carlos Lopez |
a09598 |
#define TRUE 1
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
#define MAX_DISPLAYS 64
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
static int server_pid = -1, client_pid = -1;
|
|
Carlos Lopez |
a09598 |
static int xinit_kills_server = FALSE;
|
|
Carlos Lopez |
a09598 |
static jmp_buf exit_continuation;
|
|
Carlos Lopez |
a09598 |
static const char *server_name = NULL;
|
|
Carlos Lopez |
a09598 |
static Display *server_dpy;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
static char *auth_file;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
typedef struct addr_list_struct addr_list;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
struct addr_list_struct {
|
|
Carlos Lopez |
a09598 |
addr_list *next;
|
|
Carlos Lopez |
a09598 |
Xauth auth;
|
|
Carlos Lopez |
a09598 |
};
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
static addr_list *addresses;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
/* Utility functions. */
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
/* Return the current host name. Matches what Xlib does. */
|
|
Carlos Lopez |
a09598 |
static char *
|
|
Carlos Lopez |
a09598 |
host_name (void)
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
#ifdef NEED_UTSNAME
|
|
Carlos Lopez |
a09598 |
static struct utsname name;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
uname(&name);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
return name.nodename;
|
|
Carlos Lopez |
a09598 |
#else
|
|
Carlos Lopez |
a09598 |
static char buf[100];
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
gethostname(buf, sizeof(buf));
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
return buf;
|
|
Carlos Lopez |
a09598 |
#endif
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
static int
|
|
Carlos Lopez |
a09598 |
read_boolean_pref (CFStringRef name, int default_)
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
int value;
|
|
Carlos Lopez |
a09598 |
Boolean ok;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
value = CFPreferencesGetAppBooleanValue (name,
|
|
Carlos Lopez |
a09598 |
CFSTR ("com.apple.x11"), &ok);
|
|
Carlos Lopez |
a09598 |
return ok ? value : default_;
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
static inline int
|
|
Carlos Lopez |
a09598 |
binary_equal (const void *a, const void *b, int length)
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
return memcmp (a, b, length) == 0;
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
static inline void *
|
|
Carlos Lopez |
a09598 |
binary_dup (const void *a, int length)
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
void *b = malloc (length);
|
|
Carlos Lopez |
a09598 |
if (b != NULL)
|
|
Carlos Lopez |
a09598 |
memcpy (b, a, length);
|
|
Carlos Lopez |
a09598 |
return b;
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
static inline void
|
|
Carlos Lopez |
a09598 |
binary_free (void *data, int length)
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
if (data != NULL)
|
|
Carlos Lopez |
a09598 |
free (data);
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
/* Functions for managing the authentication entries. */
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
/* Returns true if something matching AUTH is in our list of auth items */
|
|
Carlos Lopez |
a09598 |
static int
|
|
Carlos Lopez |
a09598 |
check_auth_item (Xauth *auth)
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
addr_list *a;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
for (a = addresses; a != NULL; a = a->next)
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
if (a->auth.family == auth->family
|
|
Carlos Lopez |
a09598 |
&& a->auth.address_length == auth->address_length
|
|
Carlos Lopez |
a09598 |
&& binary_equal (a->auth.address, auth->address, auth->address_length)
|
|
Carlos Lopez |
a09598 |
&& a->auth.number_length == auth->number_length
|
|
Carlos Lopez |
a09598 |
&& binary_equal (a->auth.number, auth->number, auth->number_length)
|
|
Carlos Lopez |
a09598 |
&& a->auth.name_length == auth->name_length
|
|
Carlos Lopez |
a09598 |
&& binary_equal (a->auth.name, auth->name, auth->name_length))
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
return TRUE;
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
return FALSE;
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
/* Add one item to our list of auth items. */
|
|
Carlos Lopez |
a09598 |
static void
|
|
Carlos Lopez |
a09598 |
add_auth_item (Xauth *auth)
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
addr_list *a = malloc (sizeof (addr_list));
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
a->auth.family = auth->family;
|
|
Carlos Lopez |
a09598 |
a->auth.address_length = auth->address_length;
|
|
Carlos Lopez |
a09598 |
a->auth.address = binary_dup (auth->address, auth->address_length);
|
|
Carlos Lopez |
a09598 |
a->auth.number_length = auth->number_length;
|
|
Carlos Lopez |
a09598 |
a->auth.number = binary_dup (auth->number, auth->number_length);
|
|
Carlos Lopez |
a09598 |
a->auth.name_length = auth->name_length;
|
|
Carlos Lopez |
a09598 |
a->auth.name = binary_dup (auth->name, auth->name_length);
|
|
Carlos Lopez |
a09598 |
a->auth.data_length = auth->data_length;
|
|
Carlos Lopez |
a09598 |
a->auth.data = binary_dup (auth->data, auth->data_length);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
a->next = addresses;
|
|
Carlos Lopez |
a09598 |
addresses = a;
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
/* Free all allocated auth items. */
|
|
Carlos Lopez |
a09598 |
static void
|
|
Carlos Lopez |
a09598 |
free_auth_items (void)
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
addr_list *a;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
while ((a = addresses) != NULL)
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
addresses = a->next;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
binary_free (a->auth.address, a->auth.address_length);
|
|
Carlos Lopez |
a09598 |
binary_free (a->auth.number, a->auth.number_length);
|
|
Carlos Lopez |
a09598 |
binary_free (a->auth.name, a->auth.name_length);
|
|
Carlos Lopez |
a09598 |
binary_free (a->auth.data, a->auth.data_length);
|
|
Carlos Lopez |
a09598 |
free (a);
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
/* Add the unix domain auth item. */
|
|
Carlos Lopez |
a09598 |
static void
|
|
Carlos Lopez |
a09598 |
define_local (Xauth *auth)
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
char *host = host_name ();
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
#ifdef DEBUG
|
|
Carlos Lopez |
a09598 |
fprintf (stderr, "x11: hostname is %s\n", host);
|
|
Carlos Lopez |
a09598 |
#endif
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
auth->family = FamilyLocal;
|
|
Carlos Lopez |
a09598 |
auth->address_length = strlen (host);
|
|
Carlos Lopez |
a09598 |
auth->address = host;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
add_auth_item (auth);
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
/* Add the tcp auth item. */
|
|
Carlos Lopez |
a09598 |
static void
|
|
Carlos Lopez |
a09598 |
define_named (Xauth *auth, const char *name)
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
struct ifaddrs *addrs, *ptr;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
if (getifaddrs (&addrs) != 0)
|
|
Carlos Lopez |
a09598 |
return;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
for (ptr = addrs; ptr != NULL; ptr = ptr->ifa_next)
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
if (ptr->ifa_addr->sa_family != AF_INET)
|
|
Carlos Lopez |
a09598 |
continue;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
auth->family = FamilyInternet;
|
|
Carlos Lopez |
a09598 |
auth->address_length = sizeof (struct sockaddr_in);
|
|
Carlos Lopez |
a09598 |
auth->address = (char *) &(((struct sockaddr_in *) ptr->ifa_addr)->sin_addr);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
#ifdef DEBUG
|
|
Carlos Lopez |
a09598 |
fprintf (stderr, "x11: ipaddr is %d.%d.%d.%d\n",
|
|
Carlos Lopez |
a09598 |
(unsigned char) auth->address[0],
|
|
Carlos Lopez |
a09598 |
(unsigned char) auth->address[1],
|
|
Carlos Lopez |
a09598 |
(unsigned char) auth->address[2],
|
|
Carlos Lopez |
a09598 |
(unsigned char) auth->address[3]);
|
|
Carlos Lopez |
a09598 |
#endif
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
add_auth_item (auth);
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
freeifaddrs (addrs);
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
/* Parse the display number from NAME and add it to AUTH. */
|
|
Carlos Lopez |
a09598 |
static void
|
|
Carlos Lopez |
a09598 |
set_auth_number (Xauth *auth, const char *name)
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
char *colon;
|
|
Carlos Lopez |
a09598 |
char *dot, *number;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
colon = strrchr(name, ':');
|
|
Carlos Lopez |
a09598 |
if (colon != NULL)
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
colon++;
|
|
Carlos Lopez |
a09598 |
dot = strchr(colon, '.');
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
if (dot != NULL)
|
|
Carlos Lopez |
a09598 |
auth->number_length = dot - colon;
|
|
Carlos Lopez |
a09598 |
else
|
|
Carlos Lopez |
a09598 |
auth->number_length = strlen (colon);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
number = malloc (auth->number_length + 1);
|
|
Carlos Lopez |
a09598 |
if (number != NULL)
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
strncpy (number, colon, auth->number_length);
|
|
Carlos Lopez |
a09598 |
number[auth->number_length] = '\0';
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
else
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
auth->number_length = 0;
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
auth->number = number;
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
/* Put 128 bits of random data into DATA. If possible, it will be "high
|
|
Carlos Lopez |
a09598 |
quality" */
|
|
Carlos Lopez |
a09598 |
static int
|
|
Carlos Lopez |
a09598 |
generate_mit_magic_cookie (char data[16])
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
int fd, ret, i;
|
|
Carlos Lopez |
a09598 |
long *ldata = (long *) data;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
fd = open ("/dev/random", O_RDONLY);
|
|
Carlos Lopez |
a09598 |
if (fd > 0)
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
ret = read (fd, data, 16);
|
|
Carlos Lopez |
a09598 |
if (ret == 16)
|
|
Carlos Lopez |
a09598 |
return TRUE;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
close (fd);
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
/* fall back to the usual crappy rng */
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
srand48 (getpid () ^ time (NULL));
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
for (i = 0; i < 4; i++)
|
|
Carlos Lopez |
a09598 |
ldata[i] = lrand48 ();
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
return TRUE;
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
/* Create the keys we'll be using for the display named NAME. */
|
|
Carlos Lopez |
a09598 |
static int
|
|
Carlos Lopez |
a09598 |
make_auth_keys (const char *name)
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
Xauth auth;
|
|
Carlos Lopez |
a09598 |
char key[16];
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
if (auth_file == NULL)
|
|
Carlos Lopez |
a09598 |
return FALSE;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
auth.name = "MIT-MAGIC-COOKIE-1";
|
|
Carlos Lopez |
a09598 |
auth.name_length = strlen (auth.name);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
if (!generate_mit_magic_cookie (key))
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
auth_file = NULL;
|
|
Carlos Lopez |
a09598 |
return FALSE;
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
auth.data = key;
|
|
Carlos Lopez |
a09598 |
auth.data_length = 16;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
set_auth_number (&auth, name);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
define_named (&auth, host_name ());
|
|
Carlos Lopez |
a09598 |
define_local (&auth);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
free (auth.number);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
return TRUE;
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
/* If ADD-ENTRIES is true, merge our auth entries into the existing
|
|
Carlos Lopez |
a09598 |
Xauthority file. If ADD-ENTRIES is false, remove our entries. */
|
|
Carlos Lopez |
a09598 |
static int
|
|
Carlos Lopez |
a09598 |
write_auth_file (int add_entries)
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
char *home, newname[1024];
|
|
Carlos Lopez |
a09598 |
int fd, ret;
|
|
Carlos Lopez |
a09598 |
FILE *new_fh, *old_fh;
|
|
Carlos Lopez |
a09598 |
addr_list *addr;
|
|
Carlos Lopez |
a09598 |
Xauth *auth;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
if (auth_file == NULL)
|
|
Carlos Lopez |
a09598 |
return FALSE;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
home = getenv ("HOME");
|
|
Carlos Lopez |
a09598 |
if (home == NULL)
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
auth_file = NULL;
|
|
Carlos Lopez |
a09598 |
return FALSE;
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
snprintf (newname, sizeof (newname), "%s/.XauthorityXXXXXX", home);
|
|
Carlos Lopez |
a09598 |
mktemp (newname);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
if (XauLockAuth (auth_file, 1, 2, 10) != LOCK_SUCCESS)
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
/* FIXME: do something here? */
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
auth_file = NULL;
|
|
Carlos Lopez |
a09598 |
return FALSE;
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
fd = open (newname, O_WRONLY | O_CREAT | O_TRUNC, 0600);
|
|
Carlos Lopez |
a09598 |
if (fd >= 0)
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
new_fh = fdopen (fd, "w");
|
|
Carlos Lopez |
a09598 |
if (new_fh != NULL)
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
if (add_entries)
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
for (addr = addresses; addr != NULL; addr = addr->next)
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
XauWriteAuth (new_fh, &addr->auth);
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
old_fh = fopen (auth_file, "r");
|
|
Carlos Lopez |
a09598 |
if (old_fh != NULL)
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
while ((auth = XauReadAuth (old_fh)) != NULL)
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
if (!check_auth_item (auth))
|
|
Carlos Lopez |
a09598 |
XauWriteAuth (new_fh, auth);
|
|
Carlos Lopez |
a09598 |
XauDisposeAuth (auth);
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
fclose (old_fh);
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
fclose (new_fh);
|
|
Carlos Lopez |
a09598 |
unlink (auth_file);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
ret = rename (newname, auth_file);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
if (ret != 0)
|
|
Carlos Lopez |
a09598 |
auth_file = NULL;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
XauUnlockAuth (auth_file);
|
|
Carlos Lopez |
a09598 |
return ret == 0;
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
close (fd);
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
XauUnlockAuth (auth_file);
|
|
Carlos Lopez |
a09598 |
auth_file = NULL;
|
|
Carlos Lopez |
a09598 |
return FALSE;
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
/* Subprocess management functions. */
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
static int
|
|
Carlos Lopez |
a09598 |
start_server (char **xargv)
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
int child;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
child = fork ();
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
switch (child)
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
case -1: /* error */
|
|
Carlos Lopez |
a09598 |
perror ("fork");
|
|
Carlos Lopez |
a09598 |
return FALSE;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
case 0: /* child */
|
|
Carlos Lopez |
a09598 |
execv (X_SERVER, xargv);
|
|
Carlos Lopez |
a09598 |
perror ("Couldn't exec " X_SERVER);
|
|
Carlos Lopez |
a09598 |
_exit (1);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
default: /* parent */
|
|
Carlos Lopez |
a09598 |
server_pid = child;
|
|
Carlos Lopez |
a09598 |
return TRUE;
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
static int
|
|
Carlos Lopez |
a09598 |
wait_for_server (void)
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
int count = 100;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
while (count-- > 0)
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
int status;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
server_dpy = XOpenDisplay (server_name);
|
|
Carlos Lopez |
a09598 |
if (server_dpy != NULL)
|
|
Carlos Lopez |
a09598 |
return TRUE;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
if (waitpid (server_pid, &status, WNOHANG) == server_pid)
|
|
Carlos Lopez |
a09598 |
return FALSE;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
sleep (1);
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
return FALSE;
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
static int
|
|
Carlos Lopez |
a09598 |
start_client (void)
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
int child;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
child = fork ();
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
switch (child)
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
char *tem, buf[1024];
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
case -1: /* error */
|
|
Carlos Lopez |
a09598 |
perror ("fork");
|
|
Carlos Lopez |
a09598 |
return FALSE;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
case 0: /* child */
|
|
Carlos Lopez |
a09598 |
/* cd $HOME */
|
|
Carlos Lopez |
a09598 |
tem = getenv ("HOME");
|
|
Carlos Lopez |
a09598 |
if (tem != NULL)
|
|
Carlos Lopez |
a09598 |
chdir (tem);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
/* Setup environment */
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
setenv ("DISPLAY", server_name, TRUE);
|
|
Carlos Lopez |
a09598 |
tem = getenv ("PATH");
|
|
Carlos Lopez |
a09598 |
if (tem != NULL && tem[0] != NULL)
|
|
Carlos Lopez |
a09598 |
snprintf (buf, sizeof (buf), "%s:/usr/X11R6/bin", tem);
|
|
Carlos Lopez |
a09598 |
else
|
|
Carlos Lopez |
a09598 |
snprintf (buf, sizeof (buf), "/bin:/usr/bin:/usr/X11R6/bin");
|
|
Carlos Lopez |
a09598 |
setenv ("PATH", buf, TRUE);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
#if 1
|
|
Carlos Lopez |
a09598 |
setenv("GTK_USE_XFT","1",0);
|
|
Carlos Lopez |
a09598 |
system(WM_PATH " &");
|
|
Carlos Lopez |
a09598 |
execl("/usr/local/bin/synfigstudio","/usr/local/bin/synfigstudio",NULL);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
#else
|
|
Carlos Lopez |
a09598 |
/* First look for .xinitrc in user's home directory. */
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
tem = getenv ("HOME");
|
|
Carlos Lopez |
a09598 |
if (tem != NULL)
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
snprintf (buf, sizeof (buf), "%s/.xinitrc", tem);
|
|
Carlos Lopez |
a09598 |
if (access (buf, R_OK) == 0)
|
|
Carlos Lopez |
a09598 |
execlp (SHELL, SHELL, buf, NULL);
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
/* Then try the default xinitrc in the lib directory. */
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
if (access (DEFAULT_XINITRC, R_OK) == 0)
|
|
Carlos Lopez |
a09598 |
execlp (SHELL, SHELL, DEFAULT_XINITRC, NULL);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
/* Then fallback to hardcoding an xterm and the window manager. */
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
system (XTERM_PATH " &");
|
|
Carlos Lopez |
a09598 |
execl (WM_PATH, WM_PATH, NULL);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
#endif
|
|
Carlos Lopez |
a09598 |
perror ("exec");
|
|
Carlos Lopez |
a09598 |
_exit (1);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
default: /* parent */
|
|
Carlos Lopez |
a09598 |
client_pid = child;
|
|
Carlos Lopez |
a09598 |
return TRUE;
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
static void
|
|
Carlos Lopez |
a09598 |
sigchld_handler (int sig)
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
int pid, status;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
again:
|
|
Carlos Lopez |
a09598 |
pid = waitpid (WAIT_ANY, &status, WNOHANG);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
if (pid > 0)
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
if (pid == server_pid)
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
server_pid = -1;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
if (client_pid >= 0)
|
|
Carlos Lopez |
a09598 |
kill (client_pid, SIGTERM);
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
else if (pid == client_pid)
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
client_pid = -1;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
if (server_pid >= 0 && xinit_kills_server)
|
|
Carlos Lopez |
a09598 |
kill (server_pid, SIGTERM);
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
goto again;
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
if (server_pid == -1 && client_pid == -1)
|
|
Carlos Lopez |
a09598 |
longjmp (exit_continuation, 1);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
signal (SIGCHLD, sigchld_handler);
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
/* Server utilities. */
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
static Boolean
|
|
Carlos Lopez |
a09598 |
display_exists_p (int number)
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
char buf[64];
|
|
Carlos Lopez |
a09598 |
void *conn;
|
|
Carlos Lopez |
a09598 |
char *fullname = NULL;
|
|
Carlos Lopez |
a09598 |
int idisplay, iscreen;
|
|
Carlos Lopez |
a09598 |
char *conn_auth_name, *conn_auth_data;
|
|
Carlos Lopez |
a09598 |
int conn_auth_namelen, conn_auth_datalen;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
extern void *_X11TransConnectDisplay ();
|
|
Carlos Lopez |
a09598 |
extern void _XDisconnectDisplay ();
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
/* Since connecting to the display waits for a few seconds if the
|
|
Carlos Lopez |
a09598 |
display doesn't exist, check for trivial non-existence - if the
|
|
Carlos Lopez |
a09598 |
socket in /tmp exists or not.. (note: if the socket exists, the
|
|
Carlos Lopez |
a09598 |
server may still not, so we need to try to connect in that case..) */
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
sprintf (buf, "/tmp/.X11-unix/X%d", number);
|
|
Carlos Lopez |
a09598 |
if (access (buf, F_OK) != 0)
|
|
Carlos Lopez |
a09598 |
return FALSE;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
/* This is a private function that we shouldn't really be calling,
|
|
Carlos Lopez |
a09598 |
but it's the best way to see if the server exists (without
|
|
Carlos Lopez |
a09598 |
needing to hold the necessary authentication to use it) */
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
sprintf (buf, ":%d", number);
|
|
Carlos Lopez |
a09598 |
conn = _X11TransConnectDisplay (buf, &fullname, &idisplay, &iscreen,
|
|
Carlos Lopez |
a09598 |
&conn_auth_name, &conn_auth_namelen,
|
|
Carlos Lopez |
a09598 |
&conn_auth_data, &conn_auth_datalen);
|
|
Carlos Lopez |
a09598 |
if (conn == NULL)
|
|
Carlos Lopez |
a09598 |
return FALSE;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
_XDisconnectDisplay (conn);
|
|
Carlos Lopez |
a09598 |
return TRUE;
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
/* Monitoring when the system's ip addresses change. */
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
static Boolean pending_timer;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
static void
|
|
Carlos Lopez |
a09598 |
timer_callback (CFRunLoopTimerRef timer, void *info)
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
pending_timer = FALSE;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
/* Update authentication names. Need to write .Xauthority file first
|
|
Carlos Lopez |
a09598 |
without the existing entries, then again with the new entries.. */
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
write_auth_file (FALSE);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
free_auth_items ();
|
|
Carlos Lopez |
a09598 |
make_auth_keys (server_name);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
write_auth_file (TRUE);
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
/* This function is called when the system's ip addresses may have changed. */
|
|
Carlos Lopez |
a09598 |
static void
|
|
Carlos Lopez |
a09598 |
ipaddr_callback (SCDynamicStoreRef store, CFArrayRef changed_keys, void *info)
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
if (auth_file != NULL && !pending_timer)
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
CFRunLoopTimerRef timer;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
timer = CFRunLoopTimerCreate (NULL, CFAbsoluteTimeGetCurrent () + 1.0,
|
|
Carlos Lopez |
a09598 |
0.0, 0, 0, timer_callback, NULL);
|
|
Carlos Lopez |
a09598 |
CFRunLoopAddTimer (CFRunLoopGetCurrent (), timer,
|
|
Carlos Lopez |
a09598 |
kCFRunLoopDefaultMode);
|
|
Carlos Lopez |
a09598 |
CFRelease (timer);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
pending_timer = TRUE;
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
/* This code adapted from "Living in a Dynamic TCP/IP Environment" technote. */
|
|
Carlos Lopez |
a09598 |
static Boolean
|
|
Carlos Lopez |
a09598 |
install_ipaddr_source (void)
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
CFRunLoopSourceRef source = NULL;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
SCDynamicStoreContext context = {0};
|
|
Carlos Lopez |
a09598 |
SCDynamicStoreRef ref;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
ref = SCDynamicStoreCreate (NULL,
|
|
Carlos Lopez |
a09598 |
CFSTR ("AddIPAddressListChangeCallbackSCF"),
|
|
Carlos Lopez |
a09598 |
ipaddr_callback, &context);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
if (ref != NULL)
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
const void *keys[2];
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
/* This should tell us when any IPV4 address changes */
|
|
Carlos Lopez |
a09598 |
keys[0] = (SCDynamicStoreKeyCreateNetworkServiceEntity
|
|
Carlos Lopez |
a09598 |
(NULL, kSCDynamicStoreDomainState,
|
|
Carlos Lopez |
a09598 |
kSCCompAnyRegex, kSCEntNetIPv4));
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
/* This should tell us when the hostname(s) change */
|
|
Carlos Lopez |
a09598 |
keys[1] = SCDynamicStoreKeyCreateHostNames (NULL);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
if (keys[0] != NULL && keys[1] != NULL)
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
CFArrayRef pattern_array;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
pattern_array = CFArrayCreate (NULL, keys, 2,
|
|
Carlos Lopez |
a09598 |
&kCFTypeArrayCallBacks);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
if (pattern_array != NULL)
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
SCDynamicStoreSetNotificationKeys (ref, NULL, pattern_array);
|
|
Carlos Lopez |
a09598 |
source = SCDynamicStoreCreateRunLoopSource (NULL, ref, 0);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
CFRelease (pattern_array);
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
if (keys[0] != NULL)
|
|
Carlos Lopez |
a09598 |
CFRelease (keys[0]);
|
|
Carlos Lopez |
a09598 |
if (keys[1] != NULL)
|
|
Carlos Lopez |
a09598 |
CFRelease (keys[1]);
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
CFRelease (ref);
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
if (source != NULL)
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
CFRunLoopAddSource (CFRunLoopGetCurrent (),
|
|
Carlos Lopez |
a09598 |
source, kCFRunLoopDefaultMode);
|
|
Carlos Lopez |
a09598 |
CFRelease (source);
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
return source != NULL;
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
/* Entrypoint. */
|
|
Carlos Lopez |
a09598 |
int
|
|
Carlos Lopez |
a09598 |
main (int argc, char **argv)
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
char **xargv;
|
|
Carlos Lopez |
a09598 |
int i, j;
|
|
Carlos Lopez |
a09598 |
int fd;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
xargv = alloca (sizeof (char *) * (argc + 32));
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
if (!read_boolean_pref (CFSTR ("no_auth"), FALSE))
|
|
Carlos Lopez |
a09598 |
auth_file = XauFileName ();
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
/* The standard X11 behaviour is for the server to quit when the first
|
|
Carlos Lopez |
a09598 |
client exits. But it can be useful for debugging (and to mimic our
|
|
Carlos Lopez |
a09598 |
behaviour in the beta releases) to not do that. */
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
xinit_kills_server = read_boolean_pref (CFSTR ("xinit_kills_server"), TRUE);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
for (i = 1; i < argc; i++)
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
if (argv[i][0] == ':')
|
|
Carlos Lopez |
a09598 |
server_name = argv[i];
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
if (server_name == NULL)
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
static char name[8];
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
/* No display number specified, so search for the first unused.
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
There's a big old race condition here if two servers start at
|
|
Carlos Lopez |
a09598 |
the same time, but that's fairly unlikely. We could create
|
|
Carlos Lopez |
a09598 |
lockfiles or something, but that's seems more likely to cause
|
|
Carlos Lopez |
a09598 |
problems than the race condition itself.. */
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
for (i = 2; i < MAX_DISPLAYS; i++)
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
if (!display_exists_p (i))
|
|
Carlos Lopez |
a09598 |
break;
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
if (i == MAX_DISPLAYS)
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
fprintf (stderr, "%s: couldn't allocate a display number", argv[0]);
|
|
Carlos Lopez |
a09598 |
exit (1);
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
sprintf (name, ":%d", i);
|
|
Carlos Lopez |
a09598 |
server_name = name;
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
if (auth_file != NULL)
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
/* Create new Xauth keys and add them to the .Xauthority file */
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
make_auth_keys (server_name);
|
|
Carlos Lopez |
a09598 |
write_auth_file (TRUE);
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
/* Construct our new argv */
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
i = j = 0;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
xargv[i++] = argv[j++];
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
if (auth_file != NULL)
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
xargv[i++] = "-auth";
|
|
Carlos Lopez |
a09598 |
xargv[i++] = auth_file;
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
/* By default, don't listen on tcp sockets if Xauth is disabled. */
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
if (read_boolean_pref (CFSTR ("nolisten_tcp"), auth_file == NULL))
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
xargv[i++] = "-nolisten";
|
|
Carlos Lopez |
a09598 |
xargv[i++] = "tcp";
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
while (j < argc)
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
if (argv[j++][0] != ':')
|
|
Carlos Lopez |
a09598 |
xargv[i++] = argv[j-1];
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
xargv[i++] = (char *) server_name;
|
|
Carlos Lopez |
a09598 |
xargv[i++] = NULL;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
/* Detach from any controlling terminal and connect stdin to /dev/null */
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
#ifdef TIOCNOTTY
|
|
Carlos Lopez |
a09598 |
fd = open ("/dev/tty", O_RDONLY);
|
|
Carlos Lopez |
a09598 |
if (fd != -1)
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
ioctl (fd, TIOCNOTTY, 0);
|
|
Carlos Lopez |
a09598 |
close (fd);
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
#endif
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
fd = open ("/dev/null", O_RDWR, 0);
|
|
Carlos Lopez |
a09598 |
if (fd >= 0)
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
dup2 (fd, 0);
|
|
Carlos Lopez |
a09598 |
if (fd > 0)
|
|
Carlos Lopez |
a09598 |
close (fd);
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
if (!start_server (xargv))
|
|
Carlos Lopez |
a09598 |
return 1;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
if (!wait_for_server ())
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
kill (server_pid, SIGTERM);
|
|
Carlos Lopez |
a09598 |
return 1;
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
if (!start_client ())
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
kill (server_pid, SIGTERM);
|
|
Carlos Lopez |
a09598 |
return 1;
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
signal (SIGCHLD, sigchld_handler);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
if (NSIsSymbolNameDefined("_ASKInitialize"))
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
NSSymbol *symbol = NSLookupAndBindSymbol("_ASKInitialize");
|
|
Carlos Lopez |
a09598 |
if (symbol)
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
void (*initializeASKFunc)(void) = NSAddressOfSymbol(symbol);
|
|
Carlos Lopez |
a09598 |
if (initializeASKFunc)
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
initializeASKFunc();
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
else
|
|
Carlos Lopez |
a09598 |
return 666;
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
else return 667;
|
|
Carlos Lopez |
a09598 |
}else
|
|
Carlos Lopez |
a09598 |
return 668;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
if (setjmp (exit_continuation) == 0)
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
if (install_ipaddr_source ())
|
|
Carlos Lopez |
a09598 |
CFRunLoopRun ();
|
|
Carlos Lopez |
a09598 |
else
|
|
Carlos Lopez |
a09598 |
while (1) pause ();
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
signal (SIGCHLD, SIG_IGN);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
if (auth_file != NULL)
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
/* Remove our Xauth keys */
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
write_auth_file (FALSE);
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
free_auth_items ();
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
return 0;
|
|
Carlos Lopez |
a09598 |
}
|