824N/A/*
824N/A * csfindNX.c -- DPSCAP client Xlib extension hookup
824N/A *
824N/A * (c) Copyright 1992-1994 Adobe Systems Incorporated.
824N/A * All rights reserved.
824N/A *
824N/A * Permission to use, copy, modify, distribute, and sublicense this software
824N/A * and its documentation for any purpose and without fee is hereby granted,
824N/A * provided that the above copyright notices appear in all copies and that
824N/A * both those copyright notices and this permission notice appear in
824N/A * supporting documentation and that the name of Adobe Systems Incorporated
824N/A * not be used in advertising or publicity pertaining to distribution of the
824N/A * software without specific, written prior permission. No trademark license
824N/A * to use the Adobe trademarks is hereby granted. If the Adobe trademark
824N/A * "Display PostScript"(tm) is used to describe this software, its
824N/A * functionality or for any other purpose, such use shall be limited to a
824N/A * statement that this software works in conjunction with the Display
824N/A * PostScript system. Proper trademark attribution to reflect Adobe's
824N/A * ownership of the trademark shall be given whenever any such reference to
824N/A * the Display PostScript system is made.
824N/A *
824N/A * ADOBE MAKES NO REPRESENTATIONS ABOUT THE SUITABILITY OF THE SOFTWARE FOR
824N/A * ANY PURPOSE. IT IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY.
824N/A * ADOBE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
824N/A * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
824N/A * NON- INFRINGEMENT OF THIRD PARTY RIGHTS. IN NO EVENT SHALL ADOBE BE LIABLE
824N/A * TO YOU OR ANY OTHER PARTY FOR ANY SPECIAL, INDIRECT, OR CONSEQUENTIAL
824N/A * DAMAGES OR ANY DAMAGES WHATSOEVER WHETHER IN AN ACTION OF CONTRACT,
824N/A * NEGLIGENCE, STRICT LIABILITY OR ANY OTHER ACTION ARISING OUT OF OR IN
824N/A * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ADOBE WILL NOT
824N/A * PROVIDE ANY TRAINING OR OTHER SUPPORT FOR THE SOFTWARE.
824N/A *
824N/A * Adobe, PostScript, and Display PostScript are trademarks of Adobe Systems
824N/A * Incorporated which may be registered in certain jurisdictions
824N/A *
824N/A * Author: Adobe Systems Incorporated
824N/A */
824N/A/* $XFree86: xc/lib/dps/csfindNX.c,v 1.7tsi Exp $ */
824N/A
824N/A#include <sys/param.h> /* for MAXHOSTNAMELEN */
824N/A#include <stdlib.h>
824N/A#include <stdio.h>
824N/A#include <unistd.h> /* getuid() */
824N/A#include <string.h>
824N/A#include <pwd.h>
824N/A
824N/A#include <X11/X.h>
824N/A#include <X11/Xlib.h>
824N/A#include <X11/Xlibint.h>
824N/A#include <X11/Xatom.h>
824N/A#include <X11/Xresource.h>
824N/A
824N/A#include "csfindNX.h"
824N/A#include "dpsNXprops.h"
824N/A#include "Xlibnet.h"
824N/A#include "DPS/dpsXclient.h"
824N/A#include "DPS/dpsNXargs.h"
824N/A#include <DPS/XDPSlib.h>
824N/A
824N/A#include "dpsassert.h"
824N/A#include "cslibint.h"
824N/A
824N/A/* ---Defines--- */
824N/A
824N/A#define CANTSTARTAGENT "Unable to start agent.\n"
824N/A
824N/A/* ---Types--- */
824N/A
824N/Atypedef struct {
824N/A Window id;
824N/A int willingness;
824N/A} Agent, *AgentIdList;
824N/A
824N/A/* ---Globals--- */
824N/A
824N/Astatic char *XDPSLNXHost = NULL;
824N/Astatic int XDPSLNXPort = 0; /* default port to be used */
824N/Astatic int XDPSLNXTrans = XDPSNX_TRANS_UNIX;
824N/Astatic int gXDPSNXLaunchedAgentTrans = XDPSNX_USE_BEST;
824N/Astatic int gXDPSNXLaunchedAgentPort = XDPSNX_USE_BEST;
824N/Astatic char *gXDPSNXExecObj = XDPSNX_DEFAULT_EXEC_NAME; /* NX object file */
824N/Astatic char **gXDPSNXExecArgs = NULL; /* the args for gXDPSNXExecObj */
824N/Astatic Bool gWasAgentSet = False;
824N/Astatic Bool gXDPSNXAutoLaunch = False;
824N/Aunsigned char gXDPSNXErrorCode;
824N/Aextern int gNXSndBufSize; /* Output buffer size, zero means default */
824N/A
824N/Astatic char *getHomeDir(char *);
824N/A
824N/A/* ---Private Functions--- */
824N/A
824N/Astatic int
824N/ATmpErrorHandler(
824N/A Display *dpy,
824N/A XErrorEvent *err)
824N/A{
824N/A gXDPSNXErrorCode = err->error_code;
824N/A return 0;
824N/A}
824N/A
824N/A
824N/Astatic int
824N/AGetProperty(
824N/A Display *dpy,
824N/A Window w,
824N/A Atom prop,
824N/A Atom type,
824N/A unsigned long *nitems, /* IN: if non-null then RETURN val */
824N/A char **data) /* RETURN */
824N/A{
824N/A long largest_len = ((((unsigned long) -1) >> 1) / 4);
824N/A Atom actual_type;
824N/A int actual_format;
824N/A unsigned long actual_number;
824N/A unsigned long remaining;
824N/A
824N/A if (type == None) return(!Success); /* We need to have a type */
824N/A if ((XGetWindowProperty(dpy, w, prop, 0, largest_len, False, type,
824N/A &actual_type, &actual_format, &actual_number,
824N/A &remaining, (unsigned char **) data) == Success)
824N/A && (actual_type == type)) {
824N/A if (nitems != NULL) *nitems = actual_number;
824N/A return(Success);
824N/A } else {
824N/A if (*nitems != 0) { /* if data returned, clean up */
824N/A XFree(*data);
824N/A *data = NULL; /* is this necessary? */
824N/A *nitems = 0;
824N/A }
824N/A return(!Success);
824N/A }
824N/A}
824N/A
824N/A
824N/A/*
824N/A GetAgentIdList returns a list of agents advertising on the passed display (dpy),
824N/A and it returns the number of agents in the list in the parameter nAgents.
824N/A The returned list is sorted in most to least willing order.
824N/A GetAgentIdList assumes that it has exclusive access to the server associated with
824N/A dpy (ie. it assumes that the caller has done an XGrabServer).
824N/A */
824N/Astatic AgentIdList
824N/AGetAgentIdList(
824N/A Display *dpy,
824N/A unsigned long *nAgents) /* RETURN: number of agents in list */
824N/A{
824N/A Atom serverListAtom = XInternAtom(dpy, XDPSNX_BILLBOARD_PROP, True);
824N/A Window *agents = NULL;
824N/A AgentIdList agentList = NULL;
824N/A int (*oldErrorHandler)(Display *, XErrorEvent *) = 0; /* the current error handler */
824N/A unsigned long i, current;
824N/A
824N/A if (serverListAtom == None) { /* Servers registered on dpy */
824N/A goto failed;
824N/A }
824N/A
824N/A XSync(dpy, False); /* force processing of pending requests */
824N/A
824N/A if (GetProperty(dpy, RootWindow(dpy, DefaultScreen(dpy)),
824N/A serverListAtom, XA_WINDOW, nAgents,
824N/A (char **) &agents) != Success) {
824N/A goto failed;
824N/A }
824N/A
824N/A if ((agentList = (AgentIdList)
824N/A Xcalloc(*nAgents, (unsigned) sizeof(Agent))) == NULL)
824N/A goto failed;
824N/A
824N/A /* let's go through the list and figure out which servers are okay */
824N/A oldErrorHandler = XSetErrorHandler(TmpErrorHandler);
824N/A current = 0;
824N/A for (i=0; i < *nAgents; i++) {
824N/A unsigned long len;
824N/A int *agentWillingness;
824N/A unsigned long k;
824N/A
824N/A for (k=0; k < i; k++) /* Search for duplicate ids */
824N/A if (agents[i] == agents[k]) { /* uh oh... */
824N/A agents[i] = None;
824N/A break;
824N/A }
824N/A if (k == i) { /* No duplicate ids */
824N/A if (GetProperty(dpy, agents[i],
824N/A XInternAtom(dpy, XDPSNX_WILLINGNESS_PROP, True),
824N/A XA_INTEGER, &len, (char **) &agentWillingness)
824N/A != Success) {
824N/A /* Assume that Agent i is dead... */
824N/A /* reap the agent */
824N/A agents[i] = None;
824N/A gXDPSNXErrorCode = None;
824N/A } else {
824N/A unsigned long j = 0;
824N/A
824N/A /* insert the agents into agentList in "most to least willing" order */
824N/A while ((j < current) && (agentList[j].willingness > *agentWillingness))
824N/A j++;
824N/A if (j < current)
824N/A (void) bcopy((char *) &agentList[j], (char *) &agentList[j+1],
824N/A sizeof(Agent) * (*nAgents - j - 1));
824N/A agents[current] = agents[i];
824N/A agentList[j].id = agents[current++];
824N/A agentList[j].willingness = *agentWillingness;
824N/A XFree(agentWillingness);
824N/A }
824N/A }
824N/A }
824N/A (void) XSetErrorHandler(oldErrorHandler);
824N/A oldErrorHandler = NULL;
824N/A if (*nAgents != current) { /* agent list changed */
824N/A if (current > 0) { /* are there living ones? */
824N/A *nAgents = current;
824N/A /* write the list back out onto the root window */
824N/A (void) XChangeProperty(dpy, RootWindow(dpy, DefaultScreen(dpy)),
824N/A serverListAtom, XA_WINDOW, 32,
824N/A PropModeReplace, (unsigned char *) agents, *nAgents);
824N/A } else {
824N/A (void) XDeleteProperty(dpy, RootWindow(dpy, DefaultScreen(dpy)),
824N/A serverListAtom);
824N/A goto failed;
824N/A }
824N/A }
824N/A (void) XFree(agents);
824N/A return(agentList);
824N/A
824N/A failed:
824N/A if (agents != NULL) XFree(agents);
824N/A if (agentList != NULL) XFree(agentList);
824N/A if (oldErrorHandler != NULL) (void) XSetErrorHandler(oldErrorHandler);
824N/A *nAgents = 0;
824N/A return(NULL);
824N/A}
824N/A
824N/A
824N/Astatic int
824N/AXDPSNXOnDisplay(
824N/A Display *dpy,
824N/A char *licenseMethod,
824N/A char **host,
824N/A int *transport,
824N/A int *port)
824N/A{
824N/A unsigned long nAgents = 0;
824N/A AgentIdList agentList = NULL;
824N/A Bool match = False;
824N/A unsigned long i = 0;
824N/A int status = !Success;
824N/A
824N/A#ifdef DPSLNKL
824N/A extern unsigned ANXKFunc();
824N/A#endif /* DPSLNKL */
824N/A
824N/A (void) XGrabServer(dpy); /* Can we do this later? */
824N/A if ((agentList = GetAgentIdList(dpy, &nAgents)) == NULL)
824N/A goto cleanup;
824N/A /* NOTE: agentList was sorted most to least willing by GetAgentIdList */
824N/A if (agentList[i].willingness <= 0) { /* Is there a willing agent? */
824N/A DPSWarnProc(NULL, "Found agent(s) for display, but none willing to accept connections.\n");
824N/A goto cleanup;
824N/A }
824N/A
824N/A#ifdef DPSLNKL
824N/A /* Masterkey bypass code */
824N/A if (ANXKFunc() != 0) {
824N/A /* We have a willing agent and the client has masterkeys so... */
824N/A match = True;
824N/A } else /* Search for appropriate agent */
824N/A#endif /* DPSLNKL */
824N/A {
824N/A /* need to get licensing info from dpy */
824N/A Atom desiredLicenseMethod, openLicenseMethod;
824N/A char openLicenseString[256];
824N/A
824N/A (void) sprintf(openLicenseString, "%s:%d",
824N/A LICENSE_METHOD_OPEN,
824N/A OPEN_LICENSE_VERSION);
824N/A openLicenseMethod = XInternAtom(dpy, openLicenseString, True);
824N/A
824N/A if (licenseMethod != NULL)
824N/A desiredLicenseMethod = XInternAtom(dpy, licenseMethod, True);
824N/A else
824N/A desiredLicenseMethod = None;
824N/A
824N/A if ((desiredLicenseMethod != None) || (openLicenseMethod != None)) {
824N/A for (i=0;
824N/A (i < nAgents) && (agentList[i].willingness > 0) && (match == False);
824N/A i++) {
824N/A Atom *licenseMethods = NULL;
824N/A unsigned long nMethods;
824N/A unsigned long j;
824N/A
824N/A if (GetProperty(dpy, agentList[i].id,
824N/A XInternAtom(dpy, XDPSNX_LICENSE_METHOD_PROP, True),
824N/A XA_ATOM,
824N/A &nMethods, (char **) &licenseMethods) != Success)
824N/A goto cleanup;
824N/A
824N/A /*
824N/A Check to see if the agent supports either our desired license method or
824N/A if it is an open service.
824N/A */
824N/A j = 0;
824N/A while((j < nMethods)
824N/A && (licenseMethods[j] != desiredLicenseMethod)
824N/A && (licenseMethods[j] != openLicenseMethod)) j++;
824N/A if (j < nMethods) { /* We found one */
824N/A match = True;
824N/A break;
824N/A }
824N/A (void) XFree(licenseMethods);
824N/A }
824N/A }
824N/A }
824N/A
824N/A if (match) { /* We had a match on license method */
824N/A TransportInfo *transInfo;
824N/A
824N/A if (GetProperty(dpy, agentList[i].id,
824N/A XInternAtom(dpy, XDPSNX_TRANSPORT_INFO_PROP, True),
824N/A XA_INTEGER, NULL, (char **) &transInfo) != Success) {
824N/A goto cleanup;
824N/A } else { /* We got one! */
824N/A *transport = transInfo->transport;
824N/A *port = transInfo->port;
824N/A match = True;
824N/A XFree(transInfo);
824N/A }
824N/A if (GetProperty(dpy, agentList[i].id,
824N/A XInternAtom(dpy, XDPSNX_HOST_NAME_PROP, True), XA_STRING,
824N/A NULL, (char **) host) == Success) {
824N/A status = Success;
824N/A /*
824N/A * If transport is TCP, but we are on the same host as the agent then
824N/A * trade-up to the more efficient UNIX transport...
824N/A */
824N/A if (*transport == XDPSNX_TRANS_TCP) {
824N/A char hostname[MAXHOSTNAMELEN];
824N/A (void) N_XGetHostname(hostname, MAXHOSTNAMELEN);
824N/A if (strcmp(hostname, *host) == 0)
824N/A *transport = XDPSNX_TRANS_UNIX;
824N/A }
824N/A }
824N/A }
824N/A /*
824N/A * Exit Clauses: status inited to FAILURE. Therefore cleanup "assumes"
824N/A * a failure unless noted otherwise.
824N/A */
824N/A cleanup:
824N/A (void) XUngrabServer(dpy);
824N/A (void) XDPSLFlush(dpy); /* Flush the ungrab */
824N/A if (agentList != NULL) XFree(agentList);
824N/A return(status);
824N/A}
824N/A
824N/A
824N/Astatic int
824N/AParseAgentString(
824N/A char *string,
824N/A char **hostname, /* RETURN */
824N/A int *transport, /* RETURN */
824N/A int *port) /* RETURN */
824N/A{
824N/A int dnet = 0;
824N/A Bool transportSpecified = False;
824N/A char namebuf[255];
824N/A char *p;
824N/A
824N/A (void) strncpy(namebuf, string, strlen(string)+1);
824N/A p = &namebuf[0];
824N/A /*
824N/A * Step 1, find the hostname. This is delimited by a required colon.
824N/A */
824N/A for (; *p && *p != ':'; p++);
824N/A if (!*p) return(!Success); /* There must be a colon */
824N/A
824N/A if (*(p+1) == ':') {
824N/A dnet++;
824N/A *(p++) = '\0';
824N/A }
824N/A *(p++) = '\0';
824N/A
824N/A /*
824N/A * Step 2, get the port number. It follows the colon(s)
824N/A */
824N/A if (*p == '\0') /* No port number specified... */
824N/A return(!Success);
824N/A
824N/A *port = atoi(p);
824N/A
824N/A /*
824N/A * Step 3, transport?
824N/A */
824N/A if (namebuf[0] == '\0') { /* no transport/hostname specified... */
824N/A if (dnet)
824N/A (void) strcpy(namebuf, "0");
824N/A else { /* no hostname, so must be UNIX */
824N/A *hostname = NULL;
824N/A *transport = XDPSNX_TRANS_UNIX;
824N/A return(Success);
824N/A }
824N/A } else {
824N/A /* find the delimiting '/' */
824N/A for (p = &namebuf[0]; *p && *p != '/'; p++);
824N/A if (*p == '/') {
824N/A transportSpecified = True;
824N/A *p = '\0';
824N/A p++;
824N/A } else /* no transport specified */
824N/A p = &namebuf[0];
824N/A if ((*hostname = (char *) Xmalloc(strlen(p))) == NULL)
824N/A return(!Success); /* can't alloc space for hostname */
824N/A (void) strcpy(*hostname, p);
824N/A
824N/A /* identify protocol */
824N/A if (dnet)
824N/A *transport = XDPSNX_TRANS_DECNET;
824N/A else if (transportSpecified) {
824N/A if (strcmp(namebuf, "unix") == 0)
824N/A *transport = XDPSNX_TRANS_UNIX;
824N/A else /* assume tcp */
824N/A *transport = XDPSNX_TRANS_TCP;
824N/A } else
824N/A *transport = XDPSNX_TRANS_TCP;
824N/A }
824N/A return(Success);
824N/A}
824N/A
824N/Astatic int
824N/AFindXDPSNXInXrmDatabase(
824N/A Display *dpy,
824N/A char **host,
824N/A int *transport,
824N/A int *port)
824N/A{
824N/A XrmDatabase rDB = NULL; /* for merged database */
824N/A XrmDatabase serverDB;
824N/A char filenamebuf[1024];
824N/A char *filename = &filenamebuf[0];
824N/A char *env, *str_type;
824N/A char name[255];
824N/A XrmValue value;
824N/A int retVal = !Success;
824N/A
824N/A XrmInitialize();
824N/A (void) strcpy(name, "/usr/lib/X11/app-defaults/");
824N/A (void) strcat(name, XDPSNX_X_CLASS_NAME);
824N/A
824N/A /* try to get application defaults file, if there is any */
824N/A XrmMergeDatabases(XrmGetFileDatabase(name), &rDB);
824N/A
824N/A /* try to merge the server defaults. if not defined then use .Xdefaults */
824N/A if (XResourceManagerString(dpy) != NULL) {
824N/A serverDB = XrmGetStringDatabase(XResourceManagerString(dpy));
824N/A } else { /* use the .Xdefaults */
824N/A (void) getHomeDir(filename);
824N/A (void) strcat(filename, "/.Xdefaults");
824N/A
824N/A serverDB = XrmGetFileDatabase(filename);
824N/A }
824N/A XrmMergeDatabases(serverDB, &rDB);
824N/A
824N/A /* try the XENVIRONMENT file, or if not defined, then .Xdefaults */
824N/A if ((env = getenv("XENVIRONMENT")) == NULL) {
824N/A int len;
824N/A env = getHomeDir(filename);
824N/A (void) strcat(filename, "/.Xdefaults-");
824N/A len = strlen(env);
824N/A (void) gethostname(env+len, 1024-len);
824N/A }
824N/A XrmMergeDatabases(XrmGetFileDatabase(env), &rDB);
824N/A
824N/A /* Now that the database is built, try to extract the values we want. */
824N/A
824N/A if (XrmGetResource(rDB, XDPSNX_X_RESOURCE, XDPSNX_X_CLASS_NAME, &str_type,
824N/A &value) == True) {
824N/A retVal = ParseAgentString((char *) value.addr, host, transport, port);
824N/A }
824N/A (void) XrmDestroyDatabase(rDB);
824N/A return(retVal);
824N/A}
824N/A
824N/A
824N/Astatic char *
824N/AgetHomeDir(char *dest)
824N/A{
824N/A register char *ptr;
824N/A
824N/A if ((ptr = getenv("HOME")) != NULL) {
824N/A (void) strcpy(dest, ptr);
824N/A } else {
824N/A struct passwd *pw;
824N/A
824N/A if ((ptr = getenv("USER")) != NULL) {
824N/A pw = getpwnam(ptr);
824N/A } else {
824N/A pw = getpwuid(getuid());
824N/A }
824N/A if (pw) {
824N/A (void) strcpy(dest, pw->pw_dir);
824N/A } else {
824N/A *dest = ' ';
824N/A }
824N/A }
824N/A return (dest);
824N/A}
824N/A
824N/A
824N/A
824N/A/* ---Public Functions--- */
824N/A
824N/Aint gForceLaunchHack = 0; /* Undocumented way to force autolaunch */
824N/A
824N/AXDPSNXFindNXResult
824N/AXDPSNXFindNX(
824N/A Display *dpy,
824N/A char *licenseMethod,
824N/A char **host,
824N/A int *transport,
824N/A int *port)
824N/A{
824N/A char *agentenv;
824N/A
824N/A if (gForceLaunchHack)
824N/A return(findnx_not_found);
824N/A
824N/A if (gWasAgentSet) { /* check if client set up host */
824N/A *host = XDPSLNXHost;
824N/A *transport = XDPSLNXTrans;
824N/A *port = XDPSLNXPort;
824N/A return(findnx_found);
824N/A /* check DPSNXHOST environment variable */
824N/A } else if ((agentenv = getenv(AGENT_ENV_VAR)) != NULL) {
824N/A int status = ParseAgentString(agentenv, host, transport, port);
824N/A if (status != Success) {
824N/A DPSWarnProc((DPSContext) NULL, "Illegal syntax for DPSNXHOST");
824N/A return(findnx_error);
824N/A } else return(findnx_found);
824N/A /* check advertisements... */
824N/A } else if (XDPSNXOnDisplay(dpy, licenseMethod, host, transport, port) ==
824N/A Success) {
824N/A return(findnx_found);
824N/A /* check XrmDatabase */
824N/A } else if (FindXDPSNXInXrmDatabase(dpy, host, transport, port) == Success) {
824N/A return(findnx_found);
824N/A }
824N/A /* Nada */
824N/A return(findnx_not_found);
824N/A}
824N/A
824N/A
824N/AStatus
824N/AXDPSNXSetClientArg(int arg, void *value)
824N/A{
824N/A Display *dpy;
824N/A
824N/A if (arg == XDPSNX_AGENT) {
824N/A gWasAgentSet = True;
824N/A return(ParseAgentString(value,
824N/A &XDPSLNXHost, &XDPSLNXTrans, &XDPSLNXPort));
824N/A }
824N/A else if (arg == XDPSNX_EXEC_FILE) {
824N/A if ((gXDPSNXExecObj = Xmalloc(strlen((char *) value) + 1)) == NULL) {
824N/A return(!Success);
824N/A }
824N/A gXDPSNXExecObj = strcpy(gXDPSNXExecObj, (char *) value);
824N/A } else if (arg == XDPSNX_EXEC_ARGS) {
824N/A int i;
824N/A char **cpp, **execInfo;
824N/A
824N/A execInfo = (char **) value;
824N/A for(cpp = execInfo, i = 1; *cpp != NULL; i++, cpp++); /* count */
824N/A gXDPSNXExecArgs = (char **) Xcalloc(i, sizeof(char *));
824N/A if (gXDPSNXExecArgs == NULL) return(!Success);
824N/A for(cpp = gXDPSNXExecArgs; *execInfo != NULL;
824N/A execInfo++, cpp++) {
824N/A /* copy each entry */
824N/A if ((*cpp = Xmalloc(strlen(*execInfo) + 1)) == NULL)
824N/A return(!Success);
824N/A *cpp = strcpy(*cpp, *execInfo);
824N/A }
824N/A } else if (arg == XDPSNX_AUTO_LAUNCH) {
824N/A gXDPSNXAutoLaunch = (Bool)(long) value;
824N/A } else if (arg == XDPSNX_LAUNCHED_AGENT_TRANS) {
824N/A gXDPSNXLaunchedAgentTrans = (long) value;
824N/A } else if (arg == XDPSNX_LAUNCHED_AGENT_PORT) {
824N/A gXDPSNXLaunchedAgentPort = (long) value;
824N/A } else if (arg == XDPSNX_REQUEST_XSYNC) {
824N/A dpy = (Display *) value;
824N/A if (dpy == (Display *)NULL)
824N/A return(Success);
824N/A XDPSLSetSyncMask(dpy, DPSCAP_SYNCMASK_SYNC);
824N/A } else if (arg == XDPSNX_REQUEST_RECONCILE) {
824N/A dpy = (Display *) value;
824N/A if (dpy == (Display *)NULL)
824N/A return(Success);
824N/A XDPSLSetSyncMask(dpy, DPSCAP_SYNCMASK_RECONCILE);
824N/A } else if (arg == XDPSNX_REQUEST_BUFFER) {
824N/A dpy = (Display *) value;
824N/A if (dpy == (Display *)NULL)
824N/A return(Success);
824N/A XDPSLSetSyncMask(dpy, DPSCAP_SYNCMASK_BUFFER);
824N/A } else if (arg == XDPSNX_GC_UPDATES_SLOW) {
824N/A dpy = (Display *) value;
824N/A if (dpy == (Display *)NULL)
824N/A return(Success);
824N/A XDPSLSetGCFlushMode(dpy, XDPSNX_GC_UPDATES_SLOW);
824N/A } else if (arg == XDPSNX_GC_UPDATES_FAST) {
824N/A dpy = (Display *) value;
824N/A if (dpy == (Display *)NULL)
824N/A return(Success);
824N/A XDPSLSetGCFlushMode(dpy, XDPSNX_GC_UPDATES_FAST);
824N/A } else if (arg == XDPSNX_SEND_BUF_SIZE) {
824N/A int i = (long)value;
824N/A if (i >= 4096 && i <= 65536) gNXSndBufSize = i;
824N/A }
824N/A return(Success);
824N/A}
824N/A
824N/A
824N/Avoid
824N/AXDPSGetNXArg(int arg, void **value)
824N/A{
824N/A static char agentBuffer[255];
824N/A
824N/A if (arg == XDPSNX_AGENT) {
824N/A switch(XDPSLNXTrans) {
824N/A case XDPSNX_TRANS_UNIX:
824N/A (void) sprintf(agentBuffer, "unix/");
824N/A break;
824N/A case XDPSNX_TRANS_TCP:
824N/A (void) sprintf(agentBuffer, "tcp/");
824N/A break;
824N/A case XDPSNX_TRANS_DECNET:
824N/A (void) sprintf(agentBuffer, "decnet/");
824N/A break;
824N/A default:
824N/A DPSWarnProc(NULL, "Unknown transport passed to XDPSGetNXArg ignored.\n");
824N/A agentBuffer[0] = '\0';
824N/A break;
824N/A }
824N/A (void) strcat(agentBuffer, XDPSLNXHost);
824N/A (void) strcat(agentBuffer,
824N/A (XDPSLNXTrans == XDPSNX_TRANS_DECNET ? "::" : ":"));
824N/A (void) sprintf(&agentBuffer[strlen(agentBuffer)], "%d", XDPSLNXPort);
824N/A *value = (void *) agentBuffer;
824N/A }
824N/A else if (arg == XDPSNX_EXEC_FILE) {
824N/A *value = (void *) gXDPSNXExecObj;
824N/A } else if (arg == XDPSNX_EXEC_ARGS) {
824N/A *value = (void *) gXDPSNXExecArgs;
824N/A } else if (arg == XDPSNX_AUTO_LAUNCH) {
824N/A *value = (void *) (long)gXDPSNXAutoLaunch;
824N/A } else if (arg == XDPSNX_LAUNCHED_AGENT_TRANS) {
824N/A *value = (void *) (long)gXDPSNXLaunchedAgentTrans;
824N/A } else if (arg == XDPSNX_LAUNCHED_AGENT_PORT) {
824N/A *value = (void *) (long)gXDPSNXLaunchedAgentPort;
824N/A }
824N/A}