############################################################################### # Copyright 2007 Sun Microsystems, Inc. All rights reserved. # Use subject to license terms. # # 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, and/or sell copies of the Software, and to permit persons # to whom the Software is furnished to do so, provided that the above # copyright notice(s) and this permission notice appear in all copies of # the Software and that both the above copyright notice(s) and this # permission notice appear in supporting documentation. # # 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 # OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR # HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR 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. # # Except as contained in this notice, the name of a copyright holder # shall not be used in advertising or otherwise to promote the sale, use # or other dealings in this Software without prior written authorization # of the copyright holder. # # %W% %E% # diff -urp -x '*~' -x '*.orig' src/XShm.c src/XShm.c --- src/XShm.c 2006-07-11 11:05:14.000000000 -0700 +++ src/XShm.c 2007-05-29 16:56:02.280631000 -0700 @@ -43,6 +43,17 @@ in this Software without prior written a #include #include +#ifdef SUNSOFT +#ifdef _LP64 +#include +#endif /* _LP64 */ +#include +#include +#include +#include +#include +#endif + static XExtensionInfo _shm_info_data; static XExtensionInfo *shm_info = &_shm_info_data; static /* const */ char *shm_extension_name = SHMNAME; @@ -140,6 +151,178 @@ event_to_wire (Display *dpy, XEvent *re, return False; } +#ifdef SUNSOFT +/* + * Function to determine if a connection is local or not. Note that this + * is *VERY* specific to sockets, and if alternate transport mechanisms + * are implemented, this function will have to be tuned up a bit (or + * possibly removed if we can get the server to give back the correct + * answer for non-local connections). Required for pipe transport PIPECONN + */ + +static int +LocalConnection(dpy) + Display *dpy; +{ + int c = dpy->fd; + int numifs, n, rv = 0; + char *buf; +#ifdef SIOCGLIFCONF + struct lifconf ifc; + struct lifreq *ifrp; +#ifdef SIOCGLIFNUM + struct lifnum ifn; +#endif +#else + struct ifreq *ifrp; + struct ifreq ifr; + struct ifconf ifc; +#endif + unsigned bufsize; + void *sp; + struct stat statbuf; + + union { + struct sockaddr sa; + struct sockaddr_in sa_in; +#ifdef IPv6 + struct sockaddr_in6 sa_in6; +#endif + } clientsock; + int c_len = sizeof (clientsock); + + /* + * First stat the socket fd. If we succeed and the type of file + * is a FIFO, then we must be local. + */ + if ((fstat(c, &statbuf) >= 0) && ((statbuf.st_mode & S_IFMT) == S_IFIFO)) + return 1; + + /* + * Get the peer name of the socket fd. If we get an error on this, + * we've probably got an alternate transport mechanism. In this + * case, we're not likely to be on the same machine, so go ahead + * and return false. + */ + if (getpeername (c, &clientsock.sa, &c_len) == -1) { + return 0; + } + + /* Perform appropriate code based on what type of socket we've got... */ + switch(clientsock.sa.sa_family) { + + case AF_UNIX: + /* Done! Connection must be local */ + rv = 1; + break; + + case AF_INET: +#ifdef IPv6 + case AF_INET6: +#endif + /* + * Going to have to do some work here -- Perform the following: + * + * 1) Find out how many interfaces we've got via ioctl + * 2) Get the address of all of these i/f via ioctl + * 3) Loop through list, chedkinf for match. + */ +#ifdef SIOCGLIFNUM + ifn.lifn_family = AF_UNSPEC; + ifn.lifn_flags = 0; + if(ioctl(c, SIOCGLIFNUM, (char *) &ifn) < 0) +#else + if(ioctl(c, SIOCGIFNUM, (char *)&numifs) < 0) +#endif + { + perror("ioctl (get number of interfaces)"); + break; + } + +#if defined(SIOCGLIFNUM) && defined(SIOCGLIFCONF) + bufsize = ifn.lifn_count * sizeof(struct lifreq); +#else + bufsize = numifs * sizeof(struct ifreq); +#endif + buf = Xmalloc(bufsize); +#ifdef SIOCGLIFCONF + ifc.lifc_family = AF_UNSPEC; + ifc.lifc_flags = 0; + ifc.lifc_len = bufsize; + ifc.lifc_buf = buf; + if (ioctl(c, SIOCGLIFCONF, (char *)&ifc) < 0) +#else + ifc.ifc_len = bufsize; + ifc.ifc_buf = buf; + if (ioctl(c, SIOCGIFCONF, (char *)&ifc) < 0) +#endif + { + perror("ioctl (get interface configuration)"); + (void) Xfree(buf); + break; + } + +#ifdef SIOCGLIFCONF + ifrp = ifc.lifc_req; + for (n = ifc.lifc_len / sizeof (struct lifreq); n > 0; n--, ifrp++) +#else + ifrp = ifc.ifc_req; + for (n = ifc.ifc_len / sizeof (struct ifreq); n > 0; n--, ifrp++) +#endif + { + struct sockaddr *ifsa; +#ifdef SIOCGLIFCONF + ifsa = (struct sockaddr *) &ifrp->lifr_addr; +#else + ifsa = &ifrp->ifr_addr; +#endif + + switch (ifsa->sa_family) + { + case AF_INET: + if (clientsock.sa.sa_family == AF_INET) { + if (memcmp(&((struct sockaddr_in *) ifsa)->sin_addr, + (void *)&(clientsock.sa_in.sin_addr), + sizeof(struct in_addr)) == 0) { + rv = 1; + } + } else if (clientsock.sa.sa_family == AF_INET6) { + struct in6_addr s6; + IN6_INADDR_TO_V4MAPPED(&((struct sockaddr_in *) ifsa)->sin_addr, &s6); + if (memcmp((void *)&(clientsock.sa_in6.sin6_addr),&s6, + sizeof(struct in6_addr)) == 0) { + rv = 1; + } + } + break; + +#ifdef IPv6 + case AF_INET6: + if (clientsock.sa.sa_family == AF_INET6 && + memcmp(&((struct sockaddr_in6 *)ifsa)->sin6_addr, + (void *)&(clientsock.sa_in6.sin6_addr), + sizeof(struct in6_addr)) == 0) { + rv = 1; + } + break; +#endif + } + + if (rv == 1) + break; + } + (void)Xfree(buf); + break; + + default: + /* Something we can't deal with -- assume the worst... */ + break; + } + + return rv; +} +#endif /* SUNSOFT */ + /***************************************************************************** * * * public Shared Memory Extension routines * @@ -149,6 +332,15 @@ event_to_wire (Display *dpy, XEvent *re, Bool XShmQueryExtension (Display *dpy /* int *event_basep, *error_basep */) { XExtDisplayInfo *info = find_display (dpy); +#ifdef SUNSOFT + /* + * Sun Mod -- if we're dealing with a remote connection, then the + * shared memory extension is not valid. Sigh -- this should really + * be in the server somewhere... Required for pipe transport PIPECONN + */ + if(!LocalConnection(dpy)) + return False; +#endif /* SUNSOFT */ if (XextHasExtension(info)) { /* *event_basep = info->codes->first_event; @@ -181,6 +373,15 @@ Bool XShmQueryVersion( XExtDisplayInfo *info = find_display (dpy); xShmQueryVersionReply rep; register xShmQueryVersionReq *req; +#ifdef SUNSOFT + /* + * Sun Mod -- if we're dealing with a remote connection, then the + * shared memory extension is not valid. Sigh -- this should really + * be in the server somewhere... + */ + if(!LocalConnection(dpy)) + return False; +#endif /* SUNSOFT */ ShmCheckExtension (dpy, info, False);