diff -Naur old/X11/Xarch.h new/X11/Xarch.h
--- old/X11/Xarch.h	1970-01-01 08:00:00.000000000 +0800
+++ new/X11/Xarch.h	2024-03-05 19:36:25.208040000 +0800
@@ -0,0 +1,94 @@
+#ifndef _XARCH_H_
+# define _XARCH_H_
+
+/*
+ * Copyright 1997 Metro Link Incorporated
+ *
+ *                           All Rights Reserved
+ *
+ * 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, and that the names of the above listed copyright holder(s)
+ * not be used in advertising or publicity pertaining to distribution of
+ * the software without specific, written prior permission.  The above listed
+ * copyright holder(s) make(s) no representations about the suitability of
+ * this software for any purpose.  It is provided "as is" without express or
+ * implied warranty.
+ *
+ * THE ABOVE LISTED COPYRIGHT HOLDER(S) DISCLAIM(S) ALL WARRANTIES WITH REGARD
+ * TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS, IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) 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.
+ */
+
+
+/*
+ * Determine the machine's byte order.
+ */
+
+/* See if it is set in the imake config first */
+# ifdef X_BYTE_ORDER
+
+#  define X_BIG_ENDIAN 4321
+#  define X_LITTLE_ENDIAN 1234
+
+# else
+
+#  if defined(SVR4) || defined(__SVR4)
+#   include <sys/types.h>
+#   include <sys/byteorder.h>
+#  elif defined(CSRG_BASED)
+#   if defined(__NetBSD__) || defined(__OpenBSD__)
+#    include <sys/types.h>
+#   endif
+#   include <machine/endian.h>
+#  elif defined(linux)
+#   if defined __STRICT_ANSI__
+#    undef __STRICT_ANSI__
+#    include <endian.h>
+#    define __STRICT_ANSI__
+#   else
+#    include <endian.h>
+#   endif
+/* 'endian.h' might have been included before 'Xarch.h' */
+#   if !defined(LITTLE_ENDIAN) && defined(__LITTLE_ENDIAN)
+#    define LITTLE_ENDIAN __LITTLE_ENDIAN
+#   endif
+#   if !defined(BIG_ENDIAN) && defined(__BIG_ENDIAN)
+#    define BIG_ENDIAN __BIG_ENDIAN
+#   endif
+#   if !defined(PDP_ENDIAN) && defined(__PDP_ENDIAN)
+#    define PDP_ENDIAN __PDP_ENDIAN
+#   endif
+#   if !defined(BYTE_ORDER) && defined(__BYTE_ORDER)
+#    define BYTE_ORDER __BYTE_ORDER
+#   endif
+#  endif
+
+#  ifndef BYTE_ORDER
+#   define LITTLE_ENDIAN 1234
+#   define BIG_ENDIAN    4321
+
+#   if defined(__sun) && defined(__SVR4)
+#    include <sys/isa_defs.h>
+#    ifdef _LITTLE_ENDIAN
+#     define BYTE_ORDER LITTLE_ENDIAN
+#    endif
+#    ifdef _BIG_ENDIAN
+#     define BYTE_ORDER BIG_ENDIAN
+#    endif
+#   endif /* sun */
+#  endif /* BYTE_ORDER */
+
+#  define X_BYTE_ORDER BYTE_ORDER
+#  define X_BIG_ENDIAN BIG_ENDIAN
+#  define X_LITTLE_ENDIAN LITTLE_ENDIAN
+
+# endif /* not in imake config */
+
+#endif /* _XARCH_H_ */
diff -Naur old/X11/Xfuncproto.h new/X11/Xfuncproto.h
--- old/X11/Xfuncproto.h	1970-01-01 08:00:00.000000000 +0800
+++ new/X11/Xfuncproto.h	2024-03-05 19:36:25.208040000 +0800
@@ -0,0 +1,221 @@
+/*
+ *
+Copyright 1989, 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.
+ *
+ */
+
+/* Definitions to make function prototypes manageable */
+
+#ifndef _XFUNCPROTO_H_
+#define _XFUNCPROTO_H_
+
+#ifndef NeedFunctionPrototypes
+#define NeedFunctionPrototypes 1
+#endif /* NeedFunctionPrototypes */
+
+#ifndef NeedVarargsPrototypes
+#define NeedVarargsPrototypes 1
+#endif /* NeedVarargsPrototypes */
+
+#if NeedFunctionPrototypes
+
+#ifndef NeedNestedPrototypes
+#define NeedNestedPrototypes 1
+#endif /* NeedNestedPrototypes */
+
+#ifndef _Xconst
+#define _Xconst const
+#endif /* _Xconst */
+
+/* Function prototype configuration (see configure for more info) */
+#if !defined(NARROWPROTO) && \
+    (defined(__linux__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__))
+#define NARROWPROTO
+#endif
+#ifndef FUNCPROTO
+#define FUNCPROTO 15
+#endif
+
+#ifndef NeedWidePrototypes
+#ifdef NARROWPROTO
+#define NeedWidePrototypes 0
+#else
+#define NeedWidePrototypes 1		/* default to make interropt. easier */
+#endif
+#endif /* NeedWidePrototypes */
+
+#endif /* NeedFunctionPrototypes */
+
+#ifndef _XFUNCPROTOBEGIN
+#if defined(__cplusplus) || defined(c_plusplus) /* for C++ V2.0 */
+#define _XFUNCPROTOBEGIN extern "C" {	/* do not leave open across includes */
+#define _XFUNCPROTOEND }
+#else
+#define _XFUNCPROTOBEGIN
+#define _XFUNCPROTOEND
+#endif
+#endif /* _XFUNCPROTOBEGIN */
+
+/* http://clang.llvm.org/docs/LanguageExtensions.html#has-attribute */
+#ifndef __has_attribute
+# define __has_attribute(x) 0  /* Compatibility with non-clang compilers. */
+#endif
+#ifndef __has_feature
+# define __has_feature(x) 0    /* Compatibility with non-clang compilers. */
+#endif
+#ifndef __has_extension
+# define __has_extension(x) 0  /* Compatibility with non-clang compilers. */
+#endif
+
+/* Added in X11R6.9, so available in any version of modular xproto */
+#if __has_attribute(__sentinel__) || (defined(__GNUC__) && (__GNUC__ >= 4))
+# define _X_SENTINEL(x) __attribute__ ((__sentinel__(x)))
+#else
+# define _X_SENTINEL(x)
+#endif /* GNUC >= 4 */
+
+/* Added in X11R6.9, so available in any version of modular xproto */
+#if (__has_attribute(visibility) || (defined(__GNUC__) && (__GNUC__ >= 4))) \
+    && !defined(__CYGWIN__) && !defined(__MINGW32__)
+# define _X_EXPORT      __attribute__((visibility("default")))
+# define _X_HIDDEN      __attribute__((visibility("hidden")))
+# define _X_INTERNAL    __attribute__((visibility("internal")))
+#elif defined(__SUNPRO_C) && (__SUNPRO_C >= 0x550)
+# define _X_EXPORT      __global
+# define _X_HIDDEN      __hidden
+# define _X_INTERNAL    __hidden
+#else /* not gcc >= 4 and not Sun Studio >= 8 */
+# define _X_EXPORT
+# define _X_HIDDEN
+# define _X_INTERNAL
+#endif /* GNUC >= 4 */
+
+/* Branch prediction hints for individual conditionals */
+/* requires xproto >= 7.0.9 */
+#if defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 303)
+# define _X_LIKELY(x)   __builtin_expect(!!(x), 1)
+# define _X_UNLIKELY(x) __builtin_expect(!!(x), 0)
+#else /* not gcc >= 3.3 */
+# define _X_LIKELY(x)   (x)
+# define _X_UNLIKELY(x) (x)
+#endif
+
+/* Bulk branch prediction hints via marking error path functions as "cold" */
+/* requires xproto >= 7.0.25 */
+#if __has_attribute(__cold__) || \
+    (defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 403)) /* 4.3+ */
+# define _X_COLD __attribute__((__cold__))
+#else
+# define _X_COLD /* nothing */
+#endif
+
+/* Added in X11R6.9, so available in any version of modular xproto */
+#if __has_attribute(deprecated) \
+    || (defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 301)) \
+    || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x5130))
+# define _X_DEPRECATED  __attribute__((deprecated))
+#else /* not gcc >= 3.1 */
+# define _X_DEPRECATED
+#endif
+
+/* requires xproto >= 7.0.30 */
+#if __has_extension(attribute_deprecated_with_message) || \
+                (defined(__GNUC__) && ((__GNUC__ >= 5) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5))))
+# define _X_DEPRECATED_MSG(_msg) __attribute__((deprecated(_msg)))
+#else
+# define _X_DEPRECATED_MSG(_msg) _X_DEPRECATED
+#endif
+
+/* requires xproto >= 7.0.17 */
+#if __has_attribute(noreturn) \
+    || (defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 205)) \
+    || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590))
+# define _X_NORETURN __attribute((noreturn))
+#else
+# define _X_NORETURN
+#endif /* GNUC  */
+
+/* Added in X11R6.9, so available in any version of modular xproto */
+#if __has_attribute(__format__) \
+    || defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 203)
+# define _X_ATTRIBUTE_PRINTF(x,y) __attribute__((__format__(__printf__,x,y)))
+#else /* not gcc >= 2.3 */
+# define _X_ATTRIBUTE_PRINTF(x,y)
+#endif
+
+/* requires xproto >= 7.0.22 - since this uses either gcc or C99 variable
+   argument macros, must be only used inside #ifdef _X_NONNULL guards, as
+   many legacy X clients are compiled in C89 mode still. */
+#if __has_attribute(nonnull) \
+    && defined(__STDC_VERSION__) && (__STDC_VERSION__ - 0 >= 199901L) /* C99 */
+#define _X_NONNULL(...)  __attribute__((nonnull(__VA_ARGS__)))
+#elif __has_attribute(nonnull) \
+    || defined(__GNUC__) &&  ((__GNUC__ * 100 + __GNUC_MINOR__) >= 303)
+#define _X_NONNULL(args...)  __attribute__((nonnull(args)))
+#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ - 0 >= 199901L) /* C99 */
+#define _X_NONNULL(...)  /* */
+#endif
+
+/* requires xproto >= 7.0.22 */
+#if __has_attribute(__unused__) \
+    || defined(__GNUC__) &&  ((__GNUC__ * 100 + __GNUC_MINOR__) >= 205)
+#define _X_UNUSED  __attribute__((__unused__))
+#else
+#define _X_UNUSED  /* */
+#endif
+
+/* C99 keyword "inline" or equivalent extensions in pre-C99 compilers */
+/* requires xproto >= 7.0.9
+   (introduced in 7.0.8 but didn't support all compilers until 7.0.9) */
+#if defined(inline) /* assume autoconf set it correctly */ || \
+   (defined(__STDC_VERSION__) && (__STDC_VERSION__ - 0 >= 199901L)) /* C99 */ || \
+   (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x550))
+# define _X_INLINE inline
+#elif defined(__GNUC__) && !defined(__STRICT_ANSI__) /* gcc w/C89+extensions */
+# define _X_INLINE __inline__
+#else
+# define _X_INLINE
+#endif
+
+/* C99 keyword "restrict" or equivalent extensions in pre-C99 compilers */
+/* requires xproto >= 7.0.21 */
+#ifndef _X_RESTRICT_KYWD
+# if defined(restrict) /* assume autoconf set it correctly */ || \
+    (defined(__STDC_VERSION__) && (__STDC_VERSION__ - 0 >= 199901L) /* C99 */ \
+     && !defined(__cplusplus)) /* Workaround g++ issue on Solaris */
+#  define _X_RESTRICT_KYWD  restrict
+# elif defined(__GNUC__) && !defined(__STRICT_ANSI__) /* gcc w/C89+extensions */
+#  define _X_RESTRICT_KYWD __restrict__
+# else
+#  define _X_RESTRICT_KYWD
+# endif
+#endif
+
+/* requires xproto >= 7.0.30 */
+#if __has_attribute(no_sanitize_thread)
+# define _X_NOTSAN __attribute__((no_sanitize_thread))
+#else
+# define _X_NOTSAN
+#endif
+
+#endif /* _XFUNCPROTO_H_ */
diff -Naur old/X11/Xfuncs.h new/X11/Xfuncs.h
--- old/X11/Xfuncs.h	1970-01-01 08:00:00.000000000 +0800
+++ new/X11/Xfuncs.h	2024-03-05 19:36:25.209050000 +0800
@@ -0,0 +1,69 @@
+/*
+ *
+Copyright 1990, 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.
+ *
+ */
+
+#ifndef _XFUNCS_H_
+# define _XFUNCS_H_
+
+# include <X11/Xosdefs.h>
+
+/* the old Xfuncs.h, for pre-R6 */
+# if !(defined(XFree86LOADER) && defined(IN_MODULE))
+
+#  ifdef X_USEBFUNCS
+void bcopy();
+void bzero();
+int bcmp();
+#  else
+#   if defined(SYSV) && !defined(__SCO__) && !defined(__sun) && !defined(__UNIXWARE__) && !defined(_AIX)
+#    include <memory.h>
+void bcopy();
+#    define bzero(b,len) memset(b, 0, len)
+#    define bcmp(b1,b2,len) memcmp(b1, b2, len)
+#   else
+#    include <string.h>
+#    if defined(__SCO__) || defined(__sun) || defined(__UNIXWARE__) || defined(__CYGWIN__) || defined(_AIX) || defined(__APPLE__)
+#     include <strings.h>
+#    endif
+#    define _XFUNCS_H_INCLUDED_STRING_H
+#   endif
+#  endif /* X_USEBFUNCS */
+
+/* the new Xfuncs.h */
+
+/* the ANSI C way */
+#  ifndef _XFUNCS_H_INCLUDED_STRING_H
+#   include <string.h>
+#  endif
+#  undef bzero
+#  define bzero(b,len) memset(b,0,len)
+
+#  if defined WIN32 && defined __MINGW32__
+#   define bcopy(b1,b2,len) memmove(b2, b1, (size_t)(len))
+#  endif
+
+# endif /* !(defined(XFree86LOADER) && defined(IN_MODULE)) */
+
+#endif /* _XFUNCS_H_ */
diff -Naur old/X11/Xmd.h new/X11/Xmd.h
--- old/X11/Xmd.h	1970-01-01 08:00:00.000000000 +0800
+++ new/X11/Xmd.h	2024-03-05 19:36:25.209050000 +0800
@@ -0,0 +1,142 @@
+/***********************************************************
+
+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.
+
+******************************************************************/
+#ifndef XMD_H
+# define XMD_H 1
+/*
+ *  Xmd.h: MACHINE DEPENDENT DECLARATIONS.
+ */
+
+/*
+ * Special per-machine configuration flags.
+ */
+# if defined(__sun) && defined(__SVR4)
+#  include <sys/isa_defs.h> /* Solaris: defines _LP64 if necessary */
+# endif
+
+# if defined (_LP64) || defined(__LP64__) || \
+     defined(__alpha) || defined(__alpha__) || \
+     defined(__ia64__) || defined(ia64) || \
+     defined(__sparc64__) || \
+     defined(__s390x__) || \
+     defined(__amd64__) || defined(amd64) || \
+     defined(__powerpc64__)
+#  if !defined(__ILP32__) /* amd64-x32 is 32bit */
+#   define LONG64				/* 32/64-bit architecture */
+#  endif /* !__ILP32__ */
+# endif
+
+/*
+ * Definition of macro used to set constants for size of network structures;
+ * machines with preprocessors that can't handle all of the sz_ symbols
+ * can define this macro to be sizeof(x) if and only if their compiler doesn't
+ * pad out structures (esp. the xTextElt structure which contains only two
+ * one-byte fields).  Network structures should always define sz_symbols.
+ *
+ * The sz_ prefix is used instead of something more descriptive so that the
+ * symbols are no more than 32 characters long (which causes problems for some
+ * compilers and preprocessors).
+ *
+ * The extra indirection is to get macro arguments to expand correctly before
+ * the concatenation, rather than afterward.
+ */
+# define _SIZEOF(x) sz_##x
+# define SIZEOF(x) _SIZEOF(x)
+
+/*
+ * Bitfield suffixes for the protocol structure elements, if you
+ * need them.  Note that bitfields are not guaranteed to be signed
+ * (or even unsigned) according to ANSI C.
+ */
+# define B32 /* bitfield not needed on architectures with native 32-bit type */
+# define B16 /* bitfield not needed on architectures with native 16-bit type */
+# ifdef LONG64
+typedef long INT64;
+typedef int INT32;
+# else
+typedef long INT32;
+# endif
+typedef short INT16;
+
+typedef signed char    INT8;
+
+# ifdef LONG64
+typedef unsigned long CARD64;
+typedef unsigned int CARD32;
+# else
+typedef unsigned long long CARD64;
+typedef unsigned long CARD32;
+# endif
+typedef unsigned short CARD16;
+typedef unsigned char  CARD8;
+
+typedef CARD32		BITS32;
+typedef CARD16		BITS16;
+
+typedef CARD8		BYTE;
+typedef CARD8		BOOL;
+
+/*
+ * was definitions for sign-extending bitfields on architectures without
+ * native types smaller than 64-bit, now just backwards compatibility
+ */
+# define cvtINT8toInt(val) (val)
+# define cvtINT16toInt(val) (val)
+# define cvtINT32toInt(val) (val)
+# define cvtINT8toShort(val) (val)
+# define cvtINT16toShort(val) (val)
+# define cvtINT32toShort(val) (val)
+# define cvtINT8toLong(val) (val)
+# define cvtINT16toLong(val) (val)
+# define cvtINT32toLong(val) (val)
+
+/*
+ * this version should leave result of type (t *), but that should only be
+ * used when not in MUSTCOPY
+ */
+# define NEXTPTR(p,t) (((t *)(p)) + 1)
+
+#endif /* XMD_H */
diff -Naur old/X11/Xos.h new/X11/Xos.h
--- old/X11/Xos.h	1970-01-01 08:00:00.000000000 +0800
+++ new/X11/Xos.h	2024-03-05 19:36:25.209050000 +0800
@@ -0,0 +1,148 @@
+/*
+ *
+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.
+ *
+ * The X Window System is a Trademark of The Open Group.
+ *
+ */
+
+/* This is a collection of things to try and minimize system dependencies
+ * in a "significant" number of source files.
+ */
+
+#ifndef _XOS_H_
+# define _XOS_H_
+
+# include <X11/Xosdefs.h>
+
+/*
+ * Get major data types (esp. caddr_t)
+ */
+
+# include <sys/types.h>
+
+# if defined(__SCO__) || defined(__UNIXWARE__)
+#  include <stdint.h>
+# endif
+
+
+/*
+ * Just about everyone needs the strings routines.  We provide both forms here,
+ * index/rindex and strchr/strrchr, so any systems that don't provide them all
+ * need to have #defines here.
+ *
+ * These macros are defined this way, rather than, e.g.:
+ *    #defined index(s,c) strchr(s,c)
+ * because someone might be using them as function pointers, and such
+ * a change would break compatibility for anyone who's relying on them
+ * being the way they currently are. So we're stuck with them this way,
+ * which can be really inconvenient. :-(
+ */
+
+# include <string.h>
+# if defined(__SCO__) || defined(__UNIXWARE__) || defined(__sun) || defined(__CYGWIN__) || defined(_AIX) || defined(__APPLE__)
+#  include <strings.h>
+# else
+#  ifndef index
+#   define index(s,c) (strchr((s),(c)))
+#  endif
+#  ifndef rindex
+#   define rindex(s,c) (strrchr((s),(c)))
+#  endif
+# endif
+
+/*
+ * Get open(2) constants
+ */
+# if defined(X_NOT_POSIX)
+#  include <fcntl.h>
+#  if defined(USL) || defined(__i386__) && (defined(SYSV) || defined(SVR4))
+#   include <unistd.h>
+#  endif
+#  ifdef WIN32
+#   include <X11/Xw32defs.h>
+#  else
+#   include <sys/file.h>
+#  endif
+# else /* X_NOT_POSIX */
+#  include <fcntl.h>
+#  include <unistd.h>
+# endif /* X_NOT_POSIX else */
+
+/*
+ * Get struct timeval and struct tm
+ */
+
+# if defined(_POSIX_SOURCE) && defined(SVR4)
+/* need to omit _POSIX_SOURCE in order to get what we want in SVR4 */
+#  undef _POSIX_SOURCE
+#  include <sys/time.h>
+#  define _POSIX_SOURCE
+# elif defined(WIN32)
+#  include <time.h>
+#  if !defined(_WINSOCKAPI_) && !defined(_WILLWINSOCK_) && !defined(_TIMEVAL_DEFINED) && !defined(_STRUCT_TIMEVAL)
+struct timeval {
+    long    tv_sec;         /* seconds */
+    long    tv_usec;        /* and microseconds */
+};
+#   define _TIMEVAL_DEFINED
+#  endif
+#  include <sys/timeb.h>
+#  define gettimeofday(t) \
+{ \
+    struct _timeb _gtodtmp; \
+    _ftime (&_gtodtmp); \
+    (t)->tv_sec = _gtodtmp.time; \
+    (t)->tv_usec = _gtodtmp.millitm * 1000; \
+}
+# else
+#  include <sys/time.h>
+#  include <time.h>
+# endif /* defined(_POSIX_SOURCE) && defined(SVR4) */
+
+/* define X_GETTIMEOFDAY macro, a portable gettimeofday() */
+# if defined(_XOPEN_XPG4) || defined(_XOPEN_UNIX) /* _XOPEN_UNIX is XPG4.2 */
+#  define X_GETTIMEOFDAY(t) gettimeofday(t, (struct timezone*)0)
+# else
+#  if defined(SVR4) || defined(__SVR4) || defined(WIN32)
+#   define X_GETTIMEOFDAY(t) gettimeofday(t)
+#  else
+#   define X_GETTIMEOFDAY(t) gettimeofday(t, (struct timezone*)0)
+#  endif
+# endif /* XPG4 else */
+
+
+# ifdef __GNU__
+#  define PATH_MAX 4096
+#  define MAXPATHLEN 4096
+#  define OPEN_MAX 256 /* We define a reasonable limit.  */
+# endif
+
+/* use POSIX name for signal */
+# if defined(X_NOT_POSIX) && defined(SYSV) && !defined(SIGCHLD)
+#  define SIGCHLD SIGCLD
+# endif
+
+# include <X11/Xarch.h>
+
+#endif /* _XOS_H_ */
diff -Naur old/X11/Xos_r.h new/X11/Xos_r.h
--- old/X11/Xos_r.h	1970-01-01 08:00:00.000000000 +0800
+++ new/X11/Xos_r.h	2024-03-05 19:36:25.210042000 +0800
@@ -0,0 +1,1095 @@
+/*
+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.
+*/
+
+/*
+ * Various and sundry Thread-Safe functions used by X11, Motif, and CDE.
+ *
+ * Use this file in MT-safe code where you would have included
+ *	<dirent.h>	for readdir()
+ *	<grp.h>		for getgrgid() or getgrnam()
+ *	<netdb.h>	for gethostbyname(), gethostbyaddr(), or getservbyname()
+ *	<pwd.h>		for getpwnam() or getpwuid()
+ *	<string.h>	for strtok()
+ *	<time.h>	for asctime(), ctime(), localtime(), or gmtime()
+ *	<unistd.h>	for getlogin() or ttyname()
+ * or their thread-safe analogs.
+ *
+ * If you are on a platform that defines XTHREADS but does not have
+ * MT-safe system API (e.g. UnixWare) you must define _Xos_processLock
+ * and _Xos_processUnlock macros before including this header.
+ *
+ * For convenience XOS_USE_XLIB_LOCKING or XOS_USE_XT_LOCKING may be defined
+ * to obtain either Xlib-only or Xt-based versions of these macros.  These
+ * macros won't result in truly thread-safe calls, but they are better than
+ * nothing.  If you do not want locking in this situation define
+ * XOS_USE_NO_LOCKING.
+ *
+ * NOTE: On systems lacking appropriate _r functions Gethostbyname(),
+ *	Gethostbyaddr(), and Getservbyname() do NOT copy the host or
+ *	protocol lists!
+ *
+ * NOTE: On systems lacking appropriate _r functions Getgrgid() and
+ *	Getgrnam() do NOT copy the list of group members!
+ *
+ * This header is nominally intended to simplify porting X11, Motif, and
+ * CDE; it may be useful to other people too.  The structure below is
+ * complicated, mostly because P1003.1c (the IEEE POSIX Threads spec)
+ * went through lots of drafts, and some vendors shipped systems based
+ * on draft API that were changed later.  Unfortunately POSIX did not
+ * provide a feature-test macro for distinguishing each of the drafts.
+ */
+
+/*
+ * This header has several parts.  Search for "Effective prototypes"
+ * to locate the beginning of a section.
+ */
+
+/* This header can be included multiple times with different defines! */
+#ifndef _XOS_R_H_
+# define _XOS_R_H_
+
+# include <X11/Xos.h>
+# include <X11/Xfuncs.h>
+
+# ifndef X_NOT_POSIX
+#  ifdef _POSIX_SOURCE
+#   include <limits.h>
+#  else
+#   define _POSIX_SOURCE
+#   include <limits.h>
+#   undef _POSIX_SOURCE
+#  endif
+#  ifndef LINE_MAX
+#   define X_LINE_MAX 2048
+#  else
+#   define X_LINE_MAX LINE_MAX
+#  endif
+# endif
+#endif /* _XOS_R_H */
+
+#ifndef WIN32
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+# if defined(XOS_USE_XLIB_LOCKING)
+#  ifndef XAllocIDs /* Xlibint.h does not have multiple include protection */
+typedef struct _LockInfoRec *LockInfoPtr;
+extern LockInfoPtr _Xglobal_lock;
+#  endif
+#  ifndef _Xos_isThreadInitialized
+#   define _Xos_isThreadInitialized	(_Xglobal_lock)
+#  endif
+#  if defined(XTHREADS_WARN) || defined(XTHREADS_FILE_LINE)
+#   ifndef XAllocIDs /* Xlibint.h does not have multiple include protection */
+#    include <X11/Xfuncproto.h>	/* for NeedFunctionPrototypes */
+extern void (*_XLockMutex_fn)(
+#    if NeedFunctionPrototypes
+    LockInfoPtr	/* lock */, char * /* file */, int /* line */
+#    endif
+);
+extern void (*_XUnlockMutex_fn)(
+#    if NeedFunctionPrototypes
+    LockInfoPtr	/* lock */, char * /* file */, int /* line */
+#    endif
+);
+#   endif
+#   ifndef _Xos_processLock
+#    define _Xos_processLock	\
+  (_XLockMutex_fn ? (*_XLockMutex_fn)(_Xglobal_lock,__FILE__,__LINE__) : 0)
+#   endif
+#   ifndef _Xos_processUnlock
+#    define _Xos_processUnlock	\
+  (_XUnlockMutex_fn ? (*_XUnlockMutex_fn)(_Xglobal_lock,__FILE__,__LINE__) : 0)
+#   endif
+#  else
+#   ifndef XAllocIDs /* Xlibint.h does not have multiple include protection */
+#    include <X11/Xfuncproto.h>	/* for NeedFunctionPrototypes */
+extern void (*_XLockMutex_fn)(
+#    if NeedFunctionPrototypes
+    LockInfoPtr	/* lock */
+#    endif
+);
+extern void (*_XUnlockMutex_fn)(
+#    if NeedFunctionPrototypes
+    LockInfoPtr	/* lock */
+#    endif
+);
+#   endif
+#   ifndef _Xos_processLock
+#    define _Xos_processLock	\
+  (_XLockMutex_fn ? ((*_XLockMutex_fn)(_Xglobal_lock), 0) : 0)
+#   endif
+#   ifndef _Xos_processUnlock
+#    define _Xos_processUnlock	\
+  (_XUnlockMutex_fn ? ((*_XUnlockMutex_fn)(_Xglobal_lock), 0) : 0)
+#   endif
+#  endif
+# elif defined(XOS_USE_XT_LOCKING)
+#  ifndef _XtThreadsI_h
+extern void (*_XtProcessLock)(void);
+#  endif
+#  ifndef _XtintrinsicP_h
+#   include <X11/Xfuncproto.h>	/* for NeedFunctionPrototypes */
+extern void XtProcessLock(
+#   if NeedFunctionPrototypes
+    void
+#   endif
+);
+extern void XtProcessUnlock(
+#   if NeedFunctionPrototypes
+    void
+#   endif
+);
+#  endif
+#  ifndef _Xos_isThreadInitialized
+#   define _Xos_isThreadInitialized	_XtProcessLock
+#  endif
+#  ifndef _Xos_processLock
+#   define _Xos_processLock		XtProcessLock()
+#  endif
+#  ifndef _Xos_processUnlock
+#   define _Xos_processUnlock		XtProcessUnlock()
+#  endif
+# elif defined(XOS_USE_NO_LOCKING)
+#  ifndef _Xos_isThreadInitialized
+#   define _Xos_isThreadInitialized	0
+#  endif
+#  ifndef _Xos_processLock
+#   define _Xos_processLock		0
+#  endif
+#  ifndef _Xos_processUnlock
+#   define _Xos_processUnlock		0
+#  endif
+# endif
+
+#endif /* !defined WIN32 */
+
+/*
+ * Solaris defines the POSIX thread-safe feature test macro, but
+ * uses the older SVR4 thread-safe functions unless the POSIX ones
+ * are specifically requested.  Fix the feature test macro.
+ */
+#if defined(__sun) && defined(_POSIX_THREAD_SAFE_FUNCTIONS) && \
+	(_POSIX_C_SOURCE - 0 < 199506L) && !defined(_POSIX_PTHREAD_SEMANTICS)
+# undef _POSIX_THREAD_SAFE_FUNCTIONS
+#endif
+
+/***** <pwd.h> wrappers *****/
+
+/*
+ * Effective prototypes for <pwd.h> wrappers:
+ *
+ * #define X_INCLUDE_PWD_H
+ * #define XOS_USE_..._LOCKING
+ * #include <X11/Xos_r.h>
+ *
+ * typedef ... _Xgetpwparams;
+ *
+ * struct passwd* _XGetpwnam(const char *name, _Xgetpwparams);
+ * struct passwd* _XGetpwuid(uid_t uid, _Xgetpwparams);
+ */
+
+#if defined(X_INCLUDE_PWD_H) && !defined(_XOS_INCLUDED_PWD_H)
+# include <pwd.h>
+# if defined(XUSE_MTSAFE_API) || defined(XUSE_MTSAFE_PWDAPI)
+#  define XOS_USE_MTSAFE_PWDAPI 1
+# endif
+#endif
+
+#undef X_NEEDS_PWPARAMS
+#if !defined(X_INCLUDE_PWD_H) || defined(_XOS_INCLUDED_PWD_H)
+/* Do nothing */
+
+#elif !defined(XTHREADS) && !defined(X_FORCE_USE_MTSAFE_API)
+/* Use regular, unsafe API. */
+# if defined(X_NOT_POSIX) && !defined(__i386__) && !defined(SYSV)
+extern struct passwd *getpwuid(), *getpwnam();
+# endif
+typedef int _Xgetpwparams;	/* dummy */
+# define _XGetpwuid(u,p)	getpwuid((u))
+# define _XGetpwnam(u,p)	getpwnam((u))
+
+#elif !defined(XOS_USE_MTSAFE_PWDAPI) || defined(XNO_MTSAFE_PWDAPI)
+/* UnixWare 2.0, or other systems with thread support but no _r API. */
+# define X_NEEDS_PWPARAMS
+typedef struct {
+  struct passwd pws;
+  char   pwbuf[1024];
+  struct passwd* pwp;
+  size_t len;
+} _Xgetpwparams;
+
+/*
+ * NetBSD and FreeBSD, at least, are missing several of the unixware passwd
+ * fields.
+ */
+
+#if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) || \
+    defined(__APPLE__) || defined(__DragonFly__)
+static __inline__ void _Xpw_copyPasswd(_Xgetpwparams p)
+{
+   memcpy(&(p).pws, (p).pwp, sizeof(struct passwd));
+
+   (p).pws.pw_name = (p).pwbuf;
+   (p).len = strlen((p).pwp->pw_name);
+   strcpy((p).pws.pw_name, (p).pwp->pw_name);
+
+   (p).pws.pw_passwd = (p).pws.pw_name + (p).len + 1;
+   (p).len = strlen((p).pwp->pw_passwd);
+   strcpy((p).pws.pw_passwd,(p).pwp->pw_passwd);
+
+   (p).pws.pw_class = (p).pws.pw_passwd + (p).len + 1;
+   (p).len = strlen((p).pwp->pw_class);
+   strcpy((p).pws.pw_class, (p).pwp->pw_class);
+
+   (p).pws.pw_gecos = (p).pws.pw_class + (p).len + 1;
+   (p).len = strlen((p).pwp->pw_gecos);
+   strcpy((p).pws.pw_gecos, (p).pwp->pw_gecos);
+
+   (p).pws.pw_dir = (p).pws.pw_gecos + (p).len + 1;
+   (p).len = strlen((p).pwp->pw_dir);
+   strcpy((p).pws.pw_dir, (p).pwp->pw_dir);
+
+   (p).pws.pw_shell = (p).pws.pw_dir + (p).len + 1;
+   (p).len = strlen((p).pwp->pw_shell);
+   strcpy((p).pws.pw_shell, (p).pwp->pw_shell);
+
+   (p).pwp = &(p).pws;
+}
+
+#else
+# define _Xpw_copyPasswd(p) \
+   (memcpy(&(p).pws, (p).pwp, sizeof(struct passwd)), \
+    ((p).pws.pw_name = (p).pwbuf), \
+    ((p).len = strlen((p).pwp->pw_name)), \
+    strcpy((p).pws.pw_name, (p).pwp->pw_name), \
+    ((p).pws.pw_passwd = (p).pws.pw_name + (p).len + 1), \
+    ((p).len = strlen((p).pwp->pw_passwd)), \
+    strcpy((p).pws.pw_passwd,(p).pwp->pw_passwd), \
+    ((p).pws.pw_age = (p).pws.pw_passwd + (p).len + 1), \
+    ((p).len = strlen((p).pwp->pw_age)), \
+    strcpy((p).pws.pw_age, (p).pwp->pw_age), \
+    ((p).pws.pw_comment = (p).pws.pw_age + (p).len + 1), \
+    ((p).len = strlen((p).pwp->pw_comment)), \
+    strcpy((p).pws.pw_comment, (p).pwp->pw_comment), \
+    ((p).pws.pw_gecos = (p).pws.pw_comment + (p).len + 1), \
+    ((p).len = strlen((p).pwp->pw_gecos)), \
+    strcpy((p).pws.pw_gecos, (p).pwp->pw_gecos), \
+    ((p).pws.pw_dir = (p).pws.pw_comment + (p).len + 1), \
+    ((p).len = strlen((p).pwp->pw_dir)), \
+    strcpy((p).pws.pw_dir, (p).pwp->pw_dir), \
+    ((p).pws.pw_shell = (p).pws.pw_dir + (p).len + 1), \
+    ((p).len = strlen((p).pwp->pw_shell)), \
+    strcpy((p).pws.pw_shell, (p).pwp->pw_shell), \
+    ((p).pwp = &(p).pws), \
+    0 )
+#endif
+# define _XGetpwuid(u,p) \
+( (_Xos_processLock), \
+  (((p).pwp = getpwuid((u))) ? _Xpw_copyPasswd(p), 0 : 0), \
+  (_Xos_processUnlock), \
+  (p).pwp )
+# define _XGetpwnam(u,p) \
+( (_Xos_processLock), \
+  (((p).pwp = getpwnam((u))) ? _Xpw_copyPasswd(p), 0 : 0), \
+  (_Xos_processUnlock), \
+  (p).pwp )
+
+#elif !defined(_POSIX_THREAD_SAFE_FUNCTIONS) && !defined(__APPLE__)
+# define X_NEEDS_PWPARAMS
+typedef struct {
+  struct passwd pws;
+  char pwbuf[X_LINE_MAX];
+} _Xgetpwparams;
+# if defined(_POSIX_REENTRANT_FUNCTIONS) || !defined(SVR4)
+#   define _XGetpwuid(u,p) \
+((getpwuid_r((u),&(p).pws,(p).pwbuf,sizeof((p).pwbuf)) == -1) ? NULL : &(p).pws)
+#   define _XGetpwnam(u,p) \
+((getpwnam_r((u),&(p).pws,(p).pwbuf,sizeof((p).pwbuf)) == -1) ? NULL : &(p).pws)
+# else /* SVR4 */
+#  define _XGetpwuid(u,p) \
+((getpwuid_r((u),&(p).pws,(p).pwbuf,sizeof((p).pwbuf)) == NULL) ? NULL : &(p).pws)
+#  define _XGetpwnam(u,p) \
+((getpwnam_r((u),&(p).pws,(p).pwbuf,sizeof((p).pwbuf)) == NULL) ? NULL : &(p).pws)
+# endif /* SVR4 */
+
+#else /* _POSIX_THREAD_SAFE_FUNCTIONS */
+# define X_NEEDS_PWPARAMS
+typedef struct {
+  struct passwd pws;
+  char pwbuf[X_LINE_MAX];
+  struct passwd* pwp;
+} _Xgetpwparams;
+typedef int _Xgetpwret;
+# define _XGetpwuid(u,p) \
+((getpwuid_r((u),&(p).pws,(p).pwbuf,sizeof((p).pwbuf),&(p).pwp) == 0) ? \
+ (p).pwp : NULL)
+# define _XGetpwnam(u,p) \
+((getpwnam_r((u),&(p).pws,(p).pwbuf,sizeof((p).pwbuf),&(p).pwp) == 0) ? \
+ (p).pwp : NULL)
+#endif /* X_INCLUDE_PWD_H */
+
+#if defined(X_INCLUDE_PWD_H) && !defined(_XOS_INCLUDED_PWD_H)
+# define _XOS_INCLUDED_PWD_H
+#endif
+
+
+/***** <netdb.h> wrappers *****/
+
+/*
+ * Effective prototypes for <netdb.h> wrappers:
+ *
+ * NOTE: On systems lacking the appropriate _r functions Gethostbyname(),
+ *	Gethostbyaddr(), and Getservbyname() do NOT copy the host or
+ *	protocol lists!
+ *
+ * #define X_INCLUDE_NETDB_H
+ * #define XOS_USE_..._LOCKING
+ * #include <X11/Xos_r.h>
+ *
+ * typedef ... _Xgethostbynameparams;
+ * typedef ... _Xgetservbynameparams;
+ *
+ * struct hostent* _XGethostbyname(const char* name,_Xgethostbynameparams);
+ * struct hostent* _XGethostbyaddr(const char* addr, int len, int type,
+ *				   _Xgethostbynameparams);
+ * struct servent* _XGetservbyname(const char* name, const char* proto,
+ *				 _Xgetservbynameparams);
+ */
+
+#undef XTHREADS_NEEDS_BYNAMEPARAMS
+#if defined(X_INCLUDE_NETDB_H) && !defined(_XOS_INCLUDED_NETDB_H) \
+    && !defined(WIN32)
+# include <netdb.h>
+# if defined(XUSE_MTSAFE_API) || defined(XUSE_MTSAFE_NETDBAPI)
+#  define XOS_USE_MTSAFE_NETDBAPI 1
+# endif
+#endif
+
+#if !defined(X_INCLUDE_NETDB_H) || defined(_XOS_INCLUDED_NETDB_H)
+/* Do nothing. */
+
+#elif !defined(XTHREADS) && !defined(X_FORCE_USE_MTSAFE_API)
+/* Use regular, unsafe API. */
+typedef int _Xgethostbynameparams; /* dummy */
+typedef int _Xgetservbynameparams; /* dummy */
+# define _XGethostbyname(h,hp)		gethostbyname((h))
+# define _XGethostbyaddr(a,al,t,hp)	gethostbyaddr((a),(al),(t))
+# define _XGetservbyname(s,p,sp)	getservbyname((s),(p))
+
+#elif !defined(XOS_USE_MTSAFE_NETDBAPI) || defined(XNO_MTSAFE_NETDBAPI)
+/* WARNING:  The h_addr_list and s_aliases values are *not* copied! */
+
+#if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__DragonFly__)
+#include <sys/param.h>
+#endif
+
+typedef struct {
+  struct hostent hent;
+  char           h_name[MAXHOSTNAMELEN];
+  struct hostent *hptr;
+} _Xgethostbynameparams;
+typedef struct {
+  struct servent sent;
+  char           s_name[255];
+  char		 s_proto[255];
+  struct servent *sptr;
+} _Xgetservbynameparams;
+
+# define XTHREADS_NEEDS_BYNAMEPARAMS
+
+# define _Xg_copyHostent(hp) \
+   (memcpy(&(hp).hent, (hp).hptr, sizeof(struct hostent)), \
+    strcpy((hp).h_name, (hp).hptr->h_name), \
+    ((hp).hent.h_name = (hp).h_name), \
+    ((hp).hptr = &(hp).hent), \
+     0 )
+# define _Xg_copyServent(sp) \
+   (memcpy(&(sp).sent, (sp).sptr, sizeof(struct servent)), \
+    strcpy((sp).s_name, (sp).sptr->s_name), \
+    ((sp).sent.s_name = (sp).s_name), \
+    strcpy((sp).s_proto, (sp).sptr->s_proto), \
+    ((sp).sent.s_proto = (sp).s_proto), \
+    ((sp).sptr = &(sp).sent), \
+    0 )
+# define _XGethostbyname(h,hp) \
+   ((_Xos_processLock), \
+    (((hp).hptr = gethostbyname((h))) ? _Xg_copyHostent(hp) : 0), \
+    (_Xos_processUnlock), \
+    (hp).hptr )
+# define _XGethostbyaddr(a,al,t,hp) \
+   ((_Xos_processLock), \
+    (((hp).hptr = gethostbyaddr((a),(al),(t))) ? _Xg_copyHostent(hp) : 0), \
+    (_Xos_processUnlock), \
+    (hp).hptr )
+# define _XGetservbyname(s,p,sp) \
+   ((_Xos_processLock), \
+    (((sp).sptr = getservbyname((s),(p))) ? _Xg_copyServent(sp) : 0), \
+    (_Xos_processUnlock), \
+    (sp).sptr )
+
+#elif defined(XUSE_NETDB_R_API)
+/*
+ * POSIX does not specify _r equivalents for <netdb.h> API, but some
+ * vendors provide them anyway.  Use them only when explicitly asked.
+ */
+# ifdef _POSIX_REENTRANT_FUNCTIONS
+#  ifndef _POSIX_THREAD_SAFE_FUNCTIONS
+#  endif
+# endif
+# ifdef _POSIX_THREAD_SAFE_FUNCTIONS
+#  define X_POSIX_THREAD_SAFE_FUNCTIONS 1
+# endif
+
+# define XTHREADS_NEEDS_BYNAMEPARAMS
+
+# ifndef X_POSIX_THREAD_SAFE_FUNCTIONS
+typedef struct {
+    struct hostent      hent;
+    char                hbuf[X_LINE_MAX];
+    int                 herr;
+} _Xgethostbynameparams;
+typedef struct {
+    struct servent      sent;
+    char                sbuf[X_LINE_MAX];
+} _Xgetservbynameparams;
+#  define _XGethostbyname(h,hp) \
+  gethostbyname_r((h),&(hp).hent,(hp).hbuf,sizeof((hp).hbuf),&(hp).herr)
+#  define _XGethostbyaddr(a,al,t,hp) \
+  gethostbyaddr_r((a),(al),(t),&(hp).hent,(hp).hbuf,sizeof((hp).hbuf),&(hp).herr)
+#  define _XGetservbyname(s,p,sp) \
+  getservbyname_r((s),(p),&(sp).sent,(sp).sbuf,sizeof((sp).sbuf))
+# else
+typedef struct {
+  struct hostent      hent;
+  struct hostent_data hdata;
+} _Xgethostbynameparams;
+typedef struct {
+  struct servent      sent;
+  struct servent_data sdata;
+} _Xgetservbynameparams;
+#  define _XGethostbyname(h,hp) \
+  (bzero((char*)&(hp).hdata,sizeof((hp).hdata)),	\
+   ((gethostbyname_r((h),&(hp).hent,&(hp).hdata) == -1) ? NULL : &(hp).hent))
+#  define _XGethostbyaddr(a,al,t,hp) \
+  (bzero((char*)&(hp).hdata,sizeof((hp).hdata)),	\
+   ((gethostbyaddr_r((a),(al),(t),&(hp).hent,&(hp).hdata) == -1) ? NULL : &(hp).hent))
+#  define _XGetservbyname(s,p,sp) \
+  (bzero((char*)&(sp).sdata,sizeof((sp).sdata)),	\
+   ((getservbyname_r((s),(p),&(sp).sent,&(sp).sdata) == -1) ? NULL : &(sp).sent) )
+# endif
+# ifdef X_POSIX_THREAD_SAFE_FUNCTIONS
+#  undef X_POSIX_THREAD_SAFE_FUNCTIONS
+# endif
+
+#else
+/* The regular API is assumed to be MT-safe under POSIX. */
+typedef int _Xgethostbynameparams; /* dummy */
+typedef int _Xgetservbynameparams; /* dummy */
+# define _XGethostbyname(h,hp)		gethostbyname((h))
+# define _XGethostbyaddr(a,al,t,hp)	gethostbyaddr((a),(al),(t))
+# define _XGetservbyname(s,p,sp)	getservbyname((s),(p))
+#endif /* X_INCLUDE_NETDB_H */
+
+#if defined(X_INCLUDE_NETDB_H) && !defined(_XOS_INCLUDED_NETDB_H)
+# define _XOS_INCLUDED_NETDB_H
+#endif
+
+
+/***** <dirent.h> wrappers *****/
+
+/*
+ * Effective prototypes for <dirent.h> wrappers:
+ *
+ * #define X_INCLUDE_DIRENT_H
+ * #define XOS_USE_..._LOCKING
+ * #include <X11/Xos_r.h>
+ *
+ * typedef ... _Xreaddirparams;
+ *
+ * struct dirent *_XReaddir(DIR *dir_pointer, _Xreaddirparams);
+ */
+
+#if defined(X_INCLUDE_DIRENT_H) && !defined(_XOS_INCLUDED_DIRENT_H)
+# include <sys/types.h>
+# if !defined(X_NOT_POSIX) || defined(SYSV)
+#  include <dirent.h>
+# else
+#  include <sys/dir.h>
+#  ifndef dirent
+#   define dirent direct
+#  endif
+# endif
+# if defined(XUSE_MTSAFE_API) || defined(XUSE_MTSAFE_DIRENTAPI)
+#  define XOS_USE_MTSAFE_DIRENTAPI 1
+# endif
+#endif
+
+#if !defined(X_INCLUDE_DIRENT_H) || defined(_XOS_INCLUDED_DIRENT_H)
+/* Do nothing. */
+
+#elif !defined(XTHREADS) && !defined(X_FORCE_USE_MTSAFE_API)
+/* Use regular, unsafe API. */
+typedef int _Xreaddirparams;	/* dummy */
+# define _XReaddir(d,p)	readdir(d)
+
+#elif !defined(XOS_USE_MTSAFE_DIRENTAPI) || defined(XNO_MTSAFE_DIRENTAPI)
+/* Systems with thread support but no _r API. */
+typedef struct {
+  struct dirent *result;
+  struct dirent dir_entry;
+# ifdef _POSIX_PATH_MAX
+  char buf[_POSIX_PATH_MAX];
+# elif defined(NAME_MAX)
+  char buf[NAME_MAX];
+# else
+  char buf[255];
+# endif
+} _Xreaddirparams;
+
+# define _XReaddir(d,p)	\
+ ( (_Xos_processLock),						 \
+   (((p).result = readdir((d))) ?				 \
+    (memcpy(&((p).dir_entry), (p).result, (p).result->d_reclen), \
+     ((p).result = &(p).dir_entry), 0) :			 \
+    0),								 \
+   (_Xos_processUnlock),					 \
+   (p).result )
+
+#else
+typedef struct {
+  struct dirent *result;
+  struct dirent dir_entry;
+# ifdef _POSIX_PATH_MAX
+  char buf[_POSIX_PATH_MAX];
+# elif defined(NAME_MAX)
+  char buf[NAME_MAX];
+# else
+  char buf[255];
+# endif
+} _Xreaddirparams;
+
+# if defined(_POSIX_THREAD_SAFE_FUNCTIONS) || defined(__APPLE__)
+/* POSIX final API, returns (int)0 on success. */
+#  define _XReaddir(d,p)						\
+    (readdir_r((d), &((p).dir_entry), &((p).result)) ? NULL : (p).result)
+# elif defined(_POSIX_REENTRANT_FUNCTIONS)
+/* POSIX draft API, returns (int)0 on success. */
+#  define _XReaddir(d,p)	\
+    (readdir_r((d),&((p).dir_entry)) ? NULL : &((p).dir_entry))
+# elif defined(SVR4)
+/* Pre-POSIX API, returns non-NULL on success. */
+#  define _XReaddir(d,p)	(readdir_r((d), &(p).dir_entry))
+# else
+/* We have no idea what is going on.  Fake it all using process locks. */
+#  define _XReaddir(d,p)	\
+    ( (_Xos_processLock),						\
+      (((p).result = readdir((d))) ?					\
+       (memcpy(&((p).dir_entry), (p).result, (p).result->d_reclen),	\
+	((p).result = &(p).dir_entry), 0) :				\
+       0),								\
+      (_Xos_processUnlock),						\
+      (p).result )
+# endif
+#endif /* X_INCLUDE_DIRENT_H */
+
+#if defined(X_INCLUDE_DIRENT_H) && !defined(_XOS_INCLUDED_DIRENT_H)
+# define _XOS_INCLUDED_DIRENT_H
+#endif
+
+
+/***** <unistd.h> wrappers *****/
+
+/*
+ * Effective prototypes for <unistd.h> wrappers:
+ *
+ * #define X_INCLUDE_UNISTD_H
+ * #define XOS_USE_..._LOCKING
+ * #include <X11/Xos_r.h>
+ *
+ * typedef ... _Xgetloginparams;
+ * typedef ... _Xttynameparams;
+ *
+ * char *_XGetlogin(_Xgetloginparams);
+ * char *_XTtyname(int, _Xttynameparams);
+ */
+
+#if defined(X_INCLUDE_UNISTD_H) && !defined(_XOS_INCLUDED_UNISTD_H)
+/* <unistd.h> already included by <X11/Xos.h> */
+# if defined(XUSE_MTSAFE_API) || defined(XUSE_MTSAFE_UNISTDAPI)
+#  define XOS_USE_MTSAFE_UNISTDAPI 1
+# endif
+#endif
+
+#if !defined(X_INCLUDE_UNISTD_H) || defined(_XOS_INCLUDED_UNISTD_H)
+/* Do nothing. */
+
+#elif !defined(XTHREADS) && !defined(X_FORCE_USE_MTSAFE_API)
+/* Use regular, unsafe API. */
+typedef int _Xgetloginparams;	/* dummy */
+typedef int _Xttynameparams;	/* dummy */
+# define _XGetlogin(p)	getlogin()
+# define _XTtyname(f)	ttyname((f))
+
+#elif !defined(XOS_USE_MTSAFE_UNISTDAPI) || defined(XNO_MTSAFE_UNISTDAPI)
+/* Systems with thread support but no _r API. */
+typedef struct {
+  char *result;
+# if defined(MAXLOGNAME)
+  char buf[MAXLOGNAME];
+# elif defined(LOGIN_NAME_MAX)
+  char buf[LOGIN_NAME_MAX];
+# else
+  char buf[64];
+# endif
+} _Xgetloginparams;
+typedef struct {
+  char *result;
+# ifdef TTY_NAME_MAX
+  char buf[TTY_NAME_MAX];
+# elif defined(_POSIX_TTY_NAME_MAX)
+  char buf[_POSIX_TTY_NAME_MAX];
+# elif defined(_POSIX_PATH_MAX)
+  char buf[_POSIX_PATH_MAX];
+# else
+  char buf[256];
+# endif
+} _Xttynameparams;
+
+# define _XGetlogin(p) \
+ ( (_Xos_processLock), \
+   (((p).result = getlogin()) ? \
+    (strncpy((p).buf, (p).result, sizeof((p).buf)), \
+     ((p).buf[sizeof((p).buf)-1] = '\0'), \
+     ((p).result = (p).buf), 0) : 0), \
+   (_Xos_processUnlock), \
+   (p).result )
+#define _XTtyname(f,p) \
+ ( (_Xos_processLock), \
+   (((p).result = ttyname(f)) ? \
+    (strncpy((p).buf, (p).result, sizeof((p).buf)), \
+     ((p).buf[sizeof((p).buf)-1] = '\0'), \
+     ((p).result = (p).buf), 0) : 0), \
+   (_Xos_processUnlock), \
+   (p).result )
+
+#elif defined(_POSIX_THREAD_SAFE_FUNCTIONS) || defined(_POSIX_REENTRANT_FUNCTIONS)
+/* POSIX API.
+ *
+ * extern int getlogin_r(char *, size_t);
+ * extern int ttyname_r(int, char *, size_t);
+ */
+typedef struct {
+# if defined(MAXLOGNAME)
+  char buf[MAXLOGNAME];
+# elif defined(LOGIN_NAME_MAX)
+  char buf[LOGIN_NAME_MAX];
+# else
+  char buf[64];
+# endif
+} _Xgetloginparams;
+typedef struct {
+# ifdef TTY_NAME_MAX
+  char buf[TTY_NAME_MAX];
+# elif defined(_POSIX_TTY_NAME_MAX)
+  char buf[_POSIX_TTY_NAME_MAX];
+# elif defined(_POSIX_PATH_MAX)
+  char buf[_POSIX_PATH_MAX];
+# else
+  char buf[256];
+# endif
+} _Xttynameparams;
+
+# define _XGetlogin(p)	(getlogin_r((p).buf, sizeof((p).buf)) ? NULL : (p).buf)
+# define _XTtyname(f,p)	\
+	(ttyname_r((f), (p).buf, sizeof((p).buf)) ? NULL : (p).buf)
+
+#else
+/* Pre-POSIX API.
+ *
+ * extern char *getlogin_r(char *, size_t);
+ * extern char *ttyname_r(int, char *, size_t);
+ */
+typedef struct {
+# if defined(MAXLOGNAME)
+  char buf[MAXLOGNAME];
+# elif defined(LOGIN_NAME_MAX)
+  char buf[LOGIN_NAME_MAX];
+# else
+  char buf[64];
+# endif
+} _Xgetloginparams;
+typedef struct {
+# ifdef TTY_NAME_MAX
+  char buf[TTY_NAME_MAX];
+# elif defined(_POSIX_TTY_NAME_MAX)
+  char buf[_POSIX_TTY_NAME_MAX];
+# elif defined(_POSIX_PATH_MAX)
+  char buf[_POSIX_PATH_MAX];
+# else
+  char buf[256];
+# endif
+} _Xttynameparams;
+
+# define _XGetlogin(p)	getlogin_r((p).buf, sizeof((p).buf))
+# define _XTtyname(f,p)	ttyname_r((f), (p).buf, sizeof((p).buf))
+#endif /* X_INCLUDE_UNISTD_H */
+
+#if defined(X_INCLUDE_UNISTD_H) && !defined(_XOS_INCLUDED_UNISTD_H)
+# define _XOS_INCLUDED_UNISTD_H
+#endif
+
+
+/***** <string.h> wrappers *****/
+
+/*
+ * Effective prototypes for <string.h> wrappers:
+ *
+ * #define X_INCLUDE_STRING_H
+ * #define XOS_USE_..._LOCKING
+ * #include <X11/Xos_r.h>
+ *
+ * typedef ... _Xstrtokparams;
+ *
+ * char *_XStrtok(char *, const char*, _Xstrtokparams);
+ */
+
+#if defined(X_INCLUDE_STRING_H) && !defined(_XOS_INCLUDED_STRING_H)
+/* <string.h> has already been included by <X11/Xos.h> */
+# if defined(XUSE_MTSAFE_API) || defined(XUSE_MTSAFE_STRINGAPI)
+#  define XOS_USE_MTSAFE_STRINGAPI 1
+# endif
+#endif
+
+#if !defined(X_INCLUDE_STRING_H) || defined(_XOS_INCLUDED_STRING_H)
+/* Do nothing. */
+
+#elif !defined(XTHREADS) && !defined(X_FORCE_USE_MTSAFE_API)
+/* Use regular, unsafe API. */
+typedef int _Xstrtokparams;	/* dummy */
+# define _XStrtok(s1,s2,p) \
+ ( p = 0, (void)p, strtok((s1),(s2)) )
+
+#elif !defined(XOS_USE_MTSAFE_STRINGAPI) || defined(XNO_MTSAFE_STRINGAPI)
+/* Systems with thread support but no _r API. */
+typedef char *_Xstrtokparams;
+# define _XStrtok(s1,s2,p) \
+ ( (_Xos_processLock), \
+   ((p) = strtok((s1),(s2))), \
+   (_Xos_processUnlock), \
+   (p) )
+
+#else
+/* POSIX or pre-POSIX API. */
+typedef char * _Xstrtokparams;
+# define _XStrtok(s1,s2,p)	strtok_r((s1),(s2),&(p))
+#endif /* X_INCLUDE_STRING_H */
+
+
+/***** <time.h> wrappers *****/
+
+/*
+ * Effective prototypes for <time.h> wrappers:
+ *
+ * #define X_INCLUDE_TIME_H
+ * #define XOS_USE_..._LOCKING
+ * #include <X11/Xos_r.h>
+ *
+ * typedef ... _Xatimeparams;
+ * typedef ... _Xctimeparams;
+ * typedef ... _Xgtimeparams;
+ * typedef ... _Xltimeparams;
+ *
+ * char *_XAsctime(const struct tm *, _Xatimeparams);
+ * char *_XCtime(const time_t *, _Xctimeparams);
+ * struct tm *_XGmtime(const time_t *, _Xgtimeparams);
+ * struct tm *_XLocaltime(const time_t *, _Xltimeparams);
+ */
+
+#if defined(X_INCLUDE_TIME_H) && !defined(_XOS_INCLUDED_TIME_H)
+# include <time.h>
+# if defined(XUSE_MTSAFE_API) || defined(XUSE_MTSAFE_TIMEAPI)
+#  define XOS_USE_MTSAFE_TIMEAPI 1
+# endif
+#endif
+
+#if !defined(X_INCLUDE_TIME_H) || defined(_XOS_INCLUDED_TIME_H)
+/* Do nothing. */
+
+#elif !defined(XTHREADS) && !defined(X_FORCE_USE_MTSAFE_API)
+/* Use regular, unsafe API. */
+typedef int _Xatimeparams;	/* dummy */
+# define _XAsctime(t,p)		asctime((t))
+typedef int _Xctimeparams;	/* dummy */
+# define _XCtime(t,p)		ctime((t))
+typedef int _Xgtimeparams;	/* dummy */
+# define _XGmtime(t,p)		gmtime((t))
+typedef int _Xltimeparams;	/* dummy */
+# define _XLocaltime(t,p)	localtime((t))
+
+#elif !defined(XOS_USE_MTSAFE_TIMEAPI) || defined(XNO_MTSAFE_TIMEAPI)
+/* Systems with thread support but no _r API. */
+typedef struct {
+# ifdef TIMELEN
+  char buf[TIMELEN];
+# else
+  char buf[26];
+# endif
+  char *result;
+} _Xctimeparams, _Xatimeparams;
+typedef struct {
+  struct tm buf;
+  struct tm *result;
+} _Xgtimeparams, _Xltimeparams;
+# define _XAsctime(t,p) \
+ ( (_Xos_processLock), \
+   (((p).result = asctime((t))) ? \
+    (strncpy((p).buf, (p).result, sizeof((p).buf)), (p).result = &(p).buf) : \
+    0), \
+   (_Xos_processUnlock), \
+   (p).result )
+# define _XCtime(t,p) \
+ ( (_Xos_processLock), \
+   (((p).result = ctime((t))) ? \
+    (strncpy((p).buf, (p).result, sizeof((p).buf)), (p).result = &(p).buf) : \
+    0), \
+   (_Xos_processUnlock), \
+   (p).result )
+# define _XGmtime(t,p) \
+ ( (_Xos_processLock), \
+   (((p).result = gmtime(t)) ? \
+    (memcpy(&(p).buf, (p).result, sizeof((p).buf)), (p).result = &(p).buf) : \
+    0), \
+   (_Xos_processUnlock), \
+   (p).result )
+# define _XLocaltime(t,p) \
+ ( (_Xos_processLock), \
+   (((p).result = localtime(t)) ? \
+    (memcpy(&(p).buf, (p).result, sizeof((p).buf)), (p).result = &(p).buf) : \
+    0), \
+   (_Xos_processUnlock), \
+   (p).result )
+
+#elif !defined(_POSIX_THREAD_SAFE_FUNCTIONS) &&  defined(hpV4)
+/* Returns (int)0 on success.
+ *
+ * extern int asctime_r(const struct tm *timeptr, char *buffer, int buflen);
+ * extern int ctime_r(const time_t *timer, char *buffer, int buflen);
+ * extern int gmtime_r(const time_t *timer, struct tm *result);
+ * extern int localtime_r(const time_t *timer, struct tm *result);
+ */
+# ifdef TIMELEN
+typedef char _Xatimeparams[TIMELEN];
+typedef char _Xctimeparams[TIMELEN];
+# else
+typedef char _Xatimeparams[26];
+typedef char _Xctimeparams[26];
+# endif
+typedef struct tm _Xgtimeparams;
+typedef struct tm _Xltimeparams;
+# define _XAsctime(t,p)		(asctime_r((t),(p),sizeof((p))) ? NULL : (p))
+# define _XCtime(t,p)		(ctime_r((t),(p),sizeof((p))) ? NULL : (p))
+# define _XGmtime(t,p)		(gmtime_r((t),&(p)) ? NULL : &(p))
+# define _XLocaltime(t,p)	(localtime_r((t),&(p)) ? NULL : &(p))
+
+#elif !defined(_POSIX_THREAD_SAFE_FUNCTIONS) && defined(__sun)
+/* Returns NULL on failure.  Solaris 2.5
+ *
+ * extern char *asctime_r(const struct tm *tm,char *buf, int buflen);
+ * extern char *ctime_r(const time_t *clock, char *buf, int buflen);
+ * extern struct tm *gmtime_r(const time_t *clock, struct tm *res);
+ * extern struct tm *localtime_r(const time_t *clock, struct tm *res);
+ */
+# ifdef TIMELEN
+typedef char _Xatimeparams[TIMELEN];
+typedef char _Xctimeparams[TIMELEN];
+# else
+typedef char _Xatimeparams[26];
+typedef char _Xctimeparams[26];
+# endif
+typedef struct tm _Xgtimeparams;
+typedef struct tm _Xltimeparams;
+# define _XAsctime(t,p)		asctime_r((t),(p),sizeof((p)))
+# define _XCtime(t,p)		ctime_r((t),(p),sizeof((p)))
+# define _XGmtime(t,p)		gmtime_r((t),&(p))
+# define _XLocaltime(t,p)	localtime_r((t),&(p))
+
+#else /* defined(_POSIX_THREAD_SAFE_FUNCTIONS) */
+/* POSIX final API.
+ * extern char *asctime_r(const struct tm *timeptr, char *buffer);
+ * extern char *ctime_r(const time_t *timer, char *buffer);
+ * extern struct tm *gmtime_r(const time_t *timer, struct tm *result);
+ * extern struct tm *localtime_r(const time_t *timer, struct tm *result);
+ */
+# ifdef TIMELEN
+typedef char _Xatimeparams[TIMELEN];
+typedef char _Xctimeparams[TIMELEN];
+# else
+typedef char _Xatimeparams[26];
+typedef char _Xctimeparams[26];
+# endif
+typedef struct tm _Xgtimeparams;
+typedef struct tm _Xltimeparams;
+# define _XAsctime(t,p)		asctime_r((t),(p))
+# define _XCtime(t,p)		ctime_r((t),(p))
+# define _XGmtime(t,p)		gmtime_r((t),&(p))
+# define _XLocaltime(t,p)	localtime_r((t),&(p))
+#endif /* X_INCLUDE_TIME_H */
+
+#if defined(X_INCLUDE_TIME_H) && !defined(_XOS_INCLUDED_TIME_H)
+# define _XOS_INCLUDED_TIME_H
+#endif
+
+
+/***** <grp.h> wrappers *****/
+
+/*
+ * Effective prototypes for <grp.h> wrappers:
+ *
+ * NOTE: On systems lacking appropriate _r functions Getgrgid() and
+ *	Getgrnam() do NOT copy the list of group members!
+ *
+ * Remember that fgetgrent(), setgrent(), getgrent(), and endgrent()
+ * are not included in POSIX.
+ *
+ * #define X_INCLUDE_GRP_H
+ * #define XOS_USE_..._LOCKING
+ * #include <X11/Xos_r.h>
+ *
+ * typedef ... _Xgetgrparams;
+ *
+ * struct group *_XGetgrgid(gid_t, _Xgetgrparams);
+ * struct group *_XGetgrnam(const char *, _Xgetgrparams);
+ */
+
+#if defined(X_INCLUDE_GRP_H) && !defined(_XOS_INCLUDED_GRP_H)
+# include <grp.h>
+# if defined(XUSE_MTSAFE_API) || defined(XUSE_MTSAFE_GRPAPI)
+#  define XOS_USE_MTSAFE_GRPAPI 1
+# endif
+#endif
+
+#if !defined(X_INCLUDE_GRP_H) || defined(_XOS_INCLUDED_GRP_H)
+/* Do nothing. */
+
+#elif !defined(XTHREADS) && !defined(X_FORCE_USE_MTSAFE_API)
+/* Use regular, unsafe API. */
+typedef int _Xgetgrparams;	/* dummy */
+#define _XGetgrgid(g,p)	getgrgid((g))
+#define _XGetgrnam(n,p)	getgrnam((n))
+
+#elif !defined(XOS_USE_MTSAFE_GRPAPI) || defined(XNO_MTSAFE_GRPAPI)
+/* Systems with thread support but no _r API.  UnixWare 2.0. */
+typedef struct {
+  struct group grp;
+  char buf[X_LINE_MAX];	/* Should be sysconf(_SC_GETGR_R_SIZE_MAX)? */
+  struct group *pgrp;
+  size_t len;
+} _Xgetgrparams;
+#ifdef SVR4
+/* Copy the gr_passwd field too. */
+# define _Xgrp_copyGroup(p) \
+ ( memcpy(&(p).grp, (p).pgrp, sizeof(struct group)), \
+   ((p).grp.gr_name = (p).buf), \
+   ((p).len = strlen((p).pgrp->gr_name)), \
+   strcpy((p).grp.gr_name, (p).pgrp->gr_name), \
+   ((p).grp.gr_passwd = (p).grp.gr_name + (p).len + 1), \
+   ((p).pgrp = &(p).grp), \
+   0 )
+#else
+# define _Xgrp_copyGroup(p) \
+ ( memcpy(&(p).grp, (p).pgrp, sizeof(struct group)), \
+   ((p).grp.gr_name = (p).buf), \
+   strcpy((p).grp.gr_name, (p).pgrp->gr_name), \
+   ((p).pgrp = &(p).grp), \
+   0 )
+#endif
+#define _XGetgrgid(g,p) \
+ ( (_Xos_processLock), \
+   (((p).pgrp = getgrgid((g))) ? _Xgrp_copyGroup(p) : 0), \
+   (_Xos_processUnlock), \
+   (p).pgrp )
+#define _XGetgrnam(n,p) \
+ ( (_Xos_processLock), \
+   (((p).pgrp = getgrnam((n))) ? _Xgrp_copyGroup(p) : 0), \
+   (_Xos_processUnlock), \
+   (p).pgrp )
+
+#elif !defined(_POSIX_THREAD_SAFE_FUNCTIONS) && defined(__sun)
+/* Non-POSIX API.  Solaris.
+ *
+ * extern struct group *getgrgid_r(gid_t, struct group *, char *, int);
+ * extern struct group *getgrnam_r(const char *, struct group *, char *, int);
+ */
+typedef struct {
+  struct group grp;
+  char buf[X_LINE_MAX];	/* Should be sysconf(_SC_GETGR_R_SIZE_MAX)? */
+} _Xgetgrparams;
+#define _XGetgrgid(g,p)	getgrgid_r((g), &(p).grp, (p).buf, sizeof((p).buf))
+#define _XGetgrnam(n,p)	getgrnam_r((n), &(p).grp, (p).buf, sizeof((p).buf))
+
+#elif !defined(_POSIX_THREAD_SAFE_FUNCTIONS)
+/* Non-POSIX API.
+ * extern int getgrgid_r(gid_t, struct group *, char *, int);
+ * extern int getgrnam_r(const char *, struct group *, char *, int);
+ */
+typedef struct {
+  struct group grp;
+  char buf[X_LINE_MAX];	/* Should be sysconf(_SC_GETGR_R_SIZE_MAX)? */
+} _Xgetgrparams;
+#define _XGetgrgid(g,p)	\
+ ((getgrgid_r((g), &(p).grp, (p).buf, sizeof((p).buf)) ? NULL : &(p).grp))
+#define _XGetgrnam(n,p)	\
+ ((getgrnam_r((n), &(p).grp, (p).buf, sizeof((p).buf)) ? NULL : &(p).grp))
+
+#else
+/* POSIX final API.
+ *
+ * int getgrgid_r(gid_t, struct group *, char *, size_t, struct group **);
+ * int getgrnam_r(const char *, struct group *, char *, size_t, struct group **);
+ */
+typedef struct {
+  struct group grp;
+  char buf[X_LINE_MAX];	/* Should be sysconf(_SC_GETGR_R_SIZE_MAX)? */
+  struct group *result;
+} _Xgetgrparams;
+
+#define _XGetgrgid(g,p)	\
+ ((getgrgid_r((g), &(p).grp, (p).buf, sizeof((p).buf), &(p).result) ? \
+   NULL : (p).result))
+#define _XGetgrnam(n,p)	\
+ ((getgrnam_r((n), &(p).grp, (p).buf, sizeof((p).buf), &(p).result) ? \
+   NULL : (p).result))
+#endif
+
+#if defined(X_INCLUDE_GRP_H) && !defined(_XOS_INCLUDED_GRP_H)
+# define _XOS_INCLUDED_GRP_H
+#endif
+
+
+#ifdef __cplusplus
+}  /* Close scope of 'extern "C"' declaration which encloses file. */
+#endif
diff -Naur old/X11/Xosdefs.h new/X11/Xosdefs.h
--- old/X11/Xosdefs.h	1970-01-01 08:00:00.000000000 +0800
+++ new/X11/Xosdefs.h	2024-03-05 19:36:25.210042000 +0800
@@ -0,0 +1,116 @@
+/*
+ * O/S-dependent (mis)feature macro definitions
+ *
+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.
+ */
+
+#ifndef _XOSDEFS_H_
+# define _XOSDEFS_H_
+
+/*
+ * X_NOT_POSIX means does not have POSIX header files.  Lack of this
+ * symbol does NOT mean that the POSIX environment is the default.
+ * You may still have to define _POSIX_SOURCE to get it.
+ */
+
+
+# ifdef _SCO_DS
+#  ifndef __SCO__
+#   define __SCO__
+#  endif
+# endif
+
+# ifdef __i386__
+#  ifdef SYSV
+#   if !defined(__SCO__) && \
+	!defined(__UNIXWARE__) && !defined(__sun)
+#    if !defined(_POSIX_SOURCE)
+#     define X_NOT_POSIX
+#    endif
+#   endif
+#  endif
+# endif
+
+# ifdef __sun
+/* Imake configs define SVR4 on Solaris, but cc & gcc only define __SVR4
+ * This check allows non-Imake configured programs to build correctly.
+ */
+#  if defined(__SVR4) && !defined(SVR4)
+#   define SVR4 1
+#  endif
+#  ifdef SVR4
+/* define this to whatever it needs to be */
+#   define X_POSIX_C_SOURCE 199300L
+#  endif
+# endif
+
+# ifdef WIN32
+#  ifndef _POSIX_
+#   define X_NOT_POSIX
+#  endif
+# endif
+
+
+# ifdef __APPLE__
+#  define NULL_NOT_ZERO
+
+/* Defining any of these will sanitize the namespace to JUST want is defined by
+ * that particular standard.  If that happens, we don't get some expected
+ * prototypes, typedefs, etc (like fd_mask).  We can define _DARWIN_C_SOURCE to
+ * loosen our belts a tad.
+ */
+#  if defined(_XOPEN_SOURCE) || defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE)
+#   ifndef _DARWIN_C_SOURCE
+#    define _DARWIN_C_SOURCE
+#   endif
+#  endif
+
+# endif
+
+# ifdef __GNU__
+#  ifndef PATH_MAX
+#   define PATH_MAX 4096
+#  endif
+#  ifndef MAXPATHLEN
+#   define MAXPATHLEN 4096
+#  endif
+# endif
+
+# if defined(__SCO__) || defined(__UNIXWARE__)
+#  ifndef PATH_MAX
+#   define PATH_MAX	1024
+#  endif
+#  ifndef MAXPATHLEN
+#   define MAXPATHLEN	1024
+#  endif
+# endif
+
+# if defined(__OpenBSD__) || defined(__NetBSD__) || defined(__FreeBSD__) \
+	|| defined(__APPLE__) || defined(__DragonFly__)
+#  ifndef CSRG_BASED
+#   define CSRG_BASED
+#  endif
+# endif
+
+#endif /* _XOSDEFS_H_ */
+
diff -Naur old/X11/Xtrans/Xtrans.c new/X11/Xtrans/Xtrans.c
--- old/X11/Xtrans/Xtrans.c	1970-01-01 08:00:00.000000000 +0800
+++ new/X11/Xtrans/Xtrans.c	2024-03-05 19:36:25.211041600 +0800
@@ -0,0 +1,1352 @@
+/*
+
+Copyright 1993, 1994, 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 1993, 1994 NCR Corporation - Dayton, Ohio, USA
+ *
+ * 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 NCR not be used in advertising
+ * or publicity pertaining to distribution of the software without specific,
+ * written prior permission.  NCR makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ *
+ * NCR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
+ * NO EVENT SHALL NCR 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.
+ */
+
+#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
+#ifdef HAVE_SYSTEMD_DAEMON
+#include <systemd/sd-daemon.h>
+#endif
+
+/*
+ * The transport table contains a definition for every transport (protocol)
+ * family. All operations that can be made on the transport go through this
+ * table.
+ *
+ * Each transport is assigned a unique transport id.
+ *
+ * New transports can be added by adding an entry in this table.
+ * For compatiblity, the transport ids should never be renumbered.
+ * Always add to the end of the list.
+ */
+
+#define TRANS_TLI_INET_INDEX		1
+#define TRANS_TLI_TCP_INDEX		2
+#define TRANS_TLI_TLI_INDEX		3
+#define TRANS_SOCKET_UNIX_INDEX		4
+#define TRANS_SOCKET_LOCAL_INDEX	5
+#define TRANS_SOCKET_INET_INDEX		6
+#define TRANS_SOCKET_TCP_INDEX		7
+#define TRANS_DNET_INDEX		8
+#define TRANS_LOCAL_LOCAL_INDEX		9
+#define TRANS_LOCAL_PTS_INDEX		10
+#define TRANS_LOCAL_NAMED_INDEX		11
+/* 12 used to be ISC, but that's gone. */
+#define TRANS_LOCAL_SCO_INDEX		13
+#define TRANS_SOCKET_INET6_INDEX	14
+#define TRANS_LOCAL_PIPE_INDEX		15
+
+
+static
+Xtransport_table Xtransports[] = {
+#if defined(TCPCONN)
+    { &TRANS(SocketTCPFuncs),	TRANS_SOCKET_TCP_INDEX },
+#if defined(IPv6) && defined(AF_INET6)
+    { &TRANS(SocketINET6Funcs),	TRANS_SOCKET_INET6_INDEX },
+#endif /* IPv6 */
+    { &TRANS(SocketINETFuncs),	TRANS_SOCKET_INET_INDEX },
+#endif /* TCPCONN */
+#if defined(UNIXCONN)
+#if !defined(LOCALCONN)
+    { &TRANS(SocketLocalFuncs),	TRANS_SOCKET_LOCAL_INDEX },
+#endif /* !LOCALCONN */
+    { &TRANS(SocketUNIXFuncs),	TRANS_SOCKET_UNIX_INDEX },
+#endif /* UNIXCONN */
+#if defined(LOCALCONN)
+    { &TRANS(LocalFuncs),	TRANS_LOCAL_LOCAL_INDEX },
+#ifndef __sun
+    { &TRANS(PTSFuncs),		TRANS_LOCAL_PTS_INDEX },
+#endif /* __sun */
+#if defined(SVR4) || defined(__SVR4)
+    { &TRANS(NAMEDFuncs),	TRANS_LOCAL_NAMED_INDEX },
+#endif
+#ifdef __sun
+    { &TRANS(PIPEFuncs),	TRANS_LOCAL_PIPE_INDEX },
+#endif /* __sun */
+#if defined(__SCO__) || defined(__UNIXWARE__)
+    { &TRANS(SCOFuncs),		TRANS_LOCAL_SCO_INDEX },
+#endif /* __SCO__ || __UNIXWARE__ */
+#endif /* LOCALCONN */
+};
+
+#define NUMTRANS	(sizeof(Xtransports)/sizeof(Xtransport_table))
+
+
+#ifdef WIN32
+#define ioctl ioctlsocket
+#endif
+
+
+
+/*
+ * These are a few utility function used by the public interface functions.
+ */
+
+void
+TRANS(FreeConnInfo) (XtransConnInfo ciptr)
+
+{
+    prmsg (3,"FreeConnInfo(%p)\n", ciptr);
+
+    if (ciptr->addr)
+	free (ciptr->addr);
+
+    if (ciptr->peeraddr)
+	free (ciptr->peeraddr);
+
+    if (ciptr->port)
+	free (ciptr->port);
+
+    free (ciptr);
+}
+
+
+#define PROTOBUFSIZE	20
+
+static Xtransport *
+TRANS(SelectTransport) (const char *protocol)
+
+{
+#ifndef HAVE_STRCASECMP
+    char 	protobuf[PROTOBUFSIZE];
+#endif
+    int		i;
+
+    prmsg (3,"SelectTransport(%s)\n", protocol);
+
+#ifndef HAVE_STRCASECMP
+    /*
+     * Force Protocol to be lowercase as a way of doing
+     * a case insensitive match.
+     */
+
+    strncpy (protobuf, protocol, PROTOBUFSIZE - 1);
+    protobuf[PROTOBUFSIZE-1] = '\0';
+
+    for (i = 0; i < PROTOBUFSIZE && protobuf[i] != '\0'; i++)
+	if (isupper ((unsigned char)protobuf[i]))
+	    protobuf[i] = tolower ((unsigned char)protobuf[i]);
+#endif
+
+    /* Look at all of the configured protocols */
+
+    for (i = 0; i < NUMTRANS; i++)
+    {
+#ifndef HAVE_STRCASECMP
+	if (!strcmp (protobuf, Xtransports[i].transport->TransName))
+#else
+	if (!strcasecmp (protocol, Xtransports[i].transport->TransName))
+#endif
+	    return Xtransports[i].transport;
+    }
+
+    return NULL;
+}
+
+#ifndef TEST_t
+static
+#endif /* TEST_t */
+int
+TRANS(ParseAddress) (const char *address,
+                     char **protocol, char **host, char **port)
+
+{
+    /*
+     * For the font library, the address is a string formatted
+     * as "protocol/host:port[/catalogue]".  Note that the catologue
+     * is optional.  At this time, the catologue info is ignored, but
+     * we have to parse it anyways.
+     *
+     * Other than fontlib, the address is a string formatted
+     * as "protocol/host:port".
+     *
+     * If the protocol part is missing, then assume TCP.
+     * If the protocol part and host part are missing, then assume local.
+     * If a "::" is found then assume DNET.
+     */
+
+    char	*mybuf, *tmpptr;
+    const char	*_protocol;
+    char	*_host, *_port;
+    char	hostnamebuf[256];
+    int		_host_len;
+
+    prmsg (3,"ParseAddress(%s)\n", address);
+
+    /* Copy the string so it can be changed */
+
+    tmpptr = mybuf = strdup (address);
+
+    /* Parse the string to get each component */
+
+    /* Get the protocol part */
+
+    _protocol = mybuf;
+
+
+   if ( ((mybuf = strchr (mybuf,'/')) == NULL) &&
+      ((mybuf = strrchr (tmpptr,':')) == NULL) )
+   {
+	/* address is in a bad format */
+	*protocol = NULL;
+	*host = NULL;
+	*port = NULL;
+	free (tmpptr);
+	return 0;
+    }
+
+    if (*mybuf == ':')
+    {
+	/*
+	 * If there is a hostname, then assume tcp, otherwise
+	 * it must be local.
+	 */
+	if (mybuf == tmpptr)
+	{
+	    /* There is neither a protocol or host specified */
+	    _protocol = "local";
+	}
+	else
+	{
+	    /* There is a hostname specified */
+	    _protocol = "tcp";
+	    mybuf = tmpptr;	/* reset to the begining of the host ptr */
+	}
+    }
+    else
+    {
+	/* *mybuf == '/' */
+
+	*mybuf ++= '\0'; /* put a null at the end of the protocol */
+
+	if (strlen(_protocol) == 0)
+	{
+	    /*
+	     * If there is a hostname, then assume tcp, otherwise
+	     * it must be local.
+	     */
+	    if (*mybuf != ':')
+		_protocol = "tcp";
+	    else
+		_protocol = "local";
+	}
+    }
+
+    /* Get the host part */
+
+    _host = mybuf;
+
+    if ((mybuf = strrchr (mybuf,':')) == NULL)
+    {
+	*protocol = NULL;
+	*host = NULL;
+	*port = NULL;
+	free (tmpptr);
+	return 0;
+    }
+
+    *mybuf ++= '\0';
+
+    _host_len = strlen(_host);
+    if (_host_len == 0)
+    {
+	TRANS(GetHostname) (hostnamebuf, sizeof (hostnamebuf));
+	_host = hostnamebuf;
+    }
+#if defined(IPv6) && defined(AF_INET6)
+    /* hostname in IPv6 [numeric_addr]:0 form? */
+    else if ( (_host_len > 3) &&
+      ((strcmp(_protocol, "tcp") == 0) || (strcmp(_protocol, "inet6") == 0))
+      && (*_host == '[') && (*(_host + _host_len - 1) == ']') ) {
+	struct sockaddr_in6 sin6;
+
+	*(_host + _host_len - 1) = '\0';
+
+	/* Verify address is valid IPv6 numeric form */
+	if (inet_pton(AF_INET6, _host + 1, &sin6) == 1) {
+	    /* It is. Use it as such. */
+	    _host++;
+	    _protocol = "inet6";
+	} else {
+	    /* It's not, restore it just in case some other code can use it. */
+	    *(_host + _host_len - 1) = ']';
+	}
+    }
+#endif
+
+
+    /* Get the port */
+
+    _port = mybuf;
+
+#if defined(FONT_t) || defined(FS_t)
+    /*
+     * Is there an optional catalogue list?
+     */
+
+    if ((mybuf = strchr (mybuf,'/')) != NULL)
+	*mybuf ++= '\0';
+
+    /*
+     * The rest, if any, is the (currently unused) catalogue list.
+     *
+     * _catalogue = mybuf;
+     */
+#endif
+
+#ifdef HAVE_LAUNCHD
+    /* launchd sockets will look like 'local//tmp/launch-XgkNns/:0' */
+    if(address != NULL && strlen(address)>8 && (!strncmp(address,"local//",7))) {
+      _protocol="local";
+      _host="";
+      _port=address+6;
+    }
+#endif
+
+    /*
+     * Now that we have all of the components, allocate new
+     * string space for them.
+     */
+
+    if ((*protocol = strdup (_protocol)) == NULL)
+    {
+	/* Malloc failed */
+	*port = NULL;
+	*host = NULL;
+	*protocol = NULL;
+	free (tmpptr);
+	return 0;
+    }
+
+    if ((*host = strdup (_host)) == NULL)
+    {
+	/* Malloc failed */
+	*port = NULL;
+	*host = NULL;
+	free (*protocol);
+	*protocol = NULL;
+	free (tmpptr);
+	return 0;
+    }
+
+    if ((*port = strdup (_port)) == NULL)
+    {
+	/* Malloc failed */
+	*port = NULL;
+	free (*host);
+	*host = NULL;
+	free (*protocol);
+	*protocol = NULL;
+	free (tmpptr);
+	return 0;
+    }
+
+    free (tmpptr);
+
+    return 1;
+}
+
+
+/*
+ * TRANS(Open) does all of the real work opening a connection. The only
+ * funny part about this is the type parameter which is used to decide which
+ * type of open to perform.
+ */
+
+static XtransConnInfo
+TRANS(Open) (int type, const char *address)
+
+{
+    char 		*protocol = NULL, *host = NULL, *port = NULL;
+    XtransConnInfo	ciptr = NULL;
+    Xtransport		*thistrans;
+
+    prmsg (2,"Open(%d,%s)\n", type, address);
+
+#if defined(WIN32) && defined(TCPCONN)
+    if (TRANS(WSAStartup)())
+    {
+	prmsg (1,"Open: WSAStartup failed\n");
+	return NULL;
+    }
+#endif
+
+    /* Parse the Address */
+
+    if (TRANS(ParseAddress) (address, &protocol, &host, &port) == 0)
+    {
+	prmsg (1,"Open: Unable to Parse address %s\n", address);
+	return NULL;
+    }
+
+    /* Determine the transport type */
+
+    if ((thistrans = TRANS(SelectTransport) (protocol)) == NULL)
+    {
+	prmsg (1,"Open: Unable to find transport for %s\n",
+	       protocol);
+
+	free (protocol);
+	free (host);
+	free (port);
+	return NULL;
+    }
+
+    /* Open the transport */
+
+    switch (type)
+    {
+    case XTRANS_OPEN_COTS_CLIENT:
+#ifdef TRANS_CLIENT
+	ciptr = thistrans->OpenCOTSClient(thistrans, protocol, host, port);
+#endif /* TRANS_CLIENT */
+	break;
+    case XTRANS_OPEN_COTS_SERVER:
+#ifdef TRANS_SERVER
+	ciptr = thistrans->OpenCOTSServer(thistrans, protocol, host, port);
+#endif /* TRANS_SERVER */
+	break;
+    default:
+	prmsg (1,"Open: Unknown Open type %d\n", type);
+    }
+
+    if (ciptr == NULL)
+    {
+	if (!(thistrans->flags & TRANS_DISABLED))
+	{
+	    prmsg (1,"Open: transport open failed for %s/%s:%s\n",
+	           protocol, host, port);
+	}
+	free (protocol);
+	free (host);
+	free (port);
+	return NULL;
+    }
+
+    ciptr->transptr = thistrans;
+    ciptr->port = port;			/* We need this for TRANS(Reopen) */
+
+    free (protocol);
+    free (host);
+
+    return ciptr;
+}
+
+
+#ifdef TRANS_REOPEN
+
+/*
+ * We might want to create an XtransConnInfo object based on a previously
+ * opened connection.  For example, the font server may clone itself and
+ * pass file descriptors to the parent.
+ */
+
+static XtransConnInfo
+TRANS(Reopen) (int type, int trans_id, int fd, const char *port)
+
+{
+    XtransConnInfo	ciptr = NULL;
+    Xtransport		*thistrans = NULL;
+    char		*save_port;
+    int			i;
+
+    prmsg (2,"Reopen(%d,%d,%s)\n", trans_id, fd, port);
+
+    /* Determine the transport type */
+
+    for (i = 0; i < NUMTRANS; i++)
+	if (Xtransports[i].transport_id == trans_id)
+	{
+	    thistrans = Xtransports[i].transport;
+	    break;
+	}
+
+    if (thistrans == NULL)
+    {
+	prmsg (1,"Reopen: Unable to find transport id %d\n",
+	       trans_id);
+
+	return NULL;
+    }
+
+    if ((save_port = strdup (port)) == NULL)
+    {
+	prmsg (1,"Reopen: Unable to malloc port string\n");
+
+	return NULL;
+    }
+
+    /* Get a new XtransConnInfo object */
+
+    switch (type)
+    {
+    case XTRANS_OPEN_COTS_SERVER:
+	ciptr = thistrans->ReopenCOTSServer(thistrans, fd, port);
+	break;
+    default:
+	prmsg (1,"Reopen: Bad Open type %d\n", type);
+    }
+
+    if (ciptr == NULL)
+    {
+	prmsg (1,"Reopen: transport open failed\n");
+	free (save_port);
+	return NULL;
+    }
+
+    ciptr->transptr = thistrans;
+    ciptr->port = save_port;
+
+    return ciptr;
+}
+
+#endif /* TRANS_REOPEN */
+
+
+
+/*
+ * These are the public interfaces to this Transport interface.
+ * These are the only functions that should have knowledge of the transport
+ * table.
+ */
+
+#ifdef TRANS_CLIENT
+
+XtransConnInfo
+TRANS(OpenCOTSClient) (const char *address)
+
+{
+    prmsg (2,"OpenCOTSClient(%s)\n", address);
+    return TRANS(Open) (XTRANS_OPEN_COTS_CLIENT, address);
+}
+
+#endif /* TRANS_CLIENT */
+
+
+#ifdef TRANS_SERVER
+
+XtransConnInfo
+TRANS(OpenCOTSServer) (const char *address)
+
+{
+    prmsg (2,"OpenCOTSServer(%s)\n", address);
+    return TRANS(Open) (XTRANS_OPEN_COTS_SERVER, address);
+}
+
+#endif /* TRANS_SERVER */
+
+
+#ifdef TRANS_REOPEN
+
+XtransConnInfo
+TRANS(ReopenCOTSServer) (int trans_id, int fd, const char *port)
+
+{
+    prmsg (2,"ReopenCOTSServer(%d, %d, %s)\n", trans_id, fd, port);
+    return TRANS(Reopen) (XTRANS_OPEN_COTS_SERVER, trans_id, fd, port);
+}
+
+int
+TRANS(GetReopenInfo) (XtransConnInfo ciptr,
+		      int *trans_id, int *fd, char **port)
+
+{
+    int i;
+
+    for (i = 0; i < NUMTRANS; i++)
+	if (Xtransports[i].transport == ciptr->transptr)
+	{
+	    *trans_id = Xtransports[i].transport_id;
+	    *fd = ciptr->fd;
+
+	    if ((*port = strdup (ciptr->port)) == NULL)
+		return 0;
+	    else
+		return 1;
+	}
+
+    return 0;
+}
+
+#endif /* TRANS_REOPEN */
+
+
+int
+TRANS(SetOption) (XtransConnInfo ciptr, int option, int arg)
+
+{
+    int	fd = ciptr->fd;
+    int	ret = 0;
+
+    prmsg (2,"SetOption(%d,%d,%d)\n", fd, option, arg);
+
+    /*
+     * For now, all transport type use the same stuff for setting options.
+     * As long as this is true, we can put the common code here. Once a more
+     * complicated transport such as shared memory or an OSI implementation
+     * that uses the session and application libraries is implemented, this
+     * code may have to move to a transport dependent function.
+     *
+     * ret = ciptr->transptr->SetOption (ciptr, option, arg);
+     */
+
+    switch (option)
+    {
+    case TRANS_NONBLOCKING:
+	switch (arg)
+	{
+	case 0:
+	    /* Set to blocking mode */
+	    break;
+	case 1: /* Set to non-blocking mode */
+
+#if defined(O_NONBLOCK) && !defined(SCO325)
+	    ret = fcntl (fd, F_GETFL, 0);
+	    if (ret != -1)
+		ret = fcntl (fd, F_SETFL, ret | O_NONBLOCK);
+#else
+#ifdef FIOSNBIO
+	{
+	    int arg;
+	    arg = 1;
+	    ret = ioctl (fd, FIOSNBIO, &arg);
+	}
+#else
+#if defined(WIN32)
+	{
+#ifdef WIN32
+	    u_long arg;
+#else
+	    int arg;
+#endif
+	    arg = 1;
+/* IBM TCP/IP understands this option too well: it causes TRANS(Read) to fail
+ * eventually with EWOULDBLOCK */
+	    ret = ioctl (fd, FIONBIO, &arg);
+	}
+#else
+	    ret = fcntl (fd, F_GETFL, 0);
+#ifdef FNDELAY
+	    ret = fcntl (fd, F_SETFL, ret | FNDELAY);
+#else
+	    ret = fcntl (fd, F_SETFL, ret | O_NDELAY);
+#endif
+#endif /* AIXV3  || uniosu */
+#endif /* FIOSNBIO */
+#endif /* O_NONBLOCK */
+	    break;
+	default:
+	    /* Unknown option */
+	    break;
+	}
+	break;
+    case TRANS_CLOSEONEXEC:
+#ifdef F_SETFD
+#ifdef FD_CLOEXEC
+	ret = fcntl (fd, F_SETFD, FD_CLOEXEC);
+#else
+	ret = fcntl (fd, F_SETFD, 1);
+#endif /* FD_CLOEXEC */
+#endif /* F_SETFD */
+	break;
+    }
+
+    return ret;
+}
+
+#ifdef TRANS_SERVER
+
+int
+TRANS(CreateListener) (XtransConnInfo ciptr, const char *port, unsigned int flags)
+
+{
+    return ciptr->transptr->CreateListener (ciptr, port, flags);
+}
+
+int
+TRANS(Received) (const char * protocol)
+
+{
+   Xtransport *trans;
+   int i = 0, ret = 0;
+
+   prmsg (5, "Received(%s)\n", protocol);
+
+   if ((trans = TRANS(SelectTransport)(protocol)) == NULL)
+   {
+	prmsg (1,"Received: unable to find transport: %s\n",
+	       protocol);
+
+	return -1;
+   }
+   if (trans->flags & TRANS_ALIAS) {
+       if (trans->nolisten)
+	   while (trans->nolisten[i]) {
+	       ret |= TRANS(Received)(trans->nolisten[i]);
+	       i++;
+       }
+   }
+
+   trans->flags |= TRANS_RECEIVED;
+   return ret;
+}
+
+int
+TRANS(NoListen) (const char * protocol)
+
+{
+   Xtransport *trans;
+   int i = 0, ret = 0;
+
+   if ((trans = TRANS(SelectTransport)(protocol)) == NULL)
+   {
+	prmsg (1,"TransNoListen: unable to find transport: %s\n",
+	       protocol);
+
+	return -1;
+   }
+   if (trans->flags & TRANS_ALIAS) {
+       if (trans->nolisten)
+	   while (trans->nolisten[i]) {
+	       ret |= TRANS(NoListen)(trans->nolisten[i]);
+	       i++;
+       }
+   }
+
+   trans->flags |= TRANS_NOLISTEN;
+   return ret;
+}
+
+int
+TRANS(Listen) (const char * protocol)
+{
+   Xtransport *trans;
+   int i = 0, ret = 0;
+
+   if ((trans = TRANS(SelectTransport)(protocol)) == NULL)
+   {
+	prmsg (1,"TransListen: unable to find transport: %s\n",
+	       protocol);
+
+	return -1;
+   }
+   if (trans->flags & TRANS_ALIAS) {
+       if (trans->nolisten)
+	   while (trans->nolisten[i]) {
+	       ret |= TRANS(Listen)(trans->nolisten[i]);
+	       i++;
+       }
+   }
+
+   trans->flags &= ~TRANS_NOLISTEN;
+   return ret;
+}
+
+int
+TRANS(IsListening) (const char * protocol)
+{
+   Xtransport *trans;
+
+   if ((trans = TRANS(SelectTransport)(protocol)) == NULL)
+   {
+	prmsg (1,"TransIsListening: unable to find transport: %s\n",
+	       protocol);
+
+	return 0;
+   }
+
+   return !(trans->flags & TRANS_NOLISTEN);
+}
+
+int
+TRANS(ResetListener) (XtransConnInfo ciptr)
+
+{
+    if (ciptr->transptr->ResetListener)
+	return ciptr->transptr->ResetListener (ciptr);
+    else
+	return TRANS_RESET_NOOP;
+}
+
+
+XtransConnInfo
+TRANS(Accept) (XtransConnInfo ciptr, int *status)
+
+{
+    XtransConnInfo	newciptr;
+
+    prmsg (2,"Accept(%d)\n", ciptr->fd);
+
+    newciptr = ciptr->transptr->Accept (ciptr, status);
+
+    if (newciptr)
+	newciptr->transptr = ciptr->transptr;
+
+    return newciptr;
+}
+
+#endif /* TRANS_SERVER */
+
+
+#ifdef TRANS_CLIENT
+
+int
+TRANS(Connect) (XtransConnInfo ciptr, const char *address)
+
+{
+    char	*protocol;
+    char	*host;
+    char	*port;
+    int		ret;
+
+    prmsg (2,"Connect(%d,%s)\n", ciptr->fd, address);
+
+    if (TRANS(ParseAddress) (address, &protocol, &host, &port) == 0)
+    {
+	prmsg (1,"Connect: Unable to Parse address %s\n",
+	       address);
+	return -1;
+    }
+
+#ifdef HAVE_LAUNCHD
+    if (!host) host=strdup("");
+#endif
+
+    if (!port || !*port)
+    {
+	prmsg (1,"Connect: Missing port specification in %s\n",
+	      address);
+	if (protocol) free (protocol);
+	if (host) free (host);
+	return -1;
+    }
+
+    ret = ciptr->transptr->Connect (ciptr, host, port);
+
+    if (protocol) free (protocol);
+    if (host) free (host);
+    if (port) free (port);
+
+    return ret;
+}
+
+#endif /* TRANS_CLIENT */
+
+
+int
+TRANS(BytesReadable) (XtransConnInfo ciptr, BytesReadable_t *pend)
+
+{
+    return ciptr->transptr->BytesReadable (ciptr, pend);
+}
+
+int
+TRANS(Read) (XtransConnInfo ciptr, char *buf, int size)
+
+{
+    return ciptr->transptr->Read (ciptr, buf, size);
+}
+
+int
+TRANS(Write) (XtransConnInfo ciptr, char *buf, int size)
+
+{
+    return ciptr->transptr->Write (ciptr, buf, size);
+}
+
+int
+TRANS(Readv) (XtransConnInfo ciptr, struct iovec *buf, int size)
+
+{
+    return ciptr->transptr->Readv (ciptr, buf, size);
+}
+
+int
+TRANS(Writev) (XtransConnInfo ciptr, struct iovec *buf, int size)
+
+{
+    return ciptr->transptr->Writev (ciptr, buf, size);
+}
+
+#if XTRANS_SEND_FDS
+int
+TRANS(SendFd) (XtransConnInfo ciptr, int fd, int do_close)
+{
+    return ciptr->transptr->SendFd(ciptr, fd, do_close);
+}
+
+int
+TRANS(RecvFd) (XtransConnInfo ciptr)
+{
+    return ciptr->transptr->RecvFd(ciptr);
+}
+#endif
+
+int
+TRANS(Disconnect) (XtransConnInfo ciptr)
+
+{
+    return ciptr->transptr->Disconnect (ciptr);
+}
+
+int
+TRANS(Close) (XtransConnInfo ciptr)
+
+{
+    int ret;
+
+    prmsg (2,"Close(%d)\n", ciptr->fd);
+
+    ret = ciptr->transptr->Close (ciptr);
+
+    TRANS(FreeConnInfo) (ciptr);
+
+    return ret;
+}
+
+int
+TRANS(CloseForCloning) (XtransConnInfo ciptr)
+
+{
+    int ret;
+
+    prmsg (2,"CloseForCloning(%d)\n", ciptr->fd);
+
+    ret = ciptr->transptr->CloseForCloning (ciptr);
+
+    TRANS(FreeConnInfo) (ciptr);
+
+    return ret;
+}
+
+int
+TRANS(IsLocal) (XtransConnInfo ciptr)
+
+{
+    return (ciptr->family == AF_UNIX);
+}
+
+int
+TRANS(GetPeerAddr) (XtransConnInfo ciptr, int *familyp, int *addrlenp,
+		    Xtransaddr **addrp)
+
+{
+    prmsg (2,"GetPeerAddr(%d)\n", ciptr->fd);
+
+    *familyp = ciptr->family;
+    *addrlenp = ciptr->peeraddrlen;
+
+    if ((*addrp = malloc (ciptr->peeraddrlen)) == NULL)
+    {
+	prmsg (1,"GetPeerAddr: malloc failed\n");
+	return -1;
+    }
+    memcpy(*addrp, ciptr->peeraddr, ciptr->peeraddrlen);
+
+    return 0;
+}
+
+
+int
+TRANS(GetConnectionNumber) (XtransConnInfo ciptr)
+
+{
+    return ciptr->fd;
+}
+
+
+/*
+ * These functions are really utility functions, but they require knowledge
+ * of the internal data structures, so they have to be part of the Transport
+ * Independant API.
+ */
+
+#ifdef TRANS_SERVER
+
+static int
+complete_network_count (void)
+
+{
+    int count = 0;
+    int found_local = 0;
+    int i;
+
+    /*
+     * For a complete network, we only need one LOCALCONN transport to work
+     */
+
+    for (i = 0; i < NUMTRANS; i++)
+    {
+	if (Xtransports[i].transport->flags & TRANS_ALIAS
+   	 || Xtransports[i].transport->flags & TRANS_NOLISTEN)
+	    continue;
+
+	if (Xtransports[i].transport->flags & TRANS_LOCAL)
+	    found_local = 1;
+	else
+	    count++;
+    }
+
+    return (count + found_local);
+}
+
+
+static int
+receive_listening_fds(const char* port, XtransConnInfo* temp_ciptrs,
+                      int* count_ret)
+
+{
+#ifdef HAVE_SYSTEMD_DAEMON
+    XtransConnInfo ciptr;
+    int i, systemd_listen_fds;
+
+    systemd_listen_fds = sd_listen_fds(1);
+    if (systemd_listen_fds < 0)
+    {
+        prmsg (1, "receive_listening_fds: sd_listen_fds error: %s\n",
+               strerror(-systemd_listen_fds));
+        return -1;
+    }
+
+    for (i = 0; i < systemd_listen_fds && *count_ret < NUMTRANS; i++)
+    {
+        struct sockaddr_storage a;
+        int ti;
+        const char* tn;
+        socklen_t al;
+
+        al = sizeof(a);
+        if (getsockname(i + SD_LISTEN_FDS_START, (struct sockaddr*)&a, &al) < 0) {
+            prmsg (1, "receive_listening_fds: getsockname error: %s\n",
+                   strerror(errno));
+            return -1;
+        }
+
+        switch (a.ss_family)
+        {
+        case AF_UNIX:
+            ti = TRANS_SOCKET_UNIX_INDEX;
+            if (*((struct sockaddr_un*)&a)->sun_path == '\0' &&
+                al > sizeof(sa_family_t))
+                tn = "local";
+            else
+                tn = "unix";
+            break;
+        case AF_INET:
+            ti = TRANS_SOCKET_INET_INDEX;
+            tn = "inet";
+            break;
+#if defined(IPv6) && defined(AF_INET6)
+        case AF_INET6:
+            ti = TRANS_SOCKET_INET6_INDEX;
+            tn = "inet6";
+            break;
+#endif /* IPv6 */
+        default:
+            prmsg (1, "receive_listening_fds:"
+                   "Got unknown socket address family\n");
+            return -1;
+        }
+
+        ciptr = TRANS(ReopenCOTSServer)(ti, i + SD_LISTEN_FDS_START, port);
+        if (!ciptr)
+        {
+            prmsg (1, "receive_listening_fds:"
+                   "Got NULL while trying to reopen socket received from systemd.\n");
+            return -1;
+        }
+
+        prmsg (5, "receive_listening_fds: received listener for %s, %d\n",
+               tn, ciptr->fd);
+        temp_ciptrs[(*count_ret)++] = ciptr;
+        TRANS(Received)(tn);
+    }
+#endif /* HAVE_SYSTEMD_DAEMON */
+    return 0;
+}
+
+#ifdef XQUARTZ_EXPORTS_LAUNCHD_FD
+extern int xquartz_launchd_fd;
+#endif
+
+int
+TRANS(MakeAllCOTSServerListeners) (const char *port, int *partial,
+                                   int *count_ret, XtransConnInfo **ciptrs_ret)
+
+{
+    char		buffer[256]; /* ??? What size ?? */
+    XtransConnInfo	ciptr, temp_ciptrs[NUMTRANS];
+    int			status, i, j;
+
+#if defined(IPv6) && defined(AF_INET6)
+    int		ipv6_succ = 0;
+#endif
+    prmsg (2,"MakeAllCOTSServerListeners(%s,%p)\n",
+	   port ? port : "NULL", ciptrs_ret);
+
+    *count_ret = 0;
+
+#ifdef XQUARTZ_EXPORTS_LAUNCHD_FD
+    fprintf(stderr, "Launchd socket fd: %d\n", xquartz_launchd_fd);
+    if(xquartz_launchd_fd != -1) {
+        if((ciptr = TRANS(ReopenCOTSServer(TRANS_SOCKET_LOCAL_INDEX,
+                                           xquartz_launchd_fd, getenv("DISPLAY"))))==NULL)
+            fprintf(stderr,"Got NULL while trying to Reopen launchd port\n");
+        else
+            temp_ciptrs[(*count_ret)++] = ciptr;
+    }
+#endif
+
+    if (receive_listening_fds(port, temp_ciptrs, count_ret) < 0)
+	return -1;
+
+    for (i = 0; i < NUMTRANS; i++)
+    {
+	Xtransport *trans = Xtransports[i].transport;
+	unsigned int flags = 0;
+
+	if (trans->flags&TRANS_ALIAS || trans->flags&TRANS_NOLISTEN ||
+	    trans->flags&TRANS_RECEIVED)
+	    continue;
+
+	snprintf(buffer, sizeof(buffer), "%s/:%s",
+		 trans->TransName, port ? port : "");
+
+	prmsg (5,"MakeAllCOTSServerListeners: opening %s\n",
+	       buffer);
+
+	if ((ciptr = TRANS(OpenCOTSServer(buffer))) == NULL)
+	{
+	    if (trans->flags & TRANS_DISABLED)
+		continue;
+
+	    prmsg (1,
+	  "MakeAllCOTSServerListeners: failed to open listener for %s\n",
+		  trans->TransName);
+	    continue;
+	}
+#if defined(IPv6) && defined(AF_INET6)
+		if ((Xtransports[i].transport_id == TRANS_SOCKET_INET_INDEX
+		     && ipv6_succ))
+		    flags |= ADDR_IN_USE_ALLOWED;
+#endif
+
+	if ((status = TRANS(CreateListener (ciptr, port, flags))) < 0)
+	{
+	    if (status == TRANS_ADDR_IN_USE)
+	    {
+		/*
+		 * We failed to bind to the specified address because the
+		 * address is in use.  It must be that a server is already
+		 * running at this address, and this function should fail.
+		 */
+
+		prmsg (1,
+		"MakeAllCOTSServerListeners: server already running\n");
+
+		for (j = 0; j < *count_ret; j++)
+		    TRANS(Close) (temp_ciptrs[j]);
+
+		*count_ret = 0;
+		*ciptrs_ret = NULL;
+		*partial = 0;
+		return -1;
+	    }
+	    else
+	    {
+		prmsg (1,
+	"MakeAllCOTSServerListeners: failed to create listener for %s\n",
+		  trans->TransName);
+
+		continue;
+	    }
+	}
+
+#if defined(IPv6) && defined(AF_INET6)
+	if (Xtransports[i].transport_id == TRANS_SOCKET_INET6_INDEX)
+	    ipv6_succ = 1;
+#endif
+
+	prmsg (5,
+	      "MakeAllCOTSServerListeners: opened listener for %s, %d\n",
+	      trans->TransName, ciptr->fd);
+
+	temp_ciptrs[*count_ret] = ciptr;
+	(*count_ret)++;
+    }
+
+    *partial = (*count_ret < complete_network_count());
+
+    prmsg (5,
+     "MakeAllCOTSServerListeners: partial=%d, actual=%d, complete=%d \n",
+	*partial, *count_ret, complete_network_count());
+
+    if (*count_ret > 0)
+    {
+	if ((*ciptrs_ret = malloc (
+	    *count_ret * sizeof (XtransConnInfo))) == NULL)
+	{
+	    return -1;
+	}
+
+	for (i = 0; i < *count_ret; i++)
+	{
+	    (*ciptrs_ret)[i] = temp_ciptrs[i];
+	}
+    }
+    else
+	*ciptrs_ret = NULL;
+
+    return 0;
+}
+
+#endif /* TRANS_SERVER */
+
+
+
+/*
+ * These routines are not part of the X Transport Interface, but they
+ * may be used by it.
+ */
+
+
+#ifdef WIN32
+
+/*
+ * emulate readv
+ */
+
+static int TRANS(ReadV) (XtransConnInfo ciptr, struct iovec *iov, int iovcnt)
+
+{
+    int i, len, total;
+    char *base;
+
+    ESET(0);
+    for (i = 0, total = 0;  i < iovcnt;  i++, iov++) {
+	len = iov->iov_len;
+	base = iov->iov_base;
+	while (len > 0) {
+	    register int nbytes;
+	    nbytes = TRANS(Read) (ciptr, base, len);
+	    if (nbytes < 0 && total == 0)  return -1;
+	    if (nbytes <= 0)  return total;
+	    ESET(0);
+	    len   -= nbytes;
+	    total += nbytes;
+	    base  += nbytes;
+	}
+    }
+    return total;
+}
+
+
+/*
+ * emulate writev
+ */
+
+static int TRANS(WriteV) (XtransConnInfo ciptr, struct iovec *iov, int iovcnt)
+
+{
+    int i, len, total;
+    char *base;
+
+    ESET(0);
+    for (i = 0, total = 0;  i < iovcnt;  i++, iov++) {
+	len = iov->iov_len;
+	base = iov->iov_base;
+	while (len > 0) {
+	    register int nbytes;
+	    nbytes = TRANS(Write) (ciptr, base, len);
+	    if (nbytes < 0 && total == 0)  return -1;
+	    if (nbytes <= 0)  return total;
+	    ESET(0);
+	    len   -= nbytes;
+	    total += nbytes;
+	    base  += nbytes;
+	}
+    }
+    return total;
+}
+
+#endif /* WIN32 */
+
+
+#if defined(_POSIX_SOURCE) || defined(USG) || defined(SVR4) || defined(__SVR4) || defined(__SCO__)
+#ifndef NEED_UTSNAME
+#define NEED_UTSNAME
+#endif
+#include <sys/utsname.h>
+#endif
+
+/*
+ * TRANS(GetHostname) - similar to gethostname but allows special processing.
+ */
+
+int TRANS(GetHostname) (char *buf, int maxlen)
+
+{
+    int len;
+
+#ifdef NEED_UTSNAME
+    struct utsname name;
+
+    uname (&name);
+    len = strlen (name.nodename);
+    if (len >= maxlen) len = maxlen - 1;
+    strncpy (buf, name.nodename, len);
+    buf[len] = '\0';
+#else
+    buf[0] = '\0';
+    (void) gethostname (buf, maxlen);
+    buf [maxlen - 1] = '\0';
+    len = strlen(buf);
+#endif /* NEED_UTSNAME */
+    return len;
+}
diff -Naur old/X11/Xtrans/Xtrans.h new/X11/Xtrans/Xtrans.h
--- old/X11/Xtrans/Xtrans.h	1970-01-01 08:00:00.000000000 +0800
+++ new/X11/Xtrans/Xtrans.h	2024-03-05 19:36:25.211041600 +0800
@@ -0,0 +1,416 @@
+/*
+
+Copyright 1993, 1994, 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 1993, 1994 NCR Corporation - Dayton, Ohio, USA
+ *
+ * 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 NCR not be used in advertising
+ * or publicity pertaining to distribution of the software without specific,
+ * written prior permission.  NCR makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ *
+ * NCR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
+ * NO EVENT SHALL NCR 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.
+ */
+
+#ifndef _XTRANS_H_
+#define _XTRANS_H_
+
+#include <X11/Xfuncproto.h>
+#include <X11/Xos.h>
+#include <X11/Xmd.h>
+
+#ifndef WIN32
+#include <sys/socket.h>
+#endif
+
+#ifdef __clang__
+/* Not all clients make use of all provided statics */
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wunused-function"
+#endif
+
+/*
+ * Set the functions names according to where this code is being compiled.
+ */
+
+#ifdef X11_t
+#define TRANS(func) _X11Trans##func
+#ifdef XTRANSDEBUG
+static const char *__xtransname = "_X11Trans";
+#endif
+#endif /* X11_t */
+
+#ifdef XSERV_t
+#define TRANS(func) _XSERVTrans##func
+#ifdef XTRANSDEBUG
+static const char *__xtransname = "_XSERVTrans";
+#endif
+#define X11_t
+#endif /* XSERV_t */
+
+#ifdef XIM_t
+#define TRANS(func) _XimXTrans##func
+#ifdef XTRANSDEBUG
+static const char *__xtransname = "_XimTrans";
+#endif
+#endif /* XIM_t */
+
+#ifdef FS_t
+#define TRANS(func) _FSTrans##func
+#ifdef XTRANSDEBUG
+static const char *__xtransname = "_FSTrans";
+#endif
+#endif /* FS_t */
+
+#ifdef FONT_t
+#define TRANS(func) _FontTrans##func
+#ifdef XTRANSDEBUG
+static const char *__xtransname = "_FontTrans";
+#endif
+#endif /* FONT_t */
+
+#ifdef ICE_t
+#define TRANS(func) _IceTrans##func
+#ifdef XTRANSDEBUG
+static const char *__xtransname = "_IceTrans";
+#endif
+#endif /* ICE_t */
+
+#if !defined(TRANS)
+#define TRANS(func) _XTrans##func
+#ifdef XTRANSDEBUG
+static const char *__xtransname = "_XTrans";
+#endif
+#endif /* !TRANS */
+
+#ifdef __clang__
+#pragma clang diagnostic pop
+#endif
+
+/*
+ * Create a single address structure that can be used wherever
+ * an address structure is needed. struct sockaddr is not big enough
+ * to hold a sockadd_un, so we create this definition to have a single
+ * structure that is big enough for all the structures we might need.
+ *
+ * This structure needs to be independent of the socket/TLI interface used.
+ */
+
+#if defined(IPv6) && defined(AF_INET6)
+typedef struct sockaddr_storage Xtransaddr;
+#else
+#define XTRANS_MAX_ADDR_LEN	128	/* large enough to hold sun_path */
+
+typedef	struct {
+    unsigned char	addr[XTRANS_MAX_ADDR_LEN];
+} Xtransaddr;
+#endif
+
+#ifdef LONG64
+typedef int BytesReadable_t;
+#else
+typedef long BytesReadable_t;
+#endif
+
+
+#if defined(WIN32) || defined(USG)
+
+/*
+ *      TRANS(Readv) and TRANS(Writev) use struct iovec, normally found
+ *      in Berkeley systems in <sys/uio.h>.  See the readv(2) and writev(2)
+ *      manual pages for details.
+ */
+
+struct iovec {
+    caddr_t iov_base;
+    int iov_len;
+};
+
+#else
+#include <sys/uio.h>
+#endif
+
+typedef struct _XtransConnInfo *XtransConnInfo;
+
+
+/*
+ * Transport Option definitions
+ */
+
+#define TRANS_NONBLOCKING	1
+#define	TRANS_CLOSEONEXEC	2
+
+
+/*
+ * Return values of Connect (0 is success)
+ */
+
+#define TRANS_CONNECT_FAILED 	-1
+#define TRANS_TRY_CONNECT_AGAIN -2
+#define TRANS_IN_PROGRESS	-3
+
+
+/*
+ * Return values of CreateListener (0 is success)
+ */
+
+#define TRANS_CREATE_LISTENER_FAILED 	-1
+#define TRANS_ADDR_IN_USE		-2
+
+
+/*
+ * Return values of Accept (0 is success)
+ */
+
+#define TRANS_ACCEPT_BAD_MALLOC			-1
+#define TRANS_ACCEPT_FAILED 			-2
+#define TRANS_ACCEPT_MISC_ERROR			-3
+
+
+/*
+ * ResetListener return values
+ */
+
+#define TRANS_RESET_NOOP	1
+#define TRANS_RESET_NEW_FD	2
+#define TRANS_RESET_FAILURE	3
+
+
+/*
+ * Function prototypes for the exposed interface
+ */
+
+void TRANS(FreeConnInfo) (
+    XtransConnInfo 	/* ciptr */
+);
+
+#ifdef TRANS_CLIENT
+
+XtransConnInfo TRANS(OpenCOTSClient)(
+    const char *	/* address */
+);
+
+#endif /* TRANS_CLIENT */
+
+#ifdef TRANS_SERVER
+
+XtransConnInfo TRANS(OpenCOTSServer)(
+    const char *	/* address */
+);
+
+#endif /* TRANS_SERVER */
+
+#ifdef TRANS_REOPEN
+
+XtransConnInfo TRANS(ReopenCOTSServer)(
+    int,		/* trans_id */
+    int,		/* fd */
+    const char *	/* port */
+);
+
+int TRANS(GetReopenInfo)(
+    XtransConnInfo,	/* ciptr */
+    int *,		/* trans_id */
+    int *,		/* fd */
+    char **		/* port */
+);
+
+#endif /* TRANS_REOPEN */
+
+
+int TRANS(SetOption)(
+    XtransConnInfo,	/* ciptr */
+    int,		/* option */
+    int			/* arg */
+);
+
+#ifdef TRANS_SERVER
+
+int TRANS(CreateListener)(
+    XtransConnInfo,	/* ciptr */
+    const char *,	/* port */
+    unsigned int	/* flags */
+);
+
+int TRANS(Received) (
+    const char*         /* protocol*/
+);
+
+int TRANS(NoListen) (
+    const char*         /* protocol*/
+);
+
+int TRANS(Listen) (
+    const char*         /* protocol*/
+);
+
+int TRANS(IsListening) (
+    const char*         /* protocol*/
+);
+
+int TRANS(ResetListener)(
+    XtransConnInfo	/* ciptr */
+);
+
+XtransConnInfo TRANS(Accept)(
+    XtransConnInfo,	/* ciptr */
+    int *		/* status */
+);
+
+#endif /* TRANS_SERVER */
+
+#ifdef TRANS_CLIENT
+
+int TRANS(Connect)(
+    XtransConnInfo,	/* ciptr */
+    const char *	/* address */
+);
+
+#endif /* TRANS_CLIENT */
+
+int TRANS(BytesReadable)(
+    XtransConnInfo,	/* ciptr */
+    BytesReadable_t *	/* pend */
+);
+
+int TRANS(Read)(
+    XtransConnInfo,	/* ciptr */
+    char *,		/* buf */
+    int			/* size */
+);
+
+int TRANS(Write)(
+    XtransConnInfo,	/* ciptr */
+    char *,		/* buf */
+    int			/* size */
+);
+
+int TRANS(Readv)(
+    XtransConnInfo,	/* ciptr */
+    struct iovec *,	/* buf */
+    int			/* size */
+);
+
+int TRANS(Writev)(
+    XtransConnInfo,	/* ciptr */
+    struct iovec *,	/* buf */
+    int			/* size */
+);
+
+int TRANS(SendFd) (XtransConnInfo ciptr, int fd, int do_close);
+
+int TRANS(RecvFd) (XtransConnInfo ciptr);
+
+int TRANS(Disconnect)(
+    XtransConnInfo	/* ciptr */
+);
+
+int TRANS(Close)(
+    XtransConnInfo	/* ciptr */
+);
+
+int TRANS(CloseForCloning)(
+    XtransConnInfo	/* ciptr */
+);
+
+int TRANS(IsLocal)(
+    XtransConnInfo	/* ciptr */
+);
+
+int TRANS(GetPeerAddr)(
+    XtransConnInfo,	/* ciptr */
+    int *,		/* familyp */
+    int *,		/* addrlenp */
+    Xtransaddr **	/* addrp */
+);
+
+int TRANS(GetConnectionNumber)(
+    XtransConnInfo	/* ciptr */
+);
+
+#ifdef TRANS_SERVER
+
+int TRANS(MakeAllCOTSServerListeners)(
+    const char *,	/* port */
+    int *,		/* partial */
+    int *,		/* count_ret */
+    XtransConnInfo **	/* ciptrs_ret */
+);
+
+#endif /* TRANS_SERVER */
+
+
+/*
+ * Function Prototypes for Utility Functions.
+ */
+
+#ifdef X11_t
+
+int TRANS(ConvertAddress)(
+    int *,		/* familyp */
+    int *,		/* addrlenp */
+    Xtransaddr **	/* addrp */
+);
+
+#endif /* X11_t */
+
+#ifdef ICE_t
+
+char *
+TRANS(GetMyNetworkId)(
+    XtransConnInfo	/* ciptr */
+);
+
+char *
+TRANS(GetPeerNetworkId)(
+    XtransConnInfo	/* ciptr */
+);
+
+#endif /* ICE_t */
+
+int
+TRANS(GetHostname) (
+    char *	/* buf */,
+    int 	/* maxlen */
+);
+
+#if defined(WIN32) && defined(TCPCONN)
+int TRANS(WSAStartup)();
+#endif
+
+#endif /* _XTRANS_H_ */
diff -Naur old/X11/Xtrans/Xtransint.h new/X11/Xtrans/Xtransint.h
--- old/X11/Xtrans/Xtransint.h	1970-01-01 08:00:00.000000000 +0800
+++ new/X11/Xtrans/Xtransint.h	2024-03-05 19:36:25.212041200 +0800
@@ -0,0 +1,432 @@
+/*
+
+Copyright 1993, 1994, 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 1993, 1994 NCR Corporation - Dayton, Ohio, USA
+ *
+ * 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 NCR not be used in advertising
+ * or publicity pertaining to distribution of the software without specific,
+ * written prior permission.  NCR makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ *
+ * NCR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
+ * NO EVENT SHALL NCR 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.
+ */
+
+#ifndef _XTRANSINT_H_
+#define _XTRANSINT_H_
+
+/*
+ * XTRANSDEBUG will enable the PRMSG() macros used in the X Transport
+ * Interface code. Each use of the PRMSG macro has a level associated with
+ * it. XTRANSDEBUG is defined to be a level. If the invocation level is =<
+ * the value of XTRANSDEBUG, then the message will be printed out to stderr.
+ * Recommended levels are:
+ *
+ *	XTRANSDEBUG=1	Error messages
+ *	XTRANSDEBUG=2 API Function Tracing
+ *	XTRANSDEBUG=3 All Function Tracing
+ *	XTRANSDEBUG=4 printing of intermediate values
+ *	XTRANSDEBUG=5 really detailed stuff
+#define XTRANSDEBUG 2
+ *
+ * Defining XTRANSDEBUGTIMESTAMP will cause printing timestamps with each
+ * message.
+ */
+
+#if !defined(XTRANSDEBUG) && defined(XTRANS_TRANSPORT_C)
+#  define XTRANSDEBUG 1
+#endif
+
+#ifdef WIN32
+# define _WILLWINSOCK_
+#endif
+
+#include "Xtrans.h"
+
+#ifndef _X_UNUSED  /* Defined in Xfuncproto.h in xproto >= 7.0.22 */
+# define _X_UNUSED  /* */
+#endif
+
+#ifdef XTRANSDEBUG
+# include <stdio.h>
+#endif /* XTRANSDEBUG */
+
+#include <errno.h>
+
+#ifndef WIN32
+#  include <sys/socket.h>
+# include <netinet/in.h>
+# include <arpa/inet.h>
+
+/*
+ * Moved the setting of NEED_UTSNAME to this header file from Xtrans.c,
+ * to avoid a race condition. JKJ (6/5/97)
+ */
+
+# if defined(_POSIX_SOURCE) || defined(USG) || defined(SVR4) || defined(__SVR4) || defined(__SCO__)
+#  ifndef NEED_UTSNAME
+#   define NEED_UTSNAME
+#  endif
+#  include <sys/utsname.h>
+# endif
+
+#  define ESET(val) errno = val
+# define EGET() errno
+
+#else /* WIN32 */
+
+# include <limits.h>	/* for USHRT_MAX */
+
+# define ESET(val) WSASetLastError(val)
+# define EGET() WSAGetLastError()
+
+#endif /* WIN32 */
+
+#include <stddef.h>
+
+#ifdef X11_t
+#define X_TCP_PORT	6000
+#endif
+
+#if XTRANS_SEND_FDS
+
+struct _XtransConnFd {
+    struct _XtransConnFd   *next;
+    int                    fd;
+    int                    do_close;
+};
+
+#endif
+
+struct _XtransConnInfo {
+    struct _Xtransport     *transptr;
+    int		index;
+    char	*priv;
+    int		flags;
+    int		fd;
+    char	*port;
+    int		family;
+    char	*addr;
+    int		addrlen;
+    char	*peeraddr;
+    int		peeraddrlen;
+    struct _XtransConnFd        *recv_fds;
+    struct _XtransConnFd        *send_fds;
+};
+
+#define XTRANS_OPEN_COTS_CLIENT       1
+#define XTRANS_OPEN_COTS_SERVER       2
+
+typedef struct _Xtransport {
+    const char	*TransName;
+    int		flags;
+
+#ifdef TRANS_CLIENT
+
+    XtransConnInfo (*OpenCOTSClient)(
+	struct _Xtransport *,	/* transport */
+	const char *,		/* protocol */
+	const char *,		/* host */
+	const char *		/* port */
+    );
+
+#endif /* TRANS_CLIENT */
+
+#ifdef TRANS_SERVER
+    const char **	nolisten;
+    XtransConnInfo (*OpenCOTSServer)(
+	struct _Xtransport *,	/* transport */
+	const char *,		/* protocol */
+	const char *,		/* host */
+	const char *		/* port */
+    );
+
+#endif /* TRANS_SERVER */
+
+#ifdef TRANS_REOPEN
+
+    XtransConnInfo (*ReopenCOTSServer)(
+	struct _Xtransport *,	/* transport */
+        int,			/* fd */
+        const char *		/* port */
+    );
+
+#endif /* TRANS_REOPEN */
+
+
+    int	(*SetOption)(
+	XtransConnInfo,		/* connection */
+	int,			/* option */
+	int			/* arg */
+    );
+
+#ifdef TRANS_SERVER
+/* Flags */
+# define ADDR_IN_USE_ALLOWED	1
+
+    int	(*CreateListener)(
+	XtransConnInfo,		/* connection */
+	const char *,		/* port */
+	unsigned int		/* flags */
+    );
+
+    int	(*ResetListener)(
+	XtransConnInfo		/* connection */
+    );
+
+    XtransConnInfo (*Accept)(
+	XtransConnInfo,		/* connection */
+        int *			/* status */
+    );
+
+#endif /* TRANS_SERVER */
+
+#ifdef TRANS_CLIENT
+
+    int	(*Connect)(
+	XtransConnInfo,		/* connection */
+	const char *,		/* host */
+	const char *		/* port */
+    );
+
+#endif /* TRANS_CLIENT */
+
+    int	(*BytesReadable)(
+	XtransConnInfo,		/* connection */
+	BytesReadable_t *	/* pend */
+    );
+
+    int	(*Read)(
+	XtransConnInfo,		/* connection */
+	char *,			/* buf */
+	int			/* size */
+    );
+
+    int	(*Write)(
+	XtransConnInfo,		/* connection */
+	char *,			/* buf */
+	int			/* size */
+    );
+
+    int	(*Readv)(
+	XtransConnInfo,		/* connection */
+	struct iovec *,		/* buf */
+	int			/* size */
+    );
+
+    int	(*Writev)(
+	XtransConnInfo,		/* connection */
+	struct iovec *,		/* buf */
+	int			/* size */
+    );
+
+#if XTRANS_SEND_FDS
+    int (*SendFd)(
+	XtransConnInfo,		/* connection */
+        int,                    /* fd */
+        int                     /* do_close */
+    );
+
+    int (*RecvFd)(
+	XtransConnInfo		/* connection */
+    );
+#endif
+
+    int	(*Disconnect)(
+	XtransConnInfo		/* connection */
+    );
+
+    int	(*Close)(
+	XtransConnInfo		/* connection */
+    );
+
+    int	(*CloseForCloning)(
+	XtransConnInfo		/* connection */
+    );
+
+} Xtransport;
+
+
+typedef struct _Xtransport_table {
+    Xtransport	*transport;
+    int		transport_id;
+} Xtransport_table;
+
+
+/*
+ * Flags for the flags member of Xtransport.
+ */
+
+#define TRANS_ALIAS	(1<<0)	/* record is an alias, don't create server */
+#define TRANS_LOCAL	(1<<1)	/* local transport */
+#define TRANS_DISABLED	(1<<2)	/* Don't open this one */
+#define TRANS_NOLISTEN  (1<<3)  /* Don't listen on this one */
+#define TRANS_NOUNLINK	(1<<4)	/* Don't unlink transport endpoints */
+#define TRANS_ABSTRACT	(1<<5)	/* Use abstract sockets if available */
+#define TRANS_NOXAUTH	(1<<6)	/* Don't verify authentication (because it's secure some other way at the OS layer) */
+#define TRANS_RECEIVED	(1<<7)  /* The fd for this has already been opened by someone else. */
+
+/* Flags to preserve when setting others */
+#define TRANS_KEEPFLAGS	(TRANS_NOUNLINK|TRANS_ABSTRACT)
+
+#ifdef XTRANS_TRANSPORT_C /* only provide static function prototypes when
+			     building the transport.c file that has them in */
+
+#ifdef __clang__
+/* Not all clients make use of all provided statics */
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wunused-function"
+#endif
+
+/*
+ * readv() and writev() don't exist or don't work correctly on some
+ * systems, so they may be emulated.
+ */
+
+#ifdef WIN32
+
+#define READV(ciptr, iov, iovcnt)	TRANS(ReadV)(ciptr, iov, iovcnt)
+
+static	int TRANS(ReadV)(
+    XtransConnInfo,	/* ciptr */
+    struct iovec *,	/* iov */
+    int			/* iovcnt */
+);
+
+#else
+
+#define READV(ciptr, iov, iovcnt)	readv(ciptr->fd, iov, iovcnt)
+
+#endif /* WIN32 */
+
+
+#ifdef WIN32
+
+#define WRITEV(ciptr, iov, iovcnt)	TRANS(WriteV)(ciptr, iov, iovcnt)
+
+static int TRANS(WriteV)(
+    XtransConnInfo,	/* ciptr */
+    struct iovec *,	/* iov */
+    int 		/* iovcnt */
+);
+
+#else
+
+#define WRITEV(ciptr, iov, iovcnt)	writev(ciptr->fd, iov, iovcnt)
+
+#endif /* WIN32 */
+
+
+static int is_numeric (
+    const char *	/* str */
+);
+
+#ifdef TRANS_SERVER
+static int trans_mkdir (
+    const char *,	/* path */
+    int			/* mode */
+);
+#endif
+
+#ifdef __clang__
+#pragma clang diagnostic pop
+#endif
+
+/*
+ * Some XTRANSDEBUG stuff
+ */
+
+#ifdef XTRANSDEBUG
+#include <stdarg.h>
+
+/*
+ * The X server provides ErrorF() & VErrorF(), for other software that uses
+ * xtrans, we provide our own simple versions.
+ */
+# if defined(XSERV_t) && defined(TRANS_SERVER)
+#  include "os.h"
+# else
+static inline void _X_ATTRIBUTE_PRINTF(1, 0)
+VErrorF(const char *f, va_list args)
+{
+    vfprintf(stderr, f, args);
+    fflush(stderr);
+}
+
+static inline void  _X_ATTRIBUTE_PRINTF(1, 2)
+ErrorF(const char *f, ...)
+{
+    va_list args;
+
+    va_start(args, f);
+    VErrorF(f, args);
+    va_end(args);
+}
+# endif /* xserver */
+#endif /* XTRANSDEBUG */
+
+static inline void  _X_ATTRIBUTE_PRINTF(2, 3)
+prmsg(int lvl, const char *f, ...)
+{
+#ifdef XTRANSDEBUG
+    va_list args;
+
+    va_start(args, f);
+    if (lvl <= XTRANSDEBUG) {
+	int saveerrno = errno;
+
+	ErrorF("%s", __xtransname);
+	VErrorF(f, args);
+
+# ifdef XTRANSDEBUGTIMESTAMP
+	{
+	    struct timeval tp;
+	    gettimeofday(&tp, 0);
+	    ErrorF("timestamp (ms): %d\n",
+		   tp.tv_sec * 1000 + tp.tv_usec / 1000);
+	}
+# endif
+	errno = saveerrno;
+    }
+    va_end(args);
+#endif /* XTRANSDEBUG */
+}
+
+#endif /* XTRANS_TRANSPORT_C */
+
+#endif /* _XTRANSINT_H_ */
diff -Naur old/X11/Xtrans/Xtranslcl.c new/X11/Xtrans/Xtranslcl.c
--- old/X11/Xtrans/Xtranslcl.c	1970-01-01 08:00:00.000000000 +0800
+++ new/X11/Xtrans/Xtranslcl.c	2024-03-05 19:36:25.212041200 +0800
@@ -0,0 +1,2499 @@
+/*
+
+Copyright 1993, 1994, 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 1993, 1994 NCR Corporation - Dayton, Ohio, USA
+ *
+ * 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 NCR not be used in advertising
+ * or publicity pertaining to distribution of the software without specific,
+ * written prior permission.  NCR makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ *
+ * NCR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
+ * NO EVENT SHALL NCR 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.
+ */
+
+/*
+ *
+ * The connection code/ideas in lib/X and server/os for SVR4/Intel
+ * environments was contributed by the following companies/groups:
+ *
+ *	MetroLink Inc
+ *	NCR
+ *	Pittsburgh Powercomputing Corporation (PPc)/Quarterdeck Office Systems
+ *	SGCS
+ *	Unix System Laboratories (USL) / Novell
+ *	XFree86
+ *
+ * The goal is to have common connection code among all SVR4/Intel vendors.
+ *
+ * ALL THE ABOVE COMPANIES DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
+ * IN NO EVENT SHALL THESE COMPANIES * 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.
+ */
+
+#include <errno.h>
+#include <ctype.h>
+#include <sys/signal.h>
+#include <sys/ioctl.h>
+#include <sys/stat.h>
+#if defined(SVR4) || defined(__SVR4)
+#include <sys/filio.h>
+#endif
+#ifdef __sun
+# include <stropts.h>
+#else
+# include <sys/stropts.h>
+#endif
+#include <sys/wait.h>
+#include <sys/types.h>
+
+/*
+ * The local transports should be treated the same as a UNIX domain socket
+ * wrt authentication, etc. Because of this, we will use struct sockaddr_un
+ * for the address format. This will simplify the code in other places like
+ * The X Server.
+ */
+
+#include <sys/socket.h>
+#ifndef X_NO_SYS_UN
+#include <sys/un.h>
+#endif
+
+
+/* Types of local connections supported:
+ *  - PTS
+ *  - named pipes
+ *  - SCO
+ */
+#if !defined(__sun)
+# define LOCAL_TRANS_PTS
+#endif
+#if defined(SVR4) || defined(__SVR4)
+# define LOCAL_TRANS_NAMED
+#endif
+#if defined(__SCO__) || defined(__UNIXWARE__)
+# define LOCAL_TRANS_SCO
+#endif
+
+static int TRANS(LocalClose)(XtransConnInfo ciptr);
+
+/*
+ * These functions actually implement the local connection mechanisms.
+ */
+
+/* Type Not Supported */
+
+static int
+TRANS(OpenFail)(XtransConnInfo ciptr _X_UNUSED, const char *port _X_UNUSED)
+
+{
+    return -1;
+}
+
+#ifdef TRANS_REOPEN
+
+static int
+TRANS(ReopenFail)(XtransConnInfo ciptr _X_UNUSED, int fd _X_UNUSED,
+                  const char *port _X_UNUSED)
+
+{
+    return 0;
+}
+
+#endif /* TRANS_REOPEN */
+
+#if XTRANS_SEND_FDS
+static int
+TRANS(LocalRecvFdInvalid)(XtransConnInfo ciptr)
+{
+    errno = EINVAL;
+    return -1;
+}
+
+static int
+TRANS(LocalSendFdInvalid)(XtransConnInfo ciptr, int fd, int do_close)
+{
+    errno = EINVAL;
+    return -1;
+}
+#endif
+
+
+static int
+TRANS(FillAddrInfo)(XtransConnInfo ciptr,
+                    const char *sun_path, const char *peer_sun_path)
+
+{
+    struct sockaddr_un	*sunaddr;
+    struct sockaddr_un	*p_sunaddr;
+
+    ciptr->family = AF_UNIX;
+    ciptr->addrlen = sizeof (struct sockaddr_un);
+
+    if ((sunaddr = malloc (ciptr->addrlen)) == NULL)
+    {
+	prmsg(1,"FillAddrInfo: failed to allocate memory for addr\n");
+	return 0;
+    }
+
+    sunaddr->sun_family = AF_UNIX;
+
+    if (strlen(sun_path) > sizeof(sunaddr->sun_path) - 1) {
+	prmsg(1, "FillAddrInfo: path too long\n");
+	free((char *) sunaddr);
+	return 0;
+    }
+    strcpy (sunaddr->sun_path, sun_path);
+#if defined(BSD44SOCKETS)
+    sunaddr->sun_len = strlen (sunaddr->sun_path);
+#endif
+
+    ciptr->addr = (char *) sunaddr;
+
+    ciptr->peeraddrlen = sizeof (struct sockaddr_un);
+
+    if ((p_sunaddr = malloc (ciptr->peeraddrlen)) == NULL)
+    {
+	prmsg(1,
+	   "FillAddrInfo: failed to allocate memory for peer addr\n");
+	free (sunaddr);
+	ciptr->addr = NULL;
+
+	return 0;
+    }
+
+    p_sunaddr->sun_family = AF_UNIX;
+
+    if (strlen(peer_sun_path) > sizeof(p_sunaddr->sun_path) - 1) {
+	prmsg(1, "FillAddrInfo: peer path too long\n");
+	free((char *) p_sunaddr);
+	return 0;
+    }
+    strcpy (p_sunaddr->sun_path, peer_sun_path);
+#if defined(BSD44SOCKETS)
+    p_sunaddr->sun_len = strlen (p_sunaddr->sun_path);
+#endif
+
+    ciptr->peeraddr = (char *) p_sunaddr;
+
+    return 1;
+}
+
+
+
+#ifdef LOCAL_TRANS_PTS
+/* PTS */
+
+#if defined(SYSV) && !defined(__SCO__)
+#define SIGNAL_T int
+#else
+#define SIGNAL_T void
+#endif /* SYSV */
+
+typedef SIGNAL_T (*PFV)();
+
+extern PFV signal();
+
+extern char *ptsname(
+    int
+);
+
+static void _dummy(int sig _X_UNUSED)
+
+{
+}
+#endif /* LOCAL_TRANS_PTS */
+
+#ifndef __sun
+#define X_STREAMS_DIR	"/dev/X"
+#define DEV_SPX		"/dev/spx"
+#else
+#ifndef X11_t
+#define X_STREAMS_DIR	"/dev/X"
+#else
+#define X_STREAMS_DIR	"/tmp/.X11-pipe"
+#endif
+#endif
+
+#define DEV_PTMX	"/dev/ptmx"
+
+#if defined(X11_t)
+
+#define PTSNODENAME "/dev/X/server."
+#ifdef __sun
+#define NAMEDNODENAME "/tmp/.X11-pipe/X"
+#else
+#define NAMEDNODENAME "/dev/X/Nserver."
+
+#define SCORNODENAME	"/dev/X%1sR"
+#define SCOSNODENAME	"/dev/X%1sS"
+#endif /* !__sun */
+#endif
+#if defined(XIM_t)
+#ifdef __sun
+#define NAMEDNODENAME "/tmp/.XIM-pipe/XIM"
+#else
+#define PTSNODENAME	"/dev/X/XIM."
+#define NAMEDNODENAME	"/dev/X/NXIM."
+#define SCORNODENAME	"/dev/XIM.%sR"
+#define SCOSNODENAME	"/dev/XIM.%sS"
+#endif
+#endif
+#if defined(FS_t) || defined (FONT_t)
+#ifdef __sun
+#define NAMEDNODENAME	"/tmp/.font-pipe/fs"
+#else
+/*
+ * USL has already defined something here. We need to check with them
+ * and see if their choice is usable here.
+ */
+#define PTSNODENAME	"/dev/X/fontserver."
+#define NAMEDNODENAME	"/dev/X/Nfontserver."
+#define SCORNODENAME	"/dev/fontserver.%sR"
+#define SCOSNODENAME	"/dev/fontserver.%sS"
+#endif
+#endif
+#if defined(ICE_t)
+#ifdef __sun
+#define NAMEDNODENAME	"/tmp/.ICE-pipe/"
+#else
+#define PTSNODENAME	"/dev/X/ICE."
+#define NAMEDNODENAME	"/dev/X/NICE."
+#define SCORNODENAME	"/dev/ICE.%sR"
+#define SCOSNODENAME	"/dev/ICE.%sS"
+#endif
+#endif
+#if defined(TEST_t)
+#ifdef __sun
+#define NAMEDNODENAME	"/tmp/.Test-unix/test"
+#endif
+#define PTSNODENAME	"/dev/X/transtest."
+#define NAMEDNODENAME	"/dev/X/Ntranstest."
+#define SCORNODENAME	"/dev/transtest.%sR"
+#define SCOSNODENAME	"/dev/transtest.%sS"
+#endif
+
+
+
+#ifdef LOCAL_TRANS_PTS
+#ifdef TRANS_CLIENT
+
+static int
+TRANS(PTSOpenClient)(XtransConnInfo ciptr, const char *port)
+
+{
+#ifdef PTSNODENAME
+    int			fd,server,exitval,alarm_time,ret;
+    char		server_path[64];
+    char		*slave, namelen;
+    char		buf[20]; /* MAX_PATH_LEN?? */
+    PFV			savef;
+    pid_t		saved_pid;
+#endif
+
+    prmsg(2,"PTSOpenClient(%s)\n", port);
+
+#if !defined(PTSNODENAME)
+    prmsg(1,"PTSOpenClient: Protocol is not supported by a pts connection\n");
+    return -1;
+#else
+    if (port && *port ) {
+	if( *port == '/' ) { /* A full pathname */
+	    snprintf(server_path, sizeof(server_path), "%s", port);
+	} else {
+	    snprintf(server_path, sizeof(server_path), "%s%s",
+		     PTSNODENAME, port);
+	}
+    } else {
+	snprintf(server_path, sizeof(server_path), "%s%d",
+		 PTSNODENAME, getpid());
+    }
+
+
+    /*
+     * Open the node the on which the server is listening.
+     */
+
+    if ((server = open (server_path, O_RDWR)) < 0) {
+	prmsg(1,"PTSOpenClient: failed to open %s\n", server_path);
+	return -1;
+    }
+
+
+    /*
+     * Open the streams based pipe that will be this connection.
+     */
+
+    if ((fd = open(DEV_PTMX, O_RDWR)) < 0) {
+	prmsg(1,"PTSOpenClient: failed to open %s\n", DEV_PTMX);
+	close(server);
+	return(-1);
+    }
+
+    (void) grantpt(fd);
+    (void) unlockpt(fd);
+
+    slave = ptsname(fd); /* get name */
+
+    if( slave == NULL ) {
+	prmsg(1,"PTSOpenClient: failed to get ptsname()\n");
+	close(fd);
+	close(server);
+	return -1;
+    }
+
+    /*
+     * This is neccesary for the case where a program is setuid to non-root.
+     * grantpt() calls /usr/lib/pt_chmod which is set-uid root. This program will
+     * set the owner of the pt device incorrectly if the uid is not restored
+     * before it is called. The problem is that once it gets restored, it
+     * cannot be changed back to its original condition, hence the fork().
+     */
+
+    if(!(saved_pid=fork())) {
+	uid_t       saved_euid;
+
+	saved_euid = geteuid();
+	/** sets the euid to the actual/real uid **/
+	if (setuid( getuid() ) == -1) {
+		exit(1);
+	}
+	if( chown( slave, saved_euid, -1 ) < 0 ) {
+		exit( 1 );
+		}
+
+	exit( 0 );
+    }
+
+    waitpid(saved_pid, &exitval, 0);
+    if (WIFEXITED(exitval) && WEXITSTATUS(exitval) != 0) {
+	close(fd);
+	close(server);
+	prmsg(1, "PTSOpenClient: cannot set the owner of %s\n",
+	      slave);
+	return(-1);
+    }
+    if (chmod(slave, 0666) < 0) {
+	close(fd);
+	close(server);
+	prmsg(1,"PTSOpenClient: Cannot chmod %s\n", slave);
+	return(-1);
+    }
+
+    /*
+     * write slave name to server
+     */
+
+    namelen = strlen(slave);
+    buf[0] = namelen;
+    (void) sprintf(&buf[1], slave);
+    (void) write(server, buf, namelen+1);
+    (void) close(server);
+
+    /*
+     * wait for server to respond
+     */
+
+    savef = signal(SIGALRM, _dummy);
+    alarm_time = alarm (30); /* CONNECT_TIMEOUT */
+
+    ret = read(fd, buf, 1);
+
+    (void) alarm(alarm_time);
+    (void) signal(SIGALRM, savef);
+
+    if (ret != 1) {
+	prmsg(1,
+	"PTSOpenClient: failed to get acknoledgement from server\n");
+	(void) close(fd);
+	fd = -1;
+    }
+
+    /*
+     * Everything looks good: fill in the XtransConnInfo structure.
+     */
+
+    if (TRANS(FillAddrInfo) (ciptr, slave, server_path) == 0)
+    {
+	prmsg(1,"PTSOpenClient: failed to fill in addr info\n");
+	close(fd);
+	return -1;
+    }
+
+    return(fd);
+
+#endif /* !PTSNODENAME */
+}
+
+#endif /* TRANS_CLIENT */
+
+
+#ifdef TRANS_SERVER
+
+static int
+TRANS(PTSOpenServer)(XtransConnInfo ciptr, const char *port)
+
+{
+#ifdef PTSNODENAME
+    int fd, server;
+    char server_path[64], *slave;
+    int mode;
+#endif
+
+    prmsg(2,"PTSOpenServer(%s)\n", port);
+
+#if !defined(PTSNODENAME)
+    prmsg(1,"PTSOpenServer: Protocol is not supported by a pts connection\n");
+    return -1;
+#else
+    if (port && *port ) {
+	if( *port == '/' ) { /* A full pathname */
+		(void) sprintf(server_path, "%s", port);
+	    } else {
+		(void) sprintf(server_path, "%s%s", PTSNODENAME, port);
+	    }
+    } else {
+	(void) sprintf(server_path, "%s%d", PTSNODENAME, getpid());
+    }
+
+#ifdef HAS_STICKY_DIR_BIT
+    mode = 01777;
+#else
+    mode = 0777;
+#endif
+    if (trans_mkdir(X_STREAMS_DIR, mode) == -1) {
+	prmsg (1, "PTSOpenServer: mkdir(%s) failed, errno = %d\n",
+	       X_STREAMS_DIR, errno);
+	return(-1);
+    }
+
+#if 0
+    if( (fd=open(server_path, O_RDWR)) >= 0 ) {
+	/*
+	 * This doesn't prevent the server from starting up, and doesn't
+	 * prevent clients from trying to connect to the in-use PTS (which
+	 * is often in use by something other than another server).
+	 */
+	prmsg(1, "PTSOpenServer: A server is already running on port %s\n", port);
+	prmsg(1, "PTSOpenServer: Remove %s if this is incorrect.\n", server_path);
+	close(fd);
+	return(-1);
+    }
+#else
+    /* Just remove the old path (which is what happens with UNIXCONN) */
+#endif
+
+    unlink(server_path);
+
+    if( (fd=open(DEV_PTMX, O_RDWR)) < 0) {
+	prmsg(1, "PTSOpenServer: Unable to open %s\n", DEV_PTMX);
+	return(-1);
+    }
+
+    grantpt(fd);
+    unlockpt(fd);
+
+    if( (slave=ptsname(fd)) == NULL) {
+	prmsg(1, "PTSOpenServer: Unable to get slave device name\n");
+	close(fd);
+	return(-1);
+    }
+
+    if( link(slave,server_path) < 0 ) {
+	prmsg(1, "PTSOpenServer: Unable to link %s to %s\n", slave, server_path);
+	close(fd);
+	return(-1);
+    }
+
+    if( chmod(server_path, 0666) < 0 ) {
+	prmsg(1, "PTSOpenServer: Unable to chmod %s to 0666\n", server_path);
+	close(fd);
+	return(-1);
+    }
+
+    if( (server=open(server_path, O_RDWR)) < 0 ) {
+	prmsg(1, "PTSOpenServer: Unable to open server device %s\n", server_path);
+	close(fd);
+	return(-1);
+    }
+
+    close(server);
+
+    /*
+     * Everything looks good: fill in the XtransConnInfo structure.
+     */
+
+    if (TRANS(FillAddrInfo) (ciptr, server_path, server_path) == 0)
+    {
+	prmsg(1,"PTSOpenServer: failed to fill in addr info\n");
+	close(fd);
+	return -1;
+    }
+
+    return fd;
+
+#endif /* !PTSNODENAME */
+}
+
+static int
+TRANS(PTSAccept)(XtransConnInfo ciptr, XtransConnInfo newciptr, int *status)
+
+{
+    int			newfd;
+    int			in;
+    unsigned char	length;
+    char		buf[256];
+    struct sockaddr_un	*sunaddr;
+
+    prmsg(2,"PTSAccept(%x->%d)\n",ciptr,ciptr->fd);
+
+    if( (in=read(ciptr->fd,&length,1)) <= 0 ){
+	if( !in ) {
+		prmsg(2,
+		"PTSAccept: Incoming connection closed\n");
+		}
+	else {
+		prmsg(1,
+	"PTSAccept: Error reading incoming connection. errno=%d \n",
+								errno);
+		}
+	*status = TRANS_ACCEPT_MISC_ERROR;
+	return -1;
+    }
+
+    if( (in=read(ciptr->fd,buf,length)) <= 0 ){
+	if( !in ) {
+		prmsg(2,
+		"PTSAccept: Incoming connection closed\n");
+		}
+	else {
+		prmsg(1,
+"PTSAccept: Error reading device name for new connection. errno=%d \n",
+								errno);
+		}
+	*status = TRANS_ACCEPT_MISC_ERROR;
+	return -1;
+    }
+
+    buf[length] = '\0';
+
+    if( (newfd=open(buf,O_RDWR)) < 0 ) {
+	prmsg(1, "PTSAccept: Failed to open %s\n",buf);
+	*status = TRANS_ACCEPT_MISC_ERROR;
+	return -1;
+    }
+
+    write(newfd,"1",1);
+
+    /*
+     * Everything looks good: fill in the XtransConnInfo structure.
+     */
+
+    newciptr->addrlen=ciptr->addrlen;
+    if( (newciptr->addr = malloc(newciptr->addrlen)) == NULL ) {
+	prmsg(1,"PTSAccept: failed to allocate memory for peer addr\n");
+	close(newfd);
+	*status = TRANS_ACCEPT_BAD_MALLOC;
+	return -1;
+    }
+
+    memcpy(newciptr->addr,ciptr->addr,newciptr->addrlen);
+
+    newciptr->peeraddrlen=sizeof(struct sockaddr_un);
+    if( (sunaddr = malloc(newciptr->peeraddrlen)) == NULL ) {
+	prmsg(1,"PTSAccept: failed to allocate memory for peer addr\n");
+	free(newciptr->addr);
+	close(newfd);
+	*status = TRANS_ACCEPT_BAD_MALLOC;
+	return -1;
+    }
+
+    sunaddr->sun_family=AF_UNIX;
+    strcpy(sunaddr->sun_path,buf);
+#if defined(BSD44SOCKETS)
+    sunaddr->sun_len=strlen(sunaddr->sun_path);
+#endif
+
+    newciptr->peeraddr=(char *)sunaddr;
+
+    *status = 0;
+
+    return newfd;
+}
+
+#endif /* TRANS_SERVER */
+#endif /* LOCAL_TRANS_PTS */
+
+
+#ifdef LOCAL_TRANS_NAMED
+
+/* NAMED */
+
+#ifdef TRANS_CLIENT
+
+static int
+TRANS(NAMEDOpenClient)(XtransConnInfo ciptr, const char *port)
+
+{
+#ifdef NAMEDNODENAME
+    int			fd;
+    char		server_path[64];
+    struct stat		filestat;
+# ifndef __sun
+    extern int		isastream(int);
+# endif
+#endif
+
+    prmsg(2,"NAMEDOpenClient(%s)\n", port);
+
+#if !defined(NAMEDNODENAME)
+    prmsg(1,"NAMEDOpenClient: Protocol is not supported by a NAMED connection\n");
+    return -1;
+#else
+    if ( port && *port ) {
+	if( *port == '/' ) { /* A full pathname */
+		(void) snprintf(server_path, sizeof(server_path), "%s", port);
+	    } else {
+		(void) snprintf(server_path, sizeof(server_path), "%s%s", NAMEDNODENAME, port);
+	    }
+    } else {
+	(void) snprintf(server_path, sizeof(server_path), "%s%ld", NAMEDNODENAME, (long)getpid());
+    }
+
+    if ((fd = open(server_path, O_RDWR)) < 0) {
+	prmsg(1,"NAMEDOpenClient: Cannot open %s for NAMED connection\n", server_path);
+	return -1;
+    }
+
+    if (fstat(fd, &filestat) < 0 ) {
+	prmsg(1,"NAMEDOpenClient: Cannot stat %s for NAMED connection\n", server_path);
+	(void) close(fd);
+	return -1;
+    }
+
+    if ((filestat.st_mode & S_IFMT) != S_IFIFO) {
+	prmsg(1,"NAMEDOpenClient: Device %s is not a FIFO\n", server_path);
+	/* Is this really a failure? */
+	(void) close(fd);
+	return -1;
+    }
+
+
+    if (isastream(fd) <= 0) {
+	prmsg(1,"NAMEDOpenClient: %s is not a streams device\n", server_path);
+	(void) close(fd);
+	return -1;
+    }
+
+    /*
+     * Everything looks good: fill in the XtransConnInfo structure.
+     */
+
+    if (TRANS(FillAddrInfo) (ciptr, server_path, server_path) == 0)
+    {
+	prmsg(1,"NAMEDOpenClient: failed to fill in addr info\n");
+	close(fd);
+	return -1;
+    }
+
+    return(fd);
+
+#endif /* !NAMEDNODENAME */
+}
+
+#endif /* TRANS_CLIENT */
+
+
+#ifdef TRANS_SERVER
+
+
+#ifdef NAMEDNODENAME
+static int
+TRANS(NAMEDOpenPipe)(const char *server_path)
+{
+    int			fd, pipefd[2];
+    struct stat		sbuf;
+    int			mode;
+
+    prmsg(2,"NAMEDOpenPipe(%s)\n", server_path);
+
+#ifdef HAS_STICKY_DIR_BIT
+    mode = 01777;
+#else
+    mode = 0777;
+#endif
+    if (trans_mkdir(X_STREAMS_DIR, mode) == -1) {
+	prmsg (1, "NAMEDOpenPipe: mkdir(%s) failed, errno = %d\n",
+	       X_STREAMS_DIR, errno);
+	return(-1);
+    }
+
+    if(stat(server_path, &sbuf) != 0) {
+	if (errno == ENOENT) {
+	    if ((fd = creat(server_path, (mode_t)0666)) == -1) {
+		prmsg(1, "NAMEDOpenPipe: Can't open %s\n", server_path);
+		return(-1);
+	    }
+	    if (fchmod(fd, (mode_t)0666) < 0) {
+		prmsg(1, "NAMEDOpenPipe: Can't chmod %s\n", server_path);
+		close(fd);
+		return(-1);
+	    }
+	    close(fd);
+	} else {
+	    prmsg(1, "NAMEDOpenPipe: stat on %s failed\n", server_path);
+	    return(-1);
+	}
+    }
+
+    if( pipe(pipefd) != 0) {
+	prmsg(1, "NAMEDOpenPipe: pipe() failed, errno=%d\n",errno);
+	return(-1);
+    }
+
+    if( ioctl(pipefd[0], I_PUSH, "connld") != 0) {
+	prmsg(1, "NAMEDOpenPipe: ioctl(I_PUSH,\"connld\") failed, errno=%d\n",errno);
+	close(pipefd[0]);
+	close(pipefd[1]);
+	return(-1);
+    }
+
+    if( fattach(pipefd[0], server_path) != 0) {
+	prmsg(1, "NAMEDOpenPipe: fattach(%s) failed, errno=%d\n", server_path,errno);
+	close(pipefd[0]);
+	close(pipefd[1]);
+	return(-1);
+    }
+
+    return(pipefd[1]);
+}
+#endif
+
+static int
+TRANS(NAMEDOpenServer)(XtransConnInfo ciptr, const char *port)
+{
+#ifdef NAMEDNODENAME
+    int			fd;
+    char		server_path[64];
+#endif
+
+    prmsg(2,"NAMEDOpenServer(%s)\n", port);
+
+#if !defined(NAMEDNODENAME)
+    prmsg(1,"NAMEDOpenServer: Protocol is not supported by a NAMED connection\n");
+    return -1;
+#else
+    if ( port && *port ) {
+	if( *port == '/' ) { /* A full pathname */
+	    (void) snprintf(server_path, sizeof(server_path), "%s", port);
+	} else {
+	    (void) snprintf(server_path, sizeof(server_path), "%s%s",
+			    NAMEDNODENAME, port);
+	}
+    } else {
+	(void) snprintf(server_path, sizeof(server_path), "%s%ld",
+		       NAMEDNODENAME, (long)getpid());
+    }
+
+    fd = TRANS(NAMEDOpenPipe)(server_path);
+    if (fd < 0) {
+	return -1;
+    }
+
+    /*
+     * Everything looks good: fill in the XtransConnInfo structure.
+     */
+
+    if (TRANS(FillAddrInfo) (ciptr, server_path, server_path) == 0)
+    {
+	prmsg(1,"NAMEDOpenServer: failed to fill in addr info\n");
+	TRANS(LocalClose)(ciptr);
+	return -1;
+    }
+
+    return fd;
+
+#endif /* !NAMEDNODENAME */
+}
+
+static int
+TRANS(NAMEDResetListener) (XtransConnInfo ciptr)
+
+{
+  struct sockaddr_un      *sockname=(struct sockaddr_un *) ciptr->addr;
+  struct stat     statb;
+
+  prmsg(2,"NAMEDResetListener(%p, %d)\n", ciptr, ciptr->fd);
+
+  if (ciptr->fd != -1) {
+    /*
+     * see if the pipe has disappeared
+     */
+
+    if (stat (sockname->sun_path, &statb) == -1 ||
+	(statb.st_mode & S_IFMT) != S_IFIFO) {
+      prmsg(3, "Pipe %s trashed, recreating\n", sockname->sun_path);
+      TRANS(LocalClose)(ciptr);
+      ciptr->fd = TRANS(NAMEDOpenPipe)(sockname->sun_path);
+      if (ciptr->fd >= 0)
+	  return TRANS_RESET_NEW_FD;
+      else
+	  return TRANS_CREATE_LISTENER_FAILED;
+    }
+  }
+  return TRANS_RESET_NOOP;
+}
+
+static int
+TRANS(NAMEDAccept)(XtransConnInfo ciptr, XtransConnInfo newciptr, int *status)
+
+{
+    struct strrecvfd str;
+
+    prmsg(2,"NAMEDAccept(%p->%d)\n", ciptr, ciptr->fd);
+
+    if( ioctl(ciptr->fd, I_RECVFD, &str ) < 0 ) {
+	prmsg(1, "NAMEDAccept: ioctl(I_RECVFD) failed, errno=%d\n", errno);
+	*status = TRANS_ACCEPT_MISC_ERROR;
+	return(-1);
+    }
+
+    /*
+     * Everything looks good: fill in the XtransConnInfo structure.
+     */
+    newciptr->family=ciptr->family;
+    newciptr->addrlen=ciptr->addrlen;
+    if( (newciptr->addr = malloc(newciptr->addrlen)) == NULL ) {
+	prmsg(1,
+	      "NAMEDAccept: failed to allocate memory for pipe addr\n");
+	close(str.fd);
+	*status = TRANS_ACCEPT_BAD_MALLOC;
+	return -1;
+    }
+
+    memcpy(newciptr->addr,ciptr->addr,newciptr->addrlen);
+
+    newciptr->peeraddrlen=newciptr->addrlen;
+    if( (newciptr->peeraddr = malloc(newciptr->peeraddrlen)) == NULL ) {
+	prmsg(1,
+	"NAMEDAccept: failed to allocate memory for peer addr\n");
+	free(newciptr->addr);
+	close(str.fd);
+	*status = TRANS_ACCEPT_BAD_MALLOC;
+	return -1;
+    }
+
+    memcpy(newciptr->peeraddr,newciptr->addr,newciptr->peeraddrlen);
+
+    *status = 0;
+
+    return str.fd;
+}
+
+#endif /* TRANS_SERVER */
+
+#endif /* LOCAL_TRANS_NAMED */
+
+
+
+#if defined(LOCAL_TRANS_SCO)
+
+/*
+ * connect_spipe is used by the SCO connection type.
+ */
+static int
+connect_spipe(int fd1, int fd2)
+{
+    long temp;
+    struct strfdinsert sbuf;
+
+    sbuf.databuf.maxlen = -1;
+    sbuf.databuf.len = -1;
+    sbuf.databuf.buf = NULL;
+    sbuf.ctlbuf.maxlen = sizeof(long);
+    sbuf.ctlbuf.len = sizeof(long);
+    sbuf.ctlbuf.buf = (caddr_t)&temp;
+    sbuf.offset = 0;
+    sbuf.fildes = fd2;
+    sbuf.flags = 0;
+
+    if( ioctl(fd1, I_FDINSERT, &sbuf) < 0 )
+	return(-1);
+
+    return(0);
+}
+
+/*
+ * named_spipe is used by the SCO connection type.
+ */
+
+static int
+named_spipe(int fd, char *path)
+
+{
+    int oldUmask, ret;
+    struct stat sbuf;
+
+    oldUmask = umask(0);
+
+    (void) fstat(fd, &sbuf);
+    ret = mknod(path, 0020666, sbuf.st_rdev);
+
+    umask(oldUmask);
+
+    if (ret < 0) {
+	ret = -1;
+    } else {
+	ret = fd;
+    }
+
+    return(ret);
+}
+
+#endif /* defined(LOCAL_TRANS_SCO) */
+
+
+
+
+#ifdef LOCAL_TRANS_SCO
+/* SCO */
+
+/*
+ * 2002-11-09 (jkj@sco.com)
+ *
+ * This code has been modified to match what is in the actual SCO X server.
+ * This greatly helps inter-operability between X11R6 and X11R5 (the native
+ * SCO server). Mainly, it relies on streams nodes existing in /dev, not
+ * creating them or unlinking them, which breaks the native X server.
+ *
+ * However, this is only for the X protocol. For all other protocols, we
+ * do in fact create the nodes, as only X11R6 will use them, and this makes
+ * it possible to have both types of clients running, otherwise we get all
+ * kinds of nasty errors on startup for anything that doesnt use the X
+ * protocol (like SM, when KDE starts up).
+ */
+
+#ifdef TRANS_CLIENT
+
+static int
+TRANS(SCOOpenClient)(XtransConnInfo ciptr, const char *port)
+{
+#ifdef SCORNODENAME
+    int			fd, server, fl, ret;
+    char		server_path[64];
+    struct strbuf	ctlbuf;
+    unsigned long	alarm_time;
+    void		(*savef)();
+    long		temp;
+    extern int	getmsg(), putmsg();
+#endif
+
+    prmsg(2,"SCOOpenClient(%s)\n", port);
+    if (!port || !port[0])
+	port = "0";
+
+#if !defined(SCORNODENAME)
+    prmsg(2,"SCOOpenClient: Protocol is not supported by a SCO connection\n");
+    return -1;
+#else
+    (void) sprintf(server_path, SCORNODENAME, port);
+
+    if ((server = open(server_path, O_RDWR)) < 0) {
+	prmsg(1,"SCOOpenClient: failed to open %s\n", server_path);
+	return -1;
+    }
+
+    if ((fd = open(DEV_SPX, O_RDWR)) < 0) {
+	prmsg(1,"SCOOpenClient: failed to open %s\n", DEV_SPX);
+	close(server);
+	return -1;
+    }
+
+    (void) write(server, &server, 1);
+    ctlbuf.len = 0;
+    ctlbuf.maxlen = sizeof(long);
+    ctlbuf.buf = (caddr_t)&temp;
+    fl = 0;
+
+    savef = signal(SIGALRM, _dummy);
+    alarm_time = alarm(10);
+
+    ret = getmsg(server, &ctlbuf, 0, &fl);
+
+    (void) alarm(alarm_time);
+    (void) signal(SIGALRM, savef);
+
+    if (ret < 0) {
+	prmsg(1,"SCOOpenClient: error from getmsg\n");
+	close(fd);
+	close(server);
+	return -1;
+    }
+
+    /* The msg we got via getmsg is the result of an
+     * I_FDINSERT, so if we do a putmsg with whatever
+     * we recieved, we're doing another I_FDINSERT ...
+     */
+    (void) putmsg(fd, &ctlbuf, 0, 0);
+    (void) fcntl(fd,F_SETFL,fcntl(fd,F_GETFL,0)|O_NDELAY);
+
+    (void) close(server);
+
+    /*
+     * Everything looks good: fill in the XtransConnInfo structure.
+     */
+
+#if defined(X11_t) && defined(__SCO__)
+    ciptr->flags |= TRANS_NOUNLINK;
+#endif
+    if (TRANS(FillAddrInfo) (ciptr, server_path, server_path) == 0)
+    {
+	prmsg(1,"SCOOpenClient: failed to fill addr info\n");
+	close(fd);
+	return -1;
+    }
+
+    return(fd);
+
+#endif  /* !SCORNODENAME */
+}
+
+#endif /* TRANS_CLIENT */
+
+
+#ifdef TRANS_SERVER
+
+static int
+TRANS(SCOOpenServer)(XtransConnInfo ciptr, const char *port)
+{
+#ifdef SCORNODENAME
+    char		serverR_path[64];
+    char		serverS_path[64];
+    struct flock	mylock;
+    int			fdr = -1;
+    int			fds = -1;
+#endif
+
+    prmsg(2,"SCOOpenServer(%s)\n", port);
+    if (!port || !port[0])
+	port = "0";
+
+#if !defined(SCORNODENAME)
+    prmsg(1,"SCOOpenServer: Protocol is not supported by a SCO connection\n");
+    return -1;
+#else
+    (void) sprintf(serverR_path, SCORNODENAME, port);
+    (void) sprintf(serverS_path, SCOSNODENAME, port);
+
+#if !defined(X11_t) || !defined(__SCO__)
+    unlink(serverR_path);
+    unlink(serverS_path);
+
+    if ((fds = open(DEV_SPX, O_RDWR)) < 0 ||
+	(fdr = open(DEV_SPX, O_RDWR)) < 0 ) {
+	prmsg(1,"SCOOpenServer: failed to open %s\n", DEV_SPX);
+	if (fds >= 0)
+		close(fds);
+	if (fdr >= 0)
+		close(fdr);
+	return -1;
+    }
+
+    if (named_spipe (fds, serverS_path) == -1) {
+	prmsg(1,"SCOOpenServer: failed to create %s\n", serverS_path);
+	close (fdr);
+	close (fds);
+	return -1;
+    }
+
+    if (named_spipe (fdr, serverR_path) == -1) {
+	prmsg(1,"SCOOpenServer: failed to create %s\n", serverR_path);
+	close (fdr);
+	close (fds);
+	return -1;
+    }
+#else /* X11_t */
+
+    fds = open (serverS_path, O_RDWR | O_NDELAY);
+    if (fds < 0) {
+	prmsg(1,"SCOOpenServer: failed to open %s\n", serverS_path);
+	return -1;
+    }
+
+    /*
+     * Lock the connection device for the duration of the server.
+     * This resolves multiple server starts especially on SMP machines.
+     */
+    mylock.l_type	= F_WRLCK;
+    mylock.l_whence	= 0;
+    mylock.l_start	= 0;
+    mylock.l_len	= 0;
+    if (fcntl (fds, F_SETLK, &mylock) < 0) {
+	prmsg(1,"SCOOpenServer: failed to lock %s\n", serverS_path);
+	close (fds);
+	return -1;
+    }
+
+    fdr = open (serverR_path, O_RDWR | O_NDELAY);
+    if (fdr < 0) {
+	prmsg(1,"SCOOpenServer: failed to open %s\n", serverR_path);
+	close (fds);
+	return -1;
+    }
+#endif /* X11_t */
+
+    if (connect_spipe(fds, fdr)) {
+	prmsg(1,"SCOOpenServer: ioctl(I_FDINSERT) failed on %s\n",
+	      serverS_path);
+	close (fdr);
+	close (fds);
+	return -1;
+    }
+
+    /*
+     * Everything looks good: fill in the XtransConnInfo structure.
+     */
+
+#if defined(X11_t) && defined(__SCO__)
+    ciptr->flags |= TRANS_NOUNLINK;
+#endif
+    if (TRANS(FillAddrInfo) (ciptr, serverS_path, serverR_path) == 0) {
+	prmsg(1,"SCOOpenServer: failed to fill in addr info\n");
+	close(fds);
+	close(fdr);
+	return -1;
+    }
+
+    return(fds);
+
+#endif /* !SCORNODENAME */
+}
+
+static int
+TRANS(SCOAccept)(XtransConnInfo ciptr, XtransConnInfo newciptr, int *status)
+{
+    char		c;
+    int			fd;
+
+    prmsg(2,"SCOAccept(%d)\n", ciptr->fd);
+
+    if (read(ciptr->fd, &c, 1) < 0) {
+	prmsg(1,"SCOAccept: can't read from client\n");
+	*status = TRANS_ACCEPT_MISC_ERROR;
+	return(-1);
+    }
+
+    if( (fd = open(DEV_SPX, O_RDWR)) < 0 ) {
+	prmsg(1,"SCOAccept: can't open \"%s\"\n",DEV_SPX);
+	*status = TRANS_ACCEPT_MISC_ERROR;
+	return(-1);
+    }
+
+    if (connect_spipe (ciptr->fd, fd) < 0) {
+	prmsg(1,"SCOAccept: ioctl(I_FDINSERT) failed\n");
+	close (fd);
+	*status = TRANS_ACCEPT_MISC_ERROR;
+	return -1;
+    }
+
+    /*
+     * Everything looks good: fill in the XtransConnInfo structure.
+     */
+
+    newciptr->addrlen=ciptr->addrlen;
+    if( (newciptr->addr = malloc(newciptr->addrlen)) == NULL ) {
+	prmsg(1,
+	      "SCOAccept: failed to allocate memory for peer addr\n");
+	close(fd);
+	*status = TRANS_ACCEPT_BAD_MALLOC;
+	return -1;
+    }
+
+    memcpy(newciptr->addr,ciptr->addr,newciptr->addrlen);
+#if defined(__SCO__)
+    newciptr->flags |= TRANS_NOUNLINK;
+#endif
+
+    newciptr->peeraddrlen=newciptr->addrlen;
+    if( (newciptr->peeraddr = malloc(newciptr->peeraddrlen)) == NULL ) {
+	prmsg(1,
+	      "SCOAccept: failed to allocate memory for peer addr\n");
+	free(newciptr->addr);
+	close(fd);
+	*status = TRANS_ACCEPT_BAD_MALLOC;
+	return -1;
+    }
+
+    memcpy(newciptr->peeraddr,newciptr->addr,newciptr->peeraddrlen);
+
+    *status = 0;
+
+    return(fd);
+}
+
+#endif /* TRANS_SERVER */
+#endif /* LOCAL_TRANS_SCO */
+
+
+
+#ifdef TRANS_REOPEN
+#ifdef LOCAL_TRANS_PTS
+
+static int
+TRANS(PTSReopenServer)(XtransConnInfo ciptr, int fd, const char *port)
+
+{
+#ifdef PTSNODENAME
+    char server_path[64];
+#endif
+
+    prmsg(2,"PTSReopenServer(%d,%s)\n", fd, port);
+
+#if !defined(PTSNODENAME)
+    prmsg(1,"PTSReopenServer: Protocol is not supported by a pts connection\n");
+    return 0;
+#else
+    if (port && *port ) {
+	if( *port == '/' ) { /* A full pathname */
+	    snprintf(server_path, sizeof(server_path), "%s", port);
+	} else {
+	    snprintf(server_path, sizeof(server_path), "%s%s",
+		     PTSNODENAME, port);
+	}
+    } else {
+	snprintf(server_path, sizeof(server_path), "%s%ld",
+		PTSNODENAME, (long)getpid());
+    }
+
+    if (TRANS(FillAddrInfo) (ciptr, server_path, server_path) == 0)
+    {
+	prmsg(1,"PTSReopenServer: failed to fill in addr info\n");
+	return 0;
+    }
+
+    return 1;
+
+#endif /* !PTSNODENAME */
+}
+
+#endif /* LOCAL_TRANS_PTS */
+
+#ifdef LOCAL_TRANS_NAMED
+
+static int
+TRANS(NAMEDReopenServer)(XtransConnInfo ciptr, int fd _X_UNUSED, const char *port)
+
+{
+#ifdef NAMEDNODENAME
+    char server_path[64];
+#endif
+
+    prmsg(2,"NAMEDReopenServer(%s)\n", port);
+
+#if !defined(NAMEDNODENAME)
+    prmsg(1,"NAMEDReopenServer: Protocol is not supported by a NAMED connection\n");
+    return 0;
+#else
+    if ( port && *port ) {
+	if( *port == '/' ) { /* A full pathname */
+	    snprintf(server_path, sizeof(server_path),"%s", port);
+	} else {
+	    snprintf(server_path, sizeof(server_path), "%s%s",
+		     NAMEDNODENAME, port);
+	}
+    } else {
+	snprintf(server_path, sizeof(server_path), "%s%ld",
+		NAMEDNODENAME, (long)getpid());
+    }
+
+    if (TRANS(FillAddrInfo) (ciptr, server_path, server_path) == 0)
+    {
+	prmsg(1,"NAMEDReopenServer: failed to fill in addr info\n");
+	return 0;
+    }
+
+    return 1;
+
+#endif /* !NAMEDNODENAME */
+}
+
+#endif /* LOCAL_TRANS_NAMED */
+
+
+#ifdef LOCAL_TRANS_SCO
+static int
+TRANS(SCOReopenServer)(XtransConnInfo ciptr, int fd, const char *port)
+
+{
+#ifdef SCORNODENAME
+    char serverR_path[64], serverS_path[64];
+#endif
+
+    prmsg(2,"SCOReopenServer(%s)\n", port);
+    if (!port || !port[0])
+      port = "0";
+
+#if !defined(SCORNODENAME)
+    prmsg(2,"SCOReopenServer: Protocol is not supported by a SCO connection\n");
+    return 0;
+#else
+    (void) sprintf(serverR_path, SCORNODENAME, port);
+    (void) sprintf(serverS_path, SCOSNODENAME, port);
+
+#if defined(X11_t) && defined(__SCO__)
+    ciptr->flags |= TRANS_NOUNLINK;
+#endif
+    if (TRANS(FillAddrInfo) (ciptr, serverS_path, serverR_path) == 0)
+    {
+	prmsg(1, "SCOReopenServer: failed to fill in addr info\n");
+	return 0;
+    }
+
+    return 1;
+
+#endif /* SCORNODENAME */
+}
+
+#endif /* LOCAL_TRANS_SCO */
+
+#endif /* TRANS_REOPEN */
+
+
+
+/*
+ * This table contains all of the entry points for the different local
+ * connection mechanisms.
+ */
+
+typedef struct _LOCALtrans2dev {
+    const char	*transname;
+
+#ifdef TRANS_CLIENT
+
+    int	(*devcotsopenclient)(
+	XtransConnInfo, const char * /*port*/
+);
+
+#endif /* TRANS_CLIENT */
+
+#ifdef TRANS_SERVER
+
+    int	(*devcotsopenserver)(
+	XtransConnInfo, const char * /*port*/
+);
+
+#endif /* TRANS_SERVER */
+
+#ifdef TRANS_CLIENT
+
+    int	(*devcltsopenclient)(
+	XtransConnInfo, const char * /*port*/
+);
+
+#endif /* TRANS_CLIENT */
+
+#ifdef TRANS_SERVER
+
+    int	(*devcltsopenserver)(
+	XtransConnInfo, const char * /*port*/
+);
+
+#endif /* TRANS_SERVER */
+
+#ifdef TRANS_REOPEN
+
+    int	(*devcotsreopenserver)(
+	XtransConnInfo,
+	int, 	/* fd */
+	const char * 	/* port */
+);
+
+    int	(*devcltsreopenserver)(
+	XtransConnInfo,
+	int, 	/* fd */
+	const char *	/* port */
+);
+
+#endif /* TRANS_REOPEN */
+
+#ifdef TRANS_SERVER
+
+    int (*devreset)(
+	XtransConnInfo /* ciptr */
+);
+
+    int	(*devaccept)(
+	XtransConnInfo, XtransConnInfo, int *
+);
+
+#endif /* TRANS_SERVER */
+
+} LOCALtrans2dev;
+
+static LOCALtrans2dev LOCALtrans2devtab[] = {
+#ifdef LOCAL_TRANS_PTS
+{"",
+#ifdef TRANS_CLIENT
+     TRANS(PTSOpenClient),
+#endif /* TRANS_CLIENT */
+#ifdef TRANS_SERVER
+     TRANS(PTSOpenServer),
+#endif /* TRANS_SERVER */
+#ifdef TRANS_CLIENT
+     TRANS(OpenFail),
+#endif /* TRANS_CLIENT */
+#ifdef TRANS_SERVER
+     TRANS(OpenFail),
+#endif /* TRANS_SERVER */
+#ifdef TRANS_REOPEN
+     TRANS(PTSReopenServer),
+     TRANS(ReopenFail),
+#endif
+#ifdef TRANS_SERVER
+     NULL,		/* ResetListener */
+     TRANS(PTSAccept)
+#endif /* TRANS_SERVER */
+},
+
+{"local",
+#ifdef TRANS_CLIENT
+     TRANS(PTSOpenClient),
+#endif /* TRANS_CLIENT */
+#ifdef TRANS_SERVER
+     TRANS(PTSOpenServer),
+#endif /* TRANS_SERVER */
+#ifdef TRANS_CLIENT
+     TRANS(OpenFail),
+#endif /* TRANS_CLIENT */
+#ifdef TRANS_SERVER
+     TRANS(OpenFail),
+#endif /* TRANS_SERVER */
+#ifdef TRANS_REOPEN
+     TRANS(PTSReopenServer),
+     TRANS(ReopenFail),
+#endif
+#ifdef TRANS_SERVER
+     NULL,		/* ResetListener */
+     TRANS(PTSAccept)
+#endif /* TRANS_SERVER */
+},
+
+{"pts",
+#ifdef TRANS_CLIENT
+     TRANS(PTSOpenClient),
+#endif /* TRANS_CLIENT */
+#ifdef TRANS_SERVER
+     TRANS(PTSOpenServer),
+#endif /* TRANS_SERVER */
+#ifdef TRANS_CLIENT
+     TRANS(OpenFail),
+#endif /* TRANS_CLIENT */
+#ifdef TRANS_SERVER
+     TRANS(OpenFail),
+#endif /* TRANS_SERVER */
+#ifdef TRANS_REOPEN
+     TRANS(PTSReopenServer),
+     TRANS(ReopenFail),
+#endif
+#ifdef TRANS_SERVER
+     NULL,		/* ResetListener */
+     TRANS(PTSAccept)
+#endif /* TRANS_SERVER */
+},
+#else /* !LOCAL_TRANS_PTS */
+{"",
+#ifdef TRANS_CLIENT
+     TRANS(NAMEDOpenClient),
+#endif /* TRANS_CLIENT */
+#ifdef TRANS_SERVER
+     TRANS(NAMEDOpenServer),
+#endif /* TRANS_SERVER */
+#ifdef TRANS_CLIENT
+     TRANS(OpenFail),
+#endif /* TRANS_CLIENT */
+#ifdef TRANS_SERVER
+     TRANS(OpenFail),
+#endif /* TRANS_SERVER */
+#ifdef TRANS_REOPEN
+     TRANS(NAMEDReopenServer),
+     TRANS(ReopenFail),
+#endif
+#ifdef TRANS_SERVER
+     TRANS(NAMEDResetListener),
+     TRANS(NAMEDAccept)
+#endif /* TRANS_SERVER */
+},
+
+{"local",
+#ifdef TRANS_CLIENT
+     TRANS(NAMEDOpenClient),
+#endif /* TRANS_CLIENT */
+#ifdef TRANS_SERVER
+     TRANS(NAMEDOpenServer),
+#endif /* TRANS_SERVER */
+#ifdef TRANS_CLIENT
+     TRANS(OpenFail),
+#endif /* TRANS_CLIENT */
+#ifdef TRANS_SERVER
+     TRANS(OpenFail),
+#endif /* TRANS_SERVER */
+#ifdef TRANS_REOPEN
+     TRANS(NAMEDReopenServer),
+     TRANS(ReopenFail),
+#endif
+#ifdef TRANS_SERVER
+     TRANS(NAMEDResetListener),
+     TRANS(NAMEDAccept)
+#endif /* TRANS_SERVER */
+},
+#endif /* !LOCAL_TRANS_PTS */
+
+#ifdef LOCAL_TRANS_NAMED
+{"named",
+#ifdef TRANS_CLIENT
+     TRANS(NAMEDOpenClient),
+#endif /* TRANS_CLIENT */
+#ifdef TRANS_SERVER
+     TRANS(NAMEDOpenServer),
+#endif /* TRANS_SERVER */
+#ifdef TRANS_CLIENT
+     TRANS(OpenFail),
+#endif /* TRANS_CLIENT */
+#ifdef TRANS_SERVER
+     TRANS(OpenFail),
+#endif /* TRANS_SERVER */
+#ifdef TRANS_REOPEN
+     TRANS(NAMEDReopenServer),
+     TRANS(ReopenFail),
+#endif
+#ifdef TRANS_SERVER
+     TRANS(NAMEDResetListener),
+     TRANS(NAMEDAccept)
+#endif /* TRANS_SERVER */
+},
+
+#ifdef __sun /* Alias "pipe" to named, since that's what Solaris called it */
+{"pipe",
+#ifdef TRANS_CLIENT
+     TRANS(NAMEDOpenClient),
+#endif /* TRANS_CLIENT */
+#ifdef TRANS_SERVER
+     TRANS(NAMEDOpenServer),
+#endif /* TRANS_SERVER */
+#ifdef TRANS_CLIENT
+     TRANS(OpenFail),
+#endif /* TRANS_CLIENT */
+#ifdef TRANS_SERVER
+     TRANS(OpenFail),
+#endif /* TRANS_SERVER */
+#ifdef TRANS_REOPEN
+     TRANS(NAMEDReopenServer),
+     TRANS(ReopenFail),
+#endif
+#ifdef TRANS_SERVER
+     TRANS(NAMEDResetListener),
+     TRANS(NAMEDAccept)
+#endif /* TRANS_SERVER */
+},
+#endif /* __sun */
+#endif /* LOCAL_TRANS_NAMED */
+
+
+#ifdef LOCAL_TRANS_SCO
+{"sco",
+#ifdef TRANS_CLIENT
+     TRANS(SCOOpenClient),
+#endif /* TRANS_CLIENT */
+#ifdef TRANS_SERVER
+     TRANS(SCOOpenServer),
+#endif /* TRANS_SERVER */
+#ifdef TRANS_CLIENT
+     TRANS(OpenFail),
+#endif /* TRANS_CLIENT */
+#ifdef TRANS_SERVER
+     TRANS(OpenFail),
+#endif /* TRANS_SERVER */
+#ifdef TRANS_REOPEN
+     TRANS(SCOReopenServer),
+     TRANS(ReopenFail),
+#endif
+#ifdef TRANS_SERVER
+     NULL,		/* ResetListener */
+     TRANS(SCOAccept)
+#endif /* TRANS_SERVER */
+},
+#endif /* LOCAL_TRANS_SCO */
+};
+
+#define NUMTRANSPORTS	(sizeof(LOCALtrans2devtab)/sizeof(LOCALtrans2dev))
+
+static const char	*XLOCAL=NULL;
+static	char	*workingXLOCAL=NULL;
+static	char	*freeXLOCAL=NULL;
+
+#if defined(__SCO__)
+#define DEF_XLOCAL "SCO:UNIX:PTS"
+#elif defined(__UNIXWARE__)
+#define DEF_XLOCAL "UNIX:PTS:NAMED:SCO"
+#elif defined(__sun)
+#define DEF_XLOCAL "UNIX:NAMED"
+#else
+#define DEF_XLOCAL "UNIX:PTS:NAMED:SCO"
+#endif
+
+static void
+TRANS(LocalInitTransports)(const char *protocol)
+
+{
+    prmsg(3,"LocalInitTransports(%s)\n", protocol);
+
+    if( strcmp(protocol,"local") && strcmp(protocol,"LOCAL") )
+    {
+	workingXLOCAL = freeXLOCAL = strdup (protocol);
+    }
+    else {
+	XLOCAL=(char *)getenv("XLOCAL");
+	if(XLOCAL==NULL)
+	    XLOCAL=DEF_XLOCAL;
+	workingXLOCAL = freeXLOCAL = strdup (XLOCAL);
+    }
+}
+
+static void
+TRANS(LocalEndTransports)(void)
+
+{
+    prmsg(3,"LocalEndTransports()\n");
+    free(freeXLOCAL);
+    freeXLOCAL = NULL;
+}
+
+#define TYPEBUFSIZE	32
+
+#ifdef TRANS_CLIENT
+
+static LOCALtrans2dev *
+TRANS(LocalGetNextTransport)(void)
+
+{
+    int		i;
+    char	*typetocheck;
+    prmsg(3,"LocalGetNextTransport()\n");
+
+    while(1)
+    {
+	if( workingXLOCAL == NULL || *workingXLOCAL == '\0' )
+	    return NULL;
+
+	typetocheck=workingXLOCAL;
+	workingXLOCAL=strchr(workingXLOCAL,':');
+	if(workingXLOCAL && *workingXLOCAL)
+	    *workingXLOCAL++='\0';
+
+	for(i=0;i<NUMTRANSPORTS;i++)
+	{
+#ifndef HAVE_STRCASECMP
+	    int		j;
+	    char	typebuf[TYPEBUFSIZE];
+	    /*
+	     * This is equivalent to a case insensitive strcmp(),
+	     * but should be more portable.
+	     */
+	    strncpy(typebuf,typetocheck,TYPEBUFSIZE);
+	    for(j=0;j<TYPEBUFSIZE;j++)
+		if (isupper(typebuf[j]))
+		    typebuf[j]=tolower(typebuf[j]);
+
+	    /* Now, see if they match */
+	    if(!strcmp(LOCALtrans2devtab[i].transname,typebuf))
+#else
+	    if(!strcasecmp(LOCALtrans2devtab[i].transname,typetocheck))
+#endif
+		return &LOCALtrans2devtab[i];
+	}
+    }
+#if 0
+    /*NOTREACHED*/
+    return NULL;
+#endif
+}
+
+#ifdef NEED_UTSNAME
+#include <sys/utsname.h>
+#endif
+
+/*
+ * Make sure 'host' is really local.
+ */
+
+static int
+HostReallyLocal (const char *host)
+
+{
+    /*
+     * The 'host' passed to this function may have been generated
+     * by either uname() or gethostname().  We try both if possible.
+     */
+
+#ifdef NEED_UTSNAME
+    struct utsname name;
+#endif
+    char buf[256];
+
+#ifdef NEED_UTSNAME
+    if (uname (&name) >= 0 && strcmp (host, name.nodename) == 0)
+	return (1);
+#endif
+
+    buf[0] = '\0';
+    (void) gethostname (buf, 256);
+    buf[255] = '\0';
+
+    if (strcmp (host, buf) == 0)
+	return (1);
+
+    return (0);
+}
+
+
+static XtransConnInfo
+TRANS(LocalOpenClient)(int type, const char *protocol,
+                       const char *host, const char *port)
+
+{
+    LOCALtrans2dev *transptr;
+    XtransConnInfo ciptr;
+    int index;
+
+    prmsg(3,"LocalOpenClient()\n");
+
+    /*
+     * Make sure 'host' is really local.  If not, we return failure.
+     * The reason we make this check is because a process may advertise
+     * a "local" address for which it can accept connections, but if a
+     * process on a remote machine tries to connect to this address,
+     * we know for sure it will fail.
+     */
+
+    if (strcmp (host, "unix") != 0 && !HostReallyLocal (host))
+    {
+	prmsg (1,
+	   "LocalOpenClient: Cannot connect to non-local host %s\n",
+	       host);
+	return NULL;
+    }
+
+
+#if defined(X11_t)
+    /*
+     * X has a well known port, that is transport dependant. It is easier
+     * to handle it here, than try and come up with a transport independent
+     * representation that can be passed in and resolved the usual way.
+     *
+     * The port that is passed here is really a string containing the idisplay
+     * from ConnectDisplay(). Since that is what we want for the local transports,
+     * we don't have to do anything special.
+     */
+#endif /* X11_t */
+
+    if( (ciptr = calloc(1,sizeof(struct _XtransConnInfo))) == NULL )
+    {
+	prmsg(1,"LocalOpenClient: calloc(1,%lu) failed\n",
+	      sizeof(struct _XtransConnInfo));
+	return NULL;
+    }
+
+    ciptr->fd = -1;
+
+    TRANS(LocalInitTransports)(protocol);
+
+    index = 0;
+    for(transptr=TRANS(LocalGetNextTransport)();
+	transptr!=NULL;transptr=TRANS(LocalGetNextTransport)(), index++)
+    {
+	switch( type )
+	{
+	case XTRANS_OPEN_COTS_CLIENT:
+	    ciptr->fd=transptr->devcotsopenclient(ciptr,port);
+	    break;
+	case XTRANS_OPEN_COTS_SERVER:
+	    prmsg(1,
+		  "LocalOpenClient: Should not be opening a server with this function\n");
+	    break;
+	default:
+	    prmsg(1,
+		  "LocalOpenClient: Unknown Open type %d\n",
+		  type);
+	}
+	if( ciptr->fd >= 0 )
+	    break;
+    }
+
+    TRANS(LocalEndTransports)();
+
+    if( ciptr->fd < 0 )
+    {
+	free(ciptr);
+	return NULL;
+    }
+
+    ciptr->priv=(char *)transptr;
+    ciptr->index = index;
+
+    return ciptr;
+}
+
+#endif /* TRANS_CLIENT */
+
+
+#ifdef TRANS_SERVER
+
+static XtransConnInfo
+TRANS(LocalOpenServer)(int type, const char *protocol,
+                       const char *host _X_UNUSED, const char *port)
+
+{
+    int	i;
+    XtransConnInfo ciptr;
+
+    prmsg(2,"LocalOpenServer(%d,%s,%s)\n", type, protocol, port);
+
+#if defined(X11_t)
+    /*
+     * For X11, the port will be in the format xserverN where N is the
+     * display number. All of the local connections just need to know
+     * the display number because they don't do any name resolution on
+     * the port. This just truncates port to the display portion.
+     */
+#endif /* X11_t */
+
+    if( (ciptr = calloc(1,sizeof(struct _XtransConnInfo))) == NULL )
+    {
+	prmsg(1,"LocalOpenServer: calloc(1,%lu) failed\n",
+	      sizeof(struct _XtransConnInfo));
+	return NULL;
+    }
+
+    for(i=1;i<NUMTRANSPORTS;i++)
+    {
+	if( strcmp(protocol,LOCALtrans2devtab[i].transname) != 0 )
+	    continue;
+	switch( type )
+	{
+	case XTRANS_OPEN_COTS_CLIENT:
+	    prmsg(1,
+		  "LocalOpenServer: Should not be opening a client with this function\n");
+	    break;
+	case XTRANS_OPEN_COTS_SERVER:
+	    ciptr->fd=LOCALtrans2devtab[i].devcotsopenserver(ciptr,port);
+	    break;
+	default:
+	    prmsg(1,"LocalOpenServer: Unknown Open type %d\n",
+		  type );
+	}
+	if( ciptr->fd >= 0 ) {
+	    ciptr->priv=(char *)&LOCALtrans2devtab[i];
+	    ciptr->index=i;
+	    ciptr->flags = 1 | (ciptr->flags & TRANS_KEEPFLAGS);
+	    return ciptr;
+	}
+    }
+
+    free(ciptr);
+    return NULL;
+}
+
+#endif /* TRANS_SERVER */
+
+
+#ifdef TRANS_REOPEN
+
+static XtransConnInfo
+TRANS(LocalReopenServer)(int type, int index, int fd, const char *port)
+
+{
+    XtransConnInfo ciptr;
+    int stat = 0;
+
+    prmsg(2,"LocalReopenServer(%d,%d,%d)\n", type, index, fd);
+
+    if( (ciptr = calloc(1,sizeof(struct _XtransConnInfo))) == NULL )
+    {
+	prmsg(1,"LocalReopenServer: calloc(1,%lu) failed\n",
+	      sizeof(struct _XtransConnInfo));
+	return NULL;
+    }
+
+    ciptr->fd = fd;
+
+    switch( type )
+    {
+    case XTRANS_OPEN_COTS_SERVER:
+	stat = LOCALtrans2devtab[index].devcotsreopenserver(ciptr,fd,port);
+	break;
+    default:
+	prmsg(1,"LocalReopenServer: Unknown Open type %d\n",
+	  type );
+    }
+
+    if( stat > 0 ) {
+	ciptr->priv=(char *)&LOCALtrans2devtab[index];
+	ciptr->index=index;
+	ciptr->flags = 1 | (ciptr->flags & TRANS_KEEPFLAGS);
+	return ciptr;
+    }
+
+    free(ciptr);
+    return NULL;
+}
+
+#endif /* TRANS_REOPEN */
+
+
+
+/*
+ * This is the Local implementation of the X Transport service layer
+ */
+
+#ifdef TRANS_CLIENT
+
+static XtransConnInfo
+TRANS(LocalOpenCOTSClient)(Xtransport *thistrans _X_UNUSED, const char *protocol,
+			   const char *host, const char *port)
+
+{
+    prmsg(2,"LocalOpenCOTSClient(%s,%s,%s)\n",protocol,host,port);
+
+    return TRANS(LocalOpenClient)(XTRANS_OPEN_COTS_CLIENT, protocol, host, port);
+}
+
+#endif /* TRANS_CLIENT */
+
+
+#ifdef TRANS_SERVER
+
+static XtransConnInfo
+TRANS(LocalOpenCOTSServer)(Xtransport *thistrans, const char *protocol,
+			   const char *host, const char *port)
+
+{
+    char *typetocheck = NULL;
+    int found = 0;
+
+    prmsg(2,"LocalOpenCOTSServer(%s,%s,%s)\n",protocol,host,port);
+
+    /* Check if this local type is in the XLOCAL list */
+    TRANS(LocalInitTransports)("local");
+    typetocheck = workingXLOCAL;
+    while (typetocheck && !found) {
+#ifndef HAVE_STRCASECMP
+	int j;
+	char typebuf[TYPEBUFSIZE];
+#endif
+
+	workingXLOCAL = strchr(workingXLOCAL, ':');
+	if (workingXLOCAL && *workingXLOCAL)
+	    *workingXLOCAL++ = '\0';
+#ifndef HAVE_STRCASECMP
+	strncpy(typebuf, typetocheck, TYPEBUFSIZE);
+	for (j = 0; j < TYPEBUFSIZE; j++)
+	    if (isupper(typebuf[j]))
+		typebuf[j] = tolower(typebuf[j]);
+	if (!strcmp(thistrans->TransName, typebuf))
+#else
+	if (!strcasecmp(thistrans->TransName, typetocheck))
+#endif
+	    found = 1;
+	typetocheck = workingXLOCAL;
+    }
+    TRANS(LocalEndTransports)();
+
+    if (!found) {
+	prmsg(3,"LocalOpenCOTSServer: disabling %s\n",thistrans->TransName);
+	thistrans->flags |= TRANS_DISABLED;
+	return NULL;
+    }
+
+    return TRANS(LocalOpenServer)(XTRANS_OPEN_COTS_SERVER, protocol, host, port);
+}
+
+#endif /* TRANS_SERVER */
+
+#ifdef TRANS_REOPEN
+
+static XtransConnInfo
+TRANS(LocalReopenCOTSServer)(Xtransport *thistrans, int fd, const char *port)
+
+{
+    int index;
+
+    prmsg(2,"LocalReopenCOTSServer(%d,%s)\n", fd, port);
+
+    for(index=1;index<NUMTRANSPORTS;index++)
+    {
+	if( strcmp(thistrans->TransName,
+	    LOCALtrans2devtab[index].transname) == 0 )
+	    break;
+    }
+
+    if (index >= NUMTRANSPORTS)
+    {
+	return (NULL);
+    }
+
+    return TRANS(LocalReopenServer)(XTRANS_OPEN_COTS_SERVER,
+	index, fd, port);
+}
+
+#endif /* TRANS_REOPEN */
+
+
+
+static int
+TRANS(LocalSetOption)(XtransConnInfo ciptr, int option, int arg)
+
+{
+    prmsg(2,"LocalSetOption(%d,%d,%d)\n",ciptr->fd,option,arg);
+
+    return -1;
+}
+
+
+#ifdef TRANS_SERVER
+
+static int
+TRANS(LocalCreateListener)(XtransConnInfo ciptr, const char *port,
+                           unsigned int flags _X_UNUSED)
+
+{
+    prmsg(2,"LocalCreateListener(%p->%d,%s)\n",ciptr,ciptr->fd,port);
+
+    return 0;
+}
+
+static int
+TRANS(LocalResetListener)(XtransConnInfo ciptr)
+
+{
+    LOCALtrans2dev	*transptr;
+
+    prmsg(2,"LocalResetListener(%p)\n",ciptr);
+
+    transptr=(LOCALtrans2dev *)ciptr->priv;
+    if (transptr->devreset != NULL) {
+	return transptr->devreset(ciptr);
+    }
+    return TRANS_RESET_NOOP;
+}
+
+
+static XtransConnInfo
+TRANS(LocalAccept)(XtransConnInfo ciptr, int *status)
+
+{
+    XtransConnInfo	newciptr;
+    LOCALtrans2dev	*transptr;
+
+    prmsg(2,"LocalAccept(%p->%d)\n", ciptr, ciptr->fd);
+
+    transptr=(LOCALtrans2dev *)ciptr->priv;
+
+    if( (newciptr = calloc(1,sizeof(struct _XtransConnInfo)))==NULL )
+    {
+	prmsg(1,"LocalAccept: calloc(1,%lu) failed\n",
+	      sizeof(struct _XtransConnInfo));
+	*status = TRANS_ACCEPT_BAD_MALLOC;
+	return NULL;
+    }
+
+    newciptr->fd=transptr->devaccept(ciptr,newciptr,status);
+
+    if( newciptr->fd < 0 )
+    {
+	free(newciptr);
+	return NULL;
+    }
+
+    newciptr->priv=(char *)transptr;
+    newciptr->index = ciptr->index;
+
+    *status = 0;
+
+    return newciptr;
+}
+
+#endif /* TRANS_SERVER */
+
+
+#ifdef TRANS_CLIENT
+
+static int
+TRANS(LocalConnect)(XtransConnInfo ciptr,
+                    const char *host _X_UNUSED, const char *port)
+
+{
+    prmsg(2,"LocalConnect(%p->%d,%s)\n", ciptr, ciptr->fd, port);
+
+    return 0;
+}
+
+#endif /* TRANS_CLIENT */
+
+
+static int
+TRANS(LocalBytesReadable)(XtransConnInfo ciptr, BytesReadable_t *pend )
+
+{
+    prmsg(2,"LocalBytesReadable(%p->%d,%p)\n", ciptr, ciptr->fd, pend);
+
+#if defined(SCO325)
+    return ioctl(ciptr->fd, I_NREAD, (char *)pend);
+#else
+    return ioctl(ciptr->fd, FIONREAD, (char *)pend);
+#endif
+}
+
+static int
+TRANS(LocalRead)(XtransConnInfo ciptr, char *buf, int size)
+
+{
+    prmsg(2,"LocalRead(%d,%p,%d)\n", ciptr->fd, buf, size );
+
+    return read(ciptr->fd,buf,size);
+}
+
+static int
+TRANS(LocalWrite)(XtransConnInfo ciptr, char *buf, int size)
+
+{
+    prmsg(2,"LocalWrite(%d,%p,%d)\n", ciptr->fd, buf, size );
+
+    return write(ciptr->fd,buf,size);
+}
+
+static int
+TRANS(LocalReadv)(XtransConnInfo ciptr, struct iovec *buf, int size)
+
+{
+    prmsg(2,"LocalReadv(%d,%p,%d)\n", ciptr->fd, buf, size );
+
+    return READV(ciptr,buf,size);
+}
+
+static int
+TRANS(LocalWritev)(XtransConnInfo ciptr, struct iovec *buf, int size)
+
+{
+    prmsg(2,"LocalWritev(%d,%p,%d)\n", ciptr->fd, buf, size );
+
+    return WRITEV(ciptr,buf,size);
+}
+
+static int
+TRANS(LocalDisconnect)(XtransConnInfo ciptr)
+
+{
+    prmsg(2,"LocalDisconnect(%p->%d)\n", ciptr, ciptr->fd);
+
+    return 0;
+}
+
+static int
+TRANS(LocalClose)(XtransConnInfo ciptr)
+
+{
+    struct sockaddr_un      *sockname=(struct sockaddr_un *) ciptr->addr;
+    int	ret;
+
+    prmsg(2,"LocalClose(%p->%d)\n", ciptr, ciptr->fd );
+
+    ret=close(ciptr->fd);
+
+    if(ciptr->flags
+       && sockname
+       && sockname->sun_family == AF_UNIX
+       && sockname->sun_path[0] )
+    {
+	if (!(ciptr->flags & TRANS_NOUNLINK))
+	    unlink(sockname->sun_path);
+    }
+
+    return ret;
+}
+
+static int
+TRANS(LocalCloseForCloning)(XtransConnInfo ciptr)
+
+{
+    int ret;
+
+    prmsg(2,"LocalCloseForCloning(%p->%d)\n", ciptr, ciptr->fd );
+
+    /* Don't unlink path */
+
+    ret=close(ciptr->fd);
+
+    return ret;
+}
+
+
+/*
+ * MakeAllCOTSServerListeners() will go through the entire Xtransports[]
+ * array defined in Xtrans.c and try to OpenCOTSServer() for each entry.
+ * We will add duplicate entries to that table so that the OpenCOTSServer()
+ * function will get called once for each type of local transport.
+ *
+ * The TransName is in lowercase, so it will never match during a normal
+ * call to SelectTransport() in Xtrans.c.
+ */
+
+#ifdef TRANS_SERVER
+static const char * local_aliases[] = {
+# ifdef LOCAL_TRANS_PTS
+                                  "pts",
+# endif
+				  "named",
+# ifdef __sun
+				  "pipe", /* compatibility with Solaris Xlib */
+# endif
+# ifdef LOCAL_TRANS_SCO
+				  "sco",
+# endif
+				  NULL };
+#endif
+
+Xtransport	TRANS(LocalFuncs) = {
+	/* Local Interface */
+	"local",
+	TRANS_ALIAS | TRANS_LOCAL,
+#ifdef TRANS_CLIENT
+	TRANS(LocalOpenCOTSClient),
+#endif /* TRANS_CLIENT */
+#ifdef TRANS_SERVER
+	local_aliases,
+	TRANS(LocalOpenCOTSServer),
+#endif /* TRANS_SERVER */
+#ifdef TRANS_REOPEN
+	TRANS(LocalReopenCOTSServer),
+#endif
+	TRANS(LocalSetOption),
+#ifdef TRANS_SERVER
+	TRANS(LocalCreateListener),
+	TRANS(LocalResetListener),
+	TRANS(LocalAccept),
+#endif /* TRANS_SERVER */
+#ifdef TRANS_CLIENT
+	TRANS(LocalConnect),
+#endif /* TRANS_CLIENT */
+	TRANS(LocalBytesReadable),
+	TRANS(LocalRead),
+	TRANS(LocalWrite),
+	TRANS(LocalReadv),
+	TRANS(LocalWritev),
+#if XTRANS_SEND_FDS
+	TRANS(LocalSendFdInvalid),
+	TRANS(LocalRecvFdInvalid),
+#endif
+	TRANS(LocalDisconnect),
+	TRANS(LocalClose),
+	TRANS(LocalCloseForCloning),
+};
+
+#ifdef LOCAL_TRANS_PTS
+
+Xtransport	TRANS(PTSFuncs) = {
+	/* Local Interface */
+	"pts",
+	TRANS_LOCAL,
+#ifdef TRANS_CLIENT
+	TRANS(LocalOpenCOTSClient),
+#endif /* TRANS_CLIENT */
+#ifdef TRANS_SERVER
+	NULL,
+	TRANS(LocalOpenCOTSServer),
+#endif /* TRANS_SERVER */
+#ifdef TRANS_REOPEN
+	TRANS(LocalReopenCOTSServer),
+#endif
+	TRANS(LocalSetOption),
+#ifdef TRANS_SERVER
+	TRANS(LocalCreateListener),
+	TRANS(LocalResetListener),
+	TRANS(LocalAccept),
+#endif /* TRANS_SERVER */
+#ifdef TRANS_CLIENT
+	TRANS(LocalConnect),
+#endif /* TRANS_CLIENT */
+	TRANS(LocalBytesReadable),
+	TRANS(LocalRead),
+	TRANS(LocalWrite),
+	TRANS(LocalReadv),
+	TRANS(LocalWritev),
+#if XTRANS_SEND_FDS
+	TRANS(LocalSendFdInvalid),
+	TRANS(LocalRecvFdInvalid),
+#endif
+	TRANS(LocalDisconnect),
+	TRANS(LocalClose),
+	TRANS(LocalCloseForCloning),
+};
+
+#endif /* LOCAL_TRANS_PTS */
+
+#ifdef LOCAL_TRANS_NAMED
+
+Xtransport	TRANS(NAMEDFuncs) = {
+	/* Local Interface */
+	"named",
+	TRANS_LOCAL,
+#ifdef TRANS_CLIENT
+	TRANS(LocalOpenCOTSClient),
+#endif /* TRANS_CLIENT */
+#ifdef TRANS_SERVER
+	NULL,
+	TRANS(LocalOpenCOTSServer),
+#endif /* TRANS_SERVER */
+#ifdef TRANS_REOPEN
+	TRANS(LocalReopenCOTSServer),
+#endif
+	TRANS(LocalSetOption),
+#ifdef TRANS_SERVER
+	TRANS(LocalCreateListener),
+	TRANS(LocalResetListener),
+	TRANS(LocalAccept),
+#endif /* TRANS_SERVER */
+#ifdef TRANS_CLIENT
+	TRANS(LocalConnect),
+#endif /* TRANS_CLIENT */
+	TRANS(LocalBytesReadable),
+	TRANS(LocalRead),
+	TRANS(LocalWrite),
+	TRANS(LocalReadv),
+	TRANS(LocalWritev),
+#if XTRANS_SEND_FDS
+	TRANS(LocalSendFdInvalid),
+	TRANS(LocalRecvFdInvalid),
+#endif
+	TRANS(LocalDisconnect),
+	TRANS(LocalClose),
+	TRANS(LocalCloseForCloning),
+};
+
+#ifdef __sun
+Xtransport	TRANS(PIPEFuncs) = {
+	/* Local Interface */
+	"pipe",
+	TRANS_ALIAS | TRANS_LOCAL,
+#ifdef TRANS_CLIENT
+	TRANS(LocalOpenCOTSClient),
+#endif /* TRANS_CLIENT */
+#ifdef TRANS_SERVER
+	NULL,
+	TRANS(LocalOpenCOTSServer),
+#endif /* TRANS_SERVER */
+#ifdef TRANS_REOPEN
+	TRANS(LocalReopenCOTSServer),
+#endif
+	TRANS(LocalSetOption),
+#ifdef TRANS_SERVER
+	TRANS(LocalCreateListener),
+	TRANS(LocalResetListener),
+	TRANS(LocalAccept),
+#endif /* TRANS_SERVER */
+#ifdef TRANS_CLIENT
+	TRANS(LocalConnect),
+#endif /* TRANS_CLIENT */
+	TRANS(LocalBytesReadable),
+	TRANS(LocalRead),
+	TRANS(LocalWrite),
+	TRANS(LocalReadv),
+	TRANS(LocalWritev),
+#if XTRANS_SEND_FDS
+	TRANS(LocalSendFdInvalid),
+	TRANS(LocalRecvFdInvalid),
+#endif
+	TRANS(LocalDisconnect),
+	TRANS(LocalClose),
+	TRANS(LocalCloseForCloning),
+};
+#endif /* __sun */
+#endif /* LOCAL_TRANS_NAMED */
+
+
+#ifdef LOCAL_TRANS_SCO
+Xtransport	TRANS(SCOFuncs) = {
+	/* Local Interface */
+	"sco",
+	TRANS_LOCAL,
+#ifdef TRANS_CLIENT
+	TRANS(LocalOpenCOTSClient),
+#endif /* TRANS_CLIENT */
+#ifdef TRANS_SERVER
+	NULL,
+	TRANS(LocalOpenCOTSServer),
+#endif /* TRANS_SERVER */
+#ifdef TRANS_REOPEN
+	TRANS(LocalReopenCOTSServer),
+#endif
+	TRANS(LocalSetOption),
+#ifdef TRANS_SERVER
+	TRANS(LocalCreateListener),
+	TRANS(LocalResetListener),
+	TRANS(LocalAccept),
+#endif /* TRANS_SERVER */
+#ifdef TRANS_CLIENT
+	TRANS(LocalConnect),
+#endif /* TRANS_CLIENT */
+	TRANS(LocalBytesReadable),
+	TRANS(LocalRead),
+	TRANS(LocalWrite),
+	TRANS(LocalReadv),
+	TRANS(LocalWritev),
+#if XTRANS_SEND_FDS
+	TRANS(LocalSendFdInvalid),
+	TRANS(LocalRecvFdInvalid),
+#endif
+	TRANS(LocalDisconnect),
+	TRANS(LocalClose),
+	TRANS(LocalCloseForCloning),
+};
+#endif /* LOCAL_TRANS_SCO */
diff -Naur old/X11/Xtrans/Xtranssock.c new/X11/Xtrans/Xtranssock.c
--- old/X11/Xtrans/Xtranssock.c	1970-01-01 08:00:00.000000000 +0800
+++ new/X11/Xtrans/Xtranssock.c	2024-03-05 19:36:25.213040800 +0800
@@ -0,0 +1,2575 @@
+/*
+ * Copyright (c) 2002, 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.
+ */
+/*
+
+Copyright 1993, 1994, 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 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
+from the copyright holders.
+
+ * Copyright 1993, 1994 NCR Corporation - Dayton, Ohio, USA
+ *
+ * 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 NCR not be used in advertising
+ * or publicity pertaining to distribution of the software without specific,
+ * written prior permission.  NCR makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ *
+ * NCR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
+ * NO EVENT SHALL NCR 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.
+ */
+
+#include <ctype.h>
+#ifdef XTHREADS
+#include <X11/Xthreads.h>
+#endif
+
+#ifndef WIN32
+
+#if defined(TCPCONN) || defined(UNIXCONN)
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#endif
+
+#if defined(TCPCONN) || defined(UNIXCONN)
+#define X_INCLUDE_NETDB_H
+#define XOS_USE_NO_LOCKING
+#include <X11/Xos_r.h>
+#endif
+
+#ifdef UNIXCONN
+#ifndef X_NO_SYS_UN
+#include <sys/un.h>
+#endif
+#include <sys/stat.h>
+#endif
+
+
+#ifndef NO_TCP_H
+#if defined(linux) || defined(__GLIBC__)
+#include <sys/param.h>
+#endif /* osf */
+#if defined(__NetBSD__) || defined(__OpenBSD__) || defined(__FreeBSD__) || defined(__DragonFly__)
+#include <sys/param.h>
+#include <machine/endian.h>
+#endif /* __NetBSD__ || __OpenBSD__ || __FreeBSD__ || __DragonFly__ */
+#include <netinet/tcp.h>
+#endif /* !NO_TCP_H */
+
+#include <sys/ioctl.h>
+#if defined(SVR4) || defined(__SVR4)
+#include <sys/filio.h>
+#endif
+
+#include <unistd.h>
+
+#else /* !WIN32 */
+
+#include <X11/Xwinsock.h>
+#include <X11/Xwindows.h>
+#include <X11/Xw32defs.h>
+#undef close
+#define close closesocket
+#define ECONNREFUSED WSAECONNREFUSED
+#define EADDRINUSE WSAEADDRINUSE
+#define EPROTOTYPE WSAEPROTOTYPE
+#undef EWOULDBLOCK
+#define EWOULDBLOCK WSAEWOULDBLOCK
+#define EINPROGRESS WSAEINPROGRESS
+#undef EINTR
+#define EINTR WSAEINTR
+#define X_INCLUDE_NETDB_H
+#define XOS_USE_MTSAFE_NETDBAPI
+#include <X11/Xos_r.h>
+#endif /* WIN32 */
+
+#if defined(SO_DONTLINGER) && defined(SO_LINGER)
+#undef SO_DONTLINGER
+#endif
+
+/* others don't need this */
+#define SocketInitOnce() /**/
+
+#ifdef linux
+#define HAVE_ABSTRACT_SOCKETS
+#endif
+
+#define MIN_BACKLOG 128
+#ifdef SOMAXCONN
+#if SOMAXCONN > MIN_BACKLOG
+#define BACKLOG SOMAXCONN
+#endif
+#endif
+#ifndef BACKLOG
+#define BACKLOG MIN_BACKLOG
+#endif
+
+/*
+ * This is the Socket implementation of the X Transport service layer
+ *
+ * This file contains the implementation for both the UNIX and INET domains,
+ * and can be built for either one, or both.
+ *
+ */
+
+typedef struct _Sockettrans2dev {
+    const char	*transname;
+    int		family;
+    int		devcotsname;
+    int		devcltsname;
+    int		protocol;
+} Sockettrans2dev;
+
+static Sockettrans2dev Sockettrans2devtab[] = {
+#ifdef TCPCONN
+    {"inet",AF_INET,SOCK_STREAM,SOCK_DGRAM,0},
+#if !defined(IPv6) || !defined(AF_INET6)
+    {"tcp",AF_INET,SOCK_STREAM,SOCK_DGRAM,0},
+#else /* IPv6 */
+    {"tcp",AF_INET6,SOCK_STREAM,SOCK_DGRAM,0},
+    {"tcp",AF_INET,SOCK_STREAM,SOCK_DGRAM,0}, /* fallback */
+    {"inet6",AF_INET6,SOCK_STREAM,SOCK_DGRAM,0},
+#endif
+#endif /* TCPCONN */
+#ifdef UNIXCONN
+    {"unix",AF_UNIX,SOCK_STREAM,SOCK_DGRAM,0},
+#if !defined(LOCALCONN)
+    {"local",AF_UNIX,SOCK_STREAM,SOCK_DGRAM,0},
+#endif /* !LOCALCONN */
+#endif /* UNIXCONN */
+};
+
+#define NUMSOCKETFAMILIES (sizeof(Sockettrans2devtab)/sizeof(Sockettrans2dev))
+
+#ifdef TCPCONN
+static int TRANS(SocketINETClose) (XtransConnInfo ciptr);
+#endif
+
+#ifdef UNIXCONN
+
+
+#if defined(X11_t)
+#define UNIX_PATH "/tmp/.X11-unix/X"
+#define UNIX_DIR "/tmp/.X11-unix"
+#endif /* X11_t */
+#if defined(XIM_t)
+#define UNIX_PATH "/tmp/.XIM-unix/XIM"
+#define UNIX_DIR "/tmp/.XIM-unix"
+#endif /* XIM_t */
+#if defined(FS_t) || defined(FONT_t)
+#define UNIX_PATH "/tmp/.font-unix/fs"
+#define UNIX_DIR "/tmp/.font-unix"
+#endif /* FS_t || FONT_t */
+#if defined(ICE_t)
+#define UNIX_PATH "/tmp/.ICE-unix/"
+#define UNIX_DIR "/tmp/.ICE-unix"
+#endif /* ICE_t */
+
+
+#endif /* UNIXCONN */
+
+#define PORTBUFSIZE	32
+
+#ifndef MAXHOSTNAMELEN
+#define MAXHOSTNAMELEN 255
+#endif
+
+#if defined HAVE_SOCKLEN_T || (defined(IPv6) && defined(AF_INET6))
+# define SOCKLEN_T socklen_t
+#elif defined(SVR4) || defined(__SVR4) || defined(__SCO__)
+# define SOCKLEN_T size_t
+#else
+# define SOCKLEN_T int
+#endif
+
+/*
+ * These are some utility function used by the real interface function below.
+ */
+
+static int
+TRANS(SocketSelectFamily) (int first, const char *family)
+
+{
+    int     i;
+
+    prmsg (3,"SocketSelectFamily(%s)\n", family);
+
+    for (i = first + 1; i < NUMSOCKETFAMILIES;i++)
+    {
+        if (!strcmp (family, Sockettrans2devtab[i].transname))
+	    return i;
+    }
+
+    return (first == -1 ? -2 : -1);
+}
+
+
+/*
+ * This function gets the local address of the socket and stores it in the
+ * XtransConnInfo structure for the connection.
+ */
+
+static int
+TRANS(SocketINETGetAddr) (XtransConnInfo ciptr)
+
+{
+#if defined(IPv6) && defined(AF_INET6)
+    struct sockaddr_storage socknamev6;
+#else
+    struct sockaddr_in socknamev4;
+#endif
+    void *socknamePtr;
+    SOCKLEN_T namelen;
+
+    prmsg (3,"SocketINETGetAddr(%p)\n", ciptr);
+
+#if defined(IPv6) && defined(AF_INET6)
+    namelen = sizeof(socknamev6);
+    socknamePtr = &socknamev6;
+#else
+    namelen = sizeof(socknamev4);
+    socknamePtr = &socknamev4;
+#endif
+
+    bzero(socknamePtr, namelen);
+
+    if (getsockname (ciptr->fd,(struct sockaddr *) socknamePtr,
+		     (void *)&namelen) < 0)
+    {
+#ifdef WIN32
+	errno = WSAGetLastError();
+#endif
+	prmsg (1,"SocketINETGetAddr: getsockname() failed: %d\n",
+	    EGET());
+	return -1;
+    }
+
+    /*
+     * Everything looks good: fill in the XtransConnInfo structure.
+     */
+
+    if ((ciptr->addr = malloc (namelen)) == NULL)
+    {
+        prmsg (1,
+	    "SocketINETGetAddr: Can't allocate space for the addr\n");
+        return -1;
+    }
+
+#if defined(IPv6) && defined(AF_INET6)
+    ciptr->family = ((struct sockaddr *)socknamePtr)->sa_family;
+#else
+    ciptr->family = socknamev4.sin_family;
+#endif
+    ciptr->addrlen = namelen;
+    memcpy (ciptr->addr, socknamePtr, ciptr->addrlen);
+
+    return 0;
+}
+
+
+/*
+ * This function gets the remote address of the socket and stores it in the
+ * XtransConnInfo structure for the connection.
+ */
+
+static int
+TRANS(SocketINETGetPeerAddr) (XtransConnInfo ciptr)
+
+{
+#if defined(IPv6) && defined(AF_INET6)
+    struct sockaddr_storage socknamev6;
+#endif
+    struct sockaddr_in 	socknamev4;
+    void *socknamePtr;
+    SOCKLEN_T namelen;
+
+#if defined(IPv6) && defined(AF_INET6)
+    if (ciptr->family == AF_INET6)
+    {
+	namelen = sizeof(socknamev6);
+	socknamePtr = &socknamev6;
+    }
+    else
+#endif
+    {
+	namelen = sizeof(socknamev4);
+	socknamePtr = &socknamev4;
+    }
+
+    bzero(socknamePtr, namelen);
+
+    prmsg (3,"SocketINETGetPeerAddr(%p)\n", ciptr);
+
+    if (getpeername (ciptr->fd, (struct sockaddr *) socknamePtr,
+		     (void *)&namelen) < 0)
+    {
+#ifdef WIN32
+	errno = WSAGetLastError();
+#endif
+	prmsg (1,"SocketINETGetPeerAddr: getpeername() failed: %d\n",
+	    EGET());
+	return -1;
+    }
+
+    /*
+     * Everything looks good: fill in the XtransConnInfo structure.
+     */
+
+    if ((ciptr->peeraddr = malloc (namelen)) == NULL)
+    {
+        prmsg (1,
+	   "SocketINETGetPeerAddr: Can't allocate space for the addr\n");
+        return -1;
+    }
+
+    ciptr->peeraddrlen = namelen;
+    memcpy (ciptr->peeraddr, socknamePtr, ciptr->peeraddrlen);
+
+    return 0;
+}
+
+
+static XtransConnInfo
+TRANS(SocketOpen) (int i, int type)
+
+{
+    XtransConnInfo	ciptr;
+
+    prmsg (3,"SocketOpen(%d,%d)\n", i, type);
+
+    if ((ciptr = calloc (1, sizeof(struct _XtransConnInfo))) == NULL)
+    {
+	prmsg (1, "SocketOpen: malloc failed\n");
+	return NULL;
+    }
+
+    if ((ciptr->fd = socket(Sockettrans2devtab[i].family, type,
+	Sockettrans2devtab[i].protocol)) < 0
+#ifndef WIN32
+#if (defined(X11_t) && !defined(USE_POLL)) || defined(FS_t) || defined(FONT_t)
+       || ciptr->fd >= sysconf(_SC_OPEN_MAX)
+#endif
+#endif
+      ) {
+#ifdef WIN32
+	errno = WSAGetLastError();
+#endif
+	prmsg (2, "SocketOpen: socket() failed for %s\n",
+	    Sockettrans2devtab[i].transname);
+
+	free (ciptr);
+	return NULL;
+    }
+
+#ifdef TCP_NODELAY
+    if (Sockettrans2devtab[i].family == AF_INET
+#if defined(IPv6) && defined(AF_INET6)
+      || Sockettrans2devtab[i].family == AF_INET6
+#endif
+    )
+    {
+	/*
+	 * turn off TCP coalescence for INET sockets
+	 */
+
+	int tmp = 1;
+	setsockopt (ciptr->fd, IPPROTO_TCP, TCP_NODELAY,
+	    (char *) &tmp, sizeof (int));
+    }
+#endif
+
+    /*
+     * Some systems provide a really small default buffer size for
+     * UNIX sockets.  Bump it up a bit such that large transfers don't
+     * proceed at glacial speed.
+     */
+#ifdef SO_SNDBUF
+    if (Sockettrans2devtab[i].family == AF_UNIX)
+    {
+	SOCKLEN_T len = sizeof (int);
+	int val;
+
+	if (getsockopt (ciptr->fd, SOL_SOCKET, SO_SNDBUF,
+	    (char *) &val, &len) == 0 && val < 64 * 1024)
+	{
+	    val = 64 * 1024;
+	    setsockopt (ciptr->fd, SOL_SOCKET, SO_SNDBUF,
+	        (char *) &val, sizeof (int));
+	}
+    }
+#endif
+
+    return ciptr;
+}
+
+
+#ifdef TRANS_REOPEN
+
+static XtransConnInfo
+TRANS(SocketReopen) (int i _X_UNUSED, int type, int fd, const char *port)
+
+{
+    XtransConnInfo	ciptr;
+    int portlen;
+    struct sockaddr *addr;
+    size_t addrlen;
+
+    prmsg (3,"SocketReopen(%d,%d,%s)\n", type, fd, port);
+
+    if (port == NULL) {
+      prmsg (1, "SocketReopen: port was null!\n");
+      return NULL;
+    }
+
+    portlen = strlen(port) + 1; // include space for trailing null
+#ifdef SOCK_MAXADDRLEN
+    if (portlen < 0 || portlen > (SOCK_MAXADDRLEN + 2)) {
+      prmsg (1, "SocketReopen: invalid portlen %d\n", portlen);
+      return NULL;
+    }
+    if (portlen < 14) portlen = 14;
+#else
+    if (portlen < 0 || portlen > 14) {
+      prmsg (1, "SocketReopen: invalid portlen %d\n", portlen);
+      return NULL;
+    }
+#endif /*SOCK_MAXADDRLEN*/
+
+    if ((ciptr = calloc (1, sizeof(struct _XtransConnInfo))) == NULL)
+    {
+	prmsg (1, "SocketReopen: malloc(ciptr) failed\n");
+	return NULL;
+    }
+
+    ciptr->fd = fd;
+
+    addrlen = portlen + offsetof(struct sockaddr, sa_data);
+    if ((addr = calloc (1, addrlen)) == NULL) {
+	prmsg (1, "SocketReopen: malloc(addr) failed\n");
+	free (ciptr);
+	return NULL;
+    }
+    ciptr->addr = (char *) addr;
+    ciptr->addrlen = addrlen;
+
+    if ((ciptr->peeraddr = calloc (1, addrlen)) == NULL) {
+	prmsg (1, "SocketReopen: malloc(portaddr) failed\n");
+	free (addr);
+	free (ciptr);
+	return NULL;
+    }
+    ciptr->peeraddrlen = addrlen;
+
+    /* Initialize ciptr structure as if it were a normally-opened unix socket */
+    ciptr->flags = TRANS_LOCAL | TRANS_NOUNLINK;
+#ifdef BSD44SOCKETS
+    addr->sa_len = addrlen;
+#endif
+    addr->sa_family = AF_UNIX;
+#if defined(HAVE_STRLCPY) || defined(HAS_STRLCPY)
+    strlcpy(addr->sa_data, port, portlen);
+#else
+    strncpy(addr->sa_data, port, portlen);
+#endif
+    ciptr->family = AF_UNIX;
+    memcpy(ciptr->peeraddr, ciptr->addr, addrlen);
+    ciptr->port = rindex(addr->sa_data, ':');
+    if (ciptr->port == NULL) {
+	if (is_numeric(addr->sa_data)) {
+	    ciptr->port = addr->sa_data;
+	}
+    } else if (ciptr->port[0] == ':') {
+	ciptr->port++;
+    }
+    /* port should now point to portnum or NULL */
+    return ciptr;
+}
+
+#endif /* TRANS_REOPEN */
+
+
+/*
+ * These functions are the interface supplied in the Xtransport structure
+ */
+
+#ifdef TRANS_CLIENT
+
+static XtransConnInfo
+TRANS(SocketOpenCOTSClientBase) (const char *transname, const char *protocol,
+			   const char *host, const char *port, int previndex)
+{
+    XtransConnInfo	ciptr;
+    int			i = previndex;
+
+    prmsg (2, "SocketOpenCOTSClient(%s,%s,%s)\n",
+	protocol, host, port);
+
+    SocketInitOnce();
+
+    while ((i = TRANS(SocketSelectFamily) (i, transname)) >= 0) {
+	if ((ciptr = TRANS(SocketOpen) (
+		i, Sockettrans2devtab[i].devcotsname)) != NULL) {
+	    /* Save the index for later use */
+
+	    ciptr->index = i;
+	    break;
+	}
+    }
+    if (i < 0) {
+	if (i == -1)
+	    prmsg (1,"SocketOpenCOTSClient: Unable to open socket for %s\n",
+		   transname);
+	else
+	    prmsg (1,"SocketOpenCOTSClient: Unable to determine socket type for %s\n",
+		   transname);
+	return NULL;
+    }
+
+    return ciptr;
+}
+
+static XtransConnInfo
+TRANS(SocketOpenCOTSClient) (Xtransport *thistrans, const char *protocol,
+			     const char *host, const char *port)
+{
+    return TRANS(SocketOpenCOTSClientBase)(
+			thistrans->TransName, protocol, host, port, -1);
+}
+
+
+#endif /* TRANS_CLIENT */
+
+
+#ifdef TRANS_SERVER
+
+static XtransConnInfo
+TRANS(SocketOpenCOTSServer) (Xtransport *thistrans, const char *protocol,
+			     const char *host, const char *port)
+
+{
+    XtransConnInfo	ciptr;
+    int	i = -1;
+
+    prmsg (2,"SocketOpenCOTSServer(%s,%s,%s)\n", protocol, host, port);
+
+    SocketInitOnce();
+
+    while ((i = TRANS(SocketSelectFamily) (i, thistrans->TransName)) >= 0) {
+	if ((ciptr = TRANS(SocketOpen) (
+		 i, Sockettrans2devtab[i].devcotsname)) != NULL)
+	    break;
+    }
+    if (i < 0) {
+	if (i == -1)
+	    prmsg (1,"SocketOpenCOTSServer: Unable to open socket for %s\n",
+		   thistrans->TransName);
+	else
+	    prmsg (1,"SocketOpenCOTSServer: Unable to determine socket type for %s\n",
+		   thistrans->TransName);
+	return NULL;
+    }
+
+    /*
+     * Using this prevents the bind() check for an existing server listening
+     * on the same port, but it is required for other reasons.
+     */
+#ifdef SO_REUSEADDR
+
+    /*
+     * SO_REUSEADDR only applied to AF_INET && AF_INET6
+     */
+
+    if (Sockettrans2devtab[i].family == AF_INET
+#if defined(IPv6) && defined(AF_INET6)
+      || Sockettrans2devtab[i].family == AF_INET6
+#endif
+    )
+    {
+	int one = 1;
+	setsockopt (ciptr->fd, SOL_SOCKET, SO_REUSEADDR,
+		    (char *) &one, sizeof (int));
+    }
+#endif
+#ifdef IPV6_V6ONLY
+    if (Sockettrans2devtab[i].family == AF_INET6)
+    {
+	int one = 1;
+	setsockopt(ciptr->fd, IPPROTO_IPV6, IPV6_V6ONLY, &one, sizeof(int));
+    }
+#endif
+    /* Save the index for later use */
+
+    ciptr->index = i;
+
+    return ciptr;
+}
+
+#endif /* TRANS_SERVER */
+
+
+#ifdef TRANS_REOPEN
+
+static XtransConnInfo
+TRANS(SocketReopenCOTSServer) (Xtransport *thistrans, int fd, const char *port)
+
+{
+    XtransConnInfo	ciptr;
+    int			i = -1;
+
+    prmsg (2,
+	"SocketReopenCOTSServer(%d, %s)\n", fd, port);
+
+    SocketInitOnce();
+
+    while ((i = TRANS(SocketSelectFamily) (i, thistrans->TransName)) >= 0) {
+	if ((ciptr = TRANS(SocketReopen) (
+		 i, Sockettrans2devtab[i].devcotsname, fd, port)) != NULL)
+	    break;
+    }
+    if (i < 0) {
+	if (i == -1)
+	    prmsg (1,"SocketReopenCOTSServer: Unable to open socket for %s\n",
+		   thistrans->TransName);
+	else
+	    prmsg (1,"SocketReopenCOTSServer: Unable to determine socket type for %s\n",
+		   thistrans->TransName);
+	return NULL;
+    }
+
+    /* Save the index for later use */
+
+    ciptr->index = i;
+
+    return ciptr;
+}
+
+#endif /* TRANS_REOPEN */
+
+
+static int
+TRANS(SocketSetOption) (XtransConnInfo ciptr, int option, int arg)
+
+{
+    prmsg (2,"SocketSetOption(%d,%d,%d)\n", ciptr->fd, option, arg);
+
+    return -1;
+}
+
+#ifdef UNIXCONN
+static int
+set_sun_path(const char *port, const char *upath, char *path, int abstract)
+{
+    struct sockaddr_un s;
+    int maxlen = sizeof(s.sun_path) - 1;
+    const char *at = "";
+
+    if (!port || !*port || !path)
+	return -1;
+
+#ifdef HAVE_ABSTRACT_SOCKETS
+    if (port[0] == '@')
+	upath = "";
+    else if (abstract)
+	at = "@";
+#endif
+
+    if (*port == '/') /* a full pathname */
+	upath = "";
+
+    if (strlen(port) + strlen(upath) > maxlen)
+	return -1;
+    snprintf(path, sizeof(s.sun_path), "%s%s%s", at, upath, port);
+    return 0;
+}
+#endif
+
+#ifdef TRANS_SERVER
+
+static int
+TRANS(SocketCreateListener) (XtransConnInfo ciptr,
+			     struct sockaddr *sockname,
+			     int socknamelen, unsigned int flags)
+
+{
+    SOCKLEN_T namelen = socknamelen;
+    int	fd = ciptr->fd;
+    int	retry;
+
+    prmsg (3, "SocketCreateListener(%p,%d)\n", ciptr, fd);
+
+    if (Sockettrans2devtab[ciptr->index].family == AF_INET
+#if defined(IPv6) && defined(AF_INET6)
+      || Sockettrans2devtab[ciptr->index].family == AF_INET6
+#endif
+	)
+	retry = 20;
+    else
+	retry = 0;
+
+    while (bind (fd, (struct sockaddr *) sockname, namelen) < 0)
+    {
+	if (errno == EADDRINUSE) {
+	    if (flags & ADDR_IN_USE_ALLOWED)
+		break;
+	    else
+		return TRANS_ADDR_IN_USE;
+	}
+
+	if (retry-- == 0) {
+	    prmsg (1, "SocketCreateListener: failed to bind listener\n");
+	    close (fd);
+	    return TRANS_CREATE_LISTENER_FAILED;
+	}
+#ifdef SO_REUSEADDR
+	sleep (1);
+#else
+	sleep (10);
+#endif /* SO_REUSEDADDR */
+    }
+
+    if (Sockettrans2devtab[ciptr->index].family == AF_INET
+#if defined(IPv6) && defined(AF_INET6)
+      || Sockettrans2devtab[ciptr->index].family == AF_INET6
+#endif
+	) {
+#ifdef SO_DONTLINGER
+	setsockopt (fd, SOL_SOCKET, SO_DONTLINGER, (char *) NULL, 0);
+#else
+#ifdef SO_LINGER
+    {
+	static int linger[2] = { 0, 0 };
+	setsockopt (fd, SOL_SOCKET, SO_LINGER,
+		(char *) linger, sizeof (linger));
+    }
+#endif
+#endif
+}
+
+    if (listen (fd, BACKLOG) < 0)
+    {
+	prmsg (1, "SocketCreateListener: listen() failed\n");
+	close (fd);
+	return TRANS_CREATE_LISTENER_FAILED;
+    }
+
+    /* Set a flag to indicate that this connection is a listener */
+
+    ciptr->flags = 1 | (ciptr->flags & TRANS_KEEPFLAGS);
+
+    return 0;
+}
+
+#ifdef TCPCONN
+static int
+TRANS(SocketINETCreateListener) (XtransConnInfo ciptr, const char *port,
+                                 unsigned int flags)
+
+{
+#if defined(IPv6) && defined(AF_INET6)
+    struct sockaddr_storage sockname;
+#else
+    struct sockaddr_in	    sockname;
+#endif
+    unsigned short	    sport;
+    SOCKLEN_T	namelen = sizeof(sockname);
+    int		status;
+    long	tmpport;
+#ifdef XTHREADS_NEEDS_BYNAMEPARAMS
+    _Xgetservbynameparams sparams;
+#endif
+    struct servent *servp;
+
+#ifdef X11_t
+    char	portbuf[PORTBUFSIZE];
+#endif
+
+    prmsg (2, "SocketINETCreateListener(%s)\n", port);
+
+#ifdef X11_t
+    /*
+     * X has a well known port, that is transport dependent. It is easier
+     * to handle it here, than try and come up with a transport independent
+     * representation that can be passed in and resolved the usual way.
+     *
+     * The port that is passed here is really a string containing the idisplay
+     * from ConnectDisplay().
+     */
+
+    if (is_numeric (port))
+    {
+	/* fixup the server port address */
+	tmpport = X_TCP_PORT + strtol (port, (char**)NULL, 10);
+	snprintf (portbuf, sizeof(portbuf), "%lu", tmpport);
+	port = portbuf;
+    }
+#endif
+
+    if (port && *port)
+    {
+	/* Check to see if the port string is just a number (handles X11) */
+
+	if (!is_numeric (port))
+	{
+	    if ((servp = _XGetservbyname (port,"tcp",sparams)) == NULL)
+	    {
+		prmsg (1,
+	     "SocketINETCreateListener: Unable to get service for %s\n",
+		      port);
+		return TRANS_CREATE_LISTENER_FAILED;
+	    }
+	    /* we trust getservbyname to return a valid number */
+	    sport = servp->s_port;
+	}
+	else
+	{
+	    tmpport = strtol (port, (char**)NULL, 10);
+	    /*
+	     * check that somehow the port address isn't negative or in
+	     * the range of reserved port addresses. This can happen and
+	     * be very bad if the server is suid-root and the user does
+	     * something (dumb) like `X :60049`.
+	     */
+	    if (tmpport < 1024 || tmpport > USHRT_MAX)
+		return TRANS_CREATE_LISTENER_FAILED;
+
+	    sport = (unsigned short) tmpport;
+	}
+    }
+    else
+	sport = 0;
+
+    bzero(&sockname, sizeof(sockname));
+#if defined(IPv6) && defined(AF_INET6)
+    if (Sockettrans2devtab[ciptr->index].family == AF_INET) {
+	namelen = sizeof (struct sockaddr_in);
+#ifdef BSD44SOCKETS
+	((struct sockaddr_in *)&sockname)->sin_len = namelen;
+#endif
+	((struct sockaddr_in *)&sockname)->sin_family = AF_INET;
+	((struct sockaddr_in *)&sockname)->sin_port = htons(sport);
+	((struct sockaddr_in *)&sockname)->sin_addr.s_addr = htonl(INADDR_ANY);
+    } else {
+	namelen = sizeof (struct sockaddr_in6);
+#ifdef SIN6_LEN
+	((struct sockaddr_in6 *)&sockname)->sin6_len = sizeof(sockname);
+#endif
+	((struct sockaddr_in6 *)&sockname)->sin6_family = AF_INET6;
+	((struct sockaddr_in6 *)&sockname)->sin6_port = htons(sport);
+	((struct sockaddr_in6 *)&sockname)->sin6_addr = in6addr_any;
+    }
+#else
+#ifdef BSD44SOCKETS
+    sockname.sin_len = sizeof (sockname);
+#endif
+    sockname.sin_family = AF_INET;
+    sockname.sin_port = htons (sport);
+    sockname.sin_addr.s_addr = htonl (INADDR_ANY);
+#endif
+
+    if ((status = TRANS(SocketCreateListener) (ciptr,
+	(struct sockaddr *) &sockname, namelen, flags)) < 0)
+    {
+	prmsg (1,
+    "SocketINETCreateListener: ...SocketCreateListener() failed\n");
+	return status;
+    }
+
+    if (TRANS(SocketINETGetAddr) (ciptr) < 0)
+    {
+	prmsg (1,
+       "SocketINETCreateListener: ...SocketINETGetAddr() failed\n");
+	return TRANS_CREATE_LISTENER_FAILED;
+    }
+
+    return 0;
+}
+
+#endif /* TCPCONN */
+
+
+#ifdef UNIXCONN
+
+static int
+TRANS(SocketUNIXCreateListener) (XtransConnInfo ciptr, const char *port,
+				 unsigned int flags)
+
+{
+    struct sockaddr_un	sockname;
+    int			namelen;
+    int			oldUmask;
+    int			status;
+    unsigned int	mode;
+    char		tmpport[108];
+
+    int			abstract = 0;
+#ifdef HAVE_ABSTRACT_SOCKETS
+    abstract = ciptr->transptr->flags & TRANS_ABSTRACT;
+#endif
+
+    prmsg (2, "SocketUNIXCreateListener(%s)\n",
+	port ? port : "NULL");
+
+    /* Make sure the directory is created */
+
+    oldUmask = umask (0);
+
+#ifdef UNIX_DIR
+#ifdef HAS_STICKY_DIR_BIT
+    mode = 01777;
+#else
+    mode = 0777;
+#endif
+    if (!abstract && trans_mkdir(UNIX_DIR, mode) == -1) {
+	prmsg (1, "SocketUNIXCreateListener: mkdir(%s) failed, errno = %d\n",
+	       UNIX_DIR, errno);
+	(void) umask (oldUmask);
+	return TRANS_CREATE_LISTENER_FAILED;
+    }
+#endif
+
+    memset(&sockname, 0, sizeof(sockname));
+    sockname.sun_family = AF_UNIX;
+
+    if (!(port && *port)) {
+	snprintf (tmpport, sizeof(tmpport), "%s%ld", UNIX_PATH, (long)getpid());
+	port = tmpport;
+    }
+    if (set_sun_path(port, UNIX_PATH, sockname.sun_path, abstract) != 0) {
+	prmsg (1, "SocketUNIXCreateListener: path too long\n");
+	return TRANS_CREATE_LISTENER_FAILED;
+    }
+
+#if (defined(BSD44SOCKETS) || defined(__UNIXWARE__))
+    sockname.sun_len = strlen(sockname.sun_path);
+#endif
+
+#if defined(BSD44SOCKETS) || defined(SUN_LEN)
+    namelen = SUN_LEN(&sockname);
+#else
+    namelen = strlen(sockname.sun_path) + offsetof(struct sockaddr_un, sun_path);
+#endif
+
+    if (abstract) {
+	sockname.sun_path[0] = '\0';
+	namelen = offsetof(struct sockaddr_un, sun_path) + 1 + strlen(&sockname.sun_path[1]);
+    }
+    else
+	unlink (sockname.sun_path);
+
+    if ((status = TRANS(SocketCreateListener) (ciptr,
+	(struct sockaddr *) &sockname, namelen, flags)) < 0)
+    {
+	prmsg (1,
+    "SocketUNIXCreateListener: ...SocketCreateListener() failed\n");
+	(void) umask (oldUmask);
+	return status;
+    }
+
+    /*
+     * Now that the listener is esablished, create the addr info for
+     * this connection. getpeername() doesn't work for UNIX Domain Sockets
+     * on some systems (hpux at least), so we will just do it manually, instead
+     * of calling something like TRANS(SocketUNIXGetAddr).
+     */
+
+    namelen = sizeof (sockname); /* this will always make it the same size */
+
+    if ((ciptr->addr = malloc (namelen)) == NULL)
+    {
+        prmsg (1,
+        "SocketUNIXCreateListener: Can't allocate space for the addr\n");
+	(void) umask (oldUmask);
+        return TRANS_CREATE_LISTENER_FAILED;
+    }
+
+    if (abstract)
+	sockname.sun_path[0] = '@';
+
+    ciptr->family = sockname.sun_family;
+    ciptr->addrlen = namelen;
+    memcpy (ciptr->addr, &sockname, ciptr->addrlen);
+
+    (void) umask (oldUmask);
+
+    return 0;
+}
+
+
+static int
+TRANS(SocketUNIXResetListener) (XtransConnInfo ciptr)
+
+{
+    /*
+     * See if the unix domain socket has disappeared.  If it has, recreate it.
+     */
+
+    struct sockaddr_un 	*unsock = (struct sockaddr_un *) ciptr->addr;
+    struct stat		statb;
+    int 		status = TRANS_RESET_NOOP;
+    unsigned int	mode;
+    int abstract = 0;
+#ifdef HAVE_ABSTRACT_SOCKETS
+    abstract = ciptr->transptr->flags & TRANS_ABSTRACT;
+#endif
+
+    prmsg (3, "SocketUNIXResetListener(%p,%d)\n", ciptr, ciptr->fd);
+
+    if (!abstract && (
+	stat (unsock->sun_path, &statb) == -1 ||
+        ((statb.st_mode & S_IFMT) !=
+#if defined(NCR) || defined(SCO325) || !defined(S_IFSOCK)
+	  		S_IFIFO
+#else
+			S_IFSOCK
+#endif
+				)))
+    {
+	int oldUmask = umask (0);
+
+#ifdef UNIX_DIR
+#ifdef HAS_STICKY_DIR_BIT
+	mode = 01777;
+#else
+	mode = 0777;
+#endif
+        if (trans_mkdir(UNIX_DIR, mode) == -1) {
+            prmsg (1, "SocketUNIXResetListener: mkdir(%s) failed, errno = %d\n",
+	    UNIX_DIR, errno);
+	    (void) umask (oldUmask);
+	    return TRANS_RESET_FAILURE;
+        }
+#endif
+
+	close (ciptr->fd);
+	unlink (unsock->sun_path);
+
+	if ((ciptr->fd = socket (AF_UNIX, SOCK_STREAM, 0)) < 0)
+	{
+	    TRANS(FreeConnInfo) (ciptr);
+	    (void) umask (oldUmask);
+	    return TRANS_RESET_FAILURE;
+	}
+
+	if (bind (ciptr->fd, (struct sockaddr *) unsock, ciptr->addrlen) < 0)
+	{
+	    close (ciptr->fd);
+	    TRANS(FreeConnInfo) (ciptr);
+	    return TRANS_RESET_FAILURE;
+	}
+
+	if (listen (ciptr->fd, BACKLOG) < 0)
+	{
+	    close (ciptr->fd);
+	    TRANS(FreeConnInfo) (ciptr);
+	    (void) umask (oldUmask);
+	    return TRANS_RESET_FAILURE;
+	}
+
+	umask (oldUmask);
+
+	status = TRANS_RESET_NEW_FD;
+    }
+
+    return status;
+}
+
+#endif /* UNIXCONN */
+
+
+#ifdef TCPCONN
+
+static XtransConnInfo
+TRANS(SocketINETAccept) (XtransConnInfo ciptr, int *status)
+
+{
+    XtransConnInfo	newciptr;
+    struct sockaddr_in	sockname;
+    SOCKLEN_T		namelen = sizeof(sockname);
+
+    prmsg (2, "SocketINETAccept(%p,%d)\n", ciptr, ciptr->fd);
+
+    if ((newciptr = calloc (1, sizeof(struct _XtransConnInfo))) == NULL)
+    {
+	prmsg (1, "SocketINETAccept: malloc failed\n");
+	*status = TRANS_ACCEPT_BAD_MALLOC;
+	return NULL;
+    }
+
+    if ((newciptr->fd = accept (ciptr->fd,
+	(struct sockaddr *) &sockname, (void *)&namelen)) < 0)
+    {
+#ifdef WIN32
+	errno = WSAGetLastError();
+#endif
+	prmsg (1, "SocketINETAccept: accept() failed\n");
+	free (newciptr);
+	*status = TRANS_ACCEPT_FAILED;
+	return NULL;
+    }
+
+#ifdef TCP_NODELAY
+    {
+	/*
+	 * turn off TCP coalescence for INET sockets
+	 */
+
+	int tmp = 1;
+	setsockopt (newciptr->fd, IPPROTO_TCP, TCP_NODELAY,
+	    (char *) &tmp, sizeof (int));
+    }
+#endif
+
+    /*
+     * Get this address again because the transport may give a more
+     * specific address now that a connection is established.
+     */
+
+    if (TRANS(SocketINETGetAddr) (newciptr) < 0)
+    {
+	prmsg (1,
+	    "SocketINETAccept: ...SocketINETGetAddr() failed:\n");
+	close (newciptr->fd);
+	free (newciptr);
+	*status = TRANS_ACCEPT_MISC_ERROR;
+        return NULL;
+    }
+
+    if (TRANS(SocketINETGetPeerAddr) (newciptr) < 0)
+    {
+	prmsg (1,
+	  "SocketINETAccept: ...SocketINETGetPeerAddr() failed:\n");
+	close (newciptr->fd);
+	if (newciptr->addr) free (newciptr->addr);
+	free (newciptr);
+	*status = TRANS_ACCEPT_MISC_ERROR;
+        return NULL;
+    }
+
+    *status = 0;
+
+    return newciptr;
+}
+
+#endif /* TCPCONN */
+
+
+#ifdef UNIXCONN
+static XtransConnInfo
+TRANS(SocketUNIXAccept) (XtransConnInfo ciptr, int *status)
+
+{
+    XtransConnInfo	newciptr;
+    struct sockaddr_un	sockname;
+    SOCKLEN_T 		namelen = sizeof sockname;
+
+    prmsg (2, "SocketUNIXAccept(%p,%d)\n", ciptr, ciptr->fd);
+
+    if ((newciptr = calloc (1, sizeof(struct _XtransConnInfo))) == NULL)
+    {
+	prmsg (1, "SocketUNIXAccept: malloc() failed\n");
+	*status = TRANS_ACCEPT_BAD_MALLOC;
+	return NULL;
+    }
+
+    if ((newciptr->fd = accept (ciptr->fd,
+	(struct sockaddr *) &sockname, (void *)&namelen)) < 0)
+    {
+	prmsg (1, "SocketUNIXAccept: accept() failed\n");
+	free (newciptr);
+	*status = TRANS_ACCEPT_FAILED;
+	return NULL;
+    }
+
+	ciptr->addrlen = namelen;
+    /*
+     * Get the socket name and the peer name from the listener socket,
+     * since this is unix domain.
+     */
+
+    if ((newciptr->addr = malloc (ciptr->addrlen)) == NULL)
+    {
+        prmsg (1,
+        "SocketUNIXAccept: Can't allocate space for the addr\n");
+	close (newciptr->fd);
+	free (newciptr);
+	*status = TRANS_ACCEPT_BAD_MALLOC;
+        return NULL;
+    }
+
+    /*
+     * if the socket is abstract, we already modified the address to have a
+     * @ instead of the initial NUL, so no need to do that again here.
+     */
+
+    newciptr->addrlen = ciptr->addrlen;
+    memcpy (newciptr->addr, ciptr->addr, newciptr->addrlen);
+
+    if ((newciptr->peeraddr = malloc (ciptr->addrlen)) == NULL)
+    {
+        prmsg (1,
+	      "SocketUNIXAccept: Can't allocate space for the addr\n");
+	close (newciptr->fd);
+	if (newciptr->addr) free (newciptr->addr);
+	free (newciptr);
+	*status = TRANS_ACCEPT_BAD_MALLOC;
+        return NULL;
+    }
+
+    newciptr->peeraddrlen = ciptr->addrlen;
+    memcpy (newciptr->peeraddr, ciptr->addr, newciptr->addrlen);
+
+    newciptr->family = AF_UNIX;
+
+    *status = 0;
+
+    return newciptr;
+}
+
+#endif /* UNIXCONN */
+
+#endif /* TRANS_SERVER */
+
+
+#ifdef TRANS_CLIENT
+
+#ifdef TCPCONN
+
+#if defined(IPv6) && defined(AF_INET6)
+struct addrlist {
+    struct addrinfo *	addr;
+    struct addrinfo *	firstaddr;
+    char 		port[PORTBUFSIZE];
+    char 		host[MAXHOSTNAMELEN];
+};
+static struct addrlist  *addrlist = NULL;
+#endif
+
+
+static int
+TRANS(SocketINETConnect) (XtransConnInfo ciptr,
+                          const char *host, const char *port)
+
+{
+    struct sockaddr *	socketaddr = NULL;
+    int			socketaddrlen = 0;
+    int			res;
+#if defined(IPv6) && defined(AF_INET6)
+    struct addrinfo 	hints;
+    char		ntopbuf[INET6_ADDRSTRLEN];
+    int			resetonce = 0;
+#else
+    struct sockaddr_in	sockname;
+    struct hostent	*hostp;
+    struct servent	*servp;
+    unsigned long 	tmpaddr;
+#endif
+#ifdef XTHREADS_NEEDS_BYNAMEPARAMS
+    _Xgethostbynameparams hparams;
+    _Xgetservbynameparams sparams;
+#endif
+#ifdef X11_t
+    char	portbuf[PORTBUFSIZE];
+#endif
+
+    char 		hostnamebuf[256];		/* tmp space */
+
+    prmsg (2,"SocketINETConnect(%d,%s,%s)\n", ciptr->fd, host, port);
+
+    if (!host)
+    {
+	hostnamebuf[0] = '\0';
+	(void) TRANS(GetHostname) (hostnamebuf, sizeof hostnamebuf);
+	host = hostnamebuf;
+    }
+
+#ifdef X11_t
+    /*
+     * X has a well known port, that is transport dependent. It is easier
+     * to handle it here, than try and come up with a transport independent
+     * representation that can be passed in and resolved the usual way.
+     *
+     * The port that is passed here is really a string containing the idisplay
+     * from ConnectDisplay().
+     */
+
+    if (is_numeric (port))
+    {
+	long tmpport = X_TCP_PORT + strtol (port, (char**)NULL, 10);
+	snprintf (portbuf, sizeof(portbuf), "%lu", tmpport);
+	port = portbuf;
+    }
+#endif
+
+#if defined(IPv6) && defined(AF_INET6)
+    {
+	if (addrlist != NULL) {
+	    if (strcmp(host,addrlist->host) || strcmp(port,addrlist->port)) {
+		if (addrlist->firstaddr)
+		    freeaddrinfo(addrlist->firstaddr);
+		addrlist->firstaddr = NULL;
+	    }
+	} else {
+	    addrlist = malloc(sizeof(struct addrlist));
+	    addrlist->firstaddr = NULL;
+	}
+
+	if (addrlist->firstaddr == NULL) {
+	    strncpy(addrlist->port, port, sizeof(addrlist->port));
+	    addrlist->port[sizeof(addrlist->port) - 1] = '\0';
+	    strncpy(addrlist->host, host, sizeof(addrlist->host));
+	    addrlist->host[sizeof(addrlist->host) - 1] = '\0';
+
+	    bzero(&hints,sizeof(hints));
+	    hints.ai_socktype = Sockettrans2devtab[ciptr->index].devcotsname;
+
+	    res = getaddrinfo(host,port,&hints,&addrlist->firstaddr);
+	    if (res != 0) {
+		prmsg (1, "SocketINETConnect() can't get address "
+			"for %s:%s: %s\n", host, port, gai_strerror(res));
+		ESET(EINVAL);
+		return TRANS_CONNECT_FAILED;
+	    }
+	    for (res = 0, addrlist->addr = addrlist->firstaddr;
+		 addrlist->addr ; res++) {
+		addrlist->addr = addrlist->addr->ai_next;
+	    }
+	    prmsg(4,"Got New Address list with %d addresses\n", res);
+	    res = 0;
+	    addrlist->addr = NULL;
+	}
+
+	while (socketaddr == NULL) {
+	    if (addrlist->addr == NULL) {
+		if (resetonce) {
+		    /* Already checked entire list - no usable addresses */
+		    prmsg (1, "SocketINETConnect() no usable address "
+			   "for %s:%s\n", host, port);
+		    return TRANS_CONNECT_FAILED;
+		} else {
+		    /* Go back to beginning of list */
+		    resetonce = 1;
+		    addrlist->addr = addrlist->firstaddr;
+		}
+	    }
+
+	    socketaddr = addrlist->addr->ai_addr;
+	    socketaddrlen = addrlist->addr->ai_addrlen;
+
+	    if (addrlist->addr->ai_family == AF_INET) {
+		struct sockaddr_in *sin = (struct sockaddr_in *) socketaddr;
+
+		prmsg (4,"SocketINETConnect() sockname.sin_addr = %s\n",
+			inet_ntop(addrlist->addr->ai_family,&sin->sin_addr,
+			ntopbuf,sizeof(ntopbuf)));
+
+		prmsg (4,"SocketINETConnect() sockname.sin_port = %d\n",
+			ntohs(sin->sin_port));
+
+		if (Sockettrans2devtab[ciptr->index].family == AF_INET6) {
+		    if (strcmp(Sockettrans2devtab[ciptr->index].transname,
+				"tcp") == 0) {
+			XtransConnInfo newciptr;
+
+			/*
+			 * Our socket is an IPv6 socket, but the address is
+			 * IPv4.  Close it and get an IPv4 socket.  This is
+			 * needed for IPv4 connections to work on platforms
+			 * that don't allow IPv4 over IPv6 sockets.
+			 */
+			TRANS(SocketINETClose)(ciptr);
+			newciptr = TRANS(SocketOpenCOTSClientBase)(
+					"tcp", "tcp", host, port, ciptr->index);
+			if (newciptr)
+			    ciptr->fd = newciptr->fd;
+			if (!newciptr ||
+			    Sockettrans2devtab[newciptr->index].family !=
+				AF_INET) {
+			    socketaddr = NULL;
+			    prmsg (4,"SocketINETConnect() Cannot get IPv4 "
+					" socketfor IPv4 address\n");
+			}
+			if (newciptr)
+			    free(newciptr);
+		    } else {
+			socketaddr = NULL;
+			prmsg (4,"SocketINETConnect Skipping IPv4 address\n");
+		    }
+		}
+	    } else if (addrlist->addr->ai_family == AF_INET6) {
+		struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) socketaddr;
+
+		prmsg (4,"SocketINETConnect() sockname.sin6_addr = %s\n",
+			inet_ntop(addrlist->addr->ai_family,
+				  &sin6->sin6_addr,ntopbuf,sizeof(ntopbuf)));
+		prmsg (4,"SocketINETConnect() sockname.sin6_port = %d\n",
+			ntohs(sin6->sin6_port));
+
+		if (Sockettrans2devtab[ciptr->index].family == AF_INET) {
+		    if (strcmp(Sockettrans2devtab[ciptr->index].transname,
+				"tcp") == 0) {
+			XtransConnInfo newciptr;
+
+			/*
+			 * Close the IPv4 socket and try to open an IPv6 socket.
+			 */
+			TRANS(SocketINETClose)(ciptr);
+			newciptr = TRANS(SocketOpenCOTSClientBase)(
+					"tcp", "tcp", host, port, -1);
+			if (newciptr)
+			    ciptr->fd = newciptr->fd;
+			if (!newciptr ||
+			    Sockettrans2devtab[newciptr->index].family !=
+					AF_INET6) {
+			    socketaddr = NULL;
+			    prmsg (4,"SocketINETConnect() Cannot get IPv6 "
+				   "socket for IPv6 address\n");
+			}
+			if (newciptr)
+			    free(newciptr);
+		    }
+		    else
+		    {
+			socketaddr = NULL;
+			prmsg (4,"SocketINETConnect() Skipping IPv6 address\n");
+		    }
+		}
+	    } else {
+		socketaddr = NULL; /* Unsupported address type */
+	    }
+	    if (socketaddr == NULL) {
+		addrlist->addr = addrlist->addr->ai_next;
+	    }
+	}
+    }
+#else
+    {
+	/*
+	 * Build the socket name.
+	 */
+
+#ifdef BSD44SOCKETS
+	sockname.sin_len = sizeof (struct sockaddr_in);
+#endif
+	sockname.sin_family = AF_INET;
+
+	/*
+	 * fill in sin_addr
+	 */
+
+#ifndef INADDR_NONE
+#define INADDR_NONE ((in_addr_t) 0xffffffff)
+#endif
+
+	/* check for ww.xx.yy.zz host string */
+
+	if (isascii (host[0]) && isdigit (host[0])) {
+	    tmpaddr = inet_addr (host); /* returns network byte order */
+	} else {
+	    tmpaddr = INADDR_NONE;
+	}
+
+	prmsg (4,"SocketINETConnect() inet_addr(%s) = %lx\n", host, tmpaddr);
+
+	if (tmpaddr == INADDR_NONE) {
+	    if ((hostp = _XGethostbyname(host,hparams)) == NULL) {
+		prmsg (1,"SocketINETConnect: Can't get address for %s\n",
+			host);
+		ESET(EINVAL);
+		return TRANS_CONNECT_FAILED;
+	    }
+	    if (hostp->h_addrtype != AF_INET) {  /* is IP host? */
+		prmsg (1,"SocketINETConnect: not INET host%s\n", host);
+		ESET(EPROTOTYPE);
+		return TRANS_CONNECT_FAILED;
+	    }
+
+	    memcpy ((char *) &sockname.sin_addr, (char *) hostp->h_addr,
+		    sizeof (sockname.sin_addr));
+
+	} else {
+	    sockname.sin_addr.s_addr = tmpaddr;
+        }
+
+	/*
+	 * fill in sin_port
+	 */
+
+	/* Check for number in the port string */
+
+	if (!is_numeric (port)) {
+	    if ((servp = _XGetservbyname (port,"tcp",sparams)) == NULL) {
+		prmsg (1,"SocketINETConnect: can't get service for %s\n",
+			port);
+		return TRANS_CONNECT_FAILED;
+	    }
+	    sockname.sin_port = htons (servp->s_port);
+	} else {
+	    long tmpport = strtol (port, (char**)NULL, 10);
+	    if (tmpport < 1024 || tmpport > USHRT_MAX)
+		return TRANS_CONNECT_FAILED;
+	    sockname.sin_port = htons (((unsigned short) tmpport));
+	}
+
+	prmsg (4,"SocketINETConnect: sockname.sin_port = %d\n",
+		ntohs(sockname.sin_port));
+	socketaddr = (struct sockaddr *) &sockname;
+	socketaddrlen = sizeof(sockname);
+    }
+#endif
+
+    /*
+     * Turn on socket keepalive so the client process will eventually
+     * be notified with a SIGPIPE signal if the display server fails
+     * to respond to a periodic transmission of messages
+     * on the connected socket.
+     * This is useful to avoid hung application processes when the
+     * processes are not spawned from the xdm session and
+     * the display server terminates abnormally.
+     * (Someone turned off the power switch.)
+     */
+
+    {
+	int tmp = 1;
+	setsockopt (ciptr->fd, SOL_SOCKET, SO_KEEPALIVE,
+		(char *) &tmp, sizeof (int));
+    }
+
+    /*
+     * Do the connect()
+     */
+
+    if (connect (ciptr->fd, socketaddr, socketaddrlen ) < 0)
+    {
+#ifdef WIN32
+	int olderrno = WSAGetLastError();
+#else
+	int olderrno = errno;
+#endif
+
+	/*
+	 * If the error was ECONNREFUSED, the server may be overloaded
+	 * and we should try again.
+	 *
+	 * If the error was EWOULDBLOCK or EINPROGRESS then the socket
+	 * was non-blocking and we should poll using select
+	 *
+	 * If the error was EINTR, the connect was interrupted and we
+	 * should try again.
+	 *
+	 * If multiple addresses are found for a host then we should
+	 * try to connect again with a different address for a larger
+	 * number of errors that made us quit before, since those
+	 * could be caused by trying to use an IPv6 address to contact
+	 * a machine with an IPv4-only server or other reasons that
+	 * only affect one of a set of addresses.
+	 */
+
+	if (olderrno == ECONNREFUSED || olderrno == EINTR
+#if defined(IPv6) && defined(AF_INET6)
+	  || (((addrlist->addr->ai_next != NULL) ||
+	        (addrlist->addr != addrlist->firstaddr)) &&
+               (olderrno == ENETUNREACH || olderrno == EAFNOSUPPORT ||
+		 olderrno == EADDRNOTAVAIL || olderrno == ETIMEDOUT
+#if defined(EHOSTDOWN)
+		   || olderrno == EHOSTDOWN
+#endif
+	       ))
+#endif
+	    )
+	    res = TRANS_TRY_CONNECT_AGAIN;
+	else if (olderrno == EWOULDBLOCK || olderrno == EINPROGRESS)
+	    res = TRANS_IN_PROGRESS;
+	else
+	{
+	    prmsg (2,"SocketINETConnect: Can't connect: errno = %d\n",
+		   olderrno);
+
+	    res = TRANS_CONNECT_FAILED;
+	}
+    } else {
+	res = 0;
+
+
+	/*
+	 * Sync up the address fields of ciptr.
+	 */
+
+	if (TRANS(SocketINETGetAddr) (ciptr) < 0)
+	{
+	    prmsg (1,
+	     "SocketINETConnect: ...SocketINETGetAddr() failed:\n");
+	    res = TRANS_CONNECT_FAILED;
+	}
+
+	else if (TRANS(SocketINETGetPeerAddr) (ciptr) < 0)
+	{
+	    prmsg (1,
+	      "SocketINETConnect: ...SocketINETGetPeerAddr() failed:\n");
+	    res = TRANS_CONNECT_FAILED;
+	}
+    }
+
+#if defined(IPv6) && defined(AF_INET6)
+   if (res != 0) {
+	addrlist->addr = addrlist->addr->ai_next;
+   }
+#endif
+
+    return res;
+}
+
+#endif /* TCPCONN */
+
+
+
+#ifdef UNIXCONN
+
+/*
+ * Make sure 'host' is really local.
+ */
+
+static int
+UnixHostReallyLocal (const char *host)
+
+{
+    char hostnamebuf[256];
+
+    TRANS(GetHostname) (hostnamebuf, sizeof (hostnamebuf));
+
+    if (strcmp (hostnamebuf, host) == 0)
+    {
+	return (1);
+    } else {
+#if defined(IPv6) && defined(AF_INET6)
+	struct addrinfo *localhostaddr;
+	struct addrinfo *otherhostaddr;
+	struct addrinfo *i, *j;
+	int equiv = 0;
+
+	if (getaddrinfo(hostnamebuf, NULL, NULL, &localhostaddr) != 0)
+	    return 0;
+	if (getaddrinfo(host, NULL, NULL, &otherhostaddr) != 0) {
+	    freeaddrinfo(localhostaddr);
+	    return 0;
+	}
+
+	for (i = localhostaddr; i != NULL && equiv == 0; i = i->ai_next) {
+	    for (j = otherhostaddr; j != NULL && equiv == 0; j = j->ai_next) {
+		if (i->ai_family == j->ai_family) {
+		    if (i->ai_family == AF_INET) {
+			struct sockaddr_in *sinA
+			  = (struct sockaddr_in *) i->ai_addr;
+			struct sockaddr_in *sinB
+			  = (struct sockaddr_in *) j->ai_addr;
+			struct in_addr *A = &sinA->sin_addr;
+			struct in_addr *B = &sinB->sin_addr;
+
+			if (memcmp(A,B,sizeof(struct in_addr)) == 0) {
+			    equiv = 1;
+			}
+		    } else if (i->ai_family == AF_INET6) {
+			struct sockaddr_in6 *sinA
+			  = (struct sockaddr_in6 *) i->ai_addr;
+			struct sockaddr_in6 *sinB
+			  = (struct sockaddr_in6 *) j->ai_addr;
+			struct in6_addr *A = &sinA->sin6_addr;
+			struct in6_addr *B = &sinB->sin6_addr;
+
+			if (memcmp(A,B,sizeof(struct in6_addr)) == 0) {
+			    equiv = 1;
+			}
+		    }
+		}
+	    }
+	}
+
+	freeaddrinfo(localhostaddr);
+	freeaddrinfo(otherhostaddr);
+	return equiv;
+#else
+	/*
+	 * A host may have more than one network address.  If any of the
+	 * network addresses of 'host' (specified to the connect call)
+	 * match any of the network addresses of 'hostname' (determined
+	 * by TRANS(GetHostname)), then the two hostnames are equivalent,
+	 * and we know that 'host' is really a local host.
+	 */
+	char specified_local_addr_list[10][4];
+	int scount, equiv, i, j;
+#ifdef XTHREADS_NEEDS_BYNAMEPARAMS
+	_Xgethostbynameparams hparams;
+#endif
+	struct hostent *hostp;
+
+	if ((hostp = _XGethostbyname (host,hparams)) == NULL)
+	    return (0);
+
+	scount = 0;
+	while (hostp->h_addr_list[scount] && scount <= 8)
+	{
+	    /*
+	     * The 2nd call to gethostname() overrides the data
+	     * from the 1st call, so we must save the address list.
+	     */
+
+	    specified_local_addr_list[scount][0] =
+				hostp->h_addr_list[scount][0];
+	    specified_local_addr_list[scount][1] =
+				hostp->h_addr_list[scount][1];
+	    specified_local_addr_list[scount][2] =
+				hostp->h_addr_list[scount][2];
+	    specified_local_addr_list[scount][3] =
+				hostp->h_addr_list[scount][3];
+	    scount++;
+	}
+	if ((hostp = _XGethostbyname (hostnamebuf,hparams)) == NULL)
+	    return (0);
+
+	equiv = 0;
+	i = 0;
+
+	while (i < scount && !equiv)
+	{
+	    j = 0;
+
+	    while (hostp->h_addr_list[j])
+	    {
+		if ((specified_local_addr_list[i][0] ==
+					hostp->h_addr_list[j][0]) &&
+		    (specified_local_addr_list[i][1] ==
+					hostp->h_addr_list[j][1]) &&
+		    (specified_local_addr_list[i][2] ==
+					hostp->h_addr_list[j][2]) &&
+		    (specified_local_addr_list[i][3] ==
+					hostp->h_addr_list[j][3]))
+		{
+		    /* They're equal, so we're done */
+
+		    equiv = 1;
+		    break;
+		}
+
+		j++;
+	    }
+
+	    i++;
+	}
+	return (equiv);
+#endif
+    }
+}
+
+static int
+TRANS(SocketUNIXConnect) (XtransConnInfo ciptr,
+                          const char *host, const char *port)
+
+{
+    struct sockaddr_un	sockname;
+    SOCKLEN_T		namelen;
+
+
+    int abstract = 0;
+#ifdef HAVE_ABSTRACT_SOCKETS
+    abstract = ciptr->transptr->flags & TRANS_ABSTRACT;
+#endif
+
+    prmsg (2,"SocketUNIXConnect(%d,%s,%s)\n", ciptr->fd, host, port);
+
+    /*
+     * Make sure 'host' is really local.  If not, we return failure.
+     * The reason we make this check is because a process may advertise
+     * a "local" network ID for which it can accept connections, but if
+     * a process on a remote machine tries to connect to this network ID,
+     * we know for sure it will fail.
+     */
+
+    if (host && *host && host[0]!='/' && strcmp (host, "unix") != 0 && !UnixHostReallyLocal (host))
+    {
+	prmsg (1,
+	   "SocketUNIXConnect: Cannot connect to non-local host %s\n",
+	       host);
+	return TRANS_CONNECT_FAILED;
+    }
+
+
+    /*
+     * Check the port.
+     */
+
+    if (!port || !*port)
+    {
+	prmsg (1,"SocketUNIXConnect: Missing port specification\n");
+	return TRANS_CONNECT_FAILED;
+    }
+
+    /*
+     * Build the socket name.
+     */
+
+    sockname.sun_family = AF_UNIX;
+
+    if (set_sun_path(port, UNIX_PATH, sockname.sun_path, abstract) != 0) {
+	prmsg (1, "SocketUNIXConnect: path too long\n");
+	return TRANS_CONNECT_FAILED;
+    }
+
+#if (defined(BSD44SOCKETS) || defined(__UNIXWARE__))
+    sockname.sun_len = strlen (sockname.sun_path);
+#endif
+
+#if defined(BSD44SOCKETS) || defined(SUN_LEN)
+    namelen = SUN_LEN (&sockname);
+#else
+    namelen = strlen (sockname.sun_path) + offsetof(struct sockaddr_un, sun_path);
+#endif
+
+
+
+    /*
+     * Adjust the socket path if using abstract sockets.
+     * Done here because otherwise all the strlen() calls above would fail.
+     */
+
+    if (abstract) {
+	sockname.sun_path[0] = '\0';
+    }
+
+    /*
+     * Do the connect()
+     */
+
+    if (connect (ciptr->fd, (struct sockaddr *) &sockname, namelen) < 0)
+    {
+	int olderrno = errno;
+	int connected = 0;
+
+	if (!connected)
+	{
+	    errno = olderrno;
+
+	    /*
+	     * If the error was ENOENT, the server may be starting up; we used
+	     * to suggest to try again in this case with
+	     * TRANS_TRY_CONNECT_AGAIN, but this introduced problems for
+	     * processes still referencing stale sockets in their environment.
+	     * Hence, we now return a hard error, TRANS_CONNECT_FAILED, and it
+	     * is suggested that higher level stacks handle retries on their
+	     * level when they face a slow starting server.
+	     *
+	     * If the error was EWOULDBLOCK or EINPROGRESS then the socket
+	     * was non-blocking and we should poll using select
+	     *
+	     * If the error was EINTR, the connect was interrupted and we
+	     * should try again.
+	     */
+
+	    if (olderrno == EWOULDBLOCK || olderrno == EINPROGRESS)
+		return TRANS_IN_PROGRESS;
+	    else if (olderrno == EINTR)
+		return TRANS_TRY_CONNECT_AGAIN;
+	    else if (olderrno == ENOENT || olderrno == ECONNREFUSED) {
+		/* If opening as abstract socket failed, try again normally */
+		if (abstract) {
+		    ciptr->transptr->flags &= ~(TRANS_ABSTRACT);
+		    return TRANS_TRY_CONNECT_AGAIN;
+		} else {
+		    return TRANS_CONNECT_FAILED;
+		}
+	    } else {
+		prmsg (2,"SocketUNIXConnect: Can't connect: errno = %d\n",
+		       EGET());
+
+		return TRANS_CONNECT_FAILED;
+	    }
+	}
+    }
+
+    /*
+     * Get the socket name and the peer name from the connect socket,
+     * since this is unix domain.
+     */
+
+    if ((ciptr->addr = malloc(namelen)) == NULL ||
+       (ciptr->peeraddr = malloc(namelen)) == NULL)
+    {
+        prmsg (1,
+	"SocketUNIXCreateListener: Can't allocate space for the addr\n");
+        return TRANS_CONNECT_FAILED;
+    }
+
+    if (abstract)
+	sockname.sun_path[0] = '@';
+
+    ciptr->family = AF_UNIX;
+    ciptr->addrlen = namelen;
+    ciptr->peeraddrlen = namelen;
+    memcpy (ciptr->addr, &sockname, ciptr->addrlen);
+    memcpy (ciptr->peeraddr, &sockname, ciptr->peeraddrlen);
+
+    return 0;
+}
+
+#endif /* UNIXCONN */
+
+#endif /* TRANS_CLIENT */
+
+
+static int
+TRANS(SocketBytesReadable) (XtransConnInfo ciptr, BytesReadable_t *pend)
+
+{
+    prmsg (2,"SocketBytesReadable(%p,%d,%p)\n",
+	ciptr, ciptr->fd, pend);
+#ifdef WIN32
+    {
+	int ret = ioctlsocket ((SOCKET) ciptr->fd, FIONREAD, (u_long *) pend);
+	if (ret == SOCKET_ERROR) errno = WSAGetLastError();
+	return ret;
+    }
+#else
+    return ioctl (ciptr->fd, FIONREAD, (char *) pend);
+#endif /* WIN32 */
+}
+
+#if XTRANS_SEND_FDS
+
+static void
+appendFd(struct _XtransConnFd **prev, int fd, int do_close)
+{
+    struct _XtransConnFd *cf, *new;
+
+    new = malloc (sizeof (struct _XtransConnFd));
+    if (!new) {
+        /* XXX mark connection as broken */
+        close(fd);
+        return;
+    }
+    new->next = 0;
+    new->fd = fd;
+    new->do_close = do_close;
+    /* search to end of list */
+    for (; (cf = *prev); prev = &(cf->next));
+    *prev = new;
+}
+
+static int
+removeFd(struct _XtransConnFd **prev)
+{
+    struct _XtransConnFd *cf;
+    int fd;
+
+    if ((cf = *prev)) {
+        *prev = cf->next;
+        fd = cf->fd;
+        free(cf);
+    } else
+        fd = -1;
+    return fd;
+}
+
+static void
+discardFd(struct _XtransConnFd **prev, struct _XtransConnFd *upto, int do_close)
+{
+    struct _XtransConnFd *cf, *next;
+
+    for (cf = *prev; cf != upto; cf = next) {
+        next = cf->next;
+        if (do_close || cf->do_close)
+            close(cf->fd);
+        free(cf);
+    }
+    *prev = upto;
+}
+
+static void
+cleanupFds(XtransConnInfo ciptr)
+{
+    /* Clean up the send list but don't close the fds */
+    discardFd(&ciptr->send_fds, NULL, 0);
+    /* Clean up the recv list and *do* close the fds */
+    discardFd(&ciptr->recv_fds, NULL, 1);
+}
+
+static int
+nFd(struct _XtransConnFd **prev)
+{
+    struct _XtransConnFd *cf;
+    int n = 0;
+
+    for (cf = *prev; cf; cf = cf->next)
+        n++;
+    return n;
+}
+
+static int
+TRANS(SocketRecvFd) (XtransConnInfo ciptr)
+{
+    prmsg (2, "SocketRecvFd(%d)\n", ciptr->fd);
+    return removeFd(&ciptr->recv_fds);
+}
+
+static int
+TRANS(SocketSendFd) (XtransConnInfo ciptr, int fd, int do_close)
+{
+    appendFd(&ciptr->send_fds, fd, do_close);
+    return 0;
+}
+
+static int
+TRANS(SocketRecvFdInvalid)(XtransConnInfo ciptr)
+{
+    errno = EINVAL;
+    return -1;
+}
+
+static int
+TRANS(SocketSendFdInvalid)(XtransConnInfo ciptr, int fd, int do_close)
+{
+    errno = EINVAL;
+    return -1;
+}
+
+#define MAX_FDS		128
+
+union fd_pass {
+	struct cmsghdr	cmsghdr;
+	char		buf[CMSG_SPACE(MAX_FDS * sizeof(int))];
+};
+
+#endif /* XTRANS_SEND_FDS */
+
+static int
+TRANS(SocketRead) (XtransConnInfo ciptr, char *buf, int size)
+
+{
+    prmsg (2,"SocketRead(%d,%p,%d)\n", ciptr->fd, buf, size);
+
+#if defined(WIN32)
+    {
+	int ret = recv ((SOCKET)ciptr->fd, buf, size, 0);
+#ifdef WIN32
+	if (ret == SOCKET_ERROR) errno = WSAGetLastError();
+#endif
+	return ret;
+    }
+#else
+#if XTRANS_SEND_FDS
+    {
+        struct iovec    iov = {
+            .iov_base = buf,
+            .iov_len = size
+        };
+        union fd_pass   cmsgbuf;
+        struct msghdr   msg = {
+            .msg_name = NULL,
+            .msg_namelen = 0,
+            .msg_iov = &iov,
+            .msg_iovlen = 1,
+            .msg_control = cmsgbuf.buf,
+            .msg_controllen = CMSG_LEN(MAX_FDS * sizeof(int))
+        };
+
+        size = recvmsg(ciptr->fd, &msg, 0);
+        if (size >= 0) {
+            struct cmsghdr *hdr;
+
+            for (hdr = CMSG_FIRSTHDR(&msg); hdr; hdr = CMSG_NXTHDR(&msg, hdr)) {
+                if (hdr->cmsg_level == SOL_SOCKET && hdr->cmsg_type == SCM_RIGHTS) {
+                    int nfd = (hdr->cmsg_len - CMSG_LEN(0)) / sizeof (int);
+                    int i;
+                    int *fd = (int *) CMSG_DATA(hdr);
+
+                    for (i = 0; i < nfd; i++)
+                        appendFd(&ciptr->recv_fds, fd[i], 0);
+                }
+            }
+        }
+        return size;
+    }
+#else
+    return read(ciptr->fd, buf, size);
+#endif /* XTRANS_SEND_FDS */
+#endif /* WIN32 */
+}
+
+static int
+TRANS(SocketReadv) (XtransConnInfo ciptr, struct iovec *buf, int size)
+
+{
+    prmsg (2,"SocketReadv(%d,%p,%d)\n", ciptr->fd, buf, size);
+
+#if XTRANS_SEND_FDS
+    {
+        union fd_pass   cmsgbuf;
+        struct msghdr   msg = {
+            .msg_name = NULL,
+            .msg_namelen = 0,
+            .msg_iov = buf,
+            .msg_iovlen = size,
+            .msg_control = cmsgbuf.buf,
+            .msg_controllen = CMSG_LEN(MAX_FDS * sizeof(int))
+        };
+
+        size = recvmsg(ciptr->fd, &msg, 0);
+        if (size >= 0) {
+            struct cmsghdr *hdr;
+
+            for (hdr = CMSG_FIRSTHDR(&msg); hdr; hdr = CMSG_NXTHDR(&msg, hdr)) {
+                if (hdr->cmsg_level == SOL_SOCKET && hdr->cmsg_type == SCM_RIGHTS) {
+                    int nfd = (hdr->cmsg_len - CMSG_LEN(0)) / sizeof (int);
+                    int i;
+                    int *fd = (int *) CMSG_DATA(hdr);
+
+                    for (i = 0; i < nfd; i++)
+                        appendFd(&ciptr->recv_fds, fd[i], 0);
+                }
+            }
+        }
+        return size;
+    }
+#else
+    return READV (ciptr, buf, size);
+#endif
+}
+
+
+static int
+TRANS(SocketWritev) (XtransConnInfo ciptr, struct iovec *buf, int size)
+
+{
+    prmsg (2,"SocketWritev(%d,%p,%d)\n", ciptr->fd, buf, size);
+
+#if XTRANS_SEND_FDS
+    if (ciptr->send_fds)
+    {
+        union fd_pass           cmsgbuf;
+        int                     nfd = nFd(&ciptr->send_fds);
+        struct _XtransConnFd    *cf = ciptr->send_fds;
+        struct msghdr           msg = {
+            .msg_name = NULL,
+            .msg_namelen = 0,
+            .msg_iov = buf,
+            .msg_iovlen = size,
+            .msg_control = cmsgbuf.buf,
+            .msg_controllen = CMSG_LEN(nfd * sizeof(int))
+        };
+        struct cmsghdr          *hdr = CMSG_FIRSTHDR(&msg);
+        int                     i;
+        int                     *fds;
+
+        hdr->cmsg_len = msg.msg_controllen;
+        hdr->cmsg_level = SOL_SOCKET;
+        hdr->cmsg_type = SCM_RIGHTS;
+
+        fds = (int *) CMSG_DATA(hdr);
+        /* Set up fds */
+        for (i = 0; i < nfd; i++) {
+            fds[i] = cf->fd;
+            cf = cf->next;
+        }
+
+        i = sendmsg(ciptr->fd, &msg, 0);
+        if (i > 0)
+            discardFd(&ciptr->send_fds, cf, 0);
+        return i;
+    }
+#endif
+    return WRITEV (ciptr, buf, size);
+}
+
+
+static int
+TRANS(SocketWrite) (XtransConnInfo ciptr, char *buf, int size)
+
+{
+    prmsg (2,"SocketWrite(%d,%p,%d)\n", ciptr->fd, buf, size);
+
+#if defined(WIN32)
+    {
+	int ret = send ((SOCKET)ciptr->fd, buf, size, 0);
+#ifdef WIN32
+	if (ret == SOCKET_ERROR) errno = WSAGetLastError();
+#endif
+	return ret;
+    }
+#else
+#if XTRANS_SEND_FDS
+    if (ciptr->send_fds)
+    {
+        struct iovec            iov;
+
+        iov.iov_base = buf;
+        iov.iov_len = size;
+        return TRANS(SocketWritev)(ciptr, &iov, 1);
+    }
+#endif /* XTRANS_SEND_FDS */
+    return write (ciptr->fd, buf, size);
+#endif /* WIN32 */
+}
+
+static int
+TRANS(SocketDisconnect) (XtransConnInfo ciptr)
+
+{
+    prmsg (2,"SocketDisconnect(%p,%d)\n", ciptr, ciptr->fd);
+
+#ifdef WIN32
+    {
+	int ret = shutdown (ciptr->fd, 2);
+	if (ret == SOCKET_ERROR) errno = WSAGetLastError();
+	return ret;
+    }
+#else
+    return shutdown (ciptr->fd, 2); /* disallow further sends and receives */
+#endif
+}
+
+
+#ifdef TCPCONN
+static int
+TRANS(SocketINETClose) (XtransConnInfo ciptr)
+
+{
+    prmsg (2,"SocketINETClose(%p,%d)\n", ciptr, ciptr->fd);
+
+#ifdef WIN32
+    {
+	int ret = close (ciptr->fd);
+	if (ret == SOCKET_ERROR) errno = WSAGetLastError();
+	return ret;
+    }
+#else
+    return close (ciptr->fd);
+#endif
+}
+
+#endif /* TCPCONN */
+
+
+#ifdef UNIXCONN
+static int
+TRANS(SocketUNIXClose) (XtransConnInfo ciptr)
+{
+    /*
+     * If this is the server side, then once the socket is closed,
+     * it must be unlinked to completely close it
+     */
+
+    struct sockaddr_un	*sockname = (struct sockaddr_un *) ciptr->addr;
+    int ret;
+
+    prmsg (2,"SocketUNIXClose(%p,%d)\n", ciptr, ciptr->fd);
+
+#if XTRANS_SEND_FDS
+    cleanupFds(ciptr);
+#endif
+    ret = close(ciptr->fd);
+
+    if (ciptr->flags
+       && sockname
+       && sockname->sun_family == AF_UNIX
+       && sockname->sun_path[0])
+    {
+	if (!(ciptr->flags & TRANS_NOUNLINK
+	    || ciptr->transptr->flags & TRANS_ABSTRACT))
+		unlink (sockname->sun_path);
+    }
+
+    return ret;
+}
+
+static int
+TRANS(SocketUNIXCloseForCloning) (XtransConnInfo ciptr)
+
+{
+    /*
+     * Don't unlink path.
+     */
+
+    int ret;
+
+    prmsg (2,"SocketUNIXCloseForCloning(%p,%d)\n",
+	ciptr, ciptr->fd);
+
+#if XTRANS_SEND_FDS
+    cleanupFds(ciptr);
+#endif
+    ret = close(ciptr->fd);
+
+    return ret;
+}
+
+#endif /* UNIXCONN */
+
+
+#ifdef TCPCONN
+# ifdef TRANS_SERVER
+static const char* tcp_nolisten[] = {
+	"inet",
+#if defined(IPv6) && defined(AF_INET6)
+	"inet6",
+#endif
+	NULL
+};
+# endif
+
+Xtransport	TRANS(SocketTCPFuncs) = {
+	/* Socket Interface */
+	"tcp",
+        TRANS_ALIAS,
+#ifdef TRANS_CLIENT
+	TRANS(SocketOpenCOTSClient),
+#endif /* TRANS_CLIENT */
+#ifdef TRANS_SERVER
+	tcp_nolisten,
+	TRANS(SocketOpenCOTSServer),
+#endif /* TRANS_SERVER */
+#ifdef TRANS_REOPEN
+	TRANS(SocketReopenCOTSServer),
+#endif
+	TRANS(SocketSetOption),
+#ifdef TRANS_SERVER
+	TRANS(SocketINETCreateListener),
+	NULL,		       			/* ResetListener */
+	TRANS(SocketINETAccept),
+#endif /* TRANS_SERVER */
+#ifdef TRANS_CLIENT
+	TRANS(SocketINETConnect),
+#endif /* TRANS_CLIENT */
+	TRANS(SocketBytesReadable),
+	TRANS(SocketRead),
+	TRANS(SocketWrite),
+	TRANS(SocketReadv),
+	TRANS(SocketWritev),
+#if XTRANS_SEND_FDS
+        TRANS(SocketSendFdInvalid),
+        TRANS(SocketRecvFdInvalid),
+#endif
+	TRANS(SocketDisconnect),
+	TRANS(SocketINETClose),
+	TRANS(SocketINETClose),
+	};
+
+Xtransport	TRANS(SocketINETFuncs) = {
+	/* Socket Interface */
+	"inet",
+	0,
+#ifdef TRANS_CLIENT
+	TRANS(SocketOpenCOTSClient),
+#endif /* TRANS_CLIENT */
+#ifdef TRANS_SERVER
+	NULL,
+	TRANS(SocketOpenCOTSServer),
+#endif /* TRANS_SERVER */
+#ifdef TRANS_REOPEN
+	TRANS(SocketReopenCOTSServer),
+#endif
+	TRANS(SocketSetOption),
+#ifdef TRANS_SERVER
+	TRANS(SocketINETCreateListener),
+	NULL,		       			/* ResetListener */
+	TRANS(SocketINETAccept),
+#endif /* TRANS_SERVER */
+#ifdef TRANS_CLIENT
+	TRANS(SocketINETConnect),
+#endif /* TRANS_CLIENT */
+	TRANS(SocketBytesReadable),
+	TRANS(SocketRead),
+	TRANS(SocketWrite),
+	TRANS(SocketReadv),
+	TRANS(SocketWritev),
+#if XTRANS_SEND_FDS
+        TRANS(SocketSendFdInvalid),
+        TRANS(SocketRecvFdInvalid),
+#endif
+	TRANS(SocketDisconnect),
+	TRANS(SocketINETClose),
+	TRANS(SocketINETClose),
+	};
+
+#if defined(IPv6) && defined(AF_INET6)
+Xtransport     TRANS(SocketINET6Funcs) = {
+	/* Socket Interface */
+	"inet6",
+	0,
+#ifdef TRANS_CLIENT
+	TRANS(SocketOpenCOTSClient),
+#endif /* TRANS_CLIENT */
+#ifdef TRANS_SERVER
+	NULL,
+	TRANS(SocketOpenCOTSServer),
+#endif /* TRANS_SERVER */
+#ifdef TRANS_REOPEN
+	TRANS(SocketReopenCOTSServer),
+#endif
+	TRANS(SocketSetOption),
+#ifdef TRANS_SERVER
+	TRANS(SocketINETCreateListener),
+	NULL,					/* ResetListener */
+	TRANS(SocketINETAccept),
+#endif /* TRANS_SERVER */
+#ifdef TRANS_CLIENT
+	TRANS(SocketINETConnect),
+#endif /* TRANS_CLIENT */
+	TRANS(SocketBytesReadable),
+	TRANS(SocketRead),
+	TRANS(SocketWrite),
+	TRANS(SocketReadv),
+	TRANS(SocketWritev),
+#if XTRANS_SEND_FDS
+        TRANS(SocketSendFdInvalid),
+        TRANS(SocketRecvFdInvalid),
+#endif
+	TRANS(SocketDisconnect),
+	TRANS(SocketINETClose),
+	TRANS(SocketINETClose),
+	};
+#endif /* IPv6 */
+#endif /* TCPCONN */
+
+#ifdef UNIXCONN
+#if !defined(LOCALCONN)
+Xtransport	TRANS(SocketLocalFuncs) = {
+	/* Socket Interface */
+	"local",
+#ifdef HAVE_ABSTRACT_SOCKETS
+	TRANS_ABSTRACT,
+#else
+	0,
+#endif
+#ifdef TRANS_CLIENT
+	TRANS(SocketOpenCOTSClient),
+#endif /* TRANS_CLIENT */
+#ifdef TRANS_SERVER
+	NULL,
+	TRANS(SocketOpenCOTSServer),
+#endif /* TRANS_SERVER */
+#ifdef TRANS_REOPEN
+	TRANS(SocketReopenCOTSServer),
+#endif
+	TRANS(SocketSetOption),
+#ifdef TRANS_SERVER
+	TRANS(SocketUNIXCreateListener),
+	TRANS(SocketUNIXResetListener),
+	TRANS(SocketUNIXAccept),
+#endif /* TRANS_SERVER */
+#ifdef TRANS_CLIENT
+	TRANS(SocketUNIXConnect),
+#endif /* TRANS_CLIENT */
+	TRANS(SocketBytesReadable),
+	TRANS(SocketRead),
+	TRANS(SocketWrite),
+	TRANS(SocketReadv),
+	TRANS(SocketWritev),
+#if XTRANS_SEND_FDS
+        TRANS(SocketSendFd),
+        TRANS(SocketRecvFd),
+#endif
+	TRANS(SocketDisconnect),
+	TRANS(SocketUNIXClose),
+	TRANS(SocketUNIXCloseForCloning),
+	};
+#endif /* !LOCALCONN */
+# ifdef TRANS_SERVER
+#  if !defined(LOCALCONN)
+static const char* unix_nolisten[] = { "local" , NULL };
+#  endif
+# endif
+
+Xtransport	TRANS(SocketUNIXFuncs) = {
+	/* Socket Interface */
+	"unix",
+#if !defined(LOCALCONN) && !defined(HAVE_ABSTRACT_SOCKETS)
+        TRANS_ALIAS,
+#else
+	0,
+#endif
+#ifdef TRANS_CLIENT
+	TRANS(SocketOpenCOTSClient),
+#endif /* TRANS_CLIENT */
+#ifdef TRANS_SERVER
+#if !defined(LOCALCONN)
+	unix_nolisten,
+#else
+	NULL,
+#endif
+	TRANS(SocketOpenCOTSServer),
+#endif /* TRANS_SERVER */
+#ifdef TRANS_REOPEN
+	TRANS(SocketReopenCOTSServer),
+#endif
+	TRANS(SocketSetOption),
+#ifdef TRANS_SERVER
+	TRANS(SocketUNIXCreateListener),
+	TRANS(SocketUNIXResetListener),
+	TRANS(SocketUNIXAccept),
+#endif /* TRANS_SERVER */
+#ifdef TRANS_CLIENT
+	TRANS(SocketUNIXConnect),
+#endif /* TRANS_CLIENT */
+	TRANS(SocketBytesReadable),
+	TRANS(SocketRead),
+	TRANS(SocketWrite),
+	TRANS(SocketReadv),
+	TRANS(SocketWritev),
+#if XTRANS_SEND_FDS
+        TRANS(SocketSendFd),
+        TRANS(SocketRecvFd),
+#endif
+	TRANS(SocketDisconnect),
+	TRANS(SocketUNIXClose),
+	TRANS(SocketUNIXCloseForCloning),
+	};
+
+#endif /* UNIXCONN */
diff -Naur old/X11/Xtrans/Xtransutil.c new/X11/Xtrans/Xtransutil.c
--- old/X11/Xtrans/Xtransutil.c	1970-01-01 08:00:00.000000000 +0800
+++ new/X11/Xtrans/Xtransutil.c	2024-03-05 19:36:25.213040800 +0800
@@ -0,0 +1,637 @@
+/*
+
+Copyright 1993, 1994, 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 1993, 1994 NCR Corporation - Dayton, Ohio, USA
+ *
+ * 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 NCR not be used in advertising
+ * or publicity pertaining to distribution of the software without specific,
+ * written prior permission.  NCR makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ *
+ * NCRS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
+ * NO EVENT SHALL NCR 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.
+ */
+
+/*
+ * These are some utility functions created for convenience or to provide
+ * an interface that is similar to an existing interface. These are built
+ * only using the Transport Independant API, and have no knowledge of
+ * the internal implementation.
+ */
+
+#ifdef XTHREADS
+#include <X11/Xthreads.h>
+#endif
+#ifdef WIN32
+#include <X11/Xlibint.h>
+#include <X11/Xwinsock.h>
+#endif
+
+#ifdef X11_t
+
+/*
+ * These values come from X.h and Xauth.h, and MUST match them. Some
+ * of these values are also defined by the ChangeHost protocol message.
+ */
+
+#define FamilyInternet		0	/* IPv4 */
+#define FamilyDECnet		1
+#define FamilyChaos		2
+#define FamilyInternet6		6
+#define FamilyAmoeba		33
+#define FamilyLocalHost		252
+#define FamilyKrb5Principal	253
+#define FamilyNetname		254
+#define FamilyLocal		256
+#define FamilyWild		65535
+
+/*
+ * TRANS(ConvertAddress) converts a sockaddr based address to an
+ * X authorization based address. Some of this is defined as part of
+ * the ChangeHost protocol. The rest is just done in a consistent manner.
+ */
+
+int
+TRANS(ConvertAddress)(int *familyp, int *addrlenp, Xtransaddr **addrp)
+
+{
+
+    prmsg(2,"ConvertAddress(%d,%d,%p)\n",*familyp,*addrlenp,*addrp);
+
+    switch( *familyp )
+    {
+#if defined(TCPCONN)
+    case AF_INET:
+    {
+	/*
+	 * Check for the BSD hack localhost address 127.0.0.1.
+	 * In this case, we are really FamilyLocal.
+	 */
+
+	struct sockaddr_in saddr;
+	int len = sizeof(saddr.sin_addr.s_addr);
+	char *cp = (char *) &saddr.sin_addr.s_addr;
+
+	memcpy (&saddr, *addrp, sizeof (struct sockaddr_in));
+
+	if ((len == 4) && (cp[0] == 127) && (cp[1] == 0) &&
+	    (cp[2] == 0) && (cp[3] == 1))
+	{
+	    *familyp=FamilyLocal;
+	}
+	else
+	{
+	    *familyp=FamilyInternet;
+	    *addrlenp=len;
+	    memcpy(*addrp,&saddr.sin_addr,len);
+	}
+	break;
+    }
+
+#if defined(IPv6) && defined(AF_INET6)
+    case AF_INET6:
+    {
+	struct sockaddr_in6 saddr6;
+
+	memcpy (&saddr6, *addrp, sizeof (struct sockaddr_in6));
+
+	if (IN6_IS_ADDR_LOOPBACK(&saddr6.sin6_addr))
+	{
+	    *familyp=FamilyLocal;
+	}
+	else if (IN6_IS_ADDR_V4MAPPED(&(saddr6.sin6_addr))) {
+	    char *cp = (char *) &saddr6.sin6_addr.s6_addr[12];
+
+	    if ((cp[0] == 127) && (cp[1] == 0) &&
+	      (cp[2] == 0) && (cp[3] == 1))
+	    {
+		*familyp=FamilyLocal;
+	    }
+	    else
+	    {
+		*familyp=FamilyInternet;
+		*addrlenp = sizeof (struct in_addr);
+		memcpy(*addrp,cp,*addrlenp);
+	    }
+	}
+	else
+	{
+	    *familyp=FamilyInternet6;
+	    *addrlenp=sizeof(saddr6.sin6_addr);
+	    memcpy(*addrp,&saddr6.sin6_addr,sizeof(saddr6.sin6_addr));
+	}
+	break;
+    }
+#endif /* IPv6 */
+#endif /* defined(TCPCONN) */
+
+
+#if defined(UNIXCONN) || defined(LOCALCONN)
+    case AF_UNIX:
+    {
+	*familyp=FamilyLocal;
+	break;
+    }
+#endif /* defined(UNIXCONN) || defined(LOCALCONN) */
+
+#if (defined(__SCO__) || defined(__UNIXWARE__)) && defined(LOCALCONN)
+    case 0:
+    {
+	*familyp=FamilyLocal;
+	break;
+    }
+#endif
+
+    default:
+	prmsg(1,"ConvertAddress: Unknown family type %d\n",
+	      *familyp);
+	return -1;
+    }
+
+
+    if (*familyp == FamilyLocal)
+    {
+	/*
+	 * In the case of a local connection, we need to get the
+	 * host name for authentication.
+	 */
+
+	char hostnamebuf[256];
+	int len = TRANS(GetHostname) (hostnamebuf, sizeof hostnamebuf);
+
+	if (len > 0) {
+	    if (*addrp && *addrlenp < (len + 1))
+	    {
+		free (*addrp);
+		*addrp = NULL;
+	    }
+	    if (!*addrp)
+		*addrp = malloc (len + 1);
+	    if (*addrp) {
+		strcpy ((char *) *addrp, hostnamebuf);
+		*addrlenp = len;
+	    } else {
+		*addrlenp = 0;
+	    }
+	}
+	else
+	{
+	    if (*addrp)
+		free (*addrp);
+	    *addrp = NULL;
+	    *addrlenp = 0;
+	}
+    }
+
+    return 0;
+}
+
+#endif /* X11_t */
+
+#ifdef ICE_t
+
+/* Needed for _XGethostbyaddr usage in TRANS(GetPeerNetworkId) */
+# if defined(TCPCONN) || defined(UNIXCONN)
+#  define X_INCLUDE_NETDB_H
+#  define XOS_USE_NO_LOCKING
+#  include <X11/Xos_r.h>
+# endif
+
+#include <signal.h>
+
+char *
+TRANS(GetMyNetworkId) (XtransConnInfo ciptr)
+
+{
+    int		family = ciptr->family;
+    char 	*addr = ciptr->addr;
+    char	hostnamebuf[256];
+    char 	*networkId = NULL;
+    const char	*transName = ciptr->transptr->TransName;
+
+    if (gethostname (hostnamebuf, sizeof (hostnamebuf)) < 0)
+    {
+	return (NULL);
+    }
+
+    switch (family)
+    {
+#if defined(UNIXCONN) || defined(LOCALCONN)
+    case AF_UNIX:
+    {
+	struct sockaddr_un *saddr = (struct sockaddr_un *) addr;
+	networkId = malloc (3 + strlen (transName) +
+	    strlen (hostnamebuf) + strlen (saddr->sun_path));
+	sprintf (networkId, "%s/%s:%s", transName,
+	    hostnamebuf, saddr->sun_path);
+	break;
+    }
+#endif /* defined(UNIXCONN) || defined(LOCALCONN) */
+
+#if defined(TCPCONN)
+    case AF_INET:
+#if defined(IPv6) && defined(AF_INET6)
+    case AF_INET6:
+#endif
+    {
+	struct sockaddr_in *saddr = (struct sockaddr_in *) addr;
+#if defined(IPv6) && defined(AF_INET6)
+	struct sockaddr_in6 *saddr6 = (struct sockaddr_in6 *) addr;
+#endif
+	int portnum;
+	char portnumbuf[10];
+
+
+#if defined(IPv6) && defined(AF_INET6)
+	if (family == AF_INET6)
+	    portnum = ntohs (saddr6->sin6_port);
+	else
+#endif
+	    portnum = ntohs (saddr->sin_port);
+
+	snprintf (portnumbuf, sizeof(portnumbuf), "%d", portnum);
+	networkId = malloc (3 + strlen (transName) +
+	    strlen (hostnamebuf) + strlen (portnumbuf));
+	sprintf (networkId, "%s/%s:%s", transName, hostnamebuf, portnumbuf);
+	break;
+    }
+#endif /* defined(TCPCONN) */
+
+
+    default:
+	break;
+    }
+
+    return (networkId);
+}
+
+#include <setjmp.h>
+static jmp_buf env;
+
+#ifdef SIGALRM
+static volatile int nameserver_timedout = 0;
+
+static void
+nameserver_lost(int sig _X_UNUSED)
+{
+  nameserver_timedout = 1;
+  longjmp (env, -1);
+  /* NOTREACHED */
+}
+#endif /* SIGALARM */
+
+
+char *
+TRANS(GetPeerNetworkId) (XtransConnInfo ciptr)
+
+{
+    int		family = ciptr->family;
+    char	*peer_addr = ciptr->peeraddr;
+    char	*hostname;
+    char	addrbuf[256];
+    const char	*addr = NULL;
+
+    switch (family)
+    {
+    case AF_UNSPEC:
+#if defined(UNIXCONN) || defined(LOCALCONN)
+    case AF_UNIX:
+    {
+	if (gethostname (addrbuf, sizeof (addrbuf)) == 0)
+	    addr = addrbuf;
+	break;
+    }
+#endif /* defined(UNIXCONN) || defined(LOCALCONN) */
+
+#if defined(TCPCONN)
+    case AF_INET:
+#if defined(IPv6) && defined(AF_INET6)
+    case AF_INET6:
+#endif
+    {
+	struct sockaddr_in *saddr = (struct sockaddr_in *) peer_addr;
+#if defined(IPv6) && defined(AF_INET6)
+	struct sockaddr_in6 *saddr6 = (struct sockaddr_in6 *) peer_addr;
+#endif
+	char *address;
+	int addresslen;
+#ifdef XTHREADS_NEEDS_BYNAMEPARAMS
+	_Xgethostbynameparams hparams;
+#endif
+	struct hostent * volatile hostp = NULL;
+
+#if defined(IPv6) && defined(AF_INET6)
+	if (family == AF_INET6)
+	{
+	    address = (char *) &saddr6->sin6_addr;
+	    addresslen = sizeof (saddr6->sin6_addr);
+	}
+	else
+#endif
+	{
+	    address = (char *) &saddr->sin_addr;
+	    addresslen = sizeof (saddr->sin_addr);
+	}
+
+#ifdef SIGALRM
+	/*
+	 * gethostbyaddr can take a LONG time if the host does not exist.
+	 * Assume that if it does not respond in NAMESERVER_TIMEOUT seconds
+	 * that something is wrong and do not make the user wait.
+	 * gethostbyaddr will continue after a signal, so we have to
+	 * jump out of it.
+	 */
+
+	nameserver_timedout = 0;
+	signal (SIGALRM, nameserver_lost);
+	alarm (4);
+	if (setjmp(env) == 0) {
+#endif
+	    hostp = _XGethostbyaddr (address, addresslen, family, hparams);
+#ifdef SIGALRM
+	}
+	alarm (0);
+#endif
+	if (hostp != NULL)
+	  addr = hostp->h_name;
+	else
+#if defined(IPv6) && defined(AF_INET6)
+	  addr = inet_ntop (family, address, addrbuf, sizeof (addrbuf));
+#else
+	  addr = inet_ntoa (saddr->sin_addr);
+#endif
+	break;
+    }
+
+#endif /* defined(TCPCONN) */
+
+
+    default:
+	return (NULL);
+    }
+
+
+    hostname = malloc (strlen (ciptr->transptr->TransName) + strlen (addr) + 2);
+    strcpy (hostname, ciptr->transptr->TransName);
+    strcat (hostname, "/");
+    if (addr)
+	strcat (hostname, addr);
+
+    return (hostname);
+}
+
+#endif /* ICE_t */
+
+
+#if defined(WIN32) && defined(TCPCONN)
+int
+TRANS(WSAStartup) (void)
+{
+    static WSADATA wsadata;
+
+    prmsg (2,"WSAStartup()\n");
+
+    if (!wsadata.wVersion && WSAStartup(MAKEWORD(2,2), &wsadata))
+        return 1;
+    return 0;
+}
+#endif
+
+#include <ctype.h>
+
+static int
+is_numeric (const char *str)
+{
+    int i;
+
+    for (i = 0; i < (int) strlen (str); i++)
+	if (!isdigit (str[i]))
+	    return (0);
+
+    return (1);
+}
+
+#ifdef TRANS_SERVER
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
+
+#if !defined(S_IFLNK) && !defined(S_ISLNK)
+#undef lstat
+#define lstat(a,b) stat(a,b)
+#endif
+
+#define FAIL_IF_NOMODE  1
+#define FAIL_IF_NOT_ROOT 2
+#define WARN_NO_ACCESS 4
+
+/*
+ * We make the assumption that when the 'sticky' (t) bit is requested
+ * it's not save if the directory has non-root ownership or the sticky
+ * bit cannot be set and fail.
+ */
+static int
+trans_mkdir(const char *path, int mode)
+{
+    struct stat buf;
+
+    if (lstat(path, &buf) != 0) {
+	if (errno != ENOENT) {
+	    prmsg(1, "mkdir: ERROR: (l)stat failed for %s (%d)\n",
+		  path, errno);
+	    return -1;
+	}
+	/* Dir doesn't exist. Try to create it */
+
+#if !defined(WIN32) && !defined(__CYGWIN__)
+	/*
+	 * 'sticky' bit requested: assume application makes
+	 * certain security implications. If effective user ID
+	 * is != 0: fail as we may not be able to meet them.
+	 */
+	if (geteuid() != 0) {
+	    if (mode & 01000) {
+		prmsg(1, "mkdir: ERROR: euid != 0,"
+		      "directory %s will not be created.\n",
+		      path);
+#ifdef FAIL_HARD
+		return -1;
+#endif
+	    } else {
+		prmsg(1, "mkdir: Cannot create %s with root ownership\n",
+		      path);
+	    }
+	}
+#endif
+
+#ifndef WIN32
+	if (mkdir(path, mode) == 0) {
+	    if (chmod(path, mode)) {
+		prmsg(1, "mkdir: ERROR: Mode of %s should be set to %04o\n",
+		      path, mode);
+#ifdef FAIL_HARD
+		return -1;
+#endif
+	    }
+#else
+	if (mkdir(path) == 0) {
+#endif
+	} else {
+	    prmsg(1, "mkdir: ERROR: Cannot create %s\n",
+		  path);
+	    return -1;
+	}
+
+	return 0;
+
+    } else {
+	if (S_ISDIR(buf.st_mode)) {
+	    int updateOwner = 0;
+	    int updateMode = 0;
+	    int updatedOwner = 0;
+	    int updatedMode = 0;
+	    int status = 0;
+	    /* Check if the directory's ownership is OK. */
+	    if (buf.st_uid != 0)
+		updateOwner = 1;
+
+	    /*
+	     * Check if the directory's mode is OK.  An exact match isn't
+	     * required, just a mode that isn't more permissive than the
+	     * one requested.
+	     */
+	    if ((~mode) & 0077 & buf.st_mode)
+		updateMode = 1;
+
+	    /*
+	     * If the directory is not writeable not everybody may
+	     * be able to create sockets. Therefore warn if mode
+	     * cannot be fixed.
+	     */
+	    if ((~buf.st_mode) & 0022 & mode) {
+		updateMode = 1;
+		status |= WARN_NO_ACCESS;
+	    }
+
+	    /*
+	     * If 'sticky' bit is requested fail if owner isn't root
+	     * as we assume the caller makes certain security implications
+	     */
+	    if (mode & 01000) {
+		status |= FAIL_IF_NOT_ROOT;
+		if (!(buf.st_mode & 01000)) {
+		    status |= FAIL_IF_NOMODE;
+		    updateMode = 1;
+		}
+	    }
+
+#ifdef HAS_FCHOWN
+	    /*
+	     * If fchown(2) and fchmod(2) are available, try to correct the
+	     * directory's owner and mode.  Otherwise it isn't safe to attempt
+	     * to do this.
+	     */
+	    if (updateMode || updateOwner) {
+		int fd = -1;
+		struct stat fbuf;
+		if ((fd = open(path, O_RDONLY)) != -1) {
+		    if (fstat(fd, &fbuf) == -1) {
+			prmsg(1, "mkdir: ERROR: fstat failed for %s (%d)\n",
+			      path, errno);
+			close(fd);
+			return -1;
+		    }
+		    /*
+		     * Verify that we've opened the same directory as was
+		     * checked above.
+		     */
+		    if (!S_ISDIR(fbuf.st_mode) ||
+			buf.st_dev != fbuf.st_dev ||
+			buf.st_ino != fbuf.st_ino) {
+			prmsg(1, "mkdir: ERROR: inode for %s changed\n",
+			      path);
+			close(fd);
+			return -1;
+		    }
+		    if (updateOwner && fchown(fd, 0, 0) == 0)
+			updatedOwner = 1;
+		    if (updateMode && fchmod(fd, mode) == 0)
+			updatedMode = 1;
+		    close(fd);
+		}
+	    }
+#endif
+
+	    if (updateOwner && !updatedOwner) {
+#ifdef FAIL_HARD
+		if (status & FAIL_IF_NOT_ROOT) {
+		    prmsg(1, "mkdir: ERROR: Owner of %s must be set to root\n",
+			  path);
+		    return -1;
+		}
+#endif
+#if !defined(__APPLE_CC__) && !defined(__CYGWIN__)
+		prmsg(1, "mkdir: Owner of %s should be set to root\n",
+		      path);
+#endif
+	    }
+
+	    if (updateMode && !updatedMode) {
+#ifdef FAIL_HARD
+		if (status & FAIL_IF_NOMODE) {
+		    prmsg(1, "mkdir: ERROR: Mode of %s must be set to %04o\n",
+			  path, mode);
+		    return -1;
+		}
+#endif
+		prmsg(1, "mkdir: Mode of %s should be set to %04o\n",
+		      path, mode);
+		if (status & WARN_NO_ACCESS) {
+		    prmsg(1, "mkdir: this may cause subsequent errors\n");
+		}
+	    }
+	    return 0;
+	}
+	return -1;
+    }
+
+    /* In all other cases, fail */
+    return -1;
+}
+
+#endif /* TRANS_SERVER */
diff -Naur old/X11/Xtrans/transport.c new/X11/Xtrans/transport.c
--- old/X11/Xtrans/transport.c	1970-01-01 08:00:00.000000000 +0800
+++ new/X11/Xtrans/transport.c	2024-03-05 19:36:25.213040800 +0800
@@ -0,0 +1,74 @@
+/*
+
+Copyright 1993, 1994, 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 1993, 1994 NCR Corporation - Dayton, Ohio, USA
+ *
+ * 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 NCR not be used in advertising
+ * or publicity pertaining to distribution of the software without specific,
+ * written prior permission.  NCR makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ *
+ * NCR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
+ * NO EVENT SHALL NCR 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.
+ */
+
+#include <stdlib.h>
+
+#define XTRANS_TRANSPORT_C  /* used to flag Xtransint.h that it's being used
+			       here, not just #included in another file */
+
+#include "Xtransint.h"
+
+#ifdef __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wformat-nonliteral"
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+#endif
+
+#ifdef LOCALCONN
+#include "Xtranslcl.c"
+#endif
+#if defined(TCPCONN) || defined(UNIXCONN)
+#include "Xtranssock.c"
+#endif
+#include "Xtrans.c"
+#include "Xtransutil.c"
+
+#ifdef __clang__
+#pragma clang diagnostic pop
+#endif