diff options
Diffstat (limited to 'nx-X11/lib/dps/csstartNX.c')
-rw-r--r-- | nx-X11/lib/dps/csstartNX.c | 237 |
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); +} |