aboutsummaryrefslogtreecommitdiff
path: root/nx-X11/lib/dps/csstartNX.c
diff options
context:
space:
mode:
Diffstat (limited to 'nx-X11/lib/dps/csstartNX.c')
-rw-r--r--nx-X11/lib/dps/csstartNX.c237
1 files changed, 237 insertions, 0 deletions
diff --git a/nx-X11/lib/dps/csstartNX.c b/nx-X11/lib/dps/csstartNX.c
new file mode 100644
index 000000000..0db2cbe5b
--- /dev/null
+++ b/nx-X11/lib/dps/csstartNX.c
@@ -0,0 +1,237 @@
+/*
+ csstartNX.c
+
+ * (c) Copyright 1992-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
+ *
+ * Author: Adobe Systems Incorporated
+ */
+/* $XFree86: xc/lib/dps/csstartNX.c,v 1.6 2001/10/28 03:32:43 tsi Exp $ */
+
+#include <sys/param.h>
+#include <X11/X.h>
+#include <X11/Xlibint.h>
+#include <sys/wait.h>
+#include <DPS/dpsNXargs.h>
+#include <sys/socket.h>
+#include <errno.h>
+#include <X11/Xos.h>
+
+#include "DPSCAPproto.h"
+#include "Xlibnet.h" /* New for R5, delete for R4 */
+#include "dpsassert.h"
+#include "csfindNX.h"
+#include "csstartNX.h"
+
+/* ---Defines--- */
+
+#include <stddef.h>
+
+#define DOZETIME 1 /* time to wait for agent to start up (sec) */
+
+#define BASE_TCP_PORT CSDPSPORT
+
+#ifndef CSDPSMAXPORT
+#define CSDPSMAXPORT 16
+#endif
+
+#ifndef SO_REUSEADDR
+#define SO_REUSEADDR 1
+#endif
+
+/* ---Globals--- */
+
+pid_t gSecretAgentPID = 0; /* PID of launched agent *Shh!* Not public! */
+
+/* ---Private Functions--- */
+
+static int
+TryTCP(void)
+{
+ struct sockaddr_in insock;
+ int request;
+ unsigned short port, startPort = 0;
+ struct servent *serventInfo;
+ int okay;
+
+#ifndef ultrix
+ /* Ultrix has a nasty bug in getservbyname(). If the name passed
+ to it doesn't exist in the services list it will seg. fault...
+ * sigh * */
+ if ((serventInfo = getservbyname(DPS_NX_SERV_NAME,
+ (char *) 0)) != 0)
+ if (strcmp("tcp", serventInfo->s_proto) == 0) {
+ startPort = ntohs(serventInfo->s_port);
+ }
+ /* So, for Ultrix we just default to the default default port :-) */
+#endif /* ultrix */
+ if (startPort == 0) startPort = BASE_TCP_PORT;
+ if ((request = socket (AF_INET, SOCK_STREAM, 0)) < 0)
+ {
+ DPSWarnProc(NULL, "Creating TCP socket while recommending port\n");
+ return -1;
+ }
+#ifdef SO_REUSEADDR
+ /* Necesary to restart the server without a reboot */
+ {
+ int one = 1;
+ setsockopt(request, SOL_SOCKET, SO_REUSEADDR, (char *)&one, sizeof(int));
+ }
+ /* What the hell is all this? I'll tell you. We don't know
+ a prioi what port is free, so we try to bind to each
+ in sequence and return the one that works. */
+#if !defined(AIXV3)
+ {
+ struct linger lingere;
+
+ lingere.l_onoff = 0; /* off */
+ lingere.l_linger = 0; /* don't */
+ if(setsockopt(request, SOL_SOCKET, SO_LINGER, (char *)&lingere,
+ sizeof(struct linger)) != 0)
+ DPSWarnProc(NULL,
+ "Couldn't set TCP SO_DONTLINGER while recommending port.");
+ }
+#endif /* AIXV3 */
+#endif /* SO_REUSEADDR */
+ bzero((char *)&insock, sizeof (insock));
+ insock.sin_family = AF_INET;
+ insock.sin_addr.s_addr = htonl(INADDR_ANY);
+ okay = 0;
+
+ for (port = startPort; (int) port < (int) startPort + CSDPSMAXPORT; port++)
+ {
+ int result;
+ insock.sin_port = htons(port);
+
+ errno = 0;
+ result = bind(request, (struct sockaddr *) &insock, sizeof (insock));
+ if (result < 0)
+ {
+ if (errno != EADDRINUSE)
+ {
+ DPSWarnProc(NULL, "Binding TCP socket while recommending port.\n");
+ close(request);
+ return -1;
+ }
+ continue;
+ }
+ else
+ {
+ /* We have a good port number */
+ okay = 1;
+ break;
+ }
+ }
+ close(request);
+ return (okay) ? port : -1;
+}
+
+/* ---Functions--- */
+
+int
+XDPSNXRecommendPort(int transport)
+{
+ int ret;
+
+ switch (transport)
+ {
+ case XDPSNX_TRANS_UNIX:
+ /* If the TCP socket exists, we just assume the UNIX one
+ is there too. FALL THRU! */
+ case XDPSNX_TRANS_TCP: /* TCP */
+ ret = TryTCP();
+ break;
+ default: ret = -1;
+ }
+ return(ret);
+}
+
+int
+StartXDPSNX(char **additionalArgs)
+{
+ char **args, **cpp;
+ pid_t childPid;
+ int argc = 1; /* 1, args[0]:=path, args[1]:=null */
+ int i = 0;
+ int status = Success; /* assume we'll succeed */
+ char *execObj, **execArgs;
+
+ (void) XDPSGetNXArg(XDPSNX_EXEC_FILE, (void **) &execObj);
+ if (execObj == 0) return (!Success);
+
+ /* Create the argv list for the execl() call */
+ (void) XDPSGetNXArg(XDPSNX_EXEC_ARGS, (void **) &execArgs);
+ if (execArgs != 0)
+ for(cpp = execArgs; *cpp != 0; cpp++, argc++); /* count args. */
+ if (additionalArgs != 0) /* add on the add-on args. */
+ for(cpp = additionalArgs; *cpp != 0; cpp++, argc++);
+
+ args = (char **) Xmalloc(sizeof(char *) * (argc+1));
+ if (args == 0)
+ return(!Success);
+ args[argc] = 0; /* cap end of args */
+ args[i++] = execObj;
+ if (additionalArgs != 0)
+ for(cpp = additionalArgs; *cpp != 0; cpp++, i++) args[i] = *cpp;
+ if (execArgs != 0)
+ for(cpp = execArgs; *cpp != 0; cpp++, i++) args[i] = *cpp;
+
+ /* now try to start up the agent... */
+ if ((childPid = fork()) != -1) {
+ if (childPid == 0) { /* Child process */
+#ifndef __UNIXOS2__
+ if (setsid() < 0)
+ DPSWarnProc(NULL, "Agent unable to create session. Continuing...\n");
+#endif
+
+ /* Try to start the agent */
+ if (execvp(args[0], args) < 0) { /* Error!! */
+ exit(1); /* This is OKAY, we're the child here */
+ }
+ /* SHOULD NEVER REACH HERE */
+ } else { /* Parent (NX Client) */
+ (void) sleep(DOZETIME);
+ /* if decmips, pray that we hesitate long enough for the child... */
+ /* Check on child (NX Agent) */
+ if (waitpid(childPid, NULL, WNOHANG) != 0) {
+ /* Server terminated or stopped; don't care, result is same... */
+ status = !Success;
+ } else { /* we think the agent started okay */
+ gSecretAgentPID = childPid; /* set secret global */
+ }
+ }
+ } else { /* Error in fork */
+ status = !Success;
+ }
+ if (args != 0) (void) XFree(args);
+ return(status);
+}