diff options
Diffstat (limited to 'nx-X11/lib/dps/csopendi.c')
-rw-r--r-- | nx-X11/lib/dps/csopendi.c | 567 |
1 files changed, 567 insertions, 0 deletions
diff --git a/nx-X11/lib/dps/csopendi.c b/nx-X11/lib/dps/csopendi.c new file mode 100644 index 000000000..c0eb1d373 --- /dev/null +++ b/nx-X11/lib/dps/csopendi.c @@ -0,0 +1,567 @@ +/* + * csopendi.c -- open connection to CSDPS agent + * + * (c) Copyright 1990-1994 Adobe Systems Incorporated. + * All rights reserved. + * + * Permission to use, copy, modify, distribute, and sublicense this software + * and its documentation for any purpose and without fee is hereby granted, + * provided that the above copyright notices appear in all copies and that + * both those copyright notices and this permission notice appear in + * supporting documentation and that the name of Adobe Systems Incorporated + * not be used in advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. No trademark license + * to use the Adobe trademarks is hereby granted. If the Adobe trademark + * "Display PostScript"(tm) is used to describe this software, its + * functionality or for any other purpose, such use shall be limited to a + * statement that this software works in conjunction with the Display + * PostScript system. Proper trademark attribution to reflect Adobe's + * ownership of the trademark shall be given whenever any such reference to + * the Display PostScript system is made. + * + * ADOBE MAKES NO REPRESENTATIONS ABOUT THE SUITABILITY OF THE SOFTWARE FOR + * ANY PURPOSE. IT IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY. + * ADOBE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL + * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NON- INFRINGEMENT OF THIRD PARTY RIGHTS. IN NO EVENT SHALL ADOBE BE LIABLE + * TO YOU OR ANY OTHER PARTY FOR ANY SPECIAL, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE, STRICT LIABILITY OR ANY OTHER ACTION ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ADOBE WILL NOT + * PROVIDE ANY TRAINING OR OTHER SUPPORT FOR THE SOFTWARE. + * + * Adobe, PostScript, and Display PostScript are trademarks of Adobe Systems + * Incorporated which may be registered in certain jurisdictions + * + * Portions Copyright Massachusetts Institute of Technology 1985, 1986 + * 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 name of M.I.T. not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. M.I.T. makes no representations about the + * suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + * + * Author: Adobe Systems Incorporated and MIT X Consortium + */ +/* $XFree86$ */ + +#include <stdlib.h> +#include <stdio.h> +#include <sys/param.h> /* for MAXHOSTNAMELEN */ +#define NEED_EVENTS +#include <X11/Xlibint.h> +#include <X11/Xos.h> +#include "cslibint.h" +#ifdef XXX +#include <X11/Xauth.h> +#include <X11/Xatom.h> + +extern int _Xdebug; +extern Display *_XHeadOfDisplayList; + +#ifndef lint +static int lock; /* get rid of ifdefs when locking implemented */ +#endif + +#endif /* XXX */ + +#include <X11/X.h> +#include <X11/Xproto.h> + +#include "DPSCAPClient.h" +#include <DPS/dpsXclient.h> +#include <DPS/dpsNXargs.h> +#include "dpsassert.h" +#include "dpsNXprops.h" +#include "csfindNX.h" +#include "csstartNX.h" + +#ifdef DPSLNKL +#include "dpslnkl.inc" +#endif /* DPSLNKL */ + + +/* +++ Someday make this common with XDPS.c version */ +#define DPY_NUMBER(dpy) ((dpy)->fd) + +static xReq _dummy_request = { + 0, 0, 0 +}; + +static void OutOfMemory (Display *); + +#ifdef XXX +/* + * First, a routine for setting authorization data + */ +static int xauth_namelen = 0; +static char *xauth_name = NULL; /* NULL means use default mechanism */ +static int xauth_datalen = 0; +static char *xauth_data = NULL; /* NULL means get default data */ + +void XSetAuthorization (char *name, int namelen, char *data, int datalen) +{ + char *tmpname, *tmpdata; + + if (xauth_name) Xfree (xauth_name); /* free any existing data */ + if (xauth_data) Xfree (xauth_data); + + xauth_name = xauth_data = NULL; /* mark it no longer valid */ + xauth_namelen = xauth_datalen = 0; + + if (namelen < 0) namelen = 0; /* check for bogus inputs */ + if (datalen < 0) datalen = 0; /* maybe should return? */ + + if (namelen > 0) { /* try to allocate space */ + tmpname = Xmalloc ((unsigned) namelen); + if (!tmpname) return; + bcopy (name, tmpname, namelen); + } else { + tmpname = NULL; + } + + if (datalen > 0) { + tmpdata = Xmalloc ((unsigned) datalen); + if (!tmpdata) { + if (tmpname) (void) Xfree (tmpname); + return; + } + bcopy (data, tmpdata, datalen); + } else { + tmpdata = NULL; + } + + xauth_name = tmpname; /* and store the suckers */ + xauth_namelen = namelen; + xauth_data = tmpdata; + xauth_datalen = datalen; + return; +} + +#endif /* XXX */ + +/* + * Connects to a server, creates a Display object and returns a pointer to + * the newly created Display back to the caller. + */ +XExtData * +DPSCAPOpenAgent(Display *dpy, char *trueDisplayName) +{ + register Display *agent; + char *agentHost = (char *)NULL; + register int i; + char display_name[256]; /* pointer to display name */ + char licMethBuf[256]; + char *licMeth = licMethBuf; + char *fullname = NULL; + int idisplay; + char *server_addr = NULL; + int server_addrlen = 0; + int conn_family; + int transport, port; + XExtData *ext; + DPSCAPData my; + char hostname[MAXHOSTNAMELEN]; + +/* + * Find an agent to talk to. + */ +#ifdef DPSLNKL + extern unsigned ANXPFunc(); +#ifdef PSUSEPN + (void) sprintf(licMeth, "%s%s:%d", + LICENSE_METHOD_PREFIX, + ANXVENDOR, /* From dpslnkl.inc */ + ANXPFunc()); +#else /* PSUSEPN */ + (void) sprintf(licMeth, "%s%s", + LICENSE_METHOD_PREFIX, + ANXVENDOR); /* From dpslnkl.inc */ +#endif /* PSUSEPN */ +#else /* DPSLNKL */ + licMeth = NULL; /* We want an open service */ +#endif /* DPSLNKL */ + (void) N_XGetHostname(hostname, MAXHOSTNAMELEN); + switch(XDPSNXFindNX(dpy, licMeth, &agentHost, &transport, &port)) { + case findnx_not_found: { + /* try to start-up an NX? */ + Bool autoLaunch; + + XDPSGetNXArg(XDPSNX_AUTO_LAUNCH, (void **) &autoLaunch); + if (autoLaunch == True) { + int requestedTrans; + int requestedPort = 0; + char **args = NULL; + char *additionalArgs[2]; + char transportArg[256]; + + (void) DPSWarnProc(NULL, "Auto-launching DPS NX agent."); + XDPSGetNXArg(XDPSNX_LAUNCHED_AGENT_TRANS, (void **) &requestedTrans); + if (requestedTrans == XDPSNX_USE_BEST) { + XDPSNXSetClientArg(XDPSNX_LAUNCHED_AGENT_TRANS, + (void *)XDPSNX_TRANS_UNIX); + requestedTrans = XDPSNX_TRANS_UNIX; + } + /* cons-up an arg. to pass to Agent we are forking */ + + additionalArgs[1] = (char *) NULL; + additionalArgs[0] = transportArg; + XDPSGetNXArg(XDPSNX_LAUNCHED_AGENT_PORT, (void **) &requestedPort); + if (requestedPort == XDPSNX_USE_BEST) { + requestedPort = XDPSNXRecommendPort(requestedTrans); + if (requestedPort < 0) { + DPSWarnProc(NULL, "Auto-launcher can't get a port."); + return(NULL); + } + } + (void) sprintf(transportArg, "%s/%d", + (requestedTrans == XDPSNX_TRANS_DECNET ? + "dec" : "tcp"), + requestedPort); + args = additionalArgs; + /* ASSERT: first argument in additionalArgs must be + transport/port, unless agent changes to take this + anywhere */ + if (StartXDPSNX(args) != Success) { + char tb[256], *fs, **as; + (void) XDPSGetNXArg(XDPSNX_EXEC_FILE, (void **) &fs); + (void) XDPSGetNXArg(XDPSNX_EXEC_ARGS, (void **) &as); + (void) sprintf(tb, "FAILED to auto-launch:\n %s", fs); + if (as != NULL) + for (; *as != NULL; as++) { + if ((int) (strlen(*as) + 1 + (i = strlen(tb))) > 256-1) { + if (i > 256-1-4) + strcpy(&(tb[256-1-1-4]), " ..."); + else + strcat(tb, " ..."); + break; + } + (void) strcat(tb, " "); + (void) strcat(tb, *as); + } + DPSWarnProc(NULL, tb); + return(NULL); + } else { + (void) sprintf(display_name, "%s%s%d", hostname, + (requestedTrans == XDPSNX_TRANS_DECNET ? + "::" : ":"), + requestedPort); + } + } else { /* autoLaunch != True */ + return(NULL); + } + } + break; + case findnx_found: { /* XDPSNXFindNX() == Success */ + (void) sprintf(display_name, "%s%s%d", + (transport == XDPSNX_TRANS_UNIX ? + "unix" : agentHost), + (transport == XDPSNX_TRANS_DECNET ? "::" : ":"), + port); + /* Free agentHost later */ + } + break; + case findnx_error: + return(NULL); + break; + default: + DPSFatalProc(NULL, "Illegal value returned by XDPSNXFindNX"); + break; + } + + +/* + * Attempt to allocate a display structure. Return NULL if allocation fails. + */ + if ((agent = (Display *)Xcalloc(1, sizeof(Display))) == NULL) { + return(NULL); + } + +/* + * Call the Connect routine to get the network socket. If -1 is returned, the + * connection failed. The connect routine will set fullname to point to the + * expanded name. + */ + + if ((agent->fd = DPSCAPConnect(display_name, &fullname, &idisplay, + &conn_family, + &server_addrlen, &server_addr)) < 0) { + Xfree ((char *) agent); + return(NULL); + } +#ifdef XXX +/* + * Look up the authorization protocol name and data if necessary. + */ + if (xauth_name && xauth_data) { + conn_auth_namelen = xauth_namelen; + conn_auth_name = xauth_name; + conn_auth_datalen = xauth_datalen; + conn_auth_data = xauth_data; + } else { + char dpynumbuf[40]; /* big enough to hold 2^64 and more */ + (void) sprintf (dpynumbuf, "%d", idisplay); + + authptr = XauGetAuthByAddr ((unsigned short) conn_family, + (unsigned short) server_addrlen, + server_addr, + (unsigned short) strlen (dpynumbuf), + dpynumbuf, + (unsigned short) xauth_namelen, + xauth_name); + if (authptr) { + conn_auth_namelen = authptr->name_length; + conn_auth_name = (char *)authptr->name; + conn_auth_datalen = authptr->data_length; + conn_auth_data = (char *)authptr->data; + } else { + conn_auth_namelen = 0; + conn_auth_name = NULL; + conn_auth_datalen = 0; + conn_auth_data = NULL; + } + } +#ifdef HASDES + /* + * build XDM-AUTHORIZATION-1 data + */ + if (conn_auth_namelen == 19 && + !strncmp (conn_auth_name, "XDM-AUTHORIZATION-1", 19)) + { + static char encrypted_data[192/8]; + int i, j; + struct sockaddr_in in_addr; + int addrlen; + long now; + + j = 0; + for (i = 0; i < 8; i++) + { + encrypted_data[j] = conn_auth_data[i]; + j++; + } + addrlen = sizeof (in_addr); + getsockname (dpy->fd, (struct sockaddr *) &in_addr, &addrlen); + if (in_addr.sin_family == 2) + { + encrypted_data[j] = in_addr.sin_addr.s_net; j++; + encrypted_data[j] = in_addr.sin_addr.s_host; j++; + encrypted_data[j] = in_addr.sin_addr.s_lh; j++; + encrypted_data[j] = in_addr.sin_addr.s_impno; j++; + encrypted_data[j] = (in_addr.sin_port >> 8) & 0xff; j++; + encrypted_data[j] = (in_addr.sin_port) & 0xff; j++; + } + else + { + encrypted_data[j] = 0xff; j++; + encrypted_data[j] = 0xff; j++; + encrypted_data[j] = 0xff; j++; + encrypted_data[j] = 0xff; j++; + i = getpid (); + encrypted_data[j] = (i >> 8) & 0xff; j++; + encrypted_data[j] = (i) & 0xff; j++; + } + time (&now); + for (i = 3; i >= 0; i--) + { + encrypted_data[j] = (now >> (i * 8)) & 0xff; + j++; + } + XdmcpEncrypt (encrypted_data, conn_auth_data + 8, + encrypted_data, 192/8); + conn_auth_data = encrypted_data; + conn_auth_datalen = 192 / 8; + } +#endif /* HASDES */ + if (server_addr) (void) Xfree (server_addr); + +#endif /* XXX */ + +/* + * We succeeded at authorization, so let us move the data into + * the display structure. + */ + agent->lock_meaning = NoSymbol; +#ifdef XXX + /* this field is not present in post X11R5 */ + agent->current = None; +#endif + agent->event_vec[X_Error] = N_XUnknownWireEvent; + agent->event_vec[X_Reply] = N_XUnknownWireEvent; + agent->wire_vec[X_Error] = N_XUnknownNativeEvent; + agent->wire_vec[X_Reply] = N_XUnknownNativeEvent; + for (i = KeyPress; i < 128; i++) { + agent->event_vec[i] = N_XUnknownWireEvent; + agent->wire_vec[i] = N_XUnknownNativeEvent; + } + agent->cursor_font = None; + agent->last_req = (char *)&_dummy_request; + + /* Salt away the host:display string for later use. + Storage owned by agent, Xmalloc'd by connection + call above */ + agent->display_name = fullname; + + /* Set up the output buffers. */ + if ((agent->bufptr = agent->buffer = Xmalloc(BUFSIZE)) == NULL) { + OutOfMemory (dpy); + return(NULL); + } + agent->bufmax = agent->buffer + BUFSIZE; + + + /* Create extension data */ + + my = DPSCAPCreate(dpy, agent); + if (my == (DPSCAPData)NULL) + { + OutOfMemory(agent); + return(NULL); + } + ext = (XExtData *)Xcalloc(1, sizeof(XExtData)); + ext->private_data = (char *)my; + + /* Parse names to get true display name */ + if (agentHost && strcmp(hostname, agentHost)) + { + register char *s, *p; + char *dxname; + char nametmp[MAXHOSTNAMELEN]; + /* Agent is not on the same host as client, so fix + up the stupid abbreviations used for the display, + and whoever came up with the syntax should be shot. */ + dxname = DisplayString(dpy); + for (s = dxname, p = nametmp; *s; ++s) + if (*s == ':') + break; + else + *p++ = *s; + *p = '\0'; + if (nametmp[0] == '\0' + || !strcmp(nametmp, "unix") + || !strcmp(nametmp, "localhost")) + { + strcpy(trueDisplayName, hostname); + if (*s) + strcat(trueDisplayName, s); + else + strcat(trueDisplayName, ":0.0"); + } + else + strcpy(trueDisplayName, dxname); + } + else + strcpy(trueDisplayName, DisplayString(dpy)); + if (agentHost) + Xfree(agentHost); + return(ext); +} + + +/* OutOfMemory is called if malloc fails. XOpenDisplay returns NULL + after this returns. */ + +static void OutOfMemory (Display *dpy) +{ + DPSCAPCloseAgent(dpy); +} + +#ifdef NEEDFORNX +/* XFreeDisplayStructure frees all the storage associated with a + * Display. It is used by XOpenDisplay if it runs out of memory, + * and also by XCloseDisplay. It needs to check whether all pointers + * are non-NULL before dereferencing them, since it may be called + * by XOpenDisplay before the Display structure is fully formed. + * XOpenDisplay must be sure to initialize all the pointers to NULL + * before the first possible call on this. + */ + +static void +_XFreeDisplayStructure(register Display *dpy) +{ + if (dpy->screens) { + register int i; + + for (i = 0; i < dpy->nscreens; i++) { + Screen *sp = &dpy->screens[i]; + + if (sp->depths) { + register int j; + + for (j = 0; j < sp->ndepths; j++) { + Depth *dp = &sp->depths[j]; + + if (dp->visuals) { + register int k; + + for (k = 0; k < dp->nvisuals; k++) + _XFreeExtData (dp->visuals[k].ext_data); + Xfree ((char *) dp->visuals); + } + } + + Xfree ((char *) sp->depths); + } + + _XFreeExtData (sp->ext_data); + } + + Xfree ((char *)dpy->screens); + } + + if (dpy->pixmap_format) { + register int i; + + for (i = 0; i < dpy->nformats; i++) + _XFreeExtData (dpy->pixmap_format[i].ext_data); + Xfree ((char *)dpy->pixmap_format); + } + + if (dpy->display_name) + Xfree (dpy->display_name); + if (dpy->vendor) + Xfree (dpy->vendor); + + if (dpy->buffer) + Xfree (dpy->buffer); + if (dpy->atoms) + Xfree ((char *) dpy->atoms); + if (dpy->keysyms) + Xfree ((char *) dpy->keysyms); + if (dpy->modifiermap) + XFreeModifiermap(dpy->modifiermap); + if (dpy->xdefaults) + Xfree (dpy->xdefaults); + if (dpy->key_bindings) + _XFreeKeyBindings(dpy); + + while (dpy->ext_procs) { + _XExtension *ext = dpy->ext_procs; + dpy->ext_procs = ext->next; + if (ext->name) + Xfree (ext->name); + Xfree ((char *)ext); + } + + _XFreeExtData (dpy->ext_data); + + Xfree ((char *)dpy); +} +#endif /* NEEDFORNX */ + + + +void +DPSCAPCloseAgent(Display *agent) +{ + if (!agent) return; + N_XDisconnectDisplay(agent->fd); + if (agent->display_name) + Xfree(agent->display_name); + if (agent->buffer) + Xfree(agent->buffer); + Xfree((char *)agent); +} |