This commit is contained in:
Enrico Weigelt 2025-07-04 14:51:57 -04:00 committed by GitHub
commit d9fc870293
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
20 changed files with 4966 additions and 45 deletions

View File

@ -64,8 +64,7 @@ font-util,\
khronos-opengl-registry,\
python38-lxml,\
xkbcomp-devel,\
xkeyboard-config,\
xtrans"
xkeyboard-config"
- echo Install done
- "%CYGWIN_ROOT%\\%SETUP% -qnNdO -R %CYGWIN_ROOT% -s %CYGWIN_MIRROR% -l %CACHE% -g"
cache:

View File

@ -108,7 +108,7 @@ stages:
FDO_DISTRIBUTION_TAG: '$XORG_FREEBSD_TAG'
FDO_DISTRIBUTION_VERSION: '$XORG_FREEBSD_VERSION'
FDO_DISTRIBUTION_EXEC: ''
FDO_DISTRIBUTION_PACKAGES: 'git gcc pkgconf autoconf automake libtool xorg-macros xorgproto bash meson ninja pixman xtrans libXau libXdmcp libXfont2 libxkbfile libxcvt libpciaccess font-util libepoll-shim libxvmc xcb-util xcb-util-wm'
FDO_DISTRIBUTION_PACKAGES: 'git gcc pkgconf autoconf automake libtool xorg-macros xorgproto bash meson ninja pixman libXau libXdmcp libXfont2 libxkbfile libxcvt libpciaccess font-util libepoll-shim libxvmc xcb-util xcb-util-wm'
FDO_IMAGE_SIZE: '30G'
debian-bullseye:

View File

@ -53,7 +53,6 @@ build 'https://gitlab.freedesktop.org/xorg/proto/xorgproto.git' 'xorgproto-2024.
build 'https://gitlab.freedesktop.org/xorg/lib/libXau.git' 'libXau-1.0.9'
build 'https://gitlab.freedesktop.org/xorg/proto/xcbproto.git' 'xcb-proto-1.14.1'
build 'https://gitlab.freedesktop.org/xorg/lib/libxcb.git' 'libxcb-1.14'
build 'https://gitlab.freedesktop.org/xorg/lib/libxtrans.git' 'xtrans-1.4.0'
# the default value of keysymdefdir is taken from the includedir variable for
# xproto, which isn't adjusted by pkg-config for the sysroot
# Using -fcommon to address build failure when cross-compiling for windows.

View File

@ -122,7 +122,6 @@ apt-get install -y \
x11-xkb-utils \
xfonts-utils \
xkb-data \
xtrans-dev \
xutils-dev
.gitlab-ci/cross-prereqs-build.sh i686-w64-mingw32

View File

@ -35,9 +35,7 @@
#include "windisplay.h"
#include "winmsg.h"
#define XSERV_t
#define TRANS_SERVER
#include <X11/Xtrans/Xtrans.h>
#include "os/Xtrans.h"
/*
Generate a display name string referring to the display of this server,

View File

@ -83,7 +83,6 @@ damageproto_dep = dependency('damageproto', version: '>= 1.1', fallback: ['xorgp
xcmiscproto_dep = dependency('xcmiscproto', version: '>= 1.2.0', fallback: ['xorgproto', 'ext_xorgproto'])
bigreqsproto_dep = dependency('bigreqsproto', version: '>= 1.1.0', fallback: ['xorgproto', 'ext_xorgproto'])
presentproto_dep = dependency('presentproto', version: '>= 1.4', fallback: ['xorgproto', 'ext_xorgproto'])
xtrans_dep = dependency('xtrans', version: '>= 1.3.5')
videoproto_dep = dependency('videoproto', fallback: ['xorgproto', 'ext_xorgproto'])
compositeproto_dep = dependency('compositeproto', version: '>= 0.4', fallback: ['xorgproto', 'ext_xorgproto'])
@ -578,7 +577,6 @@ common_dep = [
xcmiscproto_dep,
bigreqsproto_dep,
presentproto_dep,
xtrans_dep,
libsystemd_daemon_dep,
videoproto_dep,

1170
os/Xtrans.c Normal file

File diff suppressed because it is too large Load Diff

317
os/Xtrans.h Normal file
View File

@ -0,0 +1,317 @@
/*
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 <stdint.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 XTRANSDEBUG
static const char *__xtransname = "_XSERVTrans";
#endif
#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.
*/
/* Temporary workaround for consumers whose configure scripts were
generated with pre-1.6 versions of xtrans.m4 */
#if defined(IPv6) && !defined(HAVE_STRUCT_SOCKADDR_STORAGE)
#define HAVE_STRUCT_SOCKADDR_STORAGE
#endif
#ifdef HAVE_STRUCT_SOCKADDR_STORAGE
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)
/*
* _XSERVTransReadv and _XSERVTransWritev 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 _XSERVTransFreeConnInfo (
XtransConnInfo /* ciptr */
);
XtransConnInfo _XSERVTransOpenCOTSServer(
const char * /* address */
);
XtransConnInfo _XSERVTransReopenCOTSServer(
int, /* trans_id */
int, /* fd */
const char * /* port */
);
int _XSERVTransSetOption(
XtransConnInfo, /* ciptr */
int, /* option */
int /* arg */
);
int _XSERVTransCreateListener(
XtransConnInfo, /* ciptr */
const char *, /* port */
unsigned int /* flags */
);
int _XSERVTransReceived (
const char* /* protocol*/
);
int _XSERVTransNoListen (
const char* /* protocol*/
);
int _XSERVTransListen (
const char* /* protocol*/
);
int _XSERVTransIsListening (
const char* /* protocol*/
);
int _XSERVTransResetListener (
XtransConnInfo /* ciptr */
);
XtransConnInfo _XSERVTransAccept (
XtransConnInfo, /* ciptr */
int * /* status */
);
int _XSERVTransBytesReadable (
XtransConnInfo, /* ciptr */
BytesReadable_t * /* pend */
);
int _XSERVTransRead (
XtransConnInfo, /* ciptr */
char *, /* buf */
int /* size */
);
int _XSERVTransWrite (
XtransConnInfo, /* ciptr */
const char *, /* buf */
int /* size */
);
int _XSERVTransReadv (
XtransConnInfo, /* ciptr */
struct iovec *, /* buf */
int /* size */
);
int _XSERVTransWritev (
XtransConnInfo, /* ciptr */
struct iovec *, /* buf */
int /* size */
);
int _XSERVTransSendFd (XtransConnInfo ciptr, int fd, int do_close);
int _XSERVTransRecvFd (XtransConnInfo ciptr);
int _XSERVTransDisconnect (
XtransConnInfo /* ciptr */
);
int _XSERVTransClose (
XtransConnInfo /* ciptr */
);
int _XSERVTransCloseForCloning (
XtransConnInfo /* ciptr */
);
int _XSERVTransIsLocal (
XtransConnInfo /* ciptr */
);
int _XSERVTransGetPeerAddr (
XtransConnInfo, /* ciptr */
int *, /* familyp */
int *, /* addrlenp */
Xtransaddr ** /* addrp */
);
int _XSERVTransGetConnectionNumber (
XtransConnInfo /* ciptr */
);
int _XSERVTransMakeAllCOTSServerListeners (
const char *, /* port */
int *, /* partial */
uint32_t *, /* count_ret */
XtransConnInfo ** /* ciptrs_ret */
);
/*
* Function Prototypes for Utility Functions.
*/
int _XSERVTransConvertAddress (
int *, /* familyp */
int *, /* addrlenp */
Xtransaddr ** /* addrp */
);
int _XSERVTransGetHostname (
char * /* buf */,
int /* maxlen */
);
#if defined(WIN32) && defined(TCPCONN)
int _XSERVTransWSAStartup();
#endif
#endif /* _XTRANS_H_ */

348
os/Xtransint.h Normal file
View File

@ -0,0 +1,348 @@
/*
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
#include "os/Xtrans.h"
#ifdef XTRANSDEBUG
# include <stdio.h>
#endif /* XTRANSDEBUG */
#include <errno.h>
#ifndef WIN32
# include <sys/socket.h>
# include <netinet/in.h>
# include <arpa/inet.h>
# 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>
#define X_TCP_PORT 6000
#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;
const char ** nolisten;
XtransConnInfo (*OpenCOTSServer)(
struct _Xtransport *, /* transport */
const char *, /* protocol */
const char *, /* host */
const char * /* port */
);
XtransConnInfo (*ReopenCOTSServer)(
struct _Xtransport *, /* transport */
int, /* fd */
const char * /* port */
);
int (*SetOption)(
XtransConnInfo, /* connection */
int, /* option */
int /* arg */
);
/* 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 */
);
int (*BytesReadable)(
XtransConnInfo, /* connection */
BytesReadable_t * /* pend */
);
int (*Read)(
XtransConnInfo, /* connection */
char *, /* buf */
int /* size */
);
int (*Write)(
XtransConnInfo, /* connection */
const 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) /* This previously meant that abstract sockets should be used available. For security
* reasons, this is now a no-op on the client side, but it is still supported for servers.
*/
#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) _XSERVTransReadV(ciptr, iov, iovcnt)
static int _XSERVTransReadV(
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) _XSERVTransWriteV(ciptr, iov, iovcnt)
static int _XSERVTransWriteV(
XtransConnInfo, /* ciptr */
struct iovec *, /* iov */
int /* iovcnt */
);
#else
#define WRITEV(ciptr, iov, iovcnt) writev(ciptr->fd, iov, iovcnt)
#endif /* WIN32 */
static int trans_mkdir (
const char *, /* path */
int /* mode */
);
#ifdef __clang__
#pragma clang diagnostic pop
#endif
/*
* Some XTRANSDEBUG stuff
*/
#ifdef XTRANSDEBUG
#include <stdarg.h>
#include "os.h"
#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_ */

911
os/Xtranslcl.c Normal file
View File

@ -0,0 +1,911 @@
/*
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
# include <stropts.h>
#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>
#include <sys/un.h>
/* Types of local connections supported:
* - PTS
* - named pipes
*/
#if defined(SVR4) || defined(__SVR4)
# define LOCAL_TRANS_NAMED
#endif
static int _XSERVTransLocalClose(XtransConnInfo ciptr);
/*
* These functions actually implement the local connection mechanisms.
*/
/* Type Not Supported */
static int _XSERVTransOpenFail(XtransConnInfo ciptr _X_UNUSED, const char *port _X_UNUSED)
{
return -1;
}
static int ReopenFail(XtransConnInfo ciptr _X_UNUSED, int fd _X_UNUSED,
const char *port _X_UNUSED)
{
return 0;
}
#if XTRANS_SEND_FDS
static int _XSERVTransLocalRecvFdInvalid(XtransConnInfo ciptr)
{
errno = EINVAL;
return -1;
}
static int LocalSendFdInvalid(XtransConnInfo ciptr, int fd, int do_close)
{
errno = EINVAL;
return -1;
}
#endif
static int _XSERVTransFillAddrInfo(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;
}
#define X_STREAMS_DIR "/tmp/.X11-pipe"
#define NAMEDNODENAME "/tmp/.X11-pipe/X"
#ifdef LOCAL_TRANS_NAMED
/* NAMED */
static int _XSERVTransNAMEDOpenPipe(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]);
}
static int NAMEDOpenServer(XtransConnInfo ciptr, const char *port)
{
int fd;
char server_path[64];
prmsg(2,"NAMEDOpenServer(%s)\n", port);
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 = _XSERVTransNAMEDOpenPipe(server_path);
if (fd < 0) {
return -1;
}
/*
* Everything looks good: fill in the XtransConnInfo structure.
*/
if (_XSERVTransFillAddrInfo (ciptr, server_path, server_path) == 0)
{
prmsg(1,"NAMEDOpenServer: failed to fill in addr info\n");
_XSERVTransLocalClose(ciptr);
return -1;
}
return fd;
}
static int NAMEDResetListener (XtransConnInfo ciptr)
{
struct sockaddr_un *sockname=(struct sockaddr_un *) ciptr->addr;
struct stat statb;
prmsg(2,"NAMEDResetListener(%p, %d)\n", (void *) 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);
_XSERVTransLocalClose(ciptr);
ciptr->fd = _XSERVTransNAMEDOpenPipe(sockname->sun_path);
if (ciptr->fd >= 0)
return TRANS_RESET_NEW_FD;
else
return TRANS_CREATE_LISTENER_FAILED;
}
}
return TRANS_RESET_NOOP;
}
static int _XSERVTransNAMEDAccept(
XtransConnInfo ciptr, XtransConnInfo newciptr, int *status)
{
struct strrecvfd str;
prmsg(2,"NAMEDAccept(%p->%d)\n", (void *) 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 /* LOCAL_TRANS_NAMED */
#ifdef LOCAL_TRANS_NAMED
static int _XSERVTransNAMEDReopenServer(
XtransConnInfo ciptr, int fd _X_UNUSED, const char *port)
{
char server_path[64];
prmsg(2,"NAMEDReopenServer(%s)\n", port);
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 (_XSERVTransFillAddrInfo) (ciptr, server_path, server_path) == 0)
{
prmsg(1,"NAMEDReopenServer: failed to fill in addr info\n");
return 0;
}
return 1;
}
#endif /* LOCAL_TRANS_NAMED */
/*
* This table contains all of the entry points for the different local
* connection mechanisms.
*/
typedef struct _LOCALtrans2dev {
const char *transname;
int (*devcotsopenserver)(
XtransConnInfo, const char * /*port*/
);
int (*devcltsopenserver)(
XtransConnInfo, const char * /*port*/
);
int (*devcotsreopenserver)(
XtransConnInfo,
int, /* fd */
const char * /* port */
);
int (*devcltsreopenserver)(
XtransConnInfo,
int, /* fd */
const char * /* port */
);
int (*devreset)(
XtransConnInfo /* ciptr */
);
int (*devaccept)(
XtransConnInfo, XtransConnInfo, int *
);
} LOCALtrans2dev;
static LOCALtrans2dev LOCALtrans2devtab[] = {
{
"",
_XSERVTransNAMEDOpenServer,
_XSERVTransOpenFail,
_XSERVTransNAMEDReopenServer,
_XSERVTransReopenFail,
_XSERVTransNAMEDResetListener,
_XSERVTransNAMEDAccept
},
{
"local",
_XSERVTransNAMEDOpenServer,
_XSERVTransOpenFail,
_XSERVTransNAMEDReopenServer,
_XSERVTransReopenFail,
_XSERVTrans_NAMEDResetListener,
_XSERVTransNAMEDAccept
},
#ifdef LOCAL_TRANS_NAMED
{
"named",
_XSERVTransNAMEDOpenServer,
_XSERVTransOpenFail,
_XSERVTransNAMEDReopenServer,
_XSERVTransReopenFail,
_XSERVTransNAMEDResetListener,
_XSERVTransNAMEDAccept
},
{
"pipe",
_XSERVTransNAMEDOpenServer,
_XSERVTransOpenFail,
_XSERVTransNAMEDReopenServer,
_XSERVTransReopenFail,
_XSERVTransNAMEDResetListener,
_XSERVTransNAMEDAccept
},
#endif /* LOCAL_TRANS_NAMED */
};
#define NUMTRANSPORTS (sizeof(LOCALtrans2devtab)/sizeof(LOCALtrans2dev))
static const char *XLOCAL=NULL;
static char *workingXLOCAL=NULL;
static char *freeXLOCAL=NULL;
#define DEF_XLOCAL "UNIX:NAMED"
static void _XSERVTransLocalInitTransports(const char *protocol)
{
prmsg(3,"LocalInitTransports(%s)\n", protocol);
if( strcmp(protocol,"local") && strcmp(protocol,"LOCAL") )
{
workingXLOCAL = freeXLOCAL = strdup (protocol);
}
else {
XLOCAL = getenv("XLOCAL");
if(XLOCAL==NULL)
XLOCAL=DEF_XLOCAL;
workingXLOCAL = freeXLOCAL = strdup (XLOCAL);
}
}
static void _XSERVTransLocalEndTransports(void)
{
prmsg(3,"LocalEndTransports()\n");
free(freeXLOCAL);
freeXLOCAL = NULL;
}
#define TYPEBUFSIZE 32
static XtransConnInfo _XSERVTransLocalOpenServer(
int type, const char *protocol,
const char *host _X_UNUSED, const char *port)
{
XtransConnInfo ciptr;
prmsg(2,"LocalOpenServer(%d,%s,%s)\n", type, protocol, port);
/*
* 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.
*/
if( (ciptr = calloc(1,sizeof(struct _XtransConnInfo))) == NULL )
{
prmsg(1,"LocalOpenServer: calloc(1,%lu) failed\n",
sizeof(struct _XtransConnInfo));
return NULL;
}
for (unsigned int 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;
}
static XtransConnInfo _XSERVTransLocalReopenServer(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;
}
/*
* This is the Local implementation of the X Transport service layer
*/
static XtransConnInfo _XSERVTransLocalOpenCOTSServer(
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 */
_XSERVTransLocalInitTransports("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;
}
_XSERVTransLocalEndTransports();
if (!found) {
prmsg(3,"LocalOpenCOTSServer: disabling %s\n",thistrans->TransName);
thistrans->flags |= TRANS_DISABLED;
return NULL;
}
return _XSERVTransLocalOpenServer(XTRANS_OPEN_COTS_SERVER, protocol, host, port);
}
static XtransConnInfo _XSERVTransLocalReopenCOTSServer(
Xtransport *thistrans, int fd, const char *port)
{
unsigned 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 _XSERVTransLocalReopenServer(XTRANS_OPEN_COTS_SERVER,
index, fd, port);
}
static int _XSERVTransLocalSetOption(XtransConnInfo ciptr, int option, int arg)
{
prmsg(2,"LocalSetOption(%d,%d,%d)\n",ciptr->fd,option,arg);
return -1;
}
static int _XSERVTransLocalCreateListener(
XtransConnInfo ciptr, const char *port, unsigned int flags _X_UNUSED)
{
prmsg(2,"LocalCreateListener(%p->%d,%s)\n", (void *) ciptr, ciptr->fd, port);
return 0;
}
static int _XSERVTransLocalResetListener(XtransConnInfo ciptr)
{
LOCALtrans2dev *transptr;
prmsg(2,"LocalResetListener(%p)\n", (void *) ciptr);
transptr=(LOCALtrans2dev *)ciptr->priv;
if (transptr->devreset != NULL) {
return transptr->devreset(ciptr);
}
return TRANS_RESET_NOOP;
}
static XtransConnInfo _XSERVTransLocalAccept(XtransConnInfo ciptr, int *status)
{
XtransConnInfo newciptr;
LOCALtrans2dev *transptr;
prmsg(2,"LocalAccept(%p->%d)\n", (void *) 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;
}
static int _XSERVTransLocalBytesReadable(XtransConnInfo ciptr, BytesReadable_t *pend )
{
prmsg(2,"LocalBytesReadable(%p->%d,%p)\n",
(void *) ciptr, ciptr->fd, (void *) pend);
return ioctl(ciptr->fd, FIONREAD, (char *)pend);
}
static int _XSERVTransLocalRead(XtransConnInfo ciptr, char *buf, int size)
{
prmsg(2,"LocalRead(%d,%p,%d)\n", ciptr->fd, (void *) buf, size );
return read(ciptr->fd,buf,size);
}
static int _XSERVTransLocalWrite(XtransConnInfo ciptr, const char *buf, int size)
{
prmsg(2,"LocalWrite(%d,%p,%d)\n", ciptr->fd, (const void *) buf, size );
return write(ciptr->fd,buf,size);
}
static int _XSERVTransLocalReadv(XtransConnInfo ciptr, struct iovec *buf, int size)
{
prmsg(2,"LocalReadv(%d,%p,%d)\n", ciptr->fd, (void *) buf, size );
return READV(ciptr,buf,size);
}
static int _XSERVTransLocalWritev(XtransConnInfo ciptr, struct iovec *buf, int size)
{
prmsg(2,"LocalWritev(%d,%p,%d)\n", ciptr->fd, (const void *) buf, size );
return WRITEV(ciptr,buf,size);
}
static int _XSERVTransLocalDisconnect(XtransConnInfo ciptr)
{
prmsg(2,"LocalDisconnect(%p->%d)\n", (void *) ciptr, ciptr->fd);
return 0;
}
static int _XSERVTransLocalClose(XtransConnInfo ciptr)
{
struct sockaddr_un *sockname=(struct sockaddr_un *) ciptr->addr;
int ret;
prmsg(2,"LocalClose(%p->%d)\n", (void *) 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 _XSERVTransLocalCloseForCloning(XtransConnInfo ciptr)
{
int ret;
prmsg(2,"LocalCloseForCloning(%p->%d)\n", (void *) 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.
*/
static const char * local_aliases[] = {
"named",
"pipe", /* compatibility with Solaris Xlib */
NULL };
static Xtransport _XSERVTransLocalFuncs = {
/* Local Interface */
"local",
TRANS_ALIAS | TRANS_LOCAL,
local_aliases,
_XSERVTransLocalOpenCOTSServer,
_XSERVTransLocalReopenCOTSServer,
_XSERVTransLocalSetOption,
_XSERVTransLocalCreateListener,
_XSERVTransLocalResetListener,
_XSERVTransLocalAccept,
_XSERVTransLocalBytesReadable,
_XSERVTransLocalRead,
_XSERVTransLocalWrite,
_XSERVTransLocalReadv,
_XSERVTransLocalWritev,
#if XTRANS_SEND_FDS
_XSERVTransLocalSendFdInvalid,
_XSERVTransLocalRecvFdInvalid,
#endif
_XSERVTransLocalDisconnect,
_XSERVTransLocalClose,
_XSERVTransLocalCloseForCloning,
};
#ifdef LOCAL_TRANS_NAMED
static Xtransport _XSERVTransNAMEDFuncs = {
/* Local Interface */
"named",
TRANS_LOCAL,
NULL,
_XSERVTransLocalOpenCOTSServer,
_XSERVTransLocalReopenCOTSServer,
_XSERVTransLocalSetOption,
_XSERVTransLocalCreateListener,
_XSERVTransLocalResetListener,
_XSERVTransLocalAccept,
_XSERVTransLocalBytesReadable,
_XSERVTransLocalRead,
_XSERVTransLocalWrite,
_XSERVTransLocalReadv,
_XSERVTransLocalWritev,
#if XTRANS_SEND_FDS
_XSERVTransLocalSendFdInvalid,
_XSERVTransLocalRecvFdInvalid,
#endif
_XSERVTransLocalDisconnect,
_XSERVTransLocalClose,
_XSERVTransLocalCloseForCloning,
};
static Xtransport _XSERVTransPIPEFuncs = {
/* Local Interface */
"pipe",
TRANS_ALIAS | TRANS_LOCAL,
NULL,
_XSERVTransLocalOpenCOTSServer,
_XSERVTransLocalReopenCOTSServer,
_XSERVTransLocalSetOption,
_XSERVTransLocalCreateListener,
_XSERVTransLocalResetListener,
_XSERVTransLocalAccept,
_XSERVTransLocalBytesReadable,
_XSERVTransLocalRead,
_XSERVTransLocalWrite,
_XSERVTransLocalReadv,
_XSERVTransLocalWritev,
#if XTRANS_SEND_FDS
_XSERVTransLocalSendFdInvalid,
_XSERVTransLocalRecvFdInvalid,
#endif
_XSERVTransLocalDisconnect,
_XSERVTransLocalClose,
_XSERVTransLocalCloseForCloning,
};
#endif /* LOCAL_TRANS_NAMED */

1712
os/Xtranssock.c Normal file

File diff suppressed because it is too large Load Diff

420
os/Xtransutil.c Normal file
View File

@ -0,0 +1,420 @@
/*
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 Independent 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
#if defined(IPv6) && !defined(AF_INET6)
#error "Cannot build IPv6 support without AF_INET6"
#endif
/* Temporary workaround for consumers whose configure scripts were
generated with pre-1.6 versions of xtrans.m4 */
#if defined(IPv6) && !defined(HAVE_INET_NTOP)
#define HAVE_INET_NTOP
#endif
/*
* 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
/*
* _XSERVTransConvertAddress 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 _XSERVTransConvertAddress(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;
}
#ifdef IPv6
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) */
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 = _XSERVTransGetHostname (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;
}
#if defined(WIN32) && defined(TCPCONN)
int _XSERVTransWSAStartup (void)
{
static WSADATA wsadata;
prmsg (2,"WSAStartup()\n");
if (!wsadata.wVersion && WSAStartup(MAKEWORD(2,2), &wsadata))
return 1;
return 0;
}
#endif
#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;
}

View File

@ -84,10 +84,7 @@ SOFTWARE.
#include <stdio.h>
#include <stdlib.h>
#define XSERV_t
#define TRANS_SERVER
#define TRANS_REOPEN
#include <X11/Xtrans/Xtrans.h>
#include "os/Xtrans.h"
#include <X11/Xauth.h>
#include <X11/X.h>
#include <X11/Xproto.h>

View File

@ -67,11 +67,8 @@ SOFTWARE.
#endif
#include <X11/X.h>
#include <X11/Xproto.h>
#define XSERV_t
#define TRANS_SERVER
#define TRANS_REOPEN
#include <X11/Xtrans/Xtrans.h>
#include <X11/Xtrans/Xtransint.h>
#include "os/Xtrans.h"
#include "os/Xtransint.h"
#include <errno.h>
#include <signal.h>
#include <stdio.h>
@ -147,7 +144,7 @@ set_poll_clients(void);
static XtransConnInfo *ListenTransConns = NULL;
static int *ListenTransFds = NULL;
static int ListenTransCount;
static uint32_t ListenTransCount = 0;
static void ErrorConnMax(XtransConnInfo /* trans_conn */ );
@ -1061,7 +1058,7 @@ ListenOnOpenFD(int fd, int noxauth)
ListenTransCount++;
}
/* based on TRANS(SocketUNIXAccept) (XtransConnInfo ciptr, int *status) */
/* based on _XSERVTransSocketUNIXAccept (XtransConnInfo ciptr, int *status) */
Bool
AddClientOnOpenFD(int fd)
{

View File

@ -61,10 +61,7 @@ SOFTWARE.
#include <X11/Xwinsock.h>
#endif
#include <stdio.h>
#define XSERV_t
#define TRANS_SERVER
#define TRANS_REOPEN
#include <X11/Xtrans/Xtrans.h>
#include "os/Xtrans.h"
#include <X11/Xmd.h>
#include <errno.h>
#if !defined(WIN32)

74
os/transport.c Normal file
View File

@ -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

View File

@ -62,10 +62,7 @@ OR PERFORMANCE OF THIS SOFTWARE.
#endif
#include "misc.h"
#include <X11/X.h>
#define XSERV_t
#define TRANS_SERVER
#define TRANS_REOPEN
#include <X11/Xtrans/Xtrans.h>
#include "os/Xtrans.h"
#include <libgen.h>

View File

@ -37,12 +37,9 @@ from The Open Group.
#include <stdio.h>
#include <X11/X.h>
#define XSERV_t
#define TRANS_SERVER
#define TRANS_REOPEN
#include <X11/Xtrans/Xtrans.h>
#include "os/auth.h"
#include "os/Xtrans.h"
#include "os.h"
#include "osdep.h"

View File

@ -17,10 +17,7 @@
#ifdef WIN32
#include <X11/Xwinsock.h>
#define XSERV_t
#define TRANS_SERVER
#define TRANS_REOPEN
#include <X11/Xtrans/Xtrans.h>
#include "os/Xtrans.h"
#endif
#include <X11/Xos.h>
@ -48,10 +45,7 @@
#include "input.h"
#include "dixstruct.h"
#define XSERV_t
#define TRANS_SERVER
#define TRANS_REOPEN
#include <X11/Xtrans/Xtrans.h>
#include "os/Xtrans.h"
#ifdef XDMCP
#undef REQUEST

View File

@ -2,7 +2,4 @@
#include <X11/Xfuncproto.h>
#define TRANS_REOPEN
#define TRANS_SERVER
#define XSERV_t
#include <X11/Xtrans/transport.c>
#include "os/transport.c"