Merge remote branch 'rjy/clientids'
This commit is contained in:
		
						commit
						8e4c3ce55b
					
				| 
						 | 
					@ -40,6 +40,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 | 
				
			||||||
#include "propertyst.h"
 | 
					#include "propertyst.h"
 | 
				
			||||||
#include "extnsionst.h"
 | 
					#include "extnsionst.h"
 | 
				
			||||||
#include "xacestr.h"
 | 
					#include "xacestr.h"
 | 
				
			||||||
 | 
					#include "client.h"
 | 
				
			||||||
#include "../os/osdep.h"
 | 
					#include "../os/osdep.h"
 | 
				
			||||||
#define _XSELINUX_NEED_FLASK_MAP
 | 
					#define _XSELINUX_NEED_FLASK_MAP
 | 
				
			||||||
#include "xselinuxint.h"
 | 
					#include "xselinuxint.h"
 | 
				
			||||||
| 
						 | 
					@ -129,26 +130,25 @@ SELinuxLabelClient(ClientPtr client)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* For local clients, try and determine the executable name */
 | 
					    /* For local clients, try and determine the executable name */
 | 
				
			||||||
    if (XaceIsLocal(client)) {
 | 
					    if (XaceIsLocal(client)) {
 | 
				
			||||||
	struct ucred creds;
 | 
						/* Get cached command name if CLIENTIDS is enabled. */
 | 
				
			||||||
	socklen_t len = sizeof(creds);
 | 
						const char *cmdname = GetClientCmdName(client);
 | 
				
			||||||
	char path[PATH_MAX + 1];
 | 
						Bool cached = (cmdname != NULL);
 | 
				
			||||||
	size_t bytes;
 | 
						/* If CLIENTIDS is disabled, figure out the command name from
 | 
				
			||||||
 | 
						 * scratch. */
 | 
				
			||||||
 | 
						if (!cmdname)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
						    pid_t pid = DetermineClientPid(client);
 | 
				
			||||||
 | 
						    if (pid != -1)
 | 
				
			||||||
 | 
							DetermineClientCmd(pid, &cmdname, NULL);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	memset(&creds, 0, sizeof(creds));
 | 
						if (!cmdname)
 | 
				
			||||||
	if (getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &creds, &len) < 0)
 | 
					 | 
				
			||||||
	    goto finish;
 | 
						    goto finish;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	snprintf(path, PATH_MAX + 1, "/proc/%d/cmdline", creds.pid);
 | 
						strncpy(subj->command, cmdname, COMMAND_LEN - 1);
 | 
				
			||||||
	fd = open(path, O_RDONLY);
 | 
					 | 
				
			||||||
	if (fd < 0)
 | 
					 | 
				
			||||||
	    goto finish;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	bytes = read(fd, path, PATH_MAX + 1);
 | 
						if (!cached)
 | 
				
			||||||
	close(fd);
 | 
						    free((void *) cmdname); /* const char * */
 | 
				
			||||||
	if (bytes <= 0)
 | 
					 | 
				
			||||||
	    goto finish;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	strncpy(subj->command, path, COMMAND_LEN - 1);
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
finish:
 | 
					finish:
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										28
									
								
								configure.ac
								
								
								
								
							
							
						
						
									
										28
									
								
								configure.ac
								
								
								
								
							| 
						 | 
					@ -312,19 +312,6 @@ AC_CHECK_HEADER([execinfo.h],[
 | 
				
			||||||
    ])]
 | 
					    ])]
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
dnl ARM needs additional compiler flags for proper backtraces if GCC is
 | 
					 | 
				
			||||||
dnl used. Compile a dummy program with the -mapcs-frame option. If it
 | 
					 | 
				
			||||||
dnl succeeds, we know that we are building for ARM with GCC.
 | 
					 | 
				
			||||||
old_CFLAGS="$CFLAGS"
 | 
					 | 
				
			||||||
CFLAGS="-mapcs-frame"
 | 
					 | 
				
			||||||
AC_COMPILE_IFELSE(
 | 
					 | 
				
			||||||
        AC_LANG_PROGRAM([[ ]]),
 | 
					 | 
				
			||||||
        ARM_BACKTRACE_CFLAGS="$CFLAGS",
 | 
					 | 
				
			||||||
        ARM_BACKTRACE_CFLAGS=""
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
CFLAGS="$old_CFLAGS"
 | 
					 | 
				
			||||||
AC_SUBST(ARM_BACKTRACE_CFLAGS)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
dnl ---------------------------------------------------------------------------
 | 
					dnl ---------------------------------------------------------------------------
 | 
				
			||||||
dnl Bus options and CPU capabilities.  Replaces logic in
 | 
					dnl Bus options and CPU capabilities.  Replaces logic in
 | 
				
			||||||
dnl hw/xfree86/os-support/bus/Makefile.am, among others.
 | 
					dnl hw/xfree86/os-support/bus/Makefile.am, among others.
 | 
				
			||||||
| 
						 | 
					@ -641,6 +628,7 @@ AC_ARG_ENABLE(vbe,            AS_HELP_STRING([--enable-vbe], [Build Xorg with VB
 | 
				
			||||||
AC_ARG_ENABLE(int10-module,     AS_HELP_STRING([--enable-int10-module], [Build Xorg with int10 module (default: enabled)]), [INT10MODULE=$enableval], [INT10MODULE=yes])
 | 
					AC_ARG_ENABLE(int10-module,     AS_HELP_STRING([--enable-int10-module], [Build Xorg with int10 module (default: enabled)]), [INT10MODULE=$enableval], [INT10MODULE=yes])
 | 
				
			||||||
AC_ARG_ENABLE(windowswm,      AS_HELP_STRING([--enable-windowswm], [Build XWin with WindowsWM extension (default: no)]), [WINDOWSWM=$enableval], [WINDOWSWM=no])
 | 
					AC_ARG_ENABLE(windowswm,      AS_HELP_STRING([--enable-windowswm], [Build XWin with WindowsWM extension (default: no)]), [WINDOWSWM=$enableval], [WINDOWSWM=no])
 | 
				
			||||||
AC_ARG_ENABLE(libdrm,         AS_HELP_STRING([--enable-libdrm], [Build Xorg with libdrm support (default: enabled)]), [DRM=$enableval],[DRM=yes])
 | 
					AC_ARG_ENABLE(libdrm,         AS_HELP_STRING([--enable-libdrm], [Build Xorg with libdrm support (default: enabled)]), [DRM=$enableval],[DRM=yes])
 | 
				
			||||||
 | 
					AC_ARG_ENABLE(clientids,      AS_HELP_STRING([--disable-clientids], [Build Xorg with client ID tracking (default: enabled)]), [CLIENTIDS=$enableval], [CLIENTIDS=yes])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
dnl DDXes.
 | 
					dnl DDXes.
 | 
				
			||||||
AC_ARG_ENABLE(xorg,    	      AS_HELP_STRING([--enable-xorg], [Build Xorg server (default: auto)]), [XORG=$enableval], [XORG=auto])
 | 
					AC_ARG_ENABLE(xorg,    	      AS_HELP_STRING([--enable-xorg], [Build Xorg server (default: auto)]), [XORG=$enableval], [XORG=auto])
 | 
				
			||||||
| 
						 | 
					@ -994,6 +982,18 @@ if test "x$RES" = xyes; then
 | 
				
			||||||
	REQUIRED_MODULES="$REQUIRED_MODULES $RESOURCEPROTO"
 | 
						REQUIRED_MODULES="$REQUIRED_MODULES $RESOURCEPROTO"
 | 
				
			||||||
fi
 | 
					fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# The XRes extension may support client ID tracking only if it has
 | 
				
			||||||
 | 
					# been specifically enabled. Client ID tracking is implicitly not
 | 
				
			||||||
 | 
					# supported if XRes extension is disabled.
 | 
				
			||||||
 | 
					AC_MSG_CHECKING([whether to track client ids])
 | 
				
			||||||
 | 
					if test "x$RES" = xyes && test "x$CLIENTIDS" = xyes; then
 | 
				
			||||||
 | 
						AC_DEFINE(CLIENTIDS, 1, [Support client ID tracking])
 | 
				
			||||||
 | 
					else
 | 
				
			||||||
 | 
						CLIENTIDS=no
 | 
				
			||||||
 | 
					fi
 | 
				
			||||||
 | 
					AC_MSG_RESULT([$CLIENTIDS])
 | 
				
			||||||
 | 
					AM_CONDITIONAL(CLIENTIDS, [test "x$CLIENTIDS" = xyes])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if test "x$GLX" = xyes; then
 | 
					if test "x$GLX" = xyes; then
 | 
				
			||||||
	PKG_CHECK_MODULES([XLIB], [x11])
 | 
						PKG_CHECK_MODULES([XLIB], [x11])
 | 
				
			||||||
	PKG_CHECK_MODULES([GL], $GLPROTO $LIBGL)
 | 
						PKG_CHECK_MODULES([GL], $GLPROTO $LIBGL)
 | 
				
			||||||
| 
						 | 
					@ -1525,7 +1525,7 @@ if test "x$XNEST" = xyes; then
 | 
				
			||||||
	if test "x$have_xnest" = xno; then
 | 
						if test "x$have_xnest" = xno; then
 | 
				
			||||||
		AC_MSG_ERROR([Xnest build explicitly requested, but required modules not found.])
 | 
							AC_MSG_ERROR([Xnest build explicitly requested, but required modules not found.])
 | 
				
			||||||
	fi
 | 
						fi
 | 
				
			||||||
	XNEST_LIBS="$FB_LIB $FIXES_LIB $MI_LIB $XEXT_LIB $DBE_LIB $RECORD_LIB $GLX_LIBS $RANDR_LIB $RENDER_LIB $DAMAGE_LIB $MIEXT_SYNC_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $COMPOSITE_LIB $DIX_LIB $MAIN_LIB $OS_LIB"
 | 
						XNEST_LIBS="$FB_LIB $FIXES_LIB $MI_LIB $XEXT_LIB $DBE_LIB $RECORD_LIB $GLX_LIBS $RANDR_LIB $RENDER_LIB $DAMAGE_LIB $MIEXT_SYNC_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $COMPOSITE_LIB $MAIN_LIB $DIX_LIB $OS_LIB"
 | 
				
			||||||
	XNEST_SYS_LIBS="$XNESTMODULES_LIBS $GLX_SYS_LIBS"
 | 
						XNEST_SYS_LIBS="$XNESTMODULES_LIBS $GLX_SYS_LIBS"
 | 
				
			||||||
	AC_SUBST([XNEST_LIBS])
 | 
						AC_SUBST([XNEST_LIBS])
 | 
				
			||||||
	AC_SUBST([XNEST_SYS_LIBS])
 | 
						AC_SUBST([XNEST_SYS_LIBS])
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -130,6 +130,7 @@ int ProcInitialConnection();
 | 
				
			||||||
#include "inputstr.h"
 | 
					#include "inputstr.h"
 | 
				
			||||||
#include "xkbsrv.h"
 | 
					#include "xkbsrv.h"
 | 
				
			||||||
#include "site.h"
 | 
					#include "site.h"
 | 
				
			||||||
 | 
					#include "client.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef XSERVER_DTRACE
 | 
					#ifdef XSERVER_DTRACE
 | 
				
			||||||
#include "registry.h"
 | 
					#include "registry.h"
 | 
				
			||||||
| 
						 | 
					@ -3459,6 +3460,9 @@ CloseDownClient(ClientPtr client)
 | 
				
			||||||
	    CallCallbacks((&ClientStateCallback), (pointer)&clientinfo);
 | 
						    CallCallbacks((&ClientStateCallback), (pointer)&clientinfo);
 | 
				
			||||||
	} 	    
 | 
						} 	    
 | 
				
			||||||
	FreeClientResources(client);
 | 
						FreeClientResources(client);
 | 
				
			||||||
 | 
						/* Disable client ID tracking. This must be done after
 | 
				
			||||||
 | 
						 * ClientStateCallback. */
 | 
				
			||||||
 | 
						ReleaseClientIds(client);
 | 
				
			||||||
#ifdef XSERVER_DTRACE
 | 
					#ifdef XSERVER_DTRACE
 | 
				
			||||||
	XSERVER_CLIENT_DISCONNECT(client->index);
 | 
						XSERVER_CLIENT_DISCONNECT(client->index);
 | 
				
			||||||
#endif	
 | 
					#endif	
 | 
				
			||||||
| 
						 | 
					@ -3496,6 +3500,7 @@ void InitClient(ClientPtr client, int i, pointer ospriv)
 | 
				
			||||||
    client->smart_start_tick = SmartScheduleTime;
 | 
					    client->smart_start_tick = SmartScheduleTime;
 | 
				
			||||||
    client->smart_stop_tick = SmartScheduleTime;
 | 
					    client->smart_stop_tick = SmartScheduleTime;
 | 
				
			||||||
    client->smart_check_tick = SmartScheduleTime;
 | 
					    client->smart_check_tick = SmartScheduleTime;
 | 
				
			||||||
 | 
					    client->clientIds = NULL;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/************************
 | 
					/************************
 | 
				
			||||||
| 
						 | 
					@ -3535,6 +3540,11 @@ ClientPtr NextAvailableClient(pointer ospriv)
 | 
				
			||||||
	currentMaxClients++;
 | 
						currentMaxClients++;
 | 
				
			||||||
    while ((nextFreeClientID < MAXCLIENTS) && clients[nextFreeClientID])
 | 
					    while ((nextFreeClientID < MAXCLIENTS) && clients[nextFreeClientID])
 | 
				
			||||||
	nextFreeClientID++;
 | 
						nextFreeClientID++;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Enable client ID tracking. This must be done before
 | 
				
			||||||
 | 
					     * ClientStateCallback. */
 | 
				
			||||||
 | 
					    ReserveClientIds(client);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (ClientStateCallback)
 | 
					    if (ClientStateCallback)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
	NewClientInfoRec clientinfo;
 | 
						NewClientInfoRec clientinfo;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -104,6 +104,7 @@ Equipment Corporation.
 | 
				
			||||||
#include "extnsionst.h"
 | 
					#include "extnsionst.h"
 | 
				
			||||||
#include "privates.h"
 | 
					#include "privates.h"
 | 
				
			||||||
#include "registry.h"
 | 
					#include "registry.h"
 | 
				
			||||||
 | 
					#include "client.h"
 | 
				
			||||||
#ifdef PANORAMIX
 | 
					#ifdef PANORAMIX
 | 
				
			||||||
#include "panoramiXsrv.h"
 | 
					#include "panoramiXsrv.h"
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
| 
						 | 
					@ -258,6 +259,7 @@ int main(int argc, char *argv[], char *envp[])
 | 
				
			||||||
        InitCoreDevices();
 | 
					        InitCoreDevices();
 | 
				
			||||||
	InitInput(argc, argv);
 | 
						InitInput(argc, argv);
 | 
				
			||||||
	InitAndStartDevices();
 | 
						InitAndStartDevices();
 | 
				
			||||||
 | 
						ReserveClientIds(serverClient);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	dixSaveScreens(serverClient, SCREEN_SAVER_FORCER, ScreenSaverReset);
 | 
						dixSaveScreens(serverClient, SCREEN_SAVER_FORCER, ScreenSaverReset);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -323,6 +325,7 @@ int main(int argc, char *argv[], char *envp[])
 | 
				
			||||||
	    screenInfo.numScreens = i;
 | 
						    screenInfo.numScreens = i;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ReleaseClientIds(serverClient);
 | 
				
			||||||
	dixFreePrivates(serverClient->devPrivates, PRIVATE_CLIENT);
 | 
						dixFreePrivates(serverClient->devPrivates, PRIVATE_CLIENT);
 | 
				
			||||||
	serverClient->devPrivates = NULL;
 | 
						serverClient->devPrivates = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -259,6 +259,7 @@ cat > sdksyms.c << EOF
 | 
				
			||||||
#include "colormap.h"
 | 
					#include "colormap.h"
 | 
				
			||||||
#include "colormapst.h"
 | 
					#include "colormapst.h"
 | 
				
			||||||
#include "hotplug.h"
 | 
					#include "hotplug.h"
 | 
				
			||||||
 | 
					#include "client.h"
 | 
				
			||||||
#include "cursor.h"
 | 
					#include "cursor.h"
 | 
				
			||||||
#include "cursorstr.h"
 | 
					#include "cursorstr.h"
 | 
				
			||||||
#include "dix.h"
 | 
					#include "dix.h"
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3,6 +3,7 @@ sdk_HEADERS =		\
 | 
				
			||||||
	XIstubs.h	\
 | 
						XIstubs.h	\
 | 
				
			||||||
	Xprintf.h	\
 | 
						Xprintf.h	\
 | 
				
			||||||
	callback.h	\
 | 
						callback.h	\
 | 
				
			||||||
 | 
						client.h	\
 | 
				
			||||||
	closestr.h	\
 | 
						closestr.h	\
 | 
				
			||||||
	closure.h	\
 | 
						closure.h	\
 | 
				
			||||||
	colormap.h	\
 | 
						colormap.h	\
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,59 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). 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.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Author: Rami Ylimäki <rami.ylimaki@vincit.fi> */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef CLIENT_H
 | 
				
			||||||
 | 
					#define CLIENT_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef HAVE_DIX_CONFIG_H
 | 
				
			||||||
 | 
					#include <dix-config.h>
 | 
				
			||||||
 | 
					#endif /* HAVE_DIX_CONFIG_H */
 | 
				
			||||||
 | 
					#include <X11/Xfuncproto.h>
 | 
				
			||||||
 | 
					#include <sys/types.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Client IDs. Use GetClientPid, GetClientCmdName and GetClientCmdArgs
 | 
				
			||||||
 | 
					 * instead of accessing the fields directly. */
 | 
				
			||||||
 | 
					typedef struct {
 | 
				
			||||||
 | 
					    pid_t pid;           /* process ID, -1 if not available */
 | 
				
			||||||
 | 
					    const char *cmdname; /* process name, NULL if not available */
 | 
				
			||||||
 | 
					    const char *cmdargs; /* process arguments, NULL if not available */
 | 
				
			||||||
 | 
					} ClientIdRec, *ClientIdPtr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct _Client;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Initialize and clean up. */
 | 
				
			||||||
 | 
					void ReserveClientIds(struct _Client *client);
 | 
				
			||||||
 | 
					void ReleaseClientIds(struct _Client *client);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Determine client IDs for caching. Exported on purpose for
 | 
				
			||||||
 | 
					 * extensions such as SELinux. */
 | 
				
			||||||
 | 
					extern _X_EXPORT pid_t DetermineClientPid(struct _Client *client);
 | 
				
			||||||
 | 
					extern _X_EXPORT void DetermineClientCmd(pid_t, const char **cmdname, const char **cmdargs);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Query cached client IDs. Exported on purpose for drivers. */
 | 
				
			||||||
 | 
					extern _X_EXPORT pid_t GetClientPid(struct _Client *client);
 | 
				
			||||||
 | 
					extern _X_EXPORT const char *GetClientCmdName(struct _Client *client);
 | 
				
			||||||
 | 
					extern _X_EXPORT const char *GetClientCmdArgs(struct _Client *client);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif /* CLIENT_H */
 | 
				
			||||||
| 
						 | 
					@ -279,6 +279,9 @@
 | 
				
			||||||
/* Support X resource extension */
 | 
					/* Support X resource extension */
 | 
				
			||||||
#undef RES
 | 
					#undef RES
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Support client ID tracking in X resource extension */
 | 
				
			||||||
 | 
					#undef CLIENTIDS
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Support MIT-SCREEN-SAVER extension */
 | 
					/* Support MIT-SCREEN-SAVER extension */
 | 
				
			||||||
#undef SCREENSAVER
 | 
					#undef SCREENSAVER
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -24,6 +24,7 @@ SOFTWARE.
 | 
				
			||||||
#ifndef DIXSTRUCT_H
 | 
					#ifndef DIXSTRUCT_H
 | 
				
			||||||
#define DIXSTRUCT_H
 | 
					#define DIXSTRUCT_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "client.h"
 | 
				
			||||||
#include "dix.h"
 | 
					#include "dix.h"
 | 
				
			||||||
#include "resource.h"
 | 
					#include "resource.h"
 | 
				
			||||||
#include "cursor.h"
 | 
					#include "cursor.h"
 | 
				
			||||||
| 
						 | 
					@ -121,6 +122,7 @@ typedef struct _Client {
 | 
				
			||||||
    long    smart_check_tick;
 | 
					    long    smart_check_tick;
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    DeviceIntPtr clientPtr;
 | 
					    DeviceIntPtr clientPtr;
 | 
				
			||||||
 | 
					    ClientIdPtr  clientIds;
 | 
				
			||||||
}           ClientRec;
 | 
					}           ClientRec;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,25 +1,18 @@
 | 
				
			||||||
noinst_LTLIBRARIES = libos.la liblog.la
 | 
					noinst_LTLIBRARIES = libos.la
 | 
				
			||||||
 | 
					
 | 
				
			||||||
AM_CFLAGS = $(DIX_CFLAGS) $(SHA1_CFLAGS)
 | 
					AM_CFLAGS = $(DIX_CFLAGS) $(SHA1_CFLAGS)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
SECURERPC_SRCS = rpcauth.c
 | 
					SECURERPC_SRCS = rpcauth.c
 | 
				
			||||||
XDMCP_SRCS = xdmcp.c
 | 
					XDMCP_SRCS = xdmcp.c
 | 
				
			||||||
STRLCAT_SRCS = strlcat.c strlcpy.c
 | 
					STRLCAT_SRCS = strlcat.c strlcpy.c
 | 
				
			||||||
 | 
					XORG_SRCS = log.c
 | 
				
			||||||
# Build a convenience library liblog.la that will be added into
 | 
					 | 
				
			||||||
# libos.la. The split is done so that log.c can be built with
 | 
					 | 
				
			||||||
# different compiler options.
 | 
					 | 
				
			||||||
liblog_la_SOURCES = log.c
 | 
					 | 
				
			||||||
# Add flags needed for proper backtraces of functions marked with GCC
 | 
					 | 
				
			||||||
# __attribute__((noreturn)). Currently those flags are needed for
 | 
					 | 
				
			||||||
# FatalError and AbortServer in log.c.
 | 
					 | 
				
			||||||
liblog_la_CFLAGS = $(AM_CFLAGS) $(ARM_BACKTRACE_CFLAGS)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
libos_la_SOURCES = 	\
 | 
					libos_la_SOURCES = 	\
 | 
				
			||||||
	WaitFor.c	\
 | 
						WaitFor.c	\
 | 
				
			||||||
	access.c	\
 | 
						access.c	\
 | 
				
			||||||
	auth.c		\
 | 
						auth.c		\
 | 
				
			||||||
	backtrace.c	\
 | 
						backtrace.c	\
 | 
				
			||||||
 | 
						client.c	\
 | 
				
			||||||
	connection.c	\
 | 
						connection.c	\
 | 
				
			||||||
	io.c		\
 | 
						io.c		\
 | 
				
			||||||
	mitauth.c	\
 | 
						mitauth.c	\
 | 
				
			||||||
| 
						 | 
					@ -32,8 +25,9 @@ libos_la_SOURCES = 	\
 | 
				
			||||||
	xdmauth.c	\
 | 
						xdmauth.c	\
 | 
				
			||||||
	xsha1.c		\
 | 
						xsha1.c		\
 | 
				
			||||||
	xstrans.c	\
 | 
						xstrans.c	\
 | 
				
			||||||
	xprintf.c
 | 
						xprintf.c	\
 | 
				
			||||||
libos_la_LIBADD = @SHA1_LIBS@ $(DLOPEN_LIBS) liblog.la
 | 
						$(XORG_SRCS)
 | 
				
			||||||
 | 
					libos_la_LIBADD = @SHA1_LIBS@ $(DLOPEN_LIBS)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if SECURE_RPC
 | 
					if SECURE_RPC
 | 
				
			||||||
libos_la_SOURCES += $(SECURERPC_SRCS)
 | 
					libos_la_SOURCES += $(SECURERPC_SRCS)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,310 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * 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"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * 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 cmdsize = 0;
 | 
				
			||||||
 | 
					    int argsize = 0;
 | 
				
			||||||
 | 
					    int fd = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (cmdname)
 | 
				
			||||||
 | 
					        *cmdname = NULL;
 | 
				
			||||||
 | 
					    if (cmdargs)
 | 
				
			||||||
 | 
					        *cmdargs = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (pid == -1)
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* 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));
 | 
				
			||||||
 | 
					    if (totsize <= 0)
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    if (close(fd) < 0)
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    path[totsize - 1] = '\0';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Contruct the process name without arguments. */
 | 
				
			||||||
 | 
					    cmdsize = strlen(path) + 1;
 | 
				
			||||||
 | 
					    if (cmdname)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        char *name = malloc(cmdsize);
 | 
				
			||||||
 | 
					        if (name)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            strncpy(name, path, cmdsize);
 | 
				
			||||||
 | 
					            name[cmdsize - 1] = '\0';
 | 
				
			||||||
 | 
					            *cmdname = name;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Construct the arguments for client process. */
 | 
				
			||||||
 | 
					    argsize = totsize - cmdsize;
 | 
				
			||||||
 | 
					    if (cmdargs && (argsize > 0))
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        char *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;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * 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",
 | 
				
			||||||
 | 
					           client->clientAsMask, client->clientIds->pid);
 | 
				
			||||||
 | 
					    DebugF("client(%lx): Reserved cmdname(%s) and cmdargs(%s).\n",
 | 
				
			||||||
 | 
					           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",
 | 
				
			||||||
 | 
					           client->clientAsMask, client->clientIds->pid);
 | 
				
			||||||
 | 
					    DebugF("client(%lx): Released cmdline(%s) and cmdargs(%s).\n",
 | 
				
			||||||
 | 
					           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;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Loading…
	
		Reference in New Issue