New upstream version 3.5.99.27
This commit is contained in:
270
nx-X11/programs/Xserver/os/Imakefile
Normal file
270
nx-X11/programs/Xserver/os/Imakefile
Normal file
@@ -0,0 +1,270 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
|
||||
/* Copyright (c) 2008-2017 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
|
||||
/* Copyright (c) 2011-2022 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
|
||||
/* Copyright (c) 2014-2019 Mihai Moldovan <ionic@ionic.de> */
|
||||
/* Copyright (c) 2014-2022 Ulrich Sibiller <uli42@gmx.de> */
|
||||
/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
|
||||
/* */
|
||||
/* nx-X11, NX protocol compression and NX extensions to this software */
|
||||
/* are copyright of the aforementioned persons and companies. */
|
||||
/* */
|
||||
/* Redistribution and use of the present software is allowed according */
|
||||
/* to terms specified in the file LICENSE which comes in the source */
|
||||
/* distribution. */
|
||||
/* */
|
||||
/* All rights reserved. */
|
||||
/* */
|
||||
/* NOTE: This software has received contributions from various other */
|
||||
/* contributors, only the core maintainers and supporters are listed as */
|
||||
/* copyright holders. Please contact us, if you feel you should be listed */
|
||||
/* as copyright holder, as well. */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
#include <Server.tmpl>
|
||||
|
||||
NULL =
|
||||
|
||||
/*
|
||||
* If you have any extra files to be put into the library, define them here.
|
||||
*/
|
||||
|
||||
ZONEID_DEFINES = -UHAVE_GETZONEID
|
||||
|
||||
#if NXLibraries
|
||||
|
||||
NX_INCLUDES = -I../../../../nxcomp
|
||||
|
||||
NX_DEFINES = -DNX_TRANS_SOCKET \
|
||||
-DNX_TRANS_AUTH \
|
||||
-DNX_TRANS_FOPEN \
|
||||
-DNX_TRANS_SLEEP \
|
||||
-DNX_TRANS_EXIT \
|
||||
-DNX_TRANS_WAKEUP \
|
||||
-DNXAGENT_SERVER \
|
||||
$(NULL)
|
||||
|
||||
# -DNX_TRANS_WARN \
|
||||
# -DNX_TRANS_INFO \
|
||||
# -DNX_TRANS_TEST \
|
||||
# -DNX_TRANS_DEBUG \
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* do not modify the following two definitions
|
||||
*/
|
||||
|
||||
#ifndef OtherSources
|
||||
#define OtherSources
|
||||
#endif
|
||||
|
||||
#ifndef OtherObjects
|
||||
#define OtherObjects
|
||||
#endif
|
||||
|
||||
#if HasXdmAuth
|
||||
XDMAUTHDEFS = -DHASXDMAUTH
|
||||
XDMAUTHOBJS = xdmauth.o
|
||||
XDMAUTHSRCS = xdmauth.c
|
||||
#else
|
||||
XDMAUTHDEFS =
|
||||
XDMAUTHOBJS =
|
||||
XDMAUTHSCRS =
|
||||
#endif
|
||||
|
||||
TIRPC_INCLUDES =
|
||||
|
||||
#if HasSecureRPC
|
||||
RPCDEFS = -DSECURE_RPC
|
||||
RPCOBJS = rpcauth.o
|
||||
RPCSRCS = rpcauth.c
|
||||
|
||||
#if UseTIRPC
|
||||
TIRPC_INCLUDES = $$(pkg-config --cflags-only-I 'libtirpc')
|
||||
#endif
|
||||
|
||||
#else
|
||||
RPCDEFS =
|
||||
RPCOBJS =
|
||||
RPCSRCS =
|
||||
#endif
|
||||
|
||||
#if HasBSD44Sockets
|
||||
SOCK_DEFINES = -DBSD44SOCKETS
|
||||
#endif
|
||||
|
||||
#if HasGetIfAddrs
|
||||
IFADDRS_DEFINES = -DHAS_GETIFADDRS
|
||||
#endif
|
||||
|
||||
#if !defined(DDXOsColor)
|
||||
COLOR_SRCS=oscolor.c
|
||||
COLOR_OBJS=oscolor.o
|
||||
#endif
|
||||
|
||||
#if !HasSnprintf
|
||||
SNPRINTF_SRCS = snprintf.c
|
||||
SNPRINTF_OBJS = snprintf.o
|
||||
#endif
|
||||
|
||||
#if !HasStrlcat
|
||||
STRLCAT_SRCS = strlcat.c strlcpy.c
|
||||
STRLCAT_OBJS = strlcat.o strlcpy.o
|
||||
#endif
|
||||
|
||||
#if !HasReallocarray
|
||||
REALLOCARRAY_SRCS = reallocarray.c
|
||||
REALLOCARRAY_OBJS = reallocarray.o
|
||||
#endif
|
||||
|
||||
#if HasGetpeerucred
|
||||
GETPEER_DEFINES = -DHAS_GETPEERUCRED
|
||||
#else
|
||||
# if HasGetpeereid
|
||||
GETPEER_DEFINES = -DHAS_GETPEEREID
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if !HasTimingsafeMemcmp
|
||||
TMEMCMP_SRCS = timingsafe_memcmp.c
|
||||
TMEMCMP_OBJS = timingsafe_memcmp.o
|
||||
#endif
|
||||
|
||||
BOOTSTRAPCFLAGS =
|
||||
SRCS = WaitFor.c \
|
||||
access.c \
|
||||
client.c \
|
||||
connection.c \
|
||||
io.c \
|
||||
$(COLOR_SRCS) \
|
||||
osinit.c \
|
||||
utils.c \
|
||||
log.c \
|
||||
auth.c \
|
||||
mitauth.c \
|
||||
secauth.c \
|
||||
$(XDMAUTHSRCS) \
|
||||
$(RPCSRCS) \
|
||||
xdmcp.c \
|
||||
OtherSources \
|
||||
xstrans.c \
|
||||
$(SNPRINTF_SRCS) \
|
||||
$(STRLCAT_SRCS) \
|
||||
$(REALLOCARRAY_SRCS) \
|
||||
xprintf.c \
|
||||
$(TMEMCMP_SRCS) \
|
||||
$(NULL)
|
||||
|
||||
OBJS = WaitFor.o \
|
||||
access.o \
|
||||
client.o \
|
||||
connection.o \
|
||||
io.o \
|
||||
$(COLOR_OBJS) \
|
||||
osinit.o \
|
||||
utils.o \
|
||||
log.o \
|
||||
auth.o \
|
||||
mitauth.o \
|
||||
secauth.o \
|
||||
$(XDMAUTHOBJS) \
|
||||
$(RPCOBJS) \
|
||||
xdmcp.o \
|
||||
OtherObjects \
|
||||
xstrans.o \
|
||||
$(SNPRINTF_OBJS) \
|
||||
$(STRLCAT_OBJS) \
|
||||
$(REALLOCARRAY_OBJS) \
|
||||
xprintf.o \
|
||||
$(TMEMCMP_OBJS) \
|
||||
$(NULL)
|
||||
|
||||
#if UseMemLeak
|
||||
MEM_DEFINES = -DMEMBUG
|
||||
#endif
|
||||
ADM_DEFINES = -DADMPATH=\"$(ADMDIR)/X\%smsgs\"
|
||||
XDMCP_DEFINES = ServerXdmcpDefines
|
||||
ERROR_DEFINES = ServerErrorDefines
|
||||
#if HasPam && HasPamMisc
|
||||
PAM_DEFINES = -DUSE_PAM
|
||||
#endif
|
||||
XTRANS_DEFINES = -DXTRANS_SEND_FDS=0
|
||||
|
||||
DEFINES = $(CONNECTION_FLAGS) \
|
||||
$(MEM_DEFINES) \
|
||||
$(XDMAUTHDEFS) \
|
||||
$(RPCDEFS) \
|
||||
$(SIGNAL_DEFINES) \
|
||||
$(OS_DEFINES) \
|
||||
$(GETPEER_DEFINES) \
|
||||
$(RANDOM_DEFINES) \
|
||||
$(BUGMSG) \
|
||||
$(XTRANS_FAILDEFINES) \
|
||||
$(XTRANS_DEFINES) \
|
||||
$(NX_DEFINES) \
|
||||
$(NULL)
|
||||
|
||||
INCLUDES = -I. \
|
||||
-I../include \
|
||||
-I$(XINCLUDESRC) \
|
||||
-I$(EXTINCSRC) \
|
||||
-I$(SERVERSRC)/Xext \
|
||||
-I$(SERVERSRC)/render \
|
||||
-I$(TOP)/lib/Xau \
|
||||
$(NX_INCLUDES) \
|
||||
`pkg-config --cflags-only-I pixman-1` \
|
||||
$(TIRPC_INCLUDES) \
|
||||
$(NULL)
|
||||
|
||||
DEPEND_DEFINES = $(XDMCP_DEFINES) \
|
||||
$(EXT_DEFINES) \
|
||||
$(TRANS_INCLUDES) \
|
||||
$(CONNECTION_FLAGS) \
|
||||
$(GETPEER_DEFINES) \
|
||||
DependDefines \
|
||||
$(NULL)
|
||||
|
||||
LINTLIBS = ../dix/llib-ldix.ln
|
||||
|
||||
#ifdef NEED_ALLOCA_FROM_LIBPW
|
||||
PWLIB = /lib/libPW.a
|
||||
#endif /* NEED_ALLOCA_FROM_LIBPW */
|
||||
|
||||
NormalLibraryObjectRule()
|
||||
NormalLibraryTarget(os,$(OBJS))
|
||||
LintLibraryTarget(os,$(SRCS))
|
||||
NormalLintTarget($(SRCS))
|
||||
|
||||
#ifdef NEED_ALLOCA_FROM_LIBPW
|
||||
XCOMM
|
||||
XCOMM And this one is to get the version of alloca that lives in /lib/libPW.a
|
||||
XCOMM without getting all of the rest of the stuff in there.
|
||||
XCOMM
|
||||
alloca.o: $(PWLIB)
|
||||
rm -f alloca.o
|
||||
ar x $(PWLIB) alloca.o
|
||||
#endif /* NEED_ALLOCA_FROM_LIBPW */
|
||||
|
||||
SpecialCObjectRule(access,$(ICONFIGFILES),$(XDMCP_DEFINES) $(SOCK_DEFINES) $(IFADDRS_DEFINES) $(ZONEID_DEFINES))
|
||||
SpecialCObjectRule(auth,$(ICONFIGFILES),$(XDMCP_DEFINES))
|
||||
SpecialCObjectRule(xdmauth,$(ICONFIGFILES),$(XDMCP_DEFINES))
|
||||
SpecialCObjectRule(xdmcp,$(ICONFIGFILES),$(SOCK_DEFINES) $(XDMCP_DEFINES))
|
||||
SpecialCObjectRule(connection,$(ICONFIGFILES),$(SOCK_DEFINES) $(XDMCP_DEFINES))
|
||||
SpecialCObjectRule(osinit,$(ICONFIGFILES),$(ADM_DEFINES))
|
||||
SpecialCObjectRule(WaitFor,$(ICONFIGFILES),$(EXT_DEFINES))
|
||||
SpecialCObjectRule(io,$(ICONFIGFILES),$(EXT_DEFINES))
|
||||
SpecialCObjectRule(utils,$(ICONFIGFILES),$(XDMCP_DEFINES) $(EXT_DEFINES) $(ERROR_DEFINES) $(PAM_DEFINES))
|
||||
#if defined(SparcArchitecture) && HasGcc && !HasGcc2
|
||||
oscolor.o: oscolor.c $(ICONFIGFILES)
|
||||
$(RM) $@
|
||||
cc -c $(CDEBUGFLAGS) $(ALLDEFINES) $*.c
|
||||
#endif
|
||||
|
||||
#if !HasSnprintf
|
||||
LinkSourceFile(snprintf.c,$(LIBSRC)/misc)
|
||||
#endif
|
||||
|
||||
DependTarget()
|
||||
776
nx-X11/programs/Xserver/os/WaitFor.c
Normal file
776
nx-X11/programs/Xserver/os/WaitFor.c
Normal file
@@ -0,0 +1,776 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
|
||||
/* Copyright (c) 2008-2017 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
|
||||
/* Copyright (c) 2011-2022 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
|
||||
/* Copyright (c) 2014-2019 Mihai Moldovan <ionic@ionic.de> */
|
||||
/* Copyright (c) 2014-2022 Ulrich Sibiller <uli42@gmx.de> */
|
||||
/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
|
||||
/* */
|
||||
/* nx-X11, NX protocol compression and NX extensions to this software */
|
||||
/* are copyright of the aforementioned persons and companies. */
|
||||
/* */
|
||||
/* Redistribution and use of the present software is allowed according */
|
||||
/* to terms specified in the file LICENSE which comes in the source */
|
||||
/* distribution. */
|
||||
/* */
|
||||
/* All rights reserved. */
|
||||
/* */
|
||||
/* NOTE: This software has received contributions from various other */
|
||||
/* contributors, only the core maintainers and supporters are listed as */
|
||||
/* copyright holders. Please contact us, if you feel you should be listed */
|
||||
/* as copyright holder, as well. */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
/***********************************************************
|
||||
|
||||
Copyright 1987, 1998 The Open Group
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this software and its
|
||||
documentation for any purpose is hereby granted without fee, provided that
|
||||
the above copyright notice appear in all copies and that both that
|
||||
copyright notice and this permission notice appear in supporting
|
||||
documentation.
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
Except as contained in this notice, the name of The Open Group shall not be
|
||||
used in advertising or otherwise to promote the sale, use or other dealings
|
||||
in this Software without prior written authorization from The Open Group.
|
||||
|
||||
|
||||
Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
|
||||
|
||||
All Rights Reserved
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for any purpose and without fee is hereby granted,
|
||||
provided that the above copyright notice appear in all copies and that
|
||||
both that copyright notice and this permission notice appear in
|
||||
supporting documentation, and that the name of Digital not be
|
||||
used in advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||||
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
|
||||
DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
||||
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
SOFTWARE.
|
||||
|
||||
******************************************************************/
|
||||
|
||||
/*****************************************************************
|
||||
* OS Dependent input routines:
|
||||
*
|
||||
* WaitForSomething
|
||||
* TimerForce, TimerSet, TimerCheck, TimerFree
|
||||
*
|
||||
*****************************************************************/
|
||||
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#include <nx-X11/Xos.h> /* for strings, fcntl, time */
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <nx-X11/X.h>
|
||||
#include "misc.h"
|
||||
|
||||
#include "osdep.h"
|
||||
#include <nx-X11/Xpoll.h>
|
||||
#include "dixstruct.h"
|
||||
#include "opaque.h"
|
||||
#ifdef DPMSExtension
|
||||
#include "dpmsproc.h"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* unset defines without NX_TRANS_SOCKET. This allows for shorter
|
||||
* ifdefs below
|
||||
*/
|
||||
#ifndef NX_TRANS_SOCKET
|
||||
#ifdef NX_TRANS_DEBUG
|
||||
#undef NX_TRANS_DEBUG
|
||||
#endif
|
||||
#ifdef NX_TRANS_WAKEUP
|
||||
#undef NX_TRANS_WAKEUP
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef NX_TRANS_WAKEUP
|
||||
static unsigned long startTimeInMillis;
|
||||
#endif
|
||||
|
||||
/* This is just a fallback to errno to hide the differences between unix and
|
||||
Windows in the code */
|
||||
#define GetErrno() errno
|
||||
|
||||
/* like ffs, but uses fd_mask instead of int as argument, so it works
|
||||
when fd_mask is longer than an int, such as common 64-bit platforms */
|
||||
/* modifications by raphael */
|
||||
int
|
||||
mffs(fd_mask mask)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!mask) return 0;
|
||||
i = 1;
|
||||
while (!(mask & 1))
|
||||
{
|
||||
i++;
|
||||
mask >>= 1;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
#ifdef DPMSExtension
|
||||
#define DPMS_SERVER
|
||||
#include <nx-X11/extensions/dpms.h>
|
||||
#endif
|
||||
|
||||
struct _OsTimerRec {
|
||||
OsTimerPtr next;
|
||||
CARD32 expires;
|
||||
OsTimerCallback callback;
|
||||
void * arg;
|
||||
};
|
||||
|
||||
static void DoTimer(OsTimerPtr timer, CARD32 now, OsTimerPtr *prev);
|
||||
static OsTimerPtr timers = NULL;
|
||||
|
||||
/*****************
|
||||
* WaitForSomething:
|
||||
* Make the server suspend until there is
|
||||
* 1. data from clients or
|
||||
* 2. input events available or
|
||||
* 3. ddx notices something of interest (graphics
|
||||
* queue ready, etc.) or
|
||||
* 4. clients that have buffered replies/events are ready
|
||||
*
|
||||
* If the time between INPUT events is
|
||||
* greater than ScreenSaverTime, the display is turned off (or
|
||||
* saved, depending on the hardware). So, WaitForSomething()
|
||||
* has to handle this also (that's why the select() has a timeout.
|
||||
* For more info on ClientsWithInput, see ReadRequestFromClient().
|
||||
* pClientsReady is an array to store ready client->index values into.
|
||||
*****************/
|
||||
|
||||
int
|
||||
WaitForSomething(int *pClientsReady)
|
||||
{
|
||||
int i;
|
||||
struct timeval waittime, *wt;
|
||||
INT32 timeout = 0;
|
||||
fd_set clientsReadable;
|
||||
fd_set clientsWritable;
|
||||
int curclient;
|
||||
int selecterr;
|
||||
int nready;
|
||||
CARD32 now = 0;
|
||||
Bool someReady = FALSE;
|
||||
Bool someNotifyWriteReady = FALSE;
|
||||
|
||||
#ifdef NX_TRANS_DEBUG
|
||||
fprintf(stderr, "WaitForSomething: Got called.\n");
|
||||
#endif
|
||||
|
||||
FD_ZERO(&clientsReadable);
|
||||
|
||||
#ifdef NX_TRANS_WAKEUP
|
||||
startTimeInMillis = GetTimeInMillis();
|
||||
#endif
|
||||
|
||||
/* We need a while loop here to handle
|
||||
crashed connections and the screen saver timeout */
|
||||
while (1)
|
||||
{
|
||||
/* deal with any blocked jobs */
|
||||
if (workQueue)
|
||||
ProcessWorkQueue();
|
||||
if (XFD_ANYSET (&ClientsWithInput))
|
||||
{
|
||||
someReady = TRUE;
|
||||
waittime.tv_sec = 0;
|
||||
waittime.tv_usec = 0;
|
||||
wt = &waittime;
|
||||
}
|
||||
if (someReady)
|
||||
{
|
||||
XFD_COPYSET(&AllSockets, &LastSelectMask);
|
||||
XFD_UNSET(&LastSelectMask, &ClientsWithInput);
|
||||
}
|
||||
else
|
||||
{
|
||||
wt = NULL;
|
||||
if (timers)
|
||||
{
|
||||
now = GetTimeInMillis();
|
||||
timeout = timers->expires - now;
|
||||
if (timeout < 0)
|
||||
timeout = 0;
|
||||
waittime.tv_sec = timeout / MILLI_PER_SECOND;
|
||||
waittime.tv_usec = (timeout % MILLI_PER_SECOND) *
|
||||
(1000000 / MILLI_PER_SECOND);
|
||||
wt = &waittime;
|
||||
}
|
||||
XFD_COPYSET(&AllSockets, &LastSelectMask);
|
||||
}
|
||||
SmartScheduleStopTimer ();
|
||||
|
||||
BlockHandler((void *)&wt, (void *)&LastSelectMask);
|
||||
if (NewOutputPending)
|
||||
FlushAllOutput();
|
||||
|
||||
#ifdef NX_TRANS_WAKEUP
|
||||
|
||||
/*
|
||||
* If caller has marked the first element of pClientsReady[],
|
||||
* bail out of select after the timeout given in the second
|
||||
* element. We need this to let the NX agent remove the splash
|
||||
* screen when the timeout is expired even if there's no
|
||||
* client. Otherwise WaitForSomething would block. A better
|
||||
* option would be to use the existing screen-saver timeout
|
||||
* but it can be modified by clients, so we would need a
|
||||
* special handling. This hack is trivial and keeps
|
||||
* WaitForSomething() backward compatible with the existing
|
||||
* servers.
|
||||
*/
|
||||
|
||||
if (pClientsReady[0] == -1)
|
||||
{
|
||||
unsigned long timeoutInMillis;
|
||||
|
||||
#ifdef NX_TRANS_DEBUG
|
||||
fprintf(stderr, "WaitForSomething: pClientsReady[0] is [%d], pClientsReady[1] is [%d].\n",
|
||||
pClientsReady[0], pClientsReady[1]);
|
||||
#endif
|
||||
|
||||
timeoutInMillis = GetTimeInMillis();
|
||||
|
||||
if (timeoutInMillis - startTimeInMillis >= pClientsReady[1])
|
||||
{
|
||||
#ifdef NX_TRANS_DEBUG
|
||||
fprintf(stderr, "WaitForSomething: Returning 0 because of wakeup timeout.\n");
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
timeoutInMillis = pClientsReady[1] - (timeoutInMillis - startTimeInMillis);
|
||||
|
||||
#ifdef NX_TRANS_DEBUG
|
||||
fprintf(stderr, "WaitForSomething: Milliseconds to next wakeup are %ld.\n",
|
||||
timeoutInMillis);
|
||||
#endif
|
||||
if (wt == NULL || (wt -> tv_sec * MILLI_PER_SECOND +
|
||||
wt -> tv_usec / MILLI_PER_SECOND) > timeoutInMillis)
|
||||
{
|
||||
if ((waittime.tv_sec * MILLI_PER_SECOND +
|
||||
waittime.tv_usec / MILLI_PER_SECOND) > timeoutInMillis)
|
||||
{
|
||||
waittime.tv_sec = timeoutInMillis / MILLI_PER_SECOND;
|
||||
waittime.tv_usec = (timeoutInMillis * MILLI_PER_SECOND) %
|
||||
(MILLI_PER_SECOND * 1000);
|
||||
wt = &waittime;
|
||||
}
|
||||
|
||||
#ifdef NX_TRANS_DEBUG
|
||||
fprintf(stderr, "WaitForSomething: Next wakeup timeout set to %ld milliseconds.\n",
|
||||
(waittime.tv_sec * MILLI_PER_SECOND) +
|
||||
(waittime.tv_usec / MILLI_PER_SECOND));
|
||||
#endif
|
||||
}
|
||||
#ifdef NX_TRANS_DEBUG
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "WaitForSomething: Using existing timeout of %ld milliseconds.\n",
|
||||
(waittime.tv_sec * MILLI_PER_SECOND) +
|
||||
(waittime.tv_usec / MILLI_PER_SECOND));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif /* defined(NX_TRANS_WAKEUP) */
|
||||
|
||||
/* keep this check close to select() call to minimize race */
|
||||
#ifdef NX_TRANS_DEBUG
|
||||
if (dispatchException)
|
||||
fprintf(stderr, "WaitForSomething: Value of dispatchException is true. Set i = -1.\n");
|
||||
#endif
|
||||
if (dispatchException)
|
||||
i = -1;
|
||||
else if (AnyWritesPending)
|
||||
{
|
||||
#ifdef NX_TRANS_DEBUG
|
||||
if (wt == NULL)
|
||||
{
|
||||
fprintf(stderr, "WaitForSomething: Executing select with LastSelectMask and "
|
||||
"clientsWritable and null timeout.\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "WaitForSomething: Executing select with LastSelectMask, "
|
||||
"clientsWritable, %ld secs and %ld usecs.\n",
|
||||
wt -> tv_sec, wt -> tv_usec);
|
||||
}
|
||||
#endif
|
||||
XFD_COPYSET(&ClientsWriteBlocked, &LastSelectWriteMask);
|
||||
XFD_ORSET(&LastSelectWriteMask, &NotifyWriteFds, &LastSelectWriteMask);
|
||||
i = Select(MaxClients, &LastSelectMask, &LastSelectWriteMask, NULL, wt);
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef NX_TRANS_DEBUG
|
||||
if (wt == NULL)
|
||||
{
|
||||
fprintf(stderr, "WaitForSomething: Executing select with LastSelectMask and null timeout.\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "WaitForSomething: Executing select with LastSelectMask, %ld secs and %ld usecs.\n",
|
||||
wt -> tv_sec, wt -> tv_usec);
|
||||
}
|
||||
#endif
|
||||
i = Select (MaxClients, &LastSelectMask, NULL, NULL, wt);
|
||||
}
|
||||
#ifdef NX_TRANS_DEBUG
|
||||
fprintf(stderr, "WaitForSomething: Bailed out with i = [%d] and errno = [%d].\n", i, errno);
|
||||
if (i < 0)
|
||||
{
|
||||
fprintf(stderr, "WaitForSomething: Error is [%s].\n", strerror(errno));
|
||||
}
|
||||
#endif
|
||||
selecterr = GetErrno();
|
||||
WakeupHandler(i, (void *)&LastSelectMask);
|
||||
|
||||
SmartScheduleStartTimer ();
|
||||
|
||||
if (i <= 0) /* An error or timeout occurred */
|
||||
{
|
||||
#ifdef NX_TRANS_DEBUG
|
||||
if (dispatchException)
|
||||
{
|
||||
fprintf(stderr, "WaitForSomething: Returning 0 because of (dispatchException).\n");
|
||||
}
|
||||
#endif
|
||||
if (dispatchException)
|
||||
return 0;
|
||||
|
||||
if (i < 0)
|
||||
{
|
||||
if (selecterr == EBADF) /* Some client disconnected */
|
||||
{
|
||||
CheckConnections ();
|
||||
|
||||
#ifdef NX_TRANS_DEBUG
|
||||
if (! XFD_ANYSET (&AllClients))
|
||||
{
|
||||
fprintf(stderr, "WaitForSomething: Returning 0 because of (! XFD_ANYSET (&AllClients)).\n");
|
||||
}
|
||||
#endif
|
||||
if (! XFD_ANYSET (&AllClients))
|
||||
return 0;
|
||||
}
|
||||
else if (selecterr == EINVAL)
|
||||
{
|
||||
FatalError("WaitForSomething(): select: errno=%d\n",
|
||||
selecterr);
|
||||
}
|
||||
else if (selecterr != EINTR)
|
||||
{
|
||||
ErrorF("WaitForSomething(): select: errno=%d\n",
|
||||
selecterr);
|
||||
}
|
||||
}
|
||||
else if (someReady)
|
||||
{
|
||||
/*
|
||||
* If no-one else is home, bail quickly
|
||||
*/
|
||||
XFD_COPYSET(&ClientsWithInput, &LastSelectMask);
|
||||
XFD_COPYSET(&ClientsWithInput, &clientsReadable);
|
||||
break;
|
||||
}
|
||||
#ifdef NX_TRANS_DEBUG
|
||||
if (*checkForInput[0] != *checkForInput[1])
|
||||
{
|
||||
fprintf(stderr, "WaitForSomething: Returning 0 because of (*checkForInput[0] != *checkForInput[1]).\n");
|
||||
}
|
||||
#endif
|
||||
if (*checkForInput[0] != *checkForInput[1])
|
||||
return 0;
|
||||
|
||||
if (timers)
|
||||
{
|
||||
int expired = 0;
|
||||
now = GetTimeInMillis();
|
||||
if ((int) (timers->expires - now) <= 0)
|
||||
expired = 1;
|
||||
|
||||
while (timers && (int) (timers->expires - now) <= 0)
|
||||
DoTimer(timers, now, &timers);
|
||||
|
||||
if (expired)
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
fd_set tmp_set;
|
||||
|
||||
if (*checkForInput[0] == *checkForInput[1]) {
|
||||
if (timers)
|
||||
{
|
||||
int expired = 0;
|
||||
now = GetTimeInMillis();
|
||||
if ((int) (timers->expires - now) <= 0)
|
||||
expired = 1;
|
||||
|
||||
while (timers && (int) (timers->expires - now) <= 0)
|
||||
DoTimer(timers, now, &timers);
|
||||
|
||||
if (expired)
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if (someReady)
|
||||
XFD_ORSET(&LastSelectMask, &ClientsWithInput, &LastSelectMask);
|
||||
if (AnyWritesPending) {
|
||||
XFD_ANDSET(&clientsWritable, &LastSelectWriteMask, &ClientsWriteBlocked);
|
||||
if (XFD_ANYSET(&clientsWritable)) {
|
||||
NewOutputPending = TRUE;
|
||||
XFD_ORSET(&OutputPending, &clientsWritable, &OutputPending);
|
||||
XFD_UNSET(&ClientsWriteBlocked, &clientsWritable);
|
||||
if (!XFD_ANYSET(&ClientsWriteBlocked) && NumNotifyWriteFd == 0)
|
||||
AnyWritesPending = FALSE;
|
||||
}
|
||||
if (NumNotifyWriteFd != 0) {
|
||||
XFD_ANDSET(&tmp_set, &LastSelectWriteMask, &NotifyWriteFds);
|
||||
if (XFD_ANYSET(&tmp_set))
|
||||
someNotifyWriteReady = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
XFD_ANDSET(&clientsReadable, &LastSelectMask, &AllClients);
|
||||
|
||||
XFD_ANDSET(&tmp_set, &LastSelectMask, &NotifyReadFds);
|
||||
if (XFD_ANYSET(&tmp_set) || someNotifyWriteReady)
|
||||
HandleNotifyFds();
|
||||
|
||||
if (XFD_ANYSET (&clientsReadable))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
nready = 0;
|
||||
if (XFD_ANYSET (&clientsReadable))
|
||||
{
|
||||
for (i=0; i<howmany(XFD_SETSIZE, NFDBITS); i++)
|
||||
{
|
||||
while (clientsReadable.fds_bits[i])
|
||||
{
|
||||
int client_index;
|
||||
|
||||
curclient = mffs (clientsReadable.fds_bits[i]) - 1;
|
||||
client_index = /* raphael: modified */
|
||||
ConnectionTranslation[curclient + (i * (sizeof(fd_mask) * 8))];
|
||||
pClientsReady[nready++] = client_index;
|
||||
clientsReadable.fds_bits[i] &= ~(((fd_mask)1L) << curclient);
|
||||
}
|
||||
}
|
||||
}
|
||||
#ifdef NX_TRANS_DEBUG
|
||||
fprintf(stderr, "WaitForSomething: Returning nready.\n");
|
||||
#endif
|
||||
return nready;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/*
|
||||
* This is not always a macro.
|
||||
*/
|
||||
ANYSET(FdMask *src)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i=0; i<mskcnt; i++)
|
||||
if (src[ i ])
|
||||
return (TRUE);
|
||||
return (FALSE);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static void
|
||||
DoTimer(OsTimerPtr timer, CARD32 now, OsTimerPtr *prev)
|
||||
{
|
||||
CARD32 newTime;
|
||||
|
||||
*prev = timer->next;
|
||||
timer->next = NULL;
|
||||
newTime = (*timer->callback)(timer, now, timer->arg);
|
||||
if (newTime)
|
||||
TimerSet(timer, 0, newTime, timer->callback, timer->arg);
|
||||
}
|
||||
|
||||
OsTimerPtr
|
||||
TimerSet(OsTimerPtr timer, int flags, CARD32 millis,
|
||||
OsTimerCallback func, void * arg)
|
||||
{
|
||||
register OsTimerPtr *prev;
|
||||
CARD32 now = GetTimeInMillis();
|
||||
|
||||
if (!timer)
|
||||
{
|
||||
timer = (OsTimerPtr)malloc(sizeof(struct _OsTimerRec));
|
||||
if (!timer)
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (prev = &timers; *prev; prev = &(*prev)->next)
|
||||
{
|
||||
if (*prev == timer)
|
||||
{
|
||||
*prev = timer->next;
|
||||
if (flags & TimerForceOld)
|
||||
(void)(*timer->callback)(timer, now, timer->arg);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!millis)
|
||||
return timer;
|
||||
if (!(flags & TimerAbsolute))
|
||||
millis += now;
|
||||
timer->expires = millis;
|
||||
timer->callback = func;
|
||||
timer->arg = arg;
|
||||
if ((int) (millis - now) <= 0)
|
||||
{
|
||||
timer->next = NULL;
|
||||
millis = (*timer->callback)(timer, now, timer->arg);
|
||||
if (!millis)
|
||||
return timer;
|
||||
}
|
||||
for (prev = &timers;
|
||||
*prev && (int) ((*prev)->expires - millis) <= 0;
|
||||
prev = &(*prev)->next)
|
||||
;
|
||||
timer->next = *prev;
|
||||
*prev = timer;
|
||||
return timer;
|
||||
}
|
||||
|
||||
Bool
|
||||
TimerForce(OsTimerPtr timer)
|
||||
{
|
||||
OsTimerPtr *prev;
|
||||
|
||||
for (prev = &timers; *prev; prev = &(*prev)->next)
|
||||
{
|
||||
if (*prev == timer)
|
||||
{
|
||||
DoTimer(timer, GetTimeInMillis(), prev);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TimerCancel(OsTimerPtr timer)
|
||||
{
|
||||
OsTimerPtr *prev;
|
||||
|
||||
if (!timer)
|
||||
return;
|
||||
for (prev = &timers; *prev; prev = &(*prev)->next)
|
||||
{
|
||||
if (*prev == timer)
|
||||
{
|
||||
*prev = timer->next;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
TimerFree(OsTimerPtr timer)
|
||||
{
|
||||
if (!timer)
|
||||
return;
|
||||
TimerCancel(timer);
|
||||
free(timer);
|
||||
}
|
||||
|
||||
void
|
||||
TimerCheck(void)
|
||||
{
|
||||
CARD32 now = GetTimeInMillis();
|
||||
|
||||
while (timers && (int) (timers->expires - now) <= 0)
|
||||
DoTimer(timers, now, &timers);
|
||||
}
|
||||
|
||||
void
|
||||
TimerInit(void)
|
||||
{
|
||||
OsTimerPtr timer;
|
||||
|
||||
while ((timer = timers))
|
||||
{
|
||||
timers = timer->next;
|
||||
free(timer);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DPMSExtension
|
||||
|
||||
#define DPMS_CHECK_MODE(mode,time)\
|
||||
if (time > 0 && DPMSPowerLevel < mode && timeout >= time)\
|
||||
DPMSSet(mode);
|
||||
|
||||
#define DPMS_CHECK_TIMEOUT(time)\
|
||||
if (time > 0 && (time - timeout) > 0)\
|
||||
return time - timeout;
|
||||
|
||||
static CARD32
|
||||
NextDPMSTimeout(INT32 timeout)
|
||||
{
|
||||
/*
|
||||
* Return the amount of time remaining until we should set
|
||||
* the next power level. Fallthroughs are intentional.
|
||||
*/
|
||||
switch (DPMSPowerLevel)
|
||||
{
|
||||
case DPMSModeOn:
|
||||
DPMS_CHECK_TIMEOUT(DPMSStandbyTime)
|
||||
|
||||
case DPMSModeStandby:
|
||||
DPMS_CHECK_TIMEOUT(DPMSSuspendTime)
|
||||
|
||||
case DPMSModeSuspend:
|
||||
DPMS_CHECK_TIMEOUT(DPMSOffTime)
|
||||
|
||||
default: /* DPMSModeOff */
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#endif /* DPMSExtension */
|
||||
|
||||
static CARD32
|
||||
ScreenSaverTimeoutExpire(OsTimerPtr timer,CARD32 now,void * arg)
|
||||
{
|
||||
INT32 timeout = now - lastDeviceEventTime.milliseconds;
|
||||
CARD32 nextTimeout = 0;
|
||||
|
||||
#ifdef DPMSExtension
|
||||
/*
|
||||
* Check each mode lowest to highest, since a lower mode can
|
||||
* have the same timeout as a higher one.
|
||||
*/
|
||||
if (DPMSEnabled)
|
||||
{
|
||||
DPMS_CHECK_MODE(DPMSModeOff, DPMSOffTime)
|
||||
DPMS_CHECK_MODE(DPMSModeSuspend, DPMSSuspendTime)
|
||||
DPMS_CHECK_MODE(DPMSModeStandby, DPMSStandbyTime)
|
||||
|
||||
nextTimeout = NextDPMSTimeout(timeout);
|
||||
}
|
||||
|
||||
/*
|
||||
* Only do the screensaver checks if we're not in a DPMS
|
||||
* power saving mode
|
||||
*/
|
||||
if (DPMSPowerLevel != DPMSModeOn)
|
||||
return nextTimeout;
|
||||
#endif /* DPMSExtension */
|
||||
|
||||
if (!ScreenSaverTime)
|
||||
return nextTimeout;
|
||||
|
||||
if (timeout < ScreenSaverTime)
|
||||
{
|
||||
return nextTimeout > 0 ?
|
||||
min(ScreenSaverTime - timeout, nextTimeout) :
|
||||
ScreenSaverTime - timeout;
|
||||
}
|
||||
|
||||
ResetOsBuffers(); /* not ideal, but better than nothing */
|
||||
SaveScreens(SCREEN_SAVER_ON, ScreenSaverActive);
|
||||
|
||||
if (ScreenSaverInterval > 0)
|
||||
{
|
||||
nextTimeout = nextTimeout > 0 ?
|
||||
min(ScreenSaverInterval, nextTimeout) :
|
||||
ScreenSaverInterval;
|
||||
}
|
||||
|
||||
return nextTimeout;
|
||||
}
|
||||
|
||||
static OsTimerPtr ScreenSaverTimer = NULL;
|
||||
|
||||
void
|
||||
FreeScreenSaverTimer(void)
|
||||
{
|
||||
if (ScreenSaverTimer) {
|
||||
TimerFree(ScreenSaverTimer);
|
||||
ScreenSaverTimer = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SetScreenSaverTimer(void)
|
||||
{
|
||||
CARD32 timeout = 0;
|
||||
|
||||
#ifdef DPMSExtension
|
||||
if (DPMSEnabled)
|
||||
{
|
||||
/*
|
||||
* A higher DPMS level has a timeout that's either less
|
||||
* than or equal to that of a lower DPMS level.
|
||||
*/
|
||||
if (DPMSStandbyTime > 0)
|
||||
timeout = DPMSStandbyTime;
|
||||
|
||||
else if (DPMSSuspendTime > 0)
|
||||
timeout = DPMSSuspendTime;
|
||||
|
||||
else if (DPMSOffTime > 0)
|
||||
timeout = DPMSOffTime;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (ScreenSaverTime > 0)
|
||||
{
|
||||
timeout = timeout > 0 ?
|
||||
min(ScreenSaverTime, timeout) :
|
||||
ScreenSaverTime;
|
||||
}
|
||||
|
||||
#ifdef SCREENSAVER
|
||||
if (timeout && !screenSaverSuspended) {
|
||||
#else
|
||||
if (timeout) {
|
||||
#endif
|
||||
ScreenSaverTimer = TimerSet(ScreenSaverTimer, 0, timeout,
|
||||
ScreenSaverTimeoutExpire, NULL);
|
||||
}
|
||||
else if (ScreenSaverTimer) {
|
||||
FreeScreenSaverTimer();
|
||||
}
|
||||
}
|
||||
2236
nx-X11/programs/Xserver/os/access.c
Normal file
2236
nx-X11/programs/Xserver/os/access.c
Normal file
File diff suppressed because it is too large
Load Diff
599
nx-X11/programs/Xserver/os/auth.c
Normal file
599
nx-X11/programs/Xserver/os/auth.c
Normal file
@@ -0,0 +1,599 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
|
||||
/* Copyright (c) 2008-2017 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
|
||||
/* Copyright (c) 2011-2022 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
|
||||
/* Copyright (c) 2014-2019 Mihai Moldovan <ionic@ionic.de> */
|
||||
/* Copyright (c) 2014-2022 Ulrich Sibiller <uli42@gmx.de> */
|
||||
/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
|
||||
/* */
|
||||
/* nx-X11, NX protocol compression and NX extensions to this software */
|
||||
/* are copyright of the aforementioned persons and companies. */
|
||||
/* */
|
||||
/* Redistribution and use of the present software is allowed according */
|
||||
/* to terms specified in the file LICENSE which comes in the source */
|
||||
/* distribution. */
|
||||
/* */
|
||||
/* All rights reserved. */
|
||||
/* */
|
||||
/* NOTE: This software has received contributions from various other */
|
||||
/* contributors, only the core maintainers and supporters are listed as */
|
||||
/* copyright holders. Please contact us, if you feel you should be listed */
|
||||
/* as copyright holder, as well. */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
/*
|
||||
|
||||
Copyright 1988, 1998 The Open Group
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this software and its
|
||||
documentation for any purpose is hereby granted without fee, provided that
|
||||
the above copyright notice appear in all copies and that both that
|
||||
copyright notice and this permission notice appear in supporting
|
||||
documentation.
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
Except as contained in this notice, the name of The Open Group shall
|
||||
not be used in advertising or otherwise to promote the sale, use or
|
||||
other dealings in this Software without prior written authorization
|
||||
from The Open Group.
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
* authorization hooks for the server
|
||||
* Author: Keith Packard, MIT X Consortium
|
||||
*/
|
||||
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
# include <nx-X11/X.h>
|
||||
# include <nx-X11/Xauth.h>
|
||||
# include "misc.h"
|
||||
# include "osdep.h"
|
||||
# include "dixstruct.h"
|
||||
# include <sys/types.h>
|
||||
# include <sys/stat.h>
|
||||
#ifdef XCSECURITY
|
||||
#define _SECURITY_SERVER
|
||||
# include <nx-X11/extensions/security.h>
|
||||
#endif
|
||||
|
||||
struct protocol {
|
||||
unsigned short name_length;
|
||||
char *name;
|
||||
AuthAddCFunc Add; /* new authorization data */
|
||||
AuthCheckFunc Check; /* verify client authorization data */
|
||||
AuthRstCFunc Reset; /* delete all authorization data entries */
|
||||
AuthToIDFunc ToID; /* convert cookie to ID */
|
||||
AuthFromIDFunc FromID; /* convert ID to cookie */
|
||||
AuthRemCFunc Remove; /* remove a specific cookie */
|
||||
#ifdef XCSECURITY
|
||||
AuthGenCFunc Generate;
|
||||
#endif
|
||||
};
|
||||
|
||||
static struct protocol protocols[] = {
|
||||
{ (unsigned short) 18, "MIT-MAGIC-COOKIE-1",
|
||||
MitAddCookie, MitCheckCookie, MitResetCookie,
|
||||
MitToID, MitFromID, MitRemoveCookie,
|
||||
#ifdef XCSECURITY
|
||||
MitGenerateCookie
|
||||
#endif
|
||||
},
|
||||
#ifdef HASXDMAUTH
|
||||
{ (unsigned short) 19, "XDM-AUTHORIZATION-1",
|
||||
XdmAddCookie, XdmCheckCookie, XdmResetCookie,
|
||||
XdmToID, XdmFromID, XdmRemoveCookie,
|
||||
#ifdef XCSECURITY
|
||||
NULL
|
||||
#endif
|
||||
},
|
||||
#endif
|
||||
#ifdef SECURE_RPC
|
||||
{ (unsigned short) 9, "SUN-DES-1",
|
||||
SecureRPCAdd, SecureRPCCheck, SecureRPCReset,
|
||||
SecureRPCToID, SecureRPCFromID,SecureRPCRemove,
|
||||
#ifdef XCSECURITY
|
||||
NULL
|
||||
#endif
|
||||
},
|
||||
#endif
|
||||
#ifdef XCSECURITY
|
||||
{ (unsigned short) XSecurityAuthorizationNameLen,
|
||||
XSecurityAuthorizationName,
|
||||
NULL, AuthSecurityCheck, NULL,
|
||||
NULL, NULL, NULL,
|
||||
NULL
|
||||
},
|
||||
#endif
|
||||
};
|
||||
|
||||
# define NUM_AUTHORIZATION (sizeof (protocols) /\
|
||||
sizeof (struct protocol))
|
||||
|
||||
/*
|
||||
* Initialize all classes of authorization by reading the
|
||||
* specified authorization file
|
||||
*/
|
||||
|
||||
static char *authorization_file = (char *)NULL;
|
||||
|
||||
static Bool ShouldLoadAuth = TRUE;
|
||||
|
||||
void
|
||||
InitAuthorization (char *file_name)
|
||||
{
|
||||
#ifdef __sun
|
||||
char * envBuffer;
|
||||
#endif
|
||||
authorization_file = file_name;
|
||||
#ifdef NX_TRANS_AUTH
|
||||
#ifdef NX_TRANS_TEST
|
||||
fprintf(stderr, "InitAuthorization: Going to propagate auth file '%s' to the environment.\n",
|
||||
authorization_file);
|
||||
#endif
|
||||
#ifdef __sun
|
||||
envBuffer = malloc(15+strlen(authorization_file));
|
||||
sprintf(envBuffer,"NX_XAUTHORITY=%s",authorization_file);
|
||||
putenv(envBuffer);
|
||||
#else
|
||||
setenv("NX_XAUTHORITY", authorization_file, 1);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
static int
|
||||
LoadAuthorization (void)
|
||||
{
|
||||
FILE *f;
|
||||
Xauth *auth;
|
||||
int i;
|
||||
int count = 0;
|
||||
|
||||
ShouldLoadAuth = FALSE;
|
||||
if (!authorization_file)
|
||||
return 0;
|
||||
|
||||
#ifdef NX_TRANS_AUTH
|
||||
|
||||
/*
|
||||
* We think that the way LoadAuthorization() is working is wrong.
|
||||
* It doesn't reset the list of stored authorizations before reading
|
||||
* the new cookies. Our take is that if a new auth file is to be
|
||||
* read, the only cookies that are to be accepted are those that are
|
||||
* in the new file, not those in the file -plus- those that have
|
||||
* been in the file in the past. Furthermore, if the list can't be
|
||||
* read or it is empty, it should assume that it ignores which co-
|
||||
* okies are valid and thus it should disable any access. Your mile-
|
||||
* age can vary. A less draconian approach could be to leave the old
|
||||
* cookies if the file can't be read and remove them only if the
|
||||
* file is empty.
|
||||
*
|
||||
* Adding the cookies without removing the old values for the same
|
||||
* protocol has an important implication. If an user shares the co-
|
||||
* okie with somebody and later wants to revoke the access to the
|
||||
* display, changing the cookie will not work. This is especially
|
||||
* important with NX. For security reasons, after reconnecting the
|
||||
* session to a different display, it is advisable to generate a
|
||||
* new set of cookies, but doing that it is useless with the current
|
||||
* code, as the old cookies are going to be still accepted. On the
|
||||
* same topic, consider that once an user has got access to the X
|
||||
* server, he/she can freely enable host authentication from any
|
||||
* host, so the safe behaviour should be to reset the host based
|
||||
* authenthication at least at reconnection, and keep as valid only
|
||||
* the cookies that are actually in the file. This behaviour would
|
||||
* surely break many applications, among them a SSH connection run
|
||||
* inside a NX session, as ssh -X reads the cookie for the display
|
||||
* only at session startup and does not read the cookies again
|
||||
* when the auth file is changed.
|
||||
*
|
||||
* Another bug (or feature, depending on how you want to consider
|
||||
* it) is that if the authority file contains entries for different
|
||||
* displays (as it is the norm when the authority file is the default
|
||||
* .Xauthority in the user's home), the server will match -any- of
|
||||
* the cookies, even cookies that are not for its own display. This
|
||||
* means that you have be careful when passing an authority file to
|
||||
* nxagent or Xnest and maybe keep separate files for letting nxagent
|
||||
* find the cookie to be used to connect to the remote display and
|
||||
* for letting it find what cookies to accept. If the file is the
|
||||
* same, clients will be able to connect to nxagent with both the
|
||||
* cookies.
|
||||
*/
|
||||
|
||||
#ifdef NX_TRANS_AUTH_RESET
|
||||
|
||||
#ifdef NX_TRANS_TEST
|
||||
fprintf(stderr, "LoadAuthorization: Resetting authorization info.\n");
|
||||
#endif
|
||||
|
||||
for (i = 0; i < NUM_AUTHORIZATION; i++) {
|
||||
if (protocols[i].Reset) {
|
||||
(*protocols[i].Reset) ();
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* #ifdef NX_TRANS_AUTH */
|
||||
|
||||
f = Fopen (authorization_file, "r");
|
||||
if (!f)
|
||||
return -1;
|
||||
|
||||
while ((auth = XauReadAuth (f)) != 0) {
|
||||
for (i = 0; i < NUM_AUTHORIZATION; i++) {
|
||||
if (protocols[i].name_length == auth->name_length &&
|
||||
memcmp (protocols[i].name, auth->name, (int) auth->name_length) == 0 &&
|
||||
protocols[i].Add)
|
||||
{
|
||||
#ifdef NX_TRANS_AUTH
|
||||
|
||||
#ifdef NX_TRANS_TEST
|
||||
fprintf(stderr, "LoadAuthorization: Adding new record from file [%s].\n",
|
||||
authorization_file);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
++count;
|
||||
(*protocols[i].Add) (auth->data_length, auth->data,
|
||||
FakeClientID(0));
|
||||
}
|
||||
}
|
||||
XauDisposeAuth (auth);
|
||||
}
|
||||
|
||||
#ifdef NX_TRANS_AUTH
|
||||
|
||||
if (count == 0)
|
||||
{
|
||||
fprintf(stderr, "Warning: No authorization record could be read from file '%s'.\n",
|
||||
authorization_file);
|
||||
|
||||
fprintf(stderr, "Warning: Please, create a valid authorization cookie using the command\n"
|
||||
"Warning: 'xauth -f %s add <display> MIT-MAGIC-COOKIE-1 <cookie>'.\n",
|
||||
authorization_file);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef NX_TRANS_AUTH
|
||||
if (Fclose (f) != 0)
|
||||
{
|
||||
/*
|
||||
* If the Fclose() fails, for example because of a signal,
|
||||
* it's advisable to return the number of protocols read,
|
||||
* if any, or otherwise the server would believe that no
|
||||
* cookie is valid and eventually fall back to host based
|
||||
* authentication. Note anyway that the new code in Check-
|
||||
* Authorization() doesn't care the return value and gives
|
||||
* a chance to the function to check the file at the next
|
||||
* connection.
|
||||
*/
|
||||
|
||||
if (count > 0)
|
||||
{
|
||||
return count;
|
||||
}
|
||||
else
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
#else
|
||||
Fclose (f);
|
||||
#endif
|
||||
return count;
|
||||
}
|
||||
|
||||
#ifdef XDMCP
|
||||
/*
|
||||
* XdmcpInit calls this function to discover all authorization
|
||||
* schemes supported by the display
|
||||
*/
|
||||
void
|
||||
RegisterAuthorizations (void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < NUM_AUTHORIZATION; i++)
|
||||
XdmcpRegisterAuthorization (protocols[i].name,
|
||||
(int)protocols[i].name_length);
|
||||
}
|
||||
#endif
|
||||
|
||||
XID
|
||||
CheckAuthorization (
|
||||
unsigned int name_length,
|
||||
char *name,
|
||||
unsigned int data_length,
|
||||
char *data,
|
||||
ClientPtr client,
|
||||
char **reason) /* failure message. NULL for default msg */
|
||||
{
|
||||
int i;
|
||||
struct stat buf;
|
||||
static time_t lastmod = 0;
|
||||
|
||||
#ifndef NX_TRANS_AUTH
|
||||
static Bool loaded = FALSE;
|
||||
#endif
|
||||
|
||||
if (!authorization_file || stat(authorization_file, &buf))
|
||||
{
|
||||
if (lastmod != 0) {
|
||||
lastmod = 0;
|
||||
ShouldLoadAuth = TRUE; /* stat lost, so force reload */
|
||||
}
|
||||
}
|
||||
else if (buf.st_mtime > lastmod)
|
||||
{
|
||||
lastmod = buf.st_mtime;
|
||||
ShouldLoadAuth = TRUE;
|
||||
}
|
||||
if (ShouldLoadAuth)
|
||||
{
|
||||
int loadauth = LoadAuthorization();
|
||||
|
||||
/*
|
||||
* If the authorization file has at least one entry for this server,
|
||||
* disable local host access. (loadauth > 0)
|
||||
*
|
||||
* If there are zero entries (either initially or when the
|
||||
* authorization file is later reloaded), or if a valid
|
||||
* authorization file was never loaded, enable local host access.
|
||||
* (loadauth == 0 || !loaded)
|
||||
*
|
||||
* If the authorization file was loaded initially (with valid
|
||||
* entries for this server), and reloading it later fails, don't
|
||||
* change anything. (loadauth == -1 && loaded)
|
||||
*/
|
||||
|
||||
#ifdef NX_TRANS_AUTH
|
||||
|
||||
/*
|
||||
* The implementation of CheckAuthorization() was changed. The way
|
||||
* the auth file was handled previously was questionable and could
|
||||
* open the way to a vast array of security problems. There might be
|
||||
* ways for an attacker to prevent the server from reading the file
|
||||
* and it was enough for the server to fail reading the file once
|
||||
* (because of a not blocked signal, for example) to leave the dis-
|
||||
* play open to all the users running a session on the same terminal
|
||||
* server.
|
||||
*
|
||||
* In NX we want to have only two cases: either we have to check an
|
||||
* authorization file or we don't. In the first case we need to do our
|
||||
* best to read the file at any new client access and never fall back
|
||||
* to host based authentication. Falling back to local host access has
|
||||
* no way back, as it will always take precedence over the auth cookie
|
||||
* (unless the user explicitly disables, one by one, all the rules
|
||||
* allowing local access, if and only if he/she becomes aware of the
|
||||
* problem). In the second case we assume that user doesn't care secu-
|
||||
* rity and so allow unrestricted access from the local machine.
|
||||
*/
|
||||
|
||||
#ifdef NX_TRANS_TEST
|
||||
fprintf(stderr, "CheckAuthorization: Going to set authorization with loadauth [%d].\n",
|
||||
loadauth);
|
||||
#endif
|
||||
|
||||
if (authorization_file)
|
||||
{
|
||||
#ifdef NX_TRANS_TEST
|
||||
fprintf(stderr, "CheckAuthorization: Disabling local host access.\n");
|
||||
#endif
|
||||
|
||||
DisableLocalHost();
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* Enable host-based authentication only if
|
||||
* the authorization file was not specified
|
||||
* either on the command line or in the env-
|
||||
* ironment.
|
||||
*/
|
||||
|
||||
#ifdef NX_TRANS_TEST
|
||||
fprintf(stderr, "CheckAuthorization: Enabling local host access.\n");
|
||||
#endif
|
||||
|
||||
EnableLocalHost();
|
||||
}
|
||||
|
||||
/*
|
||||
* Avoid the 'unused variable' warning.
|
||||
*/
|
||||
|
||||
loadauth = loadauth;
|
||||
|
||||
#else /* #ifdef NX_TRANS_AUTH */
|
||||
|
||||
if (loadauth > 0)
|
||||
{
|
||||
DisableLocalHost(); /* got at least one */
|
||||
loaded = TRUE;
|
||||
}
|
||||
else if (loadauth == 0 || !loaded)
|
||||
EnableLocalHost ();
|
||||
|
||||
#endif /* #ifdef NX_TRANS_AUTH */
|
||||
}
|
||||
if (name_length) {
|
||||
for (i = 0; i < NUM_AUTHORIZATION; i++) {
|
||||
if (protocols[i].name_length == name_length &&
|
||||
memcmp (protocols[i].name, name, (int) name_length) == 0)
|
||||
{
|
||||
return (*protocols[i].Check) (data_length, data, client, reason);
|
||||
}
|
||||
*reason = "Protocol not supported by server\n";
|
||||
}
|
||||
} else *reason = "No protocol specified\n";
|
||||
return (XID) ~0L;
|
||||
}
|
||||
|
||||
void
|
||||
ResetAuthorization (void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < NUM_AUTHORIZATION; i++)
|
||||
if (protocols[i].Reset)
|
||||
(*protocols[i].Reset)();
|
||||
ShouldLoadAuth = TRUE;
|
||||
}
|
||||
|
||||
XID
|
||||
AuthorizationToID (
|
||||
unsigned short name_length,
|
||||
char *name,
|
||||
unsigned short data_length,
|
||||
char *data)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < NUM_AUTHORIZATION; i++) {
|
||||
if (protocols[i].name_length == name_length &&
|
||||
memcmp (protocols[i].name, name, (int) name_length) == 0 &&
|
||||
protocols[i].ToID)
|
||||
{
|
||||
return (*protocols[i].ToID) (data_length, data);
|
||||
}
|
||||
}
|
||||
return (XID) ~0L;
|
||||
}
|
||||
|
||||
int
|
||||
AuthorizationFromID (
|
||||
XID id,
|
||||
unsigned short *name_lenp,
|
||||
char **namep,
|
||||
unsigned short *data_lenp,
|
||||
char **datap)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < NUM_AUTHORIZATION; i++) {
|
||||
if (protocols[i].FromID &&
|
||||
(*protocols[i].FromID) (id, data_lenp, datap)) {
|
||||
*name_lenp = protocols[i].name_length;
|
||||
*namep = protocols[i].name;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
RemoveAuthorization (
|
||||
unsigned short name_length,
|
||||
char *name,
|
||||
unsigned short data_length,
|
||||
char *data)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < NUM_AUTHORIZATION; i++) {
|
||||
if (protocols[i].name_length == name_length &&
|
||||
memcmp (protocols[i].name, name, (int) name_length) == 0 &&
|
||||
protocols[i].Remove)
|
||||
{
|
||||
return (*protocols[i].Remove) (data_length, data);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
AddAuthorization (unsigned name_length, char *name, unsigned data_length, char *data)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < NUM_AUTHORIZATION; i++) {
|
||||
if (protocols[i].name_length == name_length &&
|
||||
memcmp (protocols[i].name, name, (int) name_length) == 0 &&
|
||||
protocols[i].Add)
|
||||
{
|
||||
return (*protocols[i].Add) (data_length, data, FakeClientID(0));
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef XCSECURITY
|
||||
|
||||
XID
|
||||
GenerateAuthorization(
|
||||
unsigned name_length,
|
||||
char *name,
|
||||
unsigned data_length,
|
||||
char *data,
|
||||
unsigned *data_length_return,
|
||||
char **data_return)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < NUM_AUTHORIZATION; i++) {
|
||||
if (protocols[i].name_length == name_length &&
|
||||
memcmp (protocols[i].name, name, (int) name_length) == 0 &&
|
||||
protocols[i].Generate)
|
||||
{
|
||||
return (*protocols[i].Generate) (data_length, data,
|
||||
FakeClientID(0), data_length_return, data_return);
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* A random number generator that is more unpredictable
|
||||
than that shipped with some systems.
|
||||
This code is taken from the C standard. */
|
||||
|
||||
static unsigned long int next = 1;
|
||||
|
||||
static int
|
||||
xdm_rand(void)
|
||||
{
|
||||
next = next * 1103515245 + 12345;
|
||||
return (unsigned int)(next/65536) % 32768;
|
||||
}
|
||||
|
||||
static void
|
||||
xdm_srand(unsigned int seed)
|
||||
{
|
||||
next = seed;
|
||||
}
|
||||
|
||||
void
|
||||
GenerateRandomData (int len, char *buf)
|
||||
{
|
||||
static int seed;
|
||||
int value;
|
||||
int i;
|
||||
|
||||
seed += GetTimeInMillis();
|
||||
xdm_srand (seed);
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
value = xdm_rand ();
|
||||
buf[i] ^= (value & 0xff00) >> 8;
|
||||
}
|
||||
|
||||
/* XXX add getrusage, popen("ps -ale") */
|
||||
}
|
||||
|
||||
#endif /* XCSECURITY */
|
||||
397
nx-X11/programs/Xserver/os/client.c
Normal file
397
nx-X11/programs/Xserver/os/client.c
Normal file
@@ -0,0 +1,397 @@
|
||||
/*
|
||||
* Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). All
|
||||
* rights reserved.
|
||||
* Copyright (c) 1993, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* This file contains functionality for identifying clients by various
|
||||
* means. The primary purpose of identification is to simply aid in
|
||||
* finding out which clients are using X server and how they are using
|
||||
* it. For example, it's often necessary to monitor what requests
|
||||
* clients are executing (to spot bad behaviour) and how they are
|
||||
* allocating resources in X server (to spot excessive resource
|
||||
* usage).
|
||||
*
|
||||
* This framework automatically allocates information, that can be
|
||||
* used for client identification, when a client connects to the
|
||||
* server. The information is freed when the client disconnects. The
|
||||
* allocated information is just a collection of various IDs, such as
|
||||
* PID and process name for local clients, that are likely to be
|
||||
* useful in analyzing X server usage.
|
||||
*
|
||||
* Users of the framework can query ID information about clients at
|
||||
* any time. To avoid repeated polling of IDs the users can also
|
||||
* subscribe for notifications about the availability of ID
|
||||
* information. IDs have been allocated before ClientStateCallback is
|
||||
* called with ClientStateInitial state. Similarly the IDs will be
|
||||
* released after ClientStateCallback is called with ClientStateGone
|
||||
* state.
|
||||
*
|
||||
* Author: Rami Ylimäki <rami.ylimaki@vincit.fi>
|
||||
*/
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "client.h"
|
||||
#include "os.h"
|
||||
#include "dixstruct.h"
|
||||
|
||||
#ifdef __sun
|
||||
#include <errno.h>
|
||||
#include <procfs.h>
|
||||
#endif
|
||||
|
||||
#ifdef __OpenBSD__
|
||||
#include <sys/param.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <kvm.h>
|
||||
#include <limits.h>
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Try to determine a PID for a client from its connection
|
||||
* information. This should be called only once when new client has
|
||||
* connected, use GetClientPid to determine the PID at other times.
|
||||
*
|
||||
* @param[in] client Connection linked to some process.
|
||||
*
|
||||
* @return PID of the client. Error (-1) if PID can't be determined
|
||||
* for the client.
|
||||
*
|
||||
* @see GetClientPid
|
||||
*/
|
||||
pid_t
|
||||
DetermineClientPid(struct _Client * client)
|
||||
{
|
||||
LocalClientCredRec *lcc = NULL;
|
||||
pid_t pid = -1;
|
||||
|
||||
if (client == NullClient)
|
||||
return pid;
|
||||
|
||||
if (client == serverClient)
|
||||
return getpid();
|
||||
|
||||
if (GetLocalClientCreds(client, &lcc) != -1) {
|
||||
if (lcc->fieldsSet & LCC_PID_SET)
|
||||
pid = lcc->pid;
|
||||
FreeLocalClientCreds(lcc);
|
||||
}
|
||||
|
||||
return pid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to determine a command line string for a client based on its
|
||||
* PID. Note that mapping PID to a command hasn't been implemented for
|
||||
* some operating systems. This should be called only once when a new
|
||||
* client has connected, use GetClientCmdName/Args to determine the
|
||||
* string at other times.
|
||||
*
|
||||
* @param[in] pid Process ID of a client.
|
||||
|
||||
* @param[out] cmdname Client process name without arguments. You must
|
||||
* release this by calling free. On error NULL is
|
||||
* returned. Pass NULL if you aren't interested in
|
||||
* this value.
|
||||
* @param[out] cmdargs Arguments to client process. Useful for
|
||||
* identifying a client that is executed from a
|
||||
* launcher program. You must release this by
|
||||
* calling free. On error NULL is returned. Pass
|
||||
* NULL if you aren't interested in this value.
|
||||
*
|
||||
* @see GetClientCmdName/Args
|
||||
*/
|
||||
void
|
||||
DetermineClientCmd(pid_t pid, const char **cmdname, const char **cmdargs)
|
||||
{
|
||||
char path[PATH_MAX + 1];
|
||||
int totsize = 0;
|
||||
int fd = 0;
|
||||
|
||||
if (cmdname)
|
||||
*cmdname = NULL;
|
||||
if (cmdargs)
|
||||
*cmdargs = NULL;
|
||||
|
||||
if (pid == -1)
|
||||
return;
|
||||
|
||||
#ifdef __sun /* Solaris */
|
||||
/* Solaris does not support /proc/pid/cmdline, but makes information
|
||||
* similar to what ps shows available in a binary structure in the
|
||||
* /proc/pid/psinfo file. */
|
||||
if (snprintf(path, sizeof(path), "/proc/%d/psinfo", pid) < 0)
|
||||
return;
|
||||
fd = open(path, O_RDONLY);
|
||||
if (fd < 0) {
|
||||
ErrorF("Failed to open %s: %s\n", path, strerror(errno));
|
||||
return;
|
||||
}
|
||||
else {
|
||||
psinfo_t psinfo = { 0 };
|
||||
char *sp;
|
||||
|
||||
totsize = read(fd, &psinfo, sizeof(psinfo_t));
|
||||
close(fd);
|
||||
if (totsize <= 0)
|
||||
return;
|
||||
|
||||
/* pr_psargs is the first PRARGSZ (80) characters of the command
|
||||
* line string - assume up to the first space is the command name,
|
||||
* since it's not delimited. While there is also pr_fname, that's
|
||||
* more limited, giving only the first 16 chars of the basename of
|
||||
* the file that was exec'ed, thus cutting off many long gnome
|
||||
* command names, or returning "isapython2.6" for all python scripts.
|
||||
*/
|
||||
psinfo.pr_psargs[PRARGSZ - 1] = '\0';
|
||||
sp = strchr(psinfo.pr_psargs, ' ');
|
||||
if (sp)
|
||||
*sp++ = '\0';
|
||||
|
||||
if (cmdname)
|
||||
*cmdname = strdup(psinfo.pr_psargs);
|
||||
|
||||
if (cmdargs && sp)
|
||||
*cmdargs = strdup(sp);
|
||||
}
|
||||
#elif defined(__OpenBSD__)
|
||||
/* on OpenBSD use kvm_getargv() */
|
||||
{
|
||||
kvm_t *kd;
|
||||
char errbuf[_POSIX2_LINE_MAX];
|
||||
char **argv;
|
||||
struct kinfo_proc *kp;
|
||||
size_t len = 0;
|
||||
int i, n;
|
||||
|
||||
kd = kvm_open(NULL, NULL, NULL, KVM_NO_FILES, errbuf);
|
||||
if (kd == NULL)
|
||||
return;
|
||||
kp = kvm_getprocs(kd, KERN_PROC_PID, pid, sizeof(struct kinfo_proc),
|
||||
&n);
|
||||
if (n != 1)
|
||||
return;
|
||||
argv = kvm_getargv(kd, kp, 0);
|
||||
*cmdname = strdup(argv[0]);
|
||||
i = 1;
|
||||
while (argv[i] != NULL) {
|
||||
len += strlen(argv[i]) + 1;
|
||||
i++;
|
||||
}
|
||||
*cmdargs = calloc(1, len);
|
||||
i = 1;
|
||||
while (argv[i] != NULL) {
|
||||
strlcat(*cmdargs, argv[i], len);
|
||||
strlcat(*cmdargs, " ", len);
|
||||
i++;
|
||||
}
|
||||
kvm_close(kd);
|
||||
}
|
||||
#else /* Linux using /proc/pid/cmdline */
|
||||
|
||||
/* Check if /proc/pid/cmdline exists. It's not supported on all
|
||||
* operating systems. */
|
||||
if (snprintf(path, sizeof(path), "/proc/%d/cmdline", pid) < 0)
|
||||
return;
|
||||
fd = open(path, O_RDONLY);
|
||||
if (fd < 0)
|
||||
return;
|
||||
|
||||
/* Read the contents of /proc/pid/cmdline. It should contain the
|
||||
* process name and arguments. */
|
||||
totsize = read(fd, path, sizeof(path));
|
||||
close(fd);
|
||||
if (totsize <= 0)
|
||||
return;
|
||||
path[totsize - 1] = '\0';
|
||||
|
||||
/* Contruct the process name without arguments. */
|
||||
if (cmdname) {
|
||||
*cmdname = strdup(path);
|
||||
}
|
||||
|
||||
/* Construct the arguments for client process. */
|
||||
if (cmdargs) {
|
||||
int cmdsize = strlen(path) + 1;
|
||||
int argsize = totsize - cmdsize;
|
||||
char *args = NULL;
|
||||
|
||||
if (argsize > 0)
|
||||
args = malloc(argsize);
|
||||
if (args) {
|
||||
int i = 0;
|
||||
|
||||
for (i = 0; i < (argsize - 1); ++i) {
|
||||
const char c = path[cmdsize + i];
|
||||
|
||||
args[i] = (c == '\0') ? ' ' : c;
|
||||
}
|
||||
args[argsize - 1] = '\0';
|
||||
*cmdargs = args;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a new client connects. Allocates client ID information.
|
||||
*
|
||||
* @param[in] client Recently connected client.
|
||||
*/
|
||||
void
|
||||
ReserveClientIds(struct _Client *client)
|
||||
{
|
||||
#ifdef CLIENTIDS
|
||||
if (client == NullClient)
|
||||
return;
|
||||
|
||||
assert(!client->clientIds);
|
||||
client->clientIds = calloc(1, sizeof(ClientIdRec));
|
||||
if (!client->clientIds)
|
||||
return;
|
||||
|
||||
client->clientIds->pid = DetermineClientPid(client);
|
||||
if (client->clientIds->pid != -1)
|
||||
DetermineClientCmd(client->clientIds->pid, &client->clientIds->cmdname,
|
||||
&client->clientIds->cmdargs);
|
||||
|
||||
DebugF("client(%lx): Reserved pid(%d).\n",
|
||||
(unsigned long) client->clientAsMask, client->clientIds->pid);
|
||||
DebugF("client(%lx): Reserved cmdname(%s) and cmdargs(%s).\n",
|
||||
(unsigned long) client->clientAsMask,
|
||||
client->clientIds->cmdname ? client->clientIds->cmdname : "NULL",
|
||||
client->clientIds->cmdargs ? client->clientIds->cmdargs : "NULL");
|
||||
#endif /* CLIENTIDS */
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when an existing client disconnects. Frees client ID
|
||||
* information.
|
||||
*
|
||||
* @param[in] client Recently disconnected client.
|
||||
*/
|
||||
void
|
||||
ReleaseClientIds(struct _Client *client)
|
||||
{
|
||||
#ifdef CLIENTIDS
|
||||
if (client == NullClient)
|
||||
return;
|
||||
|
||||
if (!client->clientIds)
|
||||
return;
|
||||
|
||||
DebugF("client(%lx): Released pid(%d).\n",
|
||||
(unsigned long) client->clientAsMask, client->clientIds->pid);
|
||||
DebugF("client(%lx): Released cmdline(%s) and cmdargs(%s).\n",
|
||||
(unsigned long) client->clientAsMask,
|
||||
client->clientIds->cmdname ? client->clientIds->cmdname : "NULL",
|
||||
client->clientIds->cmdargs ? client->clientIds->cmdargs : "NULL");
|
||||
|
||||
free((void *) client->clientIds->cmdname); /* const char * */
|
||||
free((void *) client->clientIds->cmdargs); /* const char * */
|
||||
free(client->clientIds);
|
||||
client->clientIds = NULL;
|
||||
#endif /* CLIENTIDS */
|
||||
}
|
||||
|
||||
/**
|
||||
* Get cached PID of a client.
|
||||
*
|
||||
* param[in] client Client whose PID has been already cached.
|
||||
*
|
||||
* @return Cached client PID. Error (-1) if called:
|
||||
* - before ClientStateInitial client state notification
|
||||
* - after ClientStateGone client state notification
|
||||
* - for remote clients
|
||||
*
|
||||
* @see DetermineClientPid
|
||||
*/
|
||||
pid_t
|
||||
GetClientPid(struct _Client *client)
|
||||
{
|
||||
if (client == NullClient)
|
||||
return -1;
|
||||
|
||||
if (!client->clientIds)
|
||||
return -1;
|
||||
|
||||
return client->clientIds->pid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get cached command name string of a client.
|
||||
*
|
||||
* param[in] client Client whose command line string has been already
|
||||
* cached.
|
||||
*
|
||||
* @return Cached client command name. Error (NULL) if called:
|
||||
* - before ClientStateInitial client state notification
|
||||
* - after ClientStateGone client state notification
|
||||
* - for remote clients
|
||||
* - on OS that doesn't support mapping of PID to command line
|
||||
*
|
||||
* @see DetermineClientCmd
|
||||
*/
|
||||
const char *
|
||||
GetClientCmdName(struct _Client *client)
|
||||
{
|
||||
if (client == NullClient)
|
||||
return NULL;
|
||||
|
||||
if (!client->clientIds)
|
||||
return NULL;
|
||||
|
||||
return client->clientIds->cmdname;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get cached command arguments string of a client.
|
||||
*
|
||||
* param[in] client Client whose command line string has been already
|
||||
* cached.
|
||||
*
|
||||
* @return Cached client command arguments. Error (NULL) if called:
|
||||
* - before ClientStateInitial client state notification
|
||||
* - after ClientStateGone client state notification
|
||||
* - for remote clients
|
||||
* - on OS that doesn't support mapping of PID to command line
|
||||
*
|
||||
* @see DetermineClientCmd
|
||||
*/
|
||||
const char *
|
||||
GetClientCmdArgs(struct _Client *client)
|
||||
{
|
||||
if (client == NullClient)
|
||||
return NULL;
|
||||
|
||||
if (!client->clientIds)
|
||||
return NULL;
|
||||
|
||||
return client->clientIds->cmdargs;
|
||||
}
|
||||
1229
nx-X11/programs/Xserver/os/connection.c
Normal file
1229
nx-X11/programs/Xserver/os/connection.c
Normal file
File diff suppressed because it is too large
Load Diff
1263
nx-X11/programs/Xserver/os/io.c
Normal file
1263
nx-X11/programs/Xserver/os/io.c
Normal file
File diff suppressed because it is too large
Load Diff
769
nx-X11/programs/Xserver/os/log.c
Normal file
769
nx-X11/programs/Xserver/os/log.c
Normal file
@@ -0,0 +1,769 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
|
||||
/* Copyright (c) 2008-2017 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
|
||||
/* Copyright (c) 2011-2022 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
|
||||
/* Copyright (c) 2014-2019 Mihai Moldovan <ionic@ionic.de> */
|
||||
/* Copyright (c) 2014-2022 Ulrich Sibiller <uli42@gmx.de> */
|
||||
/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
|
||||
/* */
|
||||
/* nx-X11, NX protocol compression and NX extensions to this software */
|
||||
/* are copyright of the aforementioned persons and companies. */
|
||||
/* */
|
||||
/* Redistribution and use of the present software is allowed according */
|
||||
/* to terms specified in the file LICENSE which comes in the source */
|
||||
/* distribution. */
|
||||
/* */
|
||||
/* All rights reserved. */
|
||||
/* */
|
||||
/* NOTE: This software has received contributions from various other */
|
||||
/* contributors, only the core maintainers and supporters are listed as */
|
||||
/* copyright holders. Please contact us, if you feel you should be listed */
|
||||
/* as copyright holder, as well. */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
/*
|
||||
|
||||
Copyright 1987, 1998 The Open Group
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this software and its
|
||||
documentation for any purpose is hereby granted without fee, provided that
|
||||
the above copyright notice appear in all copies and that both that
|
||||
copyright notice and this permission notice appear in supporting
|
||||
documentation.
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
Except as contained in this notice, the name of The Open Group shall
|
||||
not be used in advertising or otherwise to promote the sale, use or
|
||||
other dealings in this Software without prior written authorization
|
||||
from The Open Group.
|
||||
|
||||
|
||||
Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts,
|
||||
Copyright 1994 Quarterdeck Office Systems.
|
||||
|
||||
All Rights Reserved
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for any purpose and without fee is hereby granted,
|
||||
provided that the above copyright notice appear in all copies and that
|
||||
both that copyright notice and this permission notice appear in
|
||||
supporting documentation, and that the names of Digital and
|
||||
Quarterdeck not be used in advertising or publicity pertaining to
|
||||
distribution of the software without specific, written prior
|
||||
permission.
|
||||
|
||||
DIGITAL AND QUARTERDECK DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
|
||||
SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
FITNESS, IN NO EVENT SHALL DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT
|
||||
OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
|
||||
OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
|
||||
OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE
|
||||
OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 1997-2003 by The XFree86 Project, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the copyright holder(s)
|
||||
* and author(s) shall not be used in advertising or otherwise to promote
|
||||
* the sale, use or other dealings in this Software without prior written
|
||||
* authorization from the copyright holder(s) and author(s).
|
||||
*/
|
||||
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#include <nx-X11/Xos.h>
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
#include <sys/stat.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h> /* for malloc() */
|
||||
#include <errno.h>
|
||||
|
||||
#include "input.h"
|
||||
#include "site.h"
|
||||
#include "opaque.h"
|
||||
|
||||
|
||||
#ifdef NX_TRANS_SOCKET
|
||||
|
||||
#include <nx/NX.h>
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef DDXOSVERRORF
|
||||
void (*OsVendorVErrorFProc)(const char *, va_list args) = NULL;
|
||||
#ifdef NX_TRANS_EXIT
|
||||
int OsVendorVErrorFFatal = 0;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
static FILE *logFile = NULL;
|
||||
static Bool logFlush = FALSE;
|
||||
static Bool logSync = FALSE;
|
||||
static int logVerbosity = DEFAULT_LOG_VERBOSITY;
|
||||
static int logFileVerbosity = DEFAULT_LOG_FILE_VERBOSITY;
|
||||
|
||||
/* Buffer to information logged before the log file is opened. */
|
||||
static char *saveBuffer = NULL;
|
||||
static int bufferSize = 0, bufferUnused = 0, bufferPos = 0;
|
||||
static Bool needBuffer = TRUE;
|
||||
|
||||
/* Prefix strings for log messages. */
|
||||
#ifndef X_UNKNOWN_STRING
|
||||
#define X_UNKNOWN_STRING "(\?\?)"
|
||||
#endif
|
||||
#ifndef X_PROBE_STRING
|
||||
#define X_PROBE_STRING "(--)"
|
||||
#endif
|
||||
#ifndef X_CONFIG_STRING
|
||||
#define X_CONFIG_STRING "(**)"
|
||||
#endif
|
||||
#ifndef X_DEFAULT_STRING
|
||||
#define X_DEFAULT_STRING "(==)"
|
||||
#endif
|
||||
#ifndef X_CMDLINE_STRING
|
||||
#define X_CMDLINE_STRING "(++)"
|
||||
#endif
|
||||
#ifndef X_NOTICE_STRING
|
||||
#define X_NOTICE_STRING "(!!)"
|
||||
#endif
|
||||
#ifndef X_ERROR_STRING
|
||||
#define X_ERROR_STRING "(EE)"
|
||||
#endif
|
||||
#ifndef X_WARNING_STRING
|
||||
#define X_WARNING_STRING "(WW)"
|
||||
#endif
|
||||
#ifndef X_INFO_STRING
|
||||
#define X_INFO_STRING "(II)"
|
||||
#endif
|
||||
#ifndef X_NOT_IMPLEMENTED_STRING
|
||||
#define X_NOT_IMPLEMENTED_STRING "(NI)"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* LogFilePrep is called to setup files for logging, including getting
|
||||
* an old file out of the way, but it doesn't actually open the file,
|
||||
* since it may be used for renaming a file we're already logging to.
|
||||
*/
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wformat-nonliteral"
|
||||
|
||||
static char *
|
||||
LogFilePrep(const char *fname, const char *backup, const char *idstring)
|
||||
{
|
||||
char *logFileName = NULL;
|
||||
|
||||
if (asprintf(&logFileName, fname, idstring) == -1)
|
||||
FatalError("Cannot allocate space for the log file name\n");
|
||||
|
||||
if (backup && *backup) {
|
||||
struct stat buf;
|
||||
|
||||
if (!stat(logFileName, &buf) && S_ISREG(buf.st_mode)) {
|
||||
char *suffix;
|
||||
char *oldLog;
|
||||
|
||||
if ((asprintf(&suffix, backup, idstring) == -1) ||
|
||||
(asprintf(&oldLog, "%s%s", logFileName, suffix) == -1)) {
|
||||
FatalError("Cannot allocate space for the log file name\n");
|
||||
}
|
||||
free(suffix);
|
||||
|
||||
if (rename(logFileName, oldLog) == -1) {
|
||||
FatalError("Cannot move old log file \"%s\" to \"%s\"\n",
|
||||
logFileName, oldLog);
|
||||
}
|
||||
free(oldLog);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (remove(logFileName) != 0) {
|
||||
FatalError("Cannot remove old log file \"%s\": %s\n",
|
||||
logFileName, strerror(errno));
|
||||
}
|
||||
}
|
||||
|
||||
return logFileName;
|
||||
}
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
/*
|
||||
* LogInit is called to start logging to a file. It is also called (with
|
||||
* NULL arguments) when logging to a file is not wanted. It must always be
|
||||
* called, otherwise log messages will continue to accumulate in a buffer.
|
||||
*
|
||||
* %s, if present in the fname or backup strings, is expanded to the display
|
||||
* string (or to a string containing the pid if the display is not yet set).
|
||||
*/
|
||||
|
||||
static char *saved_log_fname;
|
||||
static char *saved_log_backup;
|
||||
static char *saved_log_tempname;
|
||||
|
||||
const char *
|
||||
LogInit(const char *fname, const char *backup)
|
||||
{
|
||||
char *logFileName = NULL;
|
||||
|
||||
if (fname && *fname) {
|
||||
if (displayfd != -1) {
|
||||
/* Display isn't set yet, so we can't use it in filenames yet. */
|
||||
char pidstring[32];
|
||||
snprintf(pidstring, sizeof(pidstring), "pid-%ld",
|
||||
(unsigned long) getpid());
|
||||
logFileName = LogFilePrep(fname, backup, pidstring);
|
||||
saved_log_tempname = logFileName;
|
||||
|
||||
/* Save the patterns for use when the display is named. */
|
||||
saved_log_fname = strdup(fname);
|
||||
if (backup == NULL)
|
||||
saved_log_backup = NULL;
|
||||
else
|
||||
saved_log_backup = strdup(backup);
|
||||
} else
|
||||
logFileName = LogFilePrep(fname, backup, display);
|
||||
if ((logFile = fopen(logFileName, "w")) == NULL)
|
||||
FatalError("Cannot open log file \"%s\"\n", logFileName);
|
||||
setvbuf(logFile, NULL, _IONBF, 0);
|
||||
|
||||
/* Flush saved log information. */
|
||||
if (saveBuffer && bufferSize > 0) {
|
||||
fwrite(saveBuffer, bufferPos, 1, logFile);
|
||||
fflush(logFile);
|
||||
fsync(fileno(logFile));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Unconditionally free the buffer, and flag that the buffer is no longer
|
||||
* needed.
|
||||
*/
|
||||
if (saveBuffer && bufferSize > 0) {
|
||||
free(saveBuffer); /* Must be free(), not free() */
|
||||
saveBuffer = NULL;
|
||||
bufferSize = 0;
|
||||
}
|
||||
needBuffer = FALSE;
|
||||
|
||||
return logFileName;
|
||||
}
|
||||
|
||||
void
|
||||
LogSetDisplay(void)
|
||||
{
|
||||
if (saved_log_fname) {
|
||||
char *logFileName;
|
||||
|
||||
logFileName = LogFilePrep(saved_log_fname, saved_log_backup, display);
|
||||
|
||||
if (rename(saved_log_tempname, logFileName) == 0) {
|
||||
LogMessageVerb(X_PROBED, 0,
|
||||
"Log file renamed from \"%s\" to \"%s\"\n",
|
||||
saved_log_tempname, logFileName);
|
||||
|
||||
if (strlen(saved_log_tempname) >= strlen(logFileName))
|
||||
strncpy(saved_log_tempname, logFileName,
|
||||
strlen(saved_log_tempname));
|
||||
}
|
||||
else {
|
||||
ErrorF("Failed to rename log file \"%s\" to \"%s\": %s\n",
|
||||
saved_log_tempname, logFileName, strerror(errno));
|
||||
}
|
||||
|
||||
/* free newly allocated string - can't free old one since existing
|
||||
pointers to it may exist in DDX callers. */
|
||||
free(logFileName);
|
||||
free(saved_log_fname);
|
||||
free(saved_log_backup);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
LogClose()
|
||||
{
|
||||
if (logFile) {
|
||||
fclose(logFile);
|
||||
logFile = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
Bool
|
||||
LogSetParameter(LogParameter param, int value)
|
||||
{
|
||||
switch (param) {
|
||||
case XLOG_FLUSH:
|
||||
logFlush = value ? TRUE : FALSE;
|
||||
return TRUE;
|
||||
case XLOG_SYNC:
|
||||
logSync = value ? TRUE : FALSE;
|
||||
return TRUE;
|
||||
case XLOG_VERBOSITY:
|
||||
logVerbosity = value;
|
||||
return TRUE;
|
||||
case XLOG_FILE_VERBOSITY:
|
||||
logFileVerbosity = value;
|
||||
return TRUE;
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/* This function does the actual log message writes. */
|
||||
|
||||
void
|
||||
LogVWrite(int verb, const char *f, va_list args)
|
||||
{
|
||||
static char tmpBuffer[1024];
|
||||
int len = 0;
|
||||
|
||||
/*
|
||||
* Since a va_list can only be processed once, write the string to a
|
||||
* buffer, and then write the buffer out to the appropriate output
|
||||
* stream(s).
|
||||
*/
|
||||
if (verb < 0 || logFileVerbosity >= verb || logVerbosity >= verb) {
|
||||
vsnprintf(tmpBuffer, sizeof(tmpBuffer), f, args);
|
||||
#ifdef NX_TRANS_EXIT
|
||||
/*
|
||||
* Beautify the message. Make the
|
||||
* first letter uppercase.
|
||||
*/
|
||||
|
||||
*tmpBuffer = toupper(*tmpBuffer);
|
||||
|
||||
/*
|
||||
* Remove the trailing newline.
|
||||
*/
|
||||
|
||||
if (strlen(tmpBuffer) > 0 &&
|
||||
*(tmpBuffer + strlen(tmpBuffer) - 1) == '\n') {
|
||||
*(tmpBuffer + strlen(tmpBuffer) - 1) = '\0';
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove the trailing full-stop.
|
||||
*/
|
||||
|
||||
if (strlen(tmpBuffer) > 0 &&
|
||||
*(tmpBuffer + strlen(tmpBuffer) - 1) == '.') {
|
||||
*(tmpBuffer + strlen(tmpBuffer) - 1) = '\0';
|
||||
}
|
||||
#endif /* #ifdef NX_TRANS_EXIT */
|
||||
len = strlen(tmpBuffer);
|
||||
}
|
||||
if ((verb < 0 || logVerbosity >= verb) && len > 0)
|
||||
fwrite(tmpBuffer, len, 1, stderr);
|
||||
if ((verb < 0 || logFileVerbosity >= verb) && len > 0) {
|
||||
if (logFile) {
|
||||
fwrite(tmpBuffer, len, 1, logFile);
|
||||
if (logFlush) {
|
||||
fflush(logFile);
|
||||
if (logSync)
|
||||
fsync(fileno(logFile));
|
||||
}
|
||||
} else if (needBuffer) {
|
||||
/*
|
||||
* Note, this code is used before OsInit() has been called, so
|
||||
* malloc() and friends can't be used.
|
||||
*/
|
||||
if (len > bufferUnused) {
|
||||
bufferSize += 1024;
|
||||
bufferUnused += 1024;
|
||||
if (saveBuffer)
|
||||
saveBuffer = realloc(saveBuffer, bufferSize);
|
||||
else
|
||||
saveBuffer = malloc(bufferSize);
|
||||
if (!saveBuffer)
|
||||
FatalError("realloc() failed while saving log messages\n");
|
||||
}
|
||||
bufferUnused -= len;
|
||||
memcpy(saveBuffer + bufferPos, tmpBuffer, len);
|
||||
bufferPos += len;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
LogWrite(int verb, const char *f, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
va_start(args, f);
|
||||
LogVWrite(verb, f, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
void
|
||||
LogVMessageVerb(MessageType type, int verb, const char *format, va_list args)
|
||||
{
|
||||
const char *s = X_UNKNOWN_STRING;
|
||||
char *tmpBuf = NULL;
|
||||
|
||||
/* Ignore verbosity for X_ERROR */
|
||||
if (logVerbosity >= verb || logFileVerbosity >= verb || type == X_ERROR) {
|
||||
switch (type) {
|
||||
case X_PROBED:
|
||||
s = X_PROBE_STRING;
|
||||
break;
|
||||
case X_CONFIG:
|
||||
s = X_CONFIG_STRING;
|
||||
break;
|
||||
case X_DEFAULT:
|
||||
s = X_DEFAULT_STRING;
|
||||
break;
|
||||
case X_CMDLINE:
|
||||
s = X_CMDLINE_STRING;
|
||||
break;
|
||||
case X_NOTICE:
|
||||
s = X_NOTICE_STRING;
|
||||
break;
|
||||
case X_ERROR:
|
||||
s = X_ERROR_STRING;
|
||||
if (verb > 0)
|
||||
verb = 0;
|
||||
break;
|
||||
case X_WARNING:
|
||||
s = X_WARNING_STRING;
|
||||
break;
|
||||
case X_INFO:
|
||||
s = X_INFO_STRING;
|
||||
break;
|
||||
case X_NOT_IMPLEMENTED:
|
||||
s = X_NOT_IMPLEMENTED_STRING;
|
||||
break;
|
||||
case X_UNKNOWN:
|
||||
s = X_UNKNOWN_STRING;
|
||||
break;
|
||||
case X_NONE:
|
||||
s = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Prefix the format string with the message type. We do it this way
|
||||
* so that LogVWrite() is only called once per message.
|
||||
*/
|
||||
if (s) {
|
||||
tmpBuf = malloc(strlen(format) + strlen(s) + 1 + 1);
|
||||
/* Silently return if malloc fails here. */
|
||||
if (!tmpBuf)
|
||||
return;
|
||||
sprintf(tmpBuf, "%s ", s);
|
||||
strcat(tmpBuf, format);
|
||||
LogVWrite(verb, tmpBuf, args);
|
||||
free(tmpBuf);
|
||||
} else
|
||||
LogVWrite(verb, format, args);
|
||||
}
|
||||
}
|
||||
|
||||
/* Log message with verbosity level specified. */
|
||||
void
|
||||
LogMessageVerb(MessageType type, int verb, const char *format, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, format);
|
||||
LogVMessageVerb(type, verb, format, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
/* Log a message with the standard verbosity level of 1. */
|
||||
void
|
||||
LogMessage(MessageType type, const char *format, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, format);
|
||||
LogVMessageVerb(type, 1, format, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
#ifdef __GNUC__
|
||||
void AbortServer(void) __attribute__((noreturn));
|
||||
#endif
|
||||
|
||||
void
|
||||
AbortServer(void)
|
||||
{
|
||||
#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_TEST)
|
||||
fprintf(stderr, "AbortServer: Going to abort the current server.\n");
|
||||
#endif
|
||||
OsCleanup(TRUE);
|
||||
AbortDDX();
|
||||
fflush(stderr);
|
||||
if (CoreDump)
|
||||
abort();
|
||||
#ifdef NX_TRANS_EXIT
|
||||
#ifdef NX_TRANS_TEST
|
||||
fprintf(stderr, "AbortServer: Going to clean up NX resources and exit.\n");
|
||||
#endif
|
||||
NXTransExit(1);
|
||||
#else /* #ifdef NX_TRANS_EXIT */
|
||||
exit (1);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef AUDIT_PREFIX
|
||||
#define AUDIT_PREFIX "AUDIT: %s: %ld %s: "
|
||||
#endif
|
||||
#ifndef AUDIT_TIMEOUT
|
||||
#define AUDIT_TIMEOUT ((CARD32)(120 * 1000)) /* 2 mn */
|
||||
#endif
|
||||
|
||||
static int nrepeat = 0;
|
||||
static int oldlen = -1;
|
||||
static OsTimerPtr auditTimer = NULL;
|
||||
|
||||
void
|
||||
FreeAuditTimer(void)
|
||||
{
|
||||
if (auditTimer != NULL) {
|
||||
/* Force output of pending messages */
|
||||
TimerForce(auditTimer);
|
||||
TimerFree(auditTimer);
|
||||
auditTimer = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static char *
|
||||
AuditPrefix(void)
|
||||
{
|
||||
time_t tm;
|
||||
char *autime, *s;
|
||||
char *tmpBuf;
|
||||
int len;
|
||||
|
||||
time(&tm);
|
||||
autime = ctime(&tm);
|
||||
if ((s = strchr(autime, '\n')))
|
||||
*s = '\0';
|
||||
if ((s = strrchr(argvGlobal[0], '/')))
|
||||
s++;
|
||||
else
|
||||
s = argvGlobal[0];
|
||||
len = strlen(AUDIT_PREFIX) + strlen(autime) + 10 + strlen(s) + 1;
|
||||
tmpBuf = malloc(len);
|
||||
if (!tmpBuf)
|
||||
return NULL;
|
||||
snprintf(tmpBuf, len, AUDIT_PREFIX, autime, (unsigned long)getpid(), s);
|
||||
return tmpBuf;
|
||||
}
|
||||
|
||||
void
|
||||
AuditF(const char * f, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
va_start(args, f);
|
||||
|
||||
VAuditF(f, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
static CARD32
|
||||
AuditFlush(OsTimerPtr timer, CARD32 now, void * arg)
|
||||
{
|
||||
char *prefix;
|
||||
|
||||
if (nrepeat > 0) {
|
||||
prefix = AuditPrefix();
|
||||
ErrorF("%slast message repeated %d times\n",
|
||||
prefix != NULL ? prefix : "", nrepeat);
|
||||
nrepeat = 0;
|
||||
if (prefix != NULL)
|
||||
free(prefix);
|
||||
return AUDIT_TIMEOUT;
|
||||
} else {
|
||||
/* if the timer expires without anything to print, flush the message */
|
||||
oldlen = -1;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
VAuditF(const char *f, va_list args)
|
||||
{
|
||||
char *prefix;
|
||||
char buf[1024];
|
||||
int len;
|
||||
static char oldbuf[1024];
|
||||
|
||||
prefix = AuditPrefix();
|
||||
len = vsnprintf(buf, sizeof(buf), f, args);
|
||||
|
||||
if (len == oldlen && strcmp(buf, oldbuf) == 0) {
|
||||
/* Message already seen */
|
||||
nrepeat++;
|
||||
} else {
|
||||
/* new message */
|
||||
if (auditTimer != NULL)
|
||||
TimerForce(auditTimer);
|
||||
ErrorF("%s%s", prefix != NULL ? prefix : "", buf);
|
||||
strlcpy(oldbuf, buf, sizeof(oldbuf));
|
||||
oldlen = len;
|
||||
nrepeat = 0;
|
||||
auditTimer = TimerSet(auditTimer, 0, AUDIT_TIMEOUT, AuditFlush, NULL);
|
||||
}
|
||||
if (prefix != NULL)
|
||||
free(prefix);
|
||||
}
|
||||
|
||||
void
|
||||
FatalError(const char *f, ...)
|
||||
{
|
||||
va_list args;
|
||||
static Bool beenhere = FALSE;
|
||||
|
||||
#ifdef NX_TRANS_EXIT
|
||||
if (beenhere) {
|
||||
fprintf(stderr, "Error: Aborting session with fatal error function reentered.\n");
|
||||
}
|
||||
else {
|
||||
/*
|
||||
* Tell to the log function that this
|
||||
* is a fatal error.
|
||||
*/
|
||||
|
||||
OsVendorVErrorFFatal = 1;
|
||||
|
||||
fprintf(stderr, "Error: Aborting session with '");
|
||||
|
||||
va_start(args, f);
|
||||
VErrorF(f, args);
|
||||
va_end(args);
|
||||
|
||||
fprintf(stderr, "'.\n");
|
||||
}
|
||||
#else /* #ifdef NX_TRANS_EXIT */
|
||||
if (beenhere)
|
||||
ErrorF("\nFatalError re-entered, aborting\n");
|
||||
else
|
||||
ErrorF("\nFatal server error:\n");
|
||||
|
||||
va_start(args, f);
|
||||
VErrorF(f, args);
|
||||
va_end(args);
|
||||
ErrorF("\n");
|
||||
#endif /* #ifdef NX_TRANS_EXIT */
|
||||
#ifdef DDXOSFATALERROR
|
||||
if (!beenhere)
|
||||
OsVendorFatalError();
|
||||
#endif
|
||||
#ifdef ABORTONFATALERROR
|
||||
abort();
|
||||
#endif
|
||||
if (!beenhere) {
|
||||
beenhere = TRUE;
|
||||
AbortServer();
|
||||
} else
|
||||
abort();
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
|
||||
void
|
||||
VErrorF(const char *f, va_list args)
|
||||
{
|
||||
#ifdef DDXOSVERRORF
|
||||
if (OsVendorVErrorFProc)
|
||||
OsVendorVErrorFProc(f, args);
|
||||
else
|
||||
LogVWrite(-1, f, args);
|
||||
#else
|
||||
LogVWrite(-1, f, args);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
ErrorF(const char * f, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
va_start(args, f);
|
||||
VErrorF(f, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
/* A perror() workalike. */
|
||||
|
||||
#ifndef NEED_STRERROR
|
||||
#ifdef SYSV
|
||||
#define NEED_STRERROR
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(NEED_STRERROR) && !defined(strerror)
|
||||
extern char *sys_errlist[];
|
||||
extern int sys_nerr;
|
||||
#define strerror(n) \
|
||||
((n) >= 0 && (n) < sys_nerr) ? sys_errlist[(n)] : "unknown error"
|
||||
#endif
|
||||
|
||||
void
|
||||
Error(char *str)
|
||||
{
|
||||
char *err = NULL;
|
||||
int saveErrno = errno;
|
||||
|
||||
if (str) {
|
||||
err = malloc(strlen(strerror(saveErrno)) + strlen(str) + 2 + 1);
|
||||
if (!err)
|
||||
return;
|
||||
sprintf(err, "%s: ", str);
|
||||
strcat(err, strerror(saveErrno));
|
||||
LogWrite(-1, "%s", err);
|
||||
} else
|
||||
LogWrite(-1, "%s", strerror(saveErrno));
|
||||
}
|
||||
|
||||
void
|
||||
LogPrintMarkers()
|
||||
{
|
||||
/* Show what the message marker symbols mean. */
|
||||
ErrorF("Markers: ");
|
||||
LogMessageVerb(X_PROBED, -1, "probed, ");
|
||||
LogMessageVerb(X_CONFIG, -1, "from config file, ");
|
||||
LogMessageVerb(X_DEFAULT, -1, "default setting,\n\t");
|
||||
LogMessageVerb(X_CMDLINE, -1, "from command line, ");
|
||||
LogMessageVerb(X_NOTICE, -1, "notice, ");
|
||||
LogMessageVerb(X_INFO, -1, "informational,\n\t");
|
||||
LogMessageVerb(X_WARNING, -1, "warning, ");
|
||||
LogMessageVerb(X_ERROR, -1, "error, ");
|
||||
LogMessageVerb(X_NOT_IMPLEMENTED, -1, "not implemented, ");
|
||||
LogMessageVerb(X_UNKNOWN, -1, "unknown.\n");
|
||||
}
|
||||
|
||||
197
nx-X11/programs/Xserver/os/mitauth.c
Normal file
197
nx-X11/programs/Xserver/os/mitauth.c
Normal file
@@ -0,0 +1,197 @@
|
||||
/*
|
||||
|
||||
Copyright 1988, 1998 The Open Group
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this software and its
|
||||
documentation for any purpose is hereby granted without fee, provided that
|
||||
the above copyright notice appear in all copies and that both that
|
||||
copyright notice and this permission notice appear in supporting
|
||||
documentation.
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
Except as contained in this notice, the name of The Open Group shall
|
||||
not be used in advertising or otherwise to promote the sale, use or
|
||||
other dealings in this Software without prior written authorization
|
||||
from The Open Group.
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
* MIT-MAGIC-COOKIE-1 authorization scheme
|
||||
* Author: Keith Packard, MIT X Consortium
|
||||
*/
|
||||
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#include <nx-X11/X.h>
|
||||
#include "os.h"
|
||||
#include "osdep.h"
|
||||
#include "dixstruct.h"
|
||||
|
||||
static struct auth {
|
||||
struct auth *next;
|
||||
unsigned short len;
|
||||
char *data;
|
||||
XID id;
|
||||
} *mit_auth;
|
||||
|
||||
int
|
||||
MitAddCookie (
|
||||
unsigned short data_length,
|
||||
char *data,
|
||||
XID id)
|
||||
{
|
||||
struct auth *new;
|
||||
|
||||
new = (struct auth *) malloc (sizeof (struct auth));
|
||||
if (!new)
|
||||
return 0;
|
||||
new->data = (char *) malloc ((unsigned) data_length);
|
||||
if (!new->data) {
|
||||
free(new);
|
||||
return 0;
|
||||
}
|
||||
new->next = mit_auth;
|
||||
mit_auth = new;
|
||||
memmove(new->data, data, (int) data_length);
|
||||
new->len = data_length;
|
||||
new->id = id;
|
||||
return 1;
|
||||
}
|
||||
|
||||
XID
|
||||
MitCheckCookie (
|
||||
unsigned short data_length,
|
||||
char *data,
|
||||
ClientPtr client,
|
||||
char **reason)
|
||||
{
|
||||
struct auth *auth;
|
||||
|
||||
for (auth = mit_auth; auth; auth=auth->next) {
|
||||
if (data_length == auth->len &&
|
||||
timingsafe_memcmp (data, auth->data, (int) data_length) == 0)
|
||||
return auth->id;
|
||||
}
|
||||
*reason = "Invalid MIT-MAGIC-COOKIE-1 key";
|
||||
return (XID) -1;
|
||||
}
|
||||
|
||||
int
|
||||
MitResetCookie (void)
|
||||
{
|
||||
struct auth *auth, *next;
|
||||
|
||||
for (auth = mit_auth; auth; auth=next) {
|
||||
next = auth->next;
|
||||
free (auth->data);
|
||||
free (auth);
|
||||
}
|
||||
mit_auth = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
XID
|
||||
MitToID (
|
||||
unsigned short data_length,
|
||||
char *data)
|
||||
{
|
||||
struct auth *auth;
|
||||
|
||||
for (auth = mit_auth; auth; auth=auth->next) {
|
||||
if (data_length == auth->len &&
|
||||
memcmp (data, auth->data, data_length) == 0)
|
||||
return auth->id;
|
||||
}
|
||||
return (XID) -1;
|
||||
}
|
||||
|
||||
int
|
||||
MitFromID (
|
||||
XID id,
|
||||
unsigned short *data_lenp,
|
||||
char **datap)
|
||||
{
|
||||
struct auth *auth;
|
||||
|
||||
for (auth = mit_auth; auth; auth=auth->next) {
|
||||
if (id == auth->id) {
|
||||
*data_lenp = auth->len;
|
||||
*datap = auth->data;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
MitRemoveCookie (
|
||||
unsigned short data_length,
|
||||
char *data)
|
||||
{
|
||||
struct auth *auth, *prev;
|
||||
|
||||
prev = 0;
|
||||
for (auth = mit_auth; auth; prev = auth, auth=auth->next) {
|
||||
if (data_length == auth->len &&
|
||||
memcmp (data, auth->data, data_length) == 0)
|
||||
{
|
||||
if (prev)
|
||||
prev->next = auth->next;
|
||||
else
|
||||
mit_auth = auth->next;
|
||||
free (auth->data);
|
||||
free (auth);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef XCSECURITY
|
||||
|
||||
static char cookie[16]; /* 128 bits */
|
||||
|
||||
XID
|
||||
MitGenerateCookie (
|
||||
unsigned data_length,
|
||||
char *data,
|
||||
XID id,
|
||||
unsigned *data_length_return,
|
||||
char **data_return)
|
||||
{
|
||||
int i = 0;
|
||||
int status;
|
||||
|
||||
while (data_length--)
|
||||
{
|
||||
cookie[i++] += *data++;
|
||||
if (i >= sizeof (cookie)) i = 0;
|
||||
}
|
||||
GenerateRandomData(sizeof (cookie), cookie);
|
||||
status = MitAddCookie(sizeof (cookie), cookie, id);
|
||||
if (!status)
|
||||
{
|
||||
id = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
*data_return = cookie;
|
||||
*data_length_return = sizeof (cookie);
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
#endif /* XCSECURITY */
|
||||
1661
nx-X11/programs/Xserver/os/oscolor.c
Normal file
1661
nx-X11/programs/Xserver/os/oscolor.c
Normal file
File diff suppressed because it is too large
Load Diff
297
nx-X11/programs/Xserver/os/osdep.h
Normal file
297
nx-X11/programs/Xserver/os/osdep.h
Normal file
@@ -0,0 +1,297 @@
|
||||
/***********************************************************
|
||||
|
||||
Copyright 1987, 1998 The Open Group
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this software and its
|
||||
documentation for any purpose is hereby granted without fee, provided that
|
||||
the above copyright notice appear in all copies and that both that
|
||||
copyright notice and this permission notice appear in supporting
|
||||
documentation.
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
Except as contained in this notice, the name of The Open Group shall not be
|
||||
used in advertising or otherwise to promote the sale, use or other dealings
|
||||
in this Software without prior written authorization from The Open Group.
|
||||
|
||||
|
||||
Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
|
||||
|
||||
All Rights Reserved
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for any purpose and without fee is hereby granted,
|
||||
provided that the above copyright notice appear in all copies and that
|
||||
both that copyright notice and this permission notice appear in
|
||||
supporting documentation, and that the name of Digital not be
|
||||
used in advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||||
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
|
||||
DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
||||
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
SOFTWARE.
|
||||
|
||||
******************************************************************/
|
||||
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#ifndef _OSDEP_H_
|
||||
#define _OSDEP_H_ 1
|
||||
|
||||
#define BUFSIZE 4096
|
||||
#define BUFWATERMARK 8192
|
||||
#ifndef MAXBUFSIZE
|
||||
#define MAXBUFSIZE (1 << 22)
|
||||
#endif
|
||||
|
||||
#include <X11/Xdmcp.h>
|
||||
|
||||
#ifndef X_NOT_POSIX
|
||||
#ifdef _POSIX_SOURCE
|
||||
#include <limits.h>
|
||||
#else
|
||||
#define _POSIX_SOURCE
|
||||
#include <limits.h>
|
||||
#undef _POSIX_SOURCE
|
||||
#endif
|
||||
#else /* X_NOT_POSIX */
|
||||
#endif /* X_NOT_POSIX */
|
||||
|
||||
#ifndef OPEN_MAX
|
||||
#ifdef SVR4
|
||||
#define OPEN_MAX 256
|
||||
#else
|
||||
#include <sys/param.h>
|
||||
#ifndef OPEN_MAX
|
||||
#if defined(NOFILE) && !defined(NOFILES_MAX)
|
||||
#define OPEN_MAX NOFILE
|
||||
#else
|
||||
#define OPEN_MAX NOFILES_MAX
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <nx-X11/Xpoll.h>
|
||||
|
||||
/*
|
||||
* MAXSOCKS is used only for initialising MaxClients when no other method
|
||||
* like sysconf(_SC_OPEN_MAX) is not supported.
|
||||
*/
|
||||
|
||||
#if OPEN_MAX <= 256
|
||||
#define MAXSOCKS (OPEN_MAX - 1)
|
||||
#else
|
||||
#define MAXSOCKS 256
|
||||
#endif
|
||||
|
||||
/* MAXSELECT is the number of fds that select() can handle */
|
||||
#define MAXSELECT (sizeof(fd_set) * NBBY)
|
||||
|
||||
#ifndef HAS_GETDTABLESIZE
|
||||
#if !defined(SVR4) && !defined(SYSV)
|
||||
#define HAS_GETDTABLESIZE
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
typedef Bool (*ValidatorFunc)(ARRAY8Ptr Auth, ARRAY8Ptr Data, int packet_type);
|
||||
typedef Bool (*GeneratorFunc)(ARRAY8Ptr Auth, ARRAY8Ptr Data, int packet_type);
|
||||
typedef Bool (*AddAuthorFunc)(unsigned name_length, char *name, unsigned data_length, char *data);
|
||||
|
||||
typedef struct _connectionInput {
|
||||
struct _connectionInput *next;
|
||||
char *buffer; /* contains current client input */
|
||||
char *bufptr; /* pointer to current start of data */
|
||||
int bufcnt; /* count of bytes in buffer */
|
||||
int lenLastReq;
|
||||
int size;
|
||||
unsigned int ignoreBytes; /* bytes to ignore before the next request */
|
||||
} ConnectionInput, *ConnectionInputPtr;
|
||||
|
||||
typedef struct _connectionOutput {
|
||||
struct _connectionOutput *next;
|
||||
int size;
|
||||
unsigned char *buf;
|
||||
int count;
|
||||
} ConnectionOutput, *ConnectionOutputPtr;
|
||||
|
||||
struct _osComm;
|
||||
|
||||
#define AuthInitArgs void
|
||||
typedef void (*AuthInitFunc) (AuthInitArgs);
|
||||
|
||||
#define AuthAddCArgs unsigned short data_length, char *data, XID id
|
||||
typedef int (*AuthAddCFunc) (AuthAddCArgs);
|
||||
|
||||
#define AuthCheckArgs unsigned short data_length, char *data, ClientPtr client, char **reason
|
||||
typedef XID (*AuthCheckFunc) (AuthCheckArgs);
|
||||
|
||||
#define AuthFromIDArgs XID id, unsigned short *data_lenp, char **datap
|
||||
typedef int (*AuthFromIDFunc) (AuthFromIDArgs);
|
||||
|
||||
#define AuthGenCArgs unsigned data_length, char *data, XID id, unsigned *data_length_return, char **data_return
|
||||
typedef XID (*AuthGenCFunc) (AuthGenCArgs);
|
||||
|
||||
#define AuthRemCArgs unsigned short data_length, char *data
|
||||
typedef int (*AuthRemCFunc) (AuthRemCArgs);
|
||||
|
||||
#define AuthRstCArgs void
|
||||
typedef int (*AuthRstCFunc) (AuthRstCArgs);
|
||||
|
||||
#define AuthToIDArgs unsigned short data_length, char *data
|
||||
typedef XID (*AuthToIDFunc) (AuthToIDArgs);
|
||||
|
||||
typedef void (*OsCloseFunc)(ClientPtr);
|
||||
|
||||
typedef int (*OsFlushFunc)(ClientPtr who, struct _osComm * oc, char* extraBuf, int extraCount);
|
||||
|
||||
typedef struct _osComm {
|
||||
int fd;
|
||||
ConnectionInputPtr input;
|
||||
ConnectionOutputPtr output;
|
||||
XID auth_id; /* authorization id */
|
||||
CARD32 conn_time; /* timestamp if not established, else 0 */
|
||||
struct _XtransConnInfo *trans_conn; /* transport connection object */
|
||||
} OsCommRec, *OsCommPtr;
|
||||
|
||||
extern int FlushClient(
|
||||
ClientPtr /*who*/,
|
||||
OsCommPtr /*oc*/,
|
||||
const void * /*__extraBuf*/,
|
||||
int /*extraCount*/
|
||||
);
|
||||
|
||||
extern void FreeOsBuffers(
|
||||
OsCommPtr /*oc*/
|
||||
);
|
||||
|
||||
extern void InitNotifyFds(void);
|
||||
|
||||
extern void HandleNotifyFds(void);
|
||||
|
||||
#include "dix.h"
|
||||
|
||||
extern ConnectionInputPtr AllocateInputBuffer(void);
|
||||
|
||||
extern ConnectionOutputPtr AllocateOutputBuffer(void);
|
||||
|
||||
extern fd_set AllSockets;
|
||||
extern fd_set AllClients;
|
||||
extern fd_set LastSelectMask;
|
||||
extern fd_set LastSelectWriteMask;
|
||||
extern fd_set WellKnownConnections;
|
||||
extern fd_set EnabledDevices;
|
||||
extern fd_set NotifyReadFds;
|
||||
extern fd_set NotifyWriteFds;
|
||||
extern fd_set ClientsWithInput;
|
||||
extern fd_set ClientsWriteBlocked;
|
||||
extern fd_set OutputPending;
|
||||
extern fd_set IgnoredClientsWithInput;
|
||||
|
||||
extern int *ConnectionTranslation;
|
||||
|
||||
extern Bool NewOutputPending;
|
||||
extern Bool AnyWritesPending;
|
||||
extern Bool NumNotifyWriteFd;
|
||||
extern Bool CriticalOutputPending;
|
||||
|
||||
extern int timesThisConnection;
|
||||
extern ConnectionInputPtr FreeInputs;
|
||||
extern ConnectionOutputPtr FreeOutputs;
|
||||
extern OsCommPtr AvailableInput;
|
||||
|
||||
extern WorkQueuePtr workQueue;
|
||||
|
||||
/* in WaitFor.c */
|
||||
#define ffs mffs
|
||||
extern int mffs(fd_mask);
|
||||
|
||||
/* in access.c */
|
||||
extern Bool ComputeLocalClient(ClientPtr client);
|
||||
|
||||
/* in auth.c */
|
||||
extern void GenerateRandomData (int len, char *buf);
|
||||
|
||||
/* in mitauth.c */
|
||||
extern XID MitCheckCookie (AuthCheckArgs);
|
||||
extern XID MitGenerateCookie (AuthGenCArgs);
|
||||
extern XID MitToID (AuthToIDArgs);
|
||||
extern int MitAddCookie (AuthAddCArgs);
|
||||
extern int MitFromID (AuthFromIDArgs);
|
||||
extern int MitRemoveCookie (AuthRemCArgs);
|
||||
extern int MitResetCookie (AuthRstCArgs);
|
||||
|
||||
/* in xdmauth.c */
|
||||
#ifdef HASXDMAUTH
|
||||
extern XID XdmCheckCookie (AuthCheckArgs);
|
||||
extern XID XdmToID (AuthToIDArgs);
|
||||
extern int XdmAddCookie (AuthAddCArgs);
|
||||
extern int XdmFromID (AuthFromIDArgs);
|
||||
extern int XdmRemoveCookie (AuthRemCArgs);
|
||||
extern int XdmResetCookie (AuthRstCArgs);
|
||||
#endif
|
||||
|
||||
/* in rpcauth.c */
|
||||
#ifdef SECURE_RPC
|
||||
extern void SecureRPCInit (AuthInitArgs);
|
||||
extern XID SecureRPCCheck (AuthCheckArgs);
|
||||
extern XID SecureRPCToID (AuthToIDArgs);
|
||||
extern int SecureRPCAdd (AuthAddCArgs);
|
||||
extern int SecureRPCFromID (AuthFromIDArgs);
|
||||
extern int SecureRPCRemove (AuthRemCArgs);
|
||||
extern int SecureRPCReset (AuthRstCArgs);
|
||||
#endif
|
||||
|
||||
/* in secauth.c */
|
||||
extern XID AuthSecurityCheck (AuthCheckArgs);
|
||||
|
||||
/* in xdmcp.c */
|
||||
extern void XdmcpUseMsg (void);
|
||||
extern int XdmcpOptions(int argc, char **argv, int i);
|
||||
extern void XdmcpSetAuthentication (ARRAY8Ptr name);
|
||||
extern void XdmcpRegisterConnection (
|
||||
int type,
|
||||
char *address,
|
||||
int addrlen);
|
||||
extern void XdmcpRegisterAuthorizations (void);
|
||||
extern void XdmcpRegisterAuthorization (char *name, int namelen);
|
||||
extern void XdmcpRegisterDisplayClass (char *name, int length);
|
||||
extern void XdmcpInit (void);
|
||||
extern void XdmcpReset (void);
|
||||
extern void XdmcpOpenDisplay(int sock);
|
||||
extern void XdmcpCloseDisplay(int sock);
|
||||
extern void XdmcpRegisterAuthentication (
|
||||
char *name,
|
||||
int namelen,
|
||||
char *data,
|
||||
int datalen,
|
||||
ValidatorFunc Validator,
|
||||
GeneratorFunc Generator,
|
||||
AddAuthorFunc AddAuth);
|
||||
extern int XdmcpCheckAuthentication (ARRAY8Ptr Name, ARRAY8Ptr Data, int packet_type);
|
||||
extern int XdmcpAddAuthorization (ARRAY8Ptr name, ARRAY8Ptr data);
|
||||
|
||||
struct sockaddr_in;
|
||||
extern void XdmcpRegisterBroadcastAddress (struct sockaddr_in *addr);
|
||||
|
||||
#ifdef HASXDMAUTH
|
||||
extern void XdmAuthenticationInit (char *cookie, int cookie_length);
|
||||
#endif
|
||||
|
||||
#endif /* _OSDEP_H_ */
|
||||
228
nx-X11/programs/Xserver/os/osinit.c
Normal file
228
nx-X11/programs/Xserver/os/osinit.c
Normal file
@@ -0,0 +1,228 @@
|
||||
/***********************************************************
|
||||
|
||||
Copyright 1987, 1998 The Open Group
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this software and its
|
||||
documentation for any purpose is hereby granted without fee, provided that
|
||||
the above copyright notice appear in all copies and that both that
|
||||
copyright notice and this permission notice appear in supporting
|
||||
documentation.
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
Except as contained in this notice, the name of The Open Group shall not be
|
||||
used in advertising or otherwise to promote the sale, use or other dealings
|
||||
in this Software without prior written authorization from The Open Group.
|
||||
|
||||
|
||||
Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
|
||||
|
||||
All Rights Reserved
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for any purpose and without fee is hereby granted,
|
||||
provided that the above copyright notice appear in all copies and that
|
||||
both that copyright notice and this permission notice appear in
|
||||
supporting documentation, and that the name of Digital not be
|
||||
used in advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||||
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
|
||||
DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
||||
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
SOFTWARE.
|
||||
|
||||
******************************************************************/
|
||||
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <nx-X11/X.h>
|
||||
#include "os.h"
|
||||
#include "osdep.h"
|
||||
#include <nx-X11/Xos.h>
|
||||
|
||||
#include "dixstruct.h"
|
||||
|
||||
#ifndef PATH_MAX
|
||||
#ifdef MAXPATHLEN
|
||||
#define PATH_MAX MAXPATHLEN
|
||||
#else
|
||||
#define PATH_MAX 1024
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
#if !defined(SYSV)
|
||||
#include <sys/resource.h>
|
||||
#endif
|
||||
|
||||
#ifndef ADMPATH
|
||||
#define ADMPATH "/usr/adm/X%smsgs"
|
||||
#endif
|
||||
|
||||
extern char *display;
|
||||
#ifdef RLIMIT_DATA
|
||||
int limitDataSpace = -1;
|
||||
#endif
|
||||
#ifdef RLIMIT_STACK
|
||||
int limitStackSpace = -1;
|
||||
#endif
|
||||
#ifdef RLIMIT_NOFILE
|
||||
int limitNoFile = -1;
|
||||
#endif
|
||||
|
||||
void
|
||||
OsInit(void)
|
||||
{
|
||||
static Bool been_here = FALSE;
|
||||
static char* admpath = ADMPATH;
|
||||
static char* devnull = "/dev/null";
|
||||
char fname[PATH_MAX];
|
||||
|
||||
#ifdef macII
|
||||
set42sig();
|
||||
#endif
|
||||
|
||||
if (!been_here) {
|
||||
|
||||
InitNotifyFds();
|
||||
|
||||
fclose(stdin);
|
||||
fclose(stdout);
|
||||
|
||||
/*
|
||||
* If a write of zero bytes to stderr returns non-zero, i.e. -1,
|
||||
* then writing to stderr failed, and we'll write somewhere else
|
||||
* instead. (Apparently this never happens in the Real World.)
|
||||
*/
|
||||
if (write (2, fname, 0) == -1)
|
||||
{
|
||||
FILE *err;
|
||||
|
||||
if (strlen (display) + strlen (admpath) + 1 < sizeof fname)
|
||||
sprintf (fname, admpath, display);
|
||||
else
|
||||
strcpy (fname, devnull);
|
||||
/*
|
||||
* uses stdio to avoid os dependencies here,
|
||||
* a real os would use
|
||||
* open (fname, O_WRONLY|O_APPEND|O_CREAT, 0666)
|
||||
*/
|
||||
if (!(err = fopen (fname, "a+")))
|
||||
err = fopen (devnull, "w");
|
||||
if (err && (fileno(err) != 2)) {
|
||||
dup2 (fileno (err), 2);
|
||||
fclose (err);
|
||||
}
|
||||
#if defined(SYSV) || defined(SVR4)
|
||||
{
|
||||
static char buf[BUFSIZ];
|
||||
setvbuf (stderr, buf, _IOLBF, BUFSIZ);
|
||||
}
|
||||
#else
|
||||
setlinebuf(stderr);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef X_NOT_POSIX
|
||||
if (getpgrp () == 0)
|
||||
setpgid (0, 0);
|
||||
#else
|
||||
#if !defined(SYSV)
|
||||
if (getpgrp (0) == 0)
|
||||
setpgrp (0, getpid ());
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef RLIMIT_DATA
|
||||
if (limitDataSpace >= 0)
|
||||
{
|
||||
struct rlimit rlim;
|
||||
|
||||
if (!getrlimit(RLIMIT_DATA, &rlim))
|
||||
{
|
||||
if ((limitDataSpace > 0) && (limitDataSpace < rlim.rlim_max))
|
||||
rlim.rlim_cur = limitDataSpace;
|
||||
else
|
||||
rlim.rlim_cur = rlim.rlim_max;
|
||||
(void)setrlimit(RLIMIT_DATA, &rlim);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#ifdef RLIMIT_STACK
|
||||
if (limitStackSpace >= 0)
|
||||
{
|
||||
struct rlimit rlim;
|
||||
|
||||
if (!getrlimit(RLIMIT_STACK, &rlim))
|
||||
{
|
||||
if ((limitStackSpace > 0) && (limitStackSpace < rlim.rlim_max))
|
||||
rlim.rlim_cur = limitStackSpace;
|
||||
else
|
||||
rlim.rlim_cur = rlim.rlim_max;
|
||||
(void)setrlimit(RLIMIT_STACK, &rlim);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#ifdef RLIMIT_NOFILE
|
||||
if (limitNoFile >= 0)
|
||||
{
|
||||
struct rlimit rlim;
|
||||
|
||||
if (!getrlimit(RLIMIT_NOFILE, &rlim))
|
||||
{
|
||||
if ((limitNoFile > 0) && (limitNoFile < rlim.rlim_max))
|
||||
rlim.rlim_cur = limitNoFile;
|
||||
else
|
||||
rlim.rlim_cur = rlim.rlim_max;
|
||||
#if 0
|
||||
if (rlim.rlim_cur > MAXSOCKS)
|
||||
rlim.rlim_cur = MAXSOCKS;
|
||||
#endif
|
||||
(void)setrlimit(RLIMIT_NOFILE, &rlim);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#ifdef SERVER_LOCK
|
||||
LockServer();
|
||||
#endif
|
||||
been_here = TRUE;
|
||||
}
|
||||
TimerInit();
|
||||
#ifdef DDXOSINIT
|
||||
OsVendorInit();
|
||||
#endif
|
||||
/*
|
||||
* No log file by default. OsVendorInit() should call LogInit() with the
|
||||
* log file name if logging to a file is desired.
|
||||
*/
|
||||
LogInit(NULL, NULL);
|
||||
SmartScheduleInit();
|
||||
|
||||
OsInitAllocator();
|
||||
}
|
||||
|
||||
void
|
||||
OsCleanup(Bool terminating)
|
||||
{
|
||||
#ifdef SERVER_LOCK
|
||||
if (terminating)
|
||||
{
|
||||
UnlockServer();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
43
nx-X11/programs/Xserver/os/reallocarray.c
Normal file
43
nx-X11/programs/Xserver/os/reallocarray.c
Normal file
@@ -0,0 +1,43 @@
|
||||
/* $OpenBSD: reallocarray.c,v 1.2 2014/12/08 03:45:00 bcook Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008 Otto Moerbeek <otto@drijf.net>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <errno.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include "os.h"
|
||||
|
||||
/*
|
||||
* This is sqrt(SIZE_MAX+1), as s1*s2 <= SIZE_MAX
|
||||
* if both s1 < MUL_NO_OVERFLOW and s2 < MUL_NO_OVERFLOW
|
||||
*/
|
||||
#define MUL_NO_OVERFLOW ((size_t)1 << (sizeof(size_t) * 4))
|
||||
|
||||
void *
|
||||
reallocarray(void *optr, size_t nmemb, size_t size)
|
||||
{
|
||||
if ((nmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) &&
|
||||
nmemb > 0 && SIZE_MAX / nmemb < size) {
|
||||
errno = ENOMEM;
|
||||
return NULL;
|
||||
}
|
||||
return realloc(optr, size * nmemb);
|
||||
}
|
||||
201
nx-X11/programs/Xserver/os/rpcauth.c
Normal file
201
nx-X11/programs/Xserver/os/rpcauth.c
Normal file
@@ -0,0 +1,201 @@
|
||||
/*
|
||||
|
||||
Copyright 1991, 1998 The Open Group
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this software and its
|
||||
documentation for any purpose is hereby granted without fee, provided that
|
||||
the above copyright notice appear in all copies and that both that
|
||||
copyright notice and this permission notice appear in supporting
|
||||
documentation.
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
Except as contained in this notice, the name of The Open Group shall
|
||||
not be used in advertising or otherwise to promote the sale, use or
|
||||
other dealings in this Software without prior written authorization
|
||||
from The Open Group.
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
* SUN-DES-1 authentication mechanism
|
||||
* Author: Mayank Choudhary, Sun Microsystems
|
||||
*/
|
||||
|
||||
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#ifdef SECURE_RPC
|
||||
|
||||
#include <nx-X11/X.h>
|
||||
#include <nx-X11/Xauth.h>
|
||||
#include "misc.h"
|
||||
#include "os.h"
|
||||
#include "dixstruct.h"
|
||||
|
||||
#include <rpc/rpc.h>
|
||||
|
||||
#ifdef sun
|
||||
/* <rpc/auth.h> only includes this if _KERNEL is #defined... */
|
||||
extern bool_t xdr_opaque_auth(XDR *, struct opaque_auth *);
|
||||
#endif
|
||||
|
||||
#ifdef ultrix
|
||||
#include <time.h>
|
||||
#include <rpc/auth_des.h>
|
||||
#endif
|
||||
|
||||
static enum auth_stat why;
|
||||
|
||||
static char *
|
||||
authdes_ezdecode(char *inmsg, int len)
|
||||
{
|
||||
struct rpc_msg msg;
|
||||
char cred_area[MAX_AUTH_BYTES];
|
||||
char verf_area[MAX_AUTH_BYTES];
|
||||
char *temp_inmsg;
|
||||
struct svc_req r;
|
||||
bool_t res0, res1;
|
||||
XDR xdr;
|
||||
SVCXPRT xprt;
|
||||
|
||||
temp_inmsg = (char *) malloc(len);
|
||||
if (temp_inmsg == NULL) {
|
||||
why = AUTH_FAILED; /* generic error, since there is no AUTH_BADALLOC */
|
||||
return NULL;
|
||||
}
|
||||
memmove(temp_inmsg, inmsg, len);
|
||||
|
||||
memset((char *)&msg, 0, sizeof(msg));
|
||||
memset((char *)&r, 0, sizeof(r));
|
||||
memset(cred_area, 0, sizeof(cred_area));
|
||||
memset(verf_area, 0, sizeof(verf_area));
|
||||
|
||||
msg.rm_call.cb_cred.oa_base = cred_area;
|
||||
msg.rm_call.cb_verf.oa_base = verf_area;
|
||||
why = AUTH_FAILED;
|
||||
xdrmem_create(&xdr, temp_inmsg, len, XDR_DECODE);
|
||||
|
||||
if ((r.rq_clntcred = (caddr_t) malloc(MAX_AUTH_BYTES)) == NULL)
|
||||
goto bad1;
|
||||
r.rq_xprt = &xprt;
|
||||
|
||||
/* decode into msg */
|
||||
res0 = xdr_opaque_auth(&xdr, &(msg.rm_call.cb_cred));
|
||||
res1 = xdr_opaque_auth(&xdr, &(msg.rm_call.cb_verf));
|
||||
if ( ! (res0 && res1) )
|
||||
goto bad2;
|
||||
|
||||
/* do the authentication */
|
||||
|
||||
r.rq_cred = msg.rm_call.cb_cred; /* read by opaque stuff */
|
||||
if (r.rq_cred.oa_flavor != AUTH_DES) {
|
||||
why = AUTH_TOOWEAK;
|
||||
goto bad2;
|
||||
}
|
||||
#ifdef SVR4
|
||||
if ((why = __authenticate(&r, &msg)) != AUTH_OK) {
|
||||
#else
|
||||
if ((why = _authenticate(&r, &msg)) != AUTH_OK) {
|
||||
#endif
|
||||
goto bad2;
|
||||
}
|
||||
return (((struct authdes_cred *) r.rq_clntcred)->adc_fullname.name);
|
||||
|
||||
bad2:
|
||||
free(r.rq_clntcred);
|
||||
bad1:
|
||||
return ((char *)0); /* ((struct authdes_cred *) NULL); */
|
||||
}
|
||||
|
||||
static XID rpc_id = (XID) ~0L;
|
||||
|
||||
static Bool
|
||||
CheckNetName (
|
||||
unsigned char *addr,
|
||||
short len,
|
||||
void * closure
|
||||
)
|
||||
{
|
||||
return (len == strlen ((char *) closure) &&
|
||||
strncmp ((char *) addr, (char *) closure, len) == 0);
|
||||
}
|
||||
|
||||
static char rpc_error[MAXNETNAMELEN+50];
|
||||
|
||||
XID
|
||||
SecureRPCCheck (unsigned short data_length, char *data,
|
||||
ClientPtr client, char **reason)
|
||||
{
|
||||
char *fullname;
|
||||
|
||||
if (rpc_id == (XID) ~0L) {
|
||||
*reason = "Secure RPC authorization not initialized";
|
||||
} else {
|
||||
fullname = authdes_ezdecode(data, data_length);
|
||||
if (fullname == (char *)0) {
|
||||
sprintf(rpc_error, "Unable to authenticate secure RPC client (why=%d)", why);
|
||||
*reason = rpc_error;
|
||||
} else {
|
||||
if (ForEachHostInFamily (FamilyNetname, CheckNetName, fullname))
|
||||
return rpc_id;
|
||||
sprintf(rpc_error, "Principal \"%s\" is not authorized to connect",
|
||||
fullname);
|
||||
*reason = rpc_error;
|
||||
}
|
||||
}
|
||||
return (XID) ~0L;
|
||||
}
|
||||
|
||||
void
|
||||
SecureRPCInit (void)
|
||||
{
|
||||
if (rpc_id == ~0L)
|
||||
AddAuthorization (9, "SUN-DES-1", 0, (char *) 0);
|
||||
}
|
||||
|
||||
int
|
||||
SecureRPCAdd (unsigned short data_length, char *data, XID id)
|
||||
{
|
||||
if (data_length)
|
||||
AddHost ((void *) 0, FamilyNetname, data_length, data);
|
||||
rpc_id = id;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
SecureRPCReset (void)
|
||||
{
|
||||
rpc_id = (XID) ~0L;
|
||||
return 1;
|
||||
}
|
||||
|
||||
XID
|
||||
SecureRPCToID (unsigned short data_length, char *data)
|
||||
{
|
||||
return rpc_id;
|
||||
}
|
||||
|
||||
int
|
||||
SecureRPCFromID (XID id, unsigned short *data_lenp, char **datap)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
SecureRPCRemove (unsigned short data_length, char *data)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif /* SECURE_RPC */
|
||||
203
nx-X11/programs/Xserver/os/secauth.c
Normal file
203
nx-X11/programs/Xserver/os/secauth.c
Normal file
@@ -0,0 +1,203 @@
|
||||
/*
|
||||
Copyright 1996, 1998 The Open Group
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this software and its
|
||||
documentation for any purpose is hereby granted without fee, provided that
|
||||
the above copyright notice appear in all copies and that both that
|
||||
copyright notice and this permission notice appear in supporting
|
||||
documentation.
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
Except as contained in this notice, the name of The Open Group shall
|
||||
not be used in advertising or otherwise to promote the sale, use or
|
||||
other dealings in this Software without prior written authorization
|
||||
from The Open Group.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#include <nx-X11/X.h>
|
||||
#include "os.h"
|
||||
#include "osdep.h"
|
||||
#include "dixstruct.h"
|
||||
#include "swaprep.h"
|
||||
|
||||
#ifdef XCSECURITY
|
||||
#define _SECURITY_SERVER
|
||||
#include <nx-X11/extensions/security.h>
|
||||
#endif
|
||||
|
||||
static char InvalidPolicyReason[] = "invalid policy specification";
|
||||
static char PolicyViolationReason[] = "policy violation";
|
||||
|
||||
static Bool
|
||||
AuthCheckSitePolicy(
|
||||
unsigned short *data_lengthP,
|
||||
char **dataP,
|
||||
ClientPtr client,
|
||||
char **reason)
|
||||
{
|
||||
CARD8 *policy = *(CARD8 **)dataP;
|
||||
int length;
|
||||
Bool permit;
|
||||
int nPolicies;
|
||||
char **sitePolicies;
|
||||
int nSitePolicies;
|
||||
Bool found = FALSE;
|
||||
|
||||
if ((length = *data_lengthP) < 2) {
|
||||
*reason = InvalidPolicyReason;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
permit = (*policy++ == 0);
|
||||
nPolicies = (CARD8) *policy++;
|
||||
|
||||
length -= 2;
|
||||
|
||||
sitePolicies = SecurityGetSitePolicyStrings(&nSitePolicies);
|
||||
|
||||
while (nPolicies) {
|
||||
int strLen, sitePolicy;
|
||||
|
||||
if (length == 0) {
|
||||
*reason = InvalidPolicyReason;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
strLen = (CARD8) *policy++;
|
||||
if (--length < strLen) {
|
||||
*reason = InvalidPolicyReason;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!found)
|
||||
{
|
||||
for (sitePolicy = 0; sitePolicy < nSitePolicies; sitePolicy++)
|
||||
{
|
||||
char *testPolicy = sitePolicies[sitePolicy];
|
||||
if ((strLen == strlen(testPolicy)) &&
|
||||
(strncmp((char *)policy, testPolicy, strLen) == 0))
|
||||
{
|
||||
found = TRUE; /* need to continue parsing the policy... */
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
policy += strLen;
|
||||
length -= strLen;
|
||||
nPolicies--;
|
||||
}
|
||||
|
||||
if (found != permit)
|
||||
{
|
||||
*reason = PolicyViolationReason;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
*data_lengthP = length;
|
||||
*dataP = (char *)policy;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
XID
|
||||
AuthSecurityCheck (
|
||||
unsigned short data_length,
|
||||
char *data,
|
||||
ClientPtr client,
|
||||
char **reason)
|
||||
{
|
||||
#ifdef XCSECURITY
|
||||
xConnSetupPrefix csp;
|
||||
xReq freq;
|
||||
|
||||
if (client->clientState == ClientStateCheckedSecurity)
|
||||
{
|
||||
*reason = "repeated security check not permitted";
|
||||
return (XID) -1;
|
||||
}
|
||||
else if (data_length > 0)
|
||||
{
|
||||
char policy_mask = *data++;
|
||||
|
||||
if (--data_length == 1) {
|
||||
*reason = InvalidPolicyReason;
|
||||
return (XID) -1;
|
||||
}
|
||||
|
||||
if (policy_mask & 0x01) /* Extensions policy */
|
||||
{
|
||||
/* AuthCheckExtensionPolicy(&data_length, &data, client, reason) */
|
||||
*reason = "security policy not implemented";
|
||||
return (XID) -1;
|
||||
}
|
||||
|
||||
if (policy_mask & 0x02) /* Site policy */
|
||||
{
|
||||
if (!AuthCheckSitePolicy(&data_length, &data, client, reason))
|
||||
return (XID) -1;
|
||||
}
|
||||
|
||||
if (data_length > 0) { /* did we consume the whole policy? */
|
||||
*reason = InvalidPolicyReason;
|
||||
return (XID) -1;
|
||||
}
|
||||
|
||||
}
|
||||
else if (!GetAccessControl())
|
||||
{
|
||||
/*
|
||||
* The client - possibly the X FireWall Proxy - gave
|
||||
* no auth data and host-based authorization is turned
|
||||
* off. In this case, the client should be denied
|
||||
* access to the X server.
|
||||
*/
|
||||
*reason = "server host access control is disabled";
|
||||
return (XID) -1;
|
||||
}
|
||||
|
||||
client->clientState = ClientStateCheckingSecurity;
|
||||
|
||||
csp.success = 2 /* Authenticate */;
|
||||
csp.lengthReason = 0;
|
||||
csp.length = 0;
|
||||
csp.majorVersion = X_PROTOCOL;
|
||||
csp.minorVersion = X_PROTOCOL_REVISION;
|
||||
if (client->swapped)
|
||||
WriteSConnSetupPrefix(client, &csp);
|
||||
else
|
||||
WriteToClient(client, sz_xConnSetupPrefix, &csp);
|
||||
|
||||
/*
|
||||
* Next time the client sends the real auth data, we want
|
||||
* ProcEstablishConnection to be called.
|
||||
*/
|
||||
|
||||
freq.reqType = 1;
|
||||
freq.length = (sz_xReq + sz_xConnClientPrefix) >> 2;
|
||||
client->swapped = FALSE;
|
||||
if (!InsertFakeRequest(client, (char *)&freq, sz_xReq))
|
||||
{
|
||||
*reason = "internal error";
|
||||
return (XID) -1;
|
||||
}
|
||||
|
||||
return (XID) 0;
|
||||
#else
|
||||
*reason = "method not supported";
|
||||
return (XID) -1;
|
||||
#endif
|
||||
}
|
||||
57
nx-X11/programs/Xserver/os/strlcat.c
Normal file
57
nx-X11/programs/Xserver/os/strlcat.c
Normal file
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND TODD C. MILLER DISCLAIMS ALL
|
||||
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL TODD C. MILLER BE LIABLE
|
||||
* FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_XORG_CONFIG_H
|
||||
#include <xorg-config.h>
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <string.h>
|
||||
|
||||
/*
|
||||
* Appends src to string dst of size siz (unlike strncat, siz is the
|
||||
* full size of dst, not space left). At most siz-1 characters
|
||||
* will be copied. Always NUL terminates (unless siz <= strlen(dst)).
|
||||
* Returns strlen(src) + MIN(siz, strlen(initial dst)).
|
||||
* If retval >= siz, truncation occurred.
|
||||
*/
|
||||
size_t
|
||||
strlcat(char *dst, const char *src, size_t siz)
|
||||
{
|
||||
register char *d = dst;
|
||||
register const char *s = src;
|
||||
register size_t n = siz;
|
||||
size_t dlen;
|
||||
|
||||
/* Find the end of dst and adjust bytes left but don't go past end */
|
||||
while (n-- != 0 && *d != '\0')
|
||||
d++;
|
||||
dlen = d - dst;
|
||||
n = siz - dlen;
|
||||
|
||||
if (n == 0)
|
||||
return(dlen + strlen(s));
|
||||
while (*s != '\0') {
|
||||
if (n != 1) {
|
||||
*d++ = *s;
|
||||
n--;
|
||||
}
|
||||
s++;
|
||||
}
|
||||
*d = '\0';
|
||||
|
||||
return(dlen + (s - src)); /* count does not include NUL */
|
||||
}
|
||||
53
nx-X11/programs/Xserver/os/strlcpy.c
Normal file
53
nx-X11/programs/Xserver/os/strlcpy.c
Normal file
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND TODD C. MILLER DISCLAIMS ALL
|
||||
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL TODD C. MILLER BE LIABLE
|
||||
* FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_XORG_CONFIG_H
|
||||
#include <xorg-config.h>
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <string.h>
|
||||
|
||||
/*
|
||||
* Copy src to string dst of size siz. At most siz-1 characters
|
||||
* will be copied. Always NUL terminates (unless siz == 0).
|
||||
* Returns strlen(src); if retval >= siz, truncation occurred.
|
||||
*/
|
||||
size_t
|
||||
strlcpy(char *dst, const char *src, size_t siz)
|
||||
{
|
||||
register char *d = dst;
|
||||
register const char *s = src;
|
||||
register size_t n = siz;
|
||||
|
||||
/* Copy as many bytes as will fit */
|
||||
if (n != 0 && --n != 0) {
|
||||
do {
|
||||
if ((*d++ = *s++) == 0)
|
||||
break;
|
||||
} while (--n != 0);
|
||||
}
|
||||
|
||||
/* Not enough room in dst, add NUL and traverse rest of src */
|
||||
if (n == 0) {
|
||||
if (siz != 0)
|
||||
*d = '\0'; /* NUL-terminate dst */
|
||||
while (*s++)
|
||||
;
|
||||
}
|
||||
|
||||
return(s - src - 1); /* count does not include NUL */
|
||||
}
|
||||
47
nx-X11/programs/Xserver/os/timingsafe_memcmp.c
Normal file
47
nx-X11/programs/Xserver/os/timingsafe_memcmp.c
Normal file
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (c) 2014 Google Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <limits.h>
|
||||
#include <string.h>
|
||||
#include <nx-X11/Xfuncproto.h>
|
||||
#include "os.h"
|
||||
|
||||
int
|
||||
timingsafe_memcmp(const void *b1, const void *b2, size_t len)
|
||||
{
|
||||
const unsigned char *p1 = b1, *p2 = b2;
|
||||
size_t i;
|
||||
int res = 0, done = 0;
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
/* lt is -1 if p1[i] < p2[i]; else 0. */
|
||||
int lt = (p1[i] - p2[i]) >> CHAR_BIT;
|
||||
|
||||
/* gt is -1 if p1[i] > p2[i]; else 0. */
|
||||
int gt = (p2[i] - p1[i]) >> CHAR_BIT;
|
||||
|
||||
/* cmp is 1 if p1[i] > p2[i]; -1 if p1[i] < p2[i]; else 0. */
|
||||
int cmp = lt - gt;
|
||||
|
||||
/* set res = cmp if !done. */
|
||||
res |= cmp & ~done;
|
||||
|
||||
/* set done if p1[i] != p2[i]. */
|
||||
done |= lt | gt;
|
||||
}
|
||||
|
||||
return (res);
|
||||
}
|
||||
2212
nx-X11/programs/Xserver/os/utils.c
Normal file
2212
nx-X11/programs/Xserver/os/utils.c
Normal file
File diff suppressed because it is too large
Load Diff
499
nx-X11/programs/Xserver/os/xdmauth.c
Normal file
499
nx-X11/programs/Xserver/os/xdmauth.c
Normal file
@@ -0,0 +1,499 @@
|
||||
/*
|
||||
|
||||
Copyright 1988, 1998 The Open Group
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this software and its
|
||||
documentation for any purpose is hereby granted without fee, provided that
|
||||
the above copyright notice appear in all copies and that both that
|
||||
copyright notice and this permission notice appear in supporting
|
||||
documentation.
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
Except as contained in this notice, the name of The Open Group shall
|
||||
not be used in advertising or otherwise to promote the sale, use or
|
||||
other dealings in this Software without prior written authorization
|
||||
from The Open Group.
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
* XDM-AUTHENTICATION-1 (XDMCP authentication) and
|
||||
* XDM-AUTHORIZATION-1 (client authorization) protocols
|
||||
*
|
||||
* Author: Keith Packard, MIT X Consortium
|
||||
*/
|
||||
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <nx-X11/X.h>
|
||||
#define XSERV_t
|
||||
#define TRANS_SERVER
|
||||
#define TRANS_REOPEN
|
||||
#include <nx-X11/Xtrans/Xtrans.h>
|
||||
#include "os.h"
|
||||
#include "osdep.h"
|
||||
#include "dixstruct.h"
|
||||
|
||||
#ifdef HASXDMAUTH
|
||||
|
||||
static Bool authFromXDMCP;
|
||||
|
||||
#ifdef XDMCP
|
||||
#include <nx-X11/Xmd.h>
|
||||
#undef REQUEST
|
||||
#include <X11/Xdmcp.h>
|
||||
|
||||
/* XDM-AUTHENTICATION-1 */
|
||||
|
||||
static XdmAuthKeyRec privateKey;
|
||||
static char XdmAuthenticationName[] = "XDM-AUTHENTICATION-1";
|
||||
#define XdmAuthenticationNameLen (sizeof XdmAuthenticationName - 1)
|
||||
static XdmAuthKeyRec global_rho;
|
||||
|
||||
static Bool
|
||||
XdmAuthenticationValidator (ARRAY8Ptr privateData, ARRAY8Ptr incomingData,
|
||||
xdmOpCode packet_type)
|
||||
{
|
||||
XdmAuthKeyPtr incoming;
|
||||
|
||||
XdmcpUnwrap (incomingData->data, (unsigned char *)&privateKey,
|
||||
incomingData->data,incomingData->length);
|
||||
if (packet_type == ACCEPT) {
|
||||
if (incomingData->length != 8)
|
||||
return FALSE;
|
||||
incoming = (XdmAuthKeyPtr) incomingData->data;
|
||||
XdmcpDecrementKey (incoming);
|
||||
return XdmcpCompareKeys (incoming, &global_rho);
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static Bool
|
||||
XdmAuthenticationGenerator (ARRAY8Ptr privateData, ARRAY8Ptr outgoingData,
|
||||
xdmOpCode packet_type)
|
||||
{
|
||||
outgoingData->length = 0;
|
||||
outgoingData->data = 0;
|
||||
if (packet_type == REQUEST) {
|
||||
if (XdmcpAllocARRAY8 (outgoingData, 8))
|
||||
XdmcpWrap ((unsigned char *)&global_rho, (unsigned char *)&privateKey,
|
||||
outgoingData->data, 8);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static Bool
|
||||
XdmAuthenticationAddAuth (int name_len, char *name,
|
||||
int data_len, char *data)
|
||||
{
|
||||
Bool ret;
|
||||
XdmcpUnwrap ((unsigned char *)data, (unsigned char *)&privateKey,
|
||||
(unsigned char *)data, data_len);
|
||||
authFromXDMCP = TRUE;
|
||||
ret = AddAuthorization (name_len, name, data_len, data);
|
||||
authFromXDMCP = FALSE;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
#define atox(c) ('0' <= c && c <= '9' ? c - '0' : \
|
||||
'a' <= c && c <= 'f' ? c - 'a' + 10 : \
|
||||
'A' <= c && c <= 'F' ? c - 'A' + 10 : -1)
|
||||
|
||||
static int
|
||||
HexToBinary (char *in, char *out, int len)
|
||||
{
|
||||
int top, bottom;
|
||||
|
||||
while (len > 0)
|
||||
{
|
||||
top = atox(in[0]);
|
||||
if (top == -1)
|
||||
return 0;
|
||||
bottom = atox(in[1]);
|
||||
if (bottom == -1)
|
||||
return 0;
|
||||
*out++ = (top << 4) | bottom;
|
||||
in += 2;
|
||||
len -= 2;
|
||||
}
|
||||
if (len)
|
||||
return 0;
|
||||
*out++ = '\0';
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
XdmAuthenticationInit (char *cookie, int cookie_len)
|
||||
{
|
||||
bzero (privateKey.data, 8);
|
||||
if (!strncmp (cookie, "0x", 2) || !strncmp (cookie, "0X", 2))
|
||||
{
|
||||
if (cookie_len > 2 + 2 * 8)
|
||||
cookie_len = 2 + 2 * 8;
|
||||
HexToBinary (cookie + 2, (char *)privateKey.data, cookie_len - 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (cookie_len > 7)
|
||||
cookie_len = 7;
|
||||
memmove (privateKey.data + 1, cookie, cookie_len);
|
||||
}
|
||||
XdmcpGenerateKey (&global_rho);
|
||||
XdmcpRegisterAuthentication (XdmAuthenticationName, XdmAuthenticationNameLen,
|
||||
(char *)&global_rho,
|
||||
sizeof (global_rho),
|
||||
(ValidatorFunc)XdmAuthenticationValidator,
|
||||
(GeneratorFunc)XdmAuthenticationGenerator,
|
||||
(AddAuthorFunc)XdmAuthenticationAddAuth);
|
||||
}
|
||||
|
||||
#endif /* XDMCP */
|
||||
|
||||
/* XDM-AUTHORIZATION-1 */
|
||||
typedef struct _XdmAuthorization {
|
||||
struct _XdmAuthorization *next;
|
||||
XdmAuthKeyRec rho;
|
||||
XdmAuthKeyRec key;
|
||||
XID id;
|
||||
} XdmAuthorizationRec, *XdmAuthorizationPtr;
|
||||
|
||||
static XdmAuthorizationPtr xdmAuth;
|
||||
|
||||
typedef struct _XdmClientAuth {
|
||||
struct _XdmClientAuth *next;
|
||||
XdmAuthKeyRec rho;
|
||||
char client[6];
|
||||
long time;
|
||||
} XdmClientAuthRec, *XdmClientAuthPtr;
|
||||
|
||||
static XdmClientAuthPtr xdmClients;
|
||||
static long clockOffset;
|
||||
static Bool gotClock;
|
||||
|
||||
#define TwentyMinutes (20 * 60)
|
||||
#define TwentyFiveMinutes (25 * 60)
|
||||
|
||||
static Bool
|
||||
XdmClientAuthCompare (XdmClientAuthPtr a, XdmClientAuthPtr b)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!XdmcpCompareKeys (&a->rho, &b->rho))
|
||||
return FALSE;
|
||||
for (i = 0; i < 6; i++)
|
||||
if (a->client[i] != b->client[i])
|
||||
return FALSE;
|
||||
return a->time == b->time;
|
||||
}
|
||||
|
||||
static void
|
||||
XdmClientAuthDecode (unsigned char *plain, XdmClientAuthPtr auth)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
j = 0;
|
||||
for (i = 0; i < 8; i++)
|
||||
{
|
||||
auth->rho.data[i] = plain[j];
|
||||
++j;
|
||||
}
|
||||
for (i = 0; i < 6; i++)
|
||||
{
|
||||
auth->client[i] = plain[j];
|
||||
++j;
|
||||
}
|
||||
auth->time = 0;
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
auth->time |= plain[j] << ((3 - i) << 3);
|
||||
j++;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
XdmClientAuthTimeout (long now)
|
||||
{
|
||||
XdmClientAuthPtr client, next, prev;
|
||||
|
||||
prev = 0;
|
||||
for (client = xdmClients; client; client=next)
|
||||
{
|
||||
next = client->next;
|
||||
if (abs (now - client->time) > TwentyFiveMinutes)
|
||||
{
|
||||
if (prev)
|
||||
prev->next = next;
|
||||
else
|
||||
xdmClients = next;
|
||||
free (client);
|
||||
}
|
||||
else
|
||||
prev = client;
|
||||
}
|
||||
}
|
||||
|
||||
static XdmClientAuthPtr
|
||||
XdmAuthorizationValidate (unsigned char *plain, int length,
|
||||
XdmAuthKeyPtr rho, ClientPtr xclient, char **reason)
|
||||
{
|
||||
XdmClientAuthPtr client, existing;
|
||||
long now;
|
||||
int i;
|
||||
|
||||
if (length != (192 / 8)) {
|
||||
if (reason)
|
||||
*reason = "Bad XDM authorization key length";
|
||||
return NULL;
|
||||
}
|
||||
client = (XdmClientAuthPtr) malloc (sizeof (XdmClientAuthRec));
|
||||
if (!client)
|
||||
return NULL;
|
||||
XdmClientAuthDecode (plain, client);
|
||||
if (!XdmcpCompareKeys (&client->rho, rho))
|
||||
{
|
||||
free (client);
|
||||
if (reason)
|
||||
*reason = "Invalid XDM-AUTHORIZATION-1 key (failed key comparison)";
|
||||
return NULL;
|
||||
}
|
||||
for (i = 18; i < 24; i++)
|
||||
if (plain[i] != 0) {
|
||||
free (client);
|
||||
if (reason)
|
||||
*reason = "Invalid XDM-AUTHORIZATION-1 key (failed NULL check)";
|
||||
return NULL;
|
||||
}
|
||||
if (xclient) {
|
||||
int family, addr_len;
|
||||
Xtransaddr *addr;
|
||||
|
||||
if (_XSERVTransGetPeerAddr(((OsCommPtr)xclient->osPrivate)->trans_conn,
|
||||
&family, &addr_len, &addr) == 0
|
||||
&& _XSERVTransConvertAddress(&family, &addr_len, &addr) == 0) {
|
||||
#if defined(TCPCONN)
|
||||
if (family == FamilyInternet &&
|
||||
memcmp((char *)addr, client->client, 4) != 0) {
|
||||
free (client);
|
||||
free (addr);
|
||||
if (reason)
|
||||
*reason = "Invalid XDM-AUTHORIZATION-1 key (failed address comparison)";
|
||||
return NULL;
|
||||
|
||||
}
|
||||
#endif
|
||||
free (addr);
|
||||
}
|
||||
}
|
||||
now = time(0);
|
||||
if (!gotClock)
|
||||
{
|
||||
clockOffset = client->time - now;
|
||||
gotClock = TRUE;
|
||||
}
|
||||
now += clockOffset;
|
||||
XdmClientAuthTimeout (now);
|
||||
if (abs (client->time - now) > TwentyMinutes)
|
||||
{
|
||||
free (client);
|
||||
if (reason)
|
||||
*reason = "Excessive XDM-AUTHORIZATION-1 time offset";
|
||||
return NULL;
|
||||
}
|
||||
for (existing = xdmClients; existing; existing=existing->next)
|
||||
{
|
||||
if (XdmClientAuthCompare (existing, client))
|
||||
{
|
||||
free (client);
|
||||
if (reason)
|
||||
*reason = "XDM authorization key matches an existing client!";
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
return client;
|
||||
}
|
||||
|
||||
int
|
||||
XdmAddCookie (unsigned short data_length, char *data, XID id)
|
||||
{
|
||||
XdmAuthorizationPtr new;
|
||||
unsigned char *rho_bits, *key_bits;
|
||||
|
||||
switch (data_length)
|
||||
{
|
||||
case 16: /* auth from files is 16 bytes long */
|
||||
#ifdef XDMCP
|
||||
if (authFromXDMCP)
|
||||
{
|
||||
/* R5 xdm sent bogus authorization data in the accept packet,
|
||||
* but we can recover */
|
||||
rho_bits = global_rho.data;
|
||||
key_bits = (unsigned char *) data;
|
||||
key_bits[0] = '\0';
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
rho_bits = (unsigned char *) data;
|
||||
key_bits = (unsigned char *) (data + 8);
|
||||
}
|
||||
break;
|
||||
#ifdef XDMCP
|
||||
case 8: /* auth from XDMCP is 8 bytes long */
|
||||
rho_bits = global_rho.data;
|
||||
key_bits = (unsigned char *) data;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
/* the first octet of the key must be zero */
|
||||
if (key_bits[0] != '\0')
|
||||
return 0;
|
||||
new = (XdmAuthorizationPtr) malloc (sizeof (XdmAuthorizationRec));
|
||||
if (!new)
|
||||
return 0;
|
||||
new->next = xdmAuth;
|
||||
xdmAuth = new;
|
||||
memmove (new->key.data, key_bits, (int) 8);
|
||||
memmove (new->rho.data, rho_bits, (int) 8);
|
||||
new->id = id;
|
||||
return 1;
|
||||
}
|
||||
|
||||
XID
|
||||
XdmCheckCookie (unsigned short cookie_length, char *cookie,
|
||||
ClientPtr xclient, char **reason)
|
||||
{
|
||||
XdmAuthorizationPtr auth;
|
||||
XdmClientAuthPtr client;
|
||||
unsigned char *plain;
|
||||
|
||||
/* Auth packets must be a multiple of 8 bytes long */
|
||||
if (cookie_length & 7)
|
||||
return (XID) -1;
|
||||
plain = (unsigned char *) malloc (cookie_length);
|
||||
if (!plain)
|
||||
return (XID) -1;
|
||||
for (auth = xdmAuth; auth; auth=auth->next) {
|
||||
XdmcpUnwrap ((unsigned char *)cookie, (unsigned char *)&auth->key, plain, cookie_length);
|
||||
if ((client = XdmAuthorizationValidate (plain, cookie_length, &auth->rho, xclient, reason)) != NULL)
|
||||
{
|
||||
client->next = xdmClients;
|
||||
xdmClients = client;
|
||||
free (plain);
|
||||
return auth->id;
|
||||
}
|
||||
}
|
||||
free (plain);
|
||||
return (XID) -1;
|
||||
}
|
||||
|
||||
int
|
||||
XdmResetCookie (void)
|
||||
{
|
||||
XdmAuthorizationPtr auth, next_auth;
|
||||
XdmClientAuthPtr client, next_client;
|
||||
|
||||
for (auth = xdmAuth; auth; auth=next_auth)
|
||||
{
|
||||
next_auth = auth->next;
|
||||
free (auth);
|
||||
}
|
||||
xdmAuth = 0;
|
||||
for (client = xdmClients; client; client=next_client)
|
||||
{
|
||||
next_client = client->next;
|
||||
free (client);
|
||||
}
|
||||
xdmClients = (XdmClientAuthPtr) 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
XID
|
||||
XdmToID (unsigned short cookie_length, char *cookie)
|
||||
{
|
||||
XdmAuthorizationPtr auth;
|
||||
XdmClientAuthPtr client;
|
||||
unsigned char *plain;
|
||||
|
||||
plain = (unsigned char *) malloc (cookie_length);
|
||||
if (!plain)
|
||||
return (XID) -1;
|
||||
for (auth = xdmAuth; auth; auth=auth->next) {
|
||||
XdmcpUnwrap ((unsigned char *)cookie, (unsigned char *)&auth->key, plain, cookie_length);
|
||||
if ((client = XdmAuthorizationValidate (plain, cookie_length, &auth->rho, NULL, NULL)) != NULL)
|
||||
{
|
||||
free (client);
|
||||
free (cookie);
|
||||
free (plain);
|
||||
return auth->id;
|
||||
}
|
||||
}
|
||||
free (cookie);
|
||||
free (plain);
|
||||
return (XID) -1;
|
||||
}
|
||||
|
||||
int
|
||||
XdmFromID (XID id, unsigned short *data_lenp, char **datap)
|
||||
{
|
||||
XdmAuthorizationPtr auth;
|
||||
|
||||
for (auth = xdmAuth; auth; auth=auth->next) {
|
||||
if (id == auth->id) {
|
||||
*data_lenp = 16;
|
||||
*datap = (char *) &auth->rho;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
XdmRemoveCookie (unsigned short data_length, char *data)
|
||||
{
|
||||
XdmAuthorizationPtr auth;
|
||||
XdmAuthKeyPtr key_bits, rho_bits;
|
||||
|
||||
switch (data_length)
|
||||
{
|
||||
case 16:
|
||||
rho_bits = (XdmAuthKeyPtr) data;
|
||||
key_bits = (XdmAuthKeyPtr) (data + 8);
|
||||
break;
|
||||
#ifdef XDMCP
|
||||
case 8:
|
||||
rho_bits = &global_rho;
|
||||
key_bits = (XdmAuthKeyPtr) data;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
for (auth = xdmAuth; auth; auth=auth->next) {
|
||||
if (XdmcpCompareKeys (rho_bits, &auth->rho) &&
|
||||
XdmcpCompareKeys (key_bits, &auth->key))
|
||||
{
|
||||
xdmAuth = auth->next;
|
||||
free (auth);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
1632
nx-X11/programs/Xserver/os/xdmcp.c
Normal file
1632
nx-X11/programs/Xserver/os/xdmcp.c
Normal file
File diff suppressed because it is too large
Load Diff
278
nx-X11/programs/Xserver/os/xprintf.c
Normal file
278
nx-X11/programs/Xserver/os/xprintf.c
Normal file
@@ -0,0 +1,278 @@
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* @section DESCRIPTION
|
||||
*
|
||||
* These functions provide a portable implementation of the common (but not
|
||||
* yet universal) asprintf & vasprintf routines to allocate a buffer big
|
||||
* enough to sprintf the arguments to. The XNF variants terminate the server
|
||||
* if the allocation fails.
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2004 Alexander Gottwald
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name(s) of the above copyright
|
||||
* holders shall not be used in advertising or otherwise to promote the sale,
|
||||
* use or other dealings in this Software without prior written authorization.
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#include <nx-X11/Xos.h>
|
||||
#include "os.h"
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef asprintf
|
||||
#undef asprintf
|
||||
#endif
|
||||
#ifdef vasprintf
|
||||
#undef vasprintf
|
||||
#endif
|
||||
|
||||
#ifndef va_copy
|
||||
#ifdef __va_copy
|
||||
#define va_copy __va_copy
|
||||
#else
|
||||
#error "no working va_copy was found"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Varargs sprintf that allocates a string buffer the right size for
|
||||
* the pattern & data provided and prints the requested data to it.
|
||||
*
|
||||
* @param ret Pointer to which the newly allocated buffer is written
|
||||
* (contents undefined on error)
|
||||
* @param format printf style format string
|
||||
* @param va variable argument list
|
||||
* @return size of allocated buffer, or -1 on error.
|
||||
*/
|
||||
int
|
||||
Xvasprintf(char **ret, const char *_X_RESTRICT_KYWD format, va_list va)
|
||||
{
|
||||
#ifdef HAVE_VASPRINTF
|
||||
return vasprintf(ret, format, va);
|
||||
#else
|
||||
int size;
|
||||
va_list va2;
|
||||
|
||||
va_copy(va2, va);
|
||||
size = vsnprintf(NULL, 0, format, va2);
|
||||
va_end(va2);
|
||||
|
||||
*ret = malloc(size + 1);
|
||||
if (*ret == NULL)
|
||||
return -1;
|
||||
|
||||
vsnprintf(*ret, size + 1, format, va);
|
||||
(*ret)[size] = 0;
|
||||
return size;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef HAVE_VASPRINTF
|
||||
#define vasprintf Xvasprintf
|
||||
#endif
|
||||
|
||||
/**
|
||||
* sprintf that allocates a string buffer the right size for
|
||||
* the pattern & data provided and prints the requested data to it.
|
||||
*
|
||||
* @param ret Pointer to which the newly allocated buffer is written
|
||||
* (contents undefined on error)
|
||||
* @param format printf style format string
|
||||
* @param ... arguments for specified format
|
||||
* @return size of allocated buffer, or -1 on error.
|
||||
*/
|
||||
int
|
||||
Xasprintf(char **ret, const char *_X_RESTRICT_KYWD format, ...)
|
||||
{
|
||||
int size;
|
||||
va_list va;
|
||||
|
||||
va_start(va, format);
|
||||
size = vasprintf(ret, format, va);
|
||||
va_end(va);
|
||||
return size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Varargs sprintf that allocates a string buffer the right size for
|
||||
* the pattern & data provided and prints the requested data to it.
|
||||
* On failure, issues a FatalError message and aborts the server.
|
||||
*
|
||||
* @param ret Pointer to which the newly allocated buffer is written
|
||||
* (contents undefined on error)
|
||||
* @param format printf style format string
|
||||
* @param va variable argument list
|
||||
* @return size of allocated buffer
|
||||
*/
|
||||
int
|
||||
XNFvasprintf(char **ret, const char *_X_RESTRICT_KYWD format, va_list va)
|
||||
{
|
||||
int size = vasprintf(ret, format, va);
|
||||
|
||||
if ((size == -1) || (*ret == NULL)) {
|
||||
FatalError("XNFvasprintf failed: %s", strerror(errno));
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
/**
|
||||
* sprintf that allocates a string buffer the right size for
|
||||
* the pattern & data provided and prints the requested data to it.
|
||||
* On failure, issues a FatalError message and aborts the server.
|
||||
*
|
||||
* @param ret Pointer to which the newly allocated buffer is written
|
||||
* (contents undefined on error)
|
||||
* @param format printf style format string
|
||||
* @param ... arguments for specified format
|
||||
* @return size of allocated buffer
|
||||
*/
|
||||
int
|
||||
XNFasprintf(char **ret, const char *_X_RESTRICT_KYWD format, ...)
|
||||
{
|
||||
int size;
|
||||
va_list va;
|
||||
|
||||
va_start(va, format);
|
||||
size = XNFvasprintf(ret, format, va);
|
||||
va_end(va);
|
||||
return size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Varargs snprintf that returns the actual number of bytes (excluding final
|
||||
* '\0') that were copied into the buffer.
|
||||
* This is opposed to the normal sprintf() usually returns the number of bytes
|
||||
* that would have been written.
|
||||
*
|
||||
* @param s buffer to copy into
|
||||
* @param n size of buffer s
|
||||
* @param format printf style format string
|
||||
* @param va variable argument list
|
||||
* @return number of bytes actually copied, excluding final '\0'
|
||||
*/
|
||||
int
|
||||
Xvscnprintf(char *s, int n, const char *format, va_list args)
|
||||
{
|
||||
int x;
|
||||
if (n == 0)
|
||||
return 0;
|
||||
x = vsnprintf(s, n , format, args);
|
||||
return (x >= n) ? (n - 1) : x;
|
||||
}
|
||||
|
||||
/**
|
||||
* snprintf that returns the actual number of bytes (excluding final '\0') that
|
||||
* were copied into the buffer.
|
||||
* This is opposed to the normal sprintf() usually returns the number of bytes
|
||||
* that would have been written.
|
||||
*
|
||||
* @param s buffer to copy into
|
||||
* @param n size of buffer s
|
||||
* @param format printf style format string
|
||||
* @param ... arguments for specified format
|
||||
* @return number of bytes actually copied, excluding final '\0'
|
||||
*/
|
||||
int Xscnprintf(char *s, int n, const char *format, ...)
|
||||
{
|
||||
int x;
|
||||
va_list ap;
|
||||
va_start(ap, format);
|
||||
x = Xvscnprintf(s, n, format, ap);
|
||||
va_end(ap);
|
||||
return x;
|
||||
}
|
||||
|
||||
/* Old api, now deprecated, may be removed in the future */
|
||||
char *
|
||||
Xvprintf(const char *format, va_list va)
|
||||
{
|
||||
char *ret;
|
||||
|
||||
if (vasprintf(&ret, format, va) == -1)
|
||||
ret = NULL;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
char *
|
||||
Xprintf(const char *format, ...)
|
||||
{
|
||||
char *ret;
|
||||
va_list va;
|
||||
|
||||
va_start(va, format);
|
||||
if (vasprintf(&ret, format, va) == -1)
|
||||
ret = NULL;
|
||||
va_end(va);
|
||||
return ret;
|
||||
}
|
||||
|
||||
char *
|
||||
XNFvprintf(const char *format, va_list va)
|
||||
{
|
||||
char *ret;
|
||||
|
||||
XNFvasprintf(&ret, format, va);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
char *
|
||||
XNFprintf(const char *format, ...)
|
||||
{
|
||||
char *ret;
|
||||
va_list va;
|
||||
|
||||
va_start(va, format);
|
||||
XNFvasprintf(&ret, format, va);
|
||||
va_end(va);
|
||||
return ret;
|
||||
}
|
||||
17
nx-X11/programs/Xserver/os/xstrans.c
Normal file
17
nx-X11/programs/Xserver/os/xstrans.c
Normal file
@@ -0,0 +1,17 @@
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#include <nx-X11/Xfuncproto.h>
|
||||
|
||||
/* ErrorF is used by xtrans */
|
||||
#ifndef HAVE_DIX_CONFIG_H
|
||||
extern _X_EXPORT void
|
||||
ErrorF(const char *f, ...)
|
||||
_X_ATTRIBUTE_PRINTF(1, 2);
|
||||
#endif
|
||||
|
||||
#define TRANS_REOPEN
|
||||
#define TRANS_SERVER
|
||||
#define XSERV_t
|
||||
#include <nx-X11/Xtrans/transport.c>
|
||||
Reference in New Issue
Block a user