/*
* csconndi.c -- low level connection maker for CSDPS
*
* (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 1989 Massachusetts Institute of Technology
*
* 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: xc/lib/dps/csconndi.c,v 1.11tsi Exp $ */
#endif
#define NEED_EVENTS
#include <stdio.h>
#include <stdlib.h>
the definition of NOFILE */
#include "Xlibnet.h" /* New for R5, delete for R4 */
#else
#endif
#include <ctype.h>
#ifdef DNETCONN
#endif
#include <netdb.h>
#include "DPSCAPproto.h"
#include "cslibint.h"
#include "dpsassert.h"
#define SELECT_TYPE int *
#else
#endif
#ifndef _XANYSET
#endif /* _XANYSET */
#ifndef X_CONNECTION_RETRIES /* number retries on ECONNREFUSED */
#endif
#define CONN_PARAMS char *, int , int , int *, int *, char **
#ifdef DNETCONN
static int MakeDECnetConnection(CONN_PARAMS);
#endif
#ifdef UNIXCONN
static int MakeUNIXSocketConnection(CONN_PARAMS);
#endif
#ifdef TCPCONN
static int MakeTCPConnection(CONN_PARAMS);
#endif
#ifdef STREAMSCONN
extern int _XMakeStreamsConnection(CONN_PARAMS);
#endif
/* This global controls the size of the output socket buffer. Zero
means to use the system default size. */
int gNXSndBufSize = 0;
{
if (dst) {
}
return dst;
}
/*
* Attempts to connect to agent, given name. Returns file descriptor
* (network socket) or -1 if connection fails. Names may be of the
* following format:
*
* [hostname] : [:] agentnumber
*
* The second colon indicates a DECnet style name. No hostname is interpretted
* as the most efficient local connection to a server on the same machine.
* This is usually:
*
* o shared memory
* o local stream
* o UNIX domain socket
* o TCP to local host
*/
int
char *display_name,
char **fullnamep, /* RETURN */
int *dpynump, /* RETURN */
int *familyp, /* RETURN */
int *saddrlenp, /* RETURN */
char **saddrp) /* RETURN, freed by caller */
{
p = display_name;
*saddrlenp = 0; /* set so that we can clear later */
/*
* Step 1, find the hostname. This is delimited by the required
* first colon.
*/
for (lastp = p; *p && *p != ':'; p++) ;
if (!*p) return -1; /* must have a colon */
if (p != lastp) { /* no hostname given */
}
/*
* Step 2, see if this is a DECnet address by looking for the optional
* second colon.
*/
if (p[1] == ':') { /* then DECnet format */
p++;
}
/*
* see if we're allowed to have a DECnet address
*/
#ifndef DNETCONN
#endif
/*
* Step 3, find the port number. This field is required.
* Zero is acceptable as a port number, meaning use the default.
*/
if ((p == lastp) || /* required field */
(*p != '\0' && *p != '.') || /* invalid non-digit terminator */
goto bad;
/*
* At this point, we know the following information:
*
* phostname hostname string or NULL
* iagent agent port number
* dnet DECnet boolean
*
* We can now decide which transport to use based on the ConnectionFlags
* build parameter the hostname string. If phostname is NULL or equals
* the string "local", then choose the best transport. If phostname
* is "unix", then choose BSD UNIX domain sockets (if configured).
*
* First, choose default transports: DECnet else (TCP or STREAMS)
*/
#ifdef DNETCONN
if (dnet)
else
#endif
#ifdef TCPCONN
#else
#ifdef STREAMSCONN
#else
#endif
#endif
#ifdef UNIXCONN
/*
* Now that the defaults have been established, see if we have any
* special names that we have to override:
*
* :N => if UNIXCONN then unix-domain-socket
* ::N => if UNIXCONN then unix-domain-socket
* unix:N => if UNIXCONN then unix-domain-socket
*
* Note that if UNIXCONN isn't defined, then we can use the default
* transport connection function set above.
*/
if (!phostname) {
}
}
#endif
if (!connfunc)
goto bad;
#ifdef UNIXCONN
#else
#define LOCALCONNECTION (!phostname)
#endif
if (LOCALCONNECTION) {
/*
* Get the auth info for local hosts so that it doesn't have to be
* repeated everywhere; the particular values in these fields are
* not part of the protocol.
*/
*familyp = FamilyLocal;
if (len > 0) {
if (*saddrp) {
} else {
*saddrlenp = 0;
}
}
}
#ifndef ultrix
/* Ultrix has a nasty bug in getservbyname(); if the name passed to
it is not in the services list it seg faults! *sigh* So, we
don't ever look in the services info for ultrix... */
if (iagent == 0) { /* find service default, if one's defined */
} else /* extract the port number */
}
}
#endif /* ultrix */
/*
* Make the connection, also need to get the auth address info for
* non-local connections. Do retries in case server host has hit its
* backlog (which, unfortunately, isn't distinguishable from there not
* being a server listening at all, which is why we have to not retry
* too many times).
*/
goto bad;
/*
* Set the connection non-blocking since we use select() to block; also
* set close-on-exec so that programs that fork() doesn't get confused.
*/
#ifdef FIOSNBIO
{
}
#else
#if defined(O_NONBLOCK)
#else
#endif /* O_NONBLOCK/FNDELAY */
#endif /* FIOSNBIO */
/*
* Build the expanded display name:
*
* [host] : [:] agent \0
*/
iagent);
return fd;
/*
* error return; make sure everything is cleaned up.
*/
bad:
if (*saddrp) {
}
*saddrlenp = 0;
return -1;
}
/*****************************************************************************
* *
* Make Connection Routines *
* *
*****************************************************************************/
#ifdef DNETCONN /* stupid makedepend */
#define NEED_BSDISH
#endif
#ifdef UNIXCONN
#define NEED_BSDISH
#endif
#ifdef TCPCONN
#define NEED_BSDISH
#endif
#ifdef NEED_BSDISH /* makedepend can't handle #if */
/*
* 4.2bsd-based systems
*/
#ifndef hpux
#ifdef apollo /* nest if(n)defs because makedepend is broken */
#ifndef NO_TCP_H
#endif /* NO_TCP_H */
#else /* apollo */
#endif /* apollo */
#endif
#endif /* NEED_BSDISH */
#ifdef DNETCONN
char *phostname;
int iagent;
int retries;
int *familyp; /* RETURN */
int *saddrlenp; /* RETURN */
char **saddrp; /* RETURN */
{
int fd;
extern int dnet_conn();
/*
* build the target object name.
*/
/*
* Attempt to open the DECnet connection, return -1 if fails; ought to
* do some retries here....
*/
return -1;
}
*familyp = FamilyDECnet;
} else {
return -1;
}
}
if (!*saddrp) {
return -1;
}
return fd;
}
#endif /* DNETCONN */
#ifdef UNIXCONN
#ifndef X_NO_SYS_UN
#endif
#ifndef CSDPS_UNIX_PATH
#ifdef hpux
#else
#endif
#endif
static int MakeUNIXSocketConnection (
char *phostname,
int iagent,
int retries,
int *familyp, /* RETURN */
int *saddrlenp, /* RETURN */
char **saddrp) /* RETURN */
{
/*
* Open the network connection.
*/
do {
return -1;
}
if (gNXSndBufSize > 0)
return -1;
}
sleep (1);
} else {
break;
}
} while (retries-- > 0);
/*
* Don't need to get auth info since we're local
*/
return fd;
}
#endif /* UNIXCONN */
#ifdef TCPCONN
static int MakeTCPConnection (
char *phostname,
int iagent,
int retries,
int *familyp, /* RETURN */
int *saddrlenp, /* RETURN */
char **saddrp) /* RETURN */
{
if (!phostname) {
hostnamebuf[0] = '\0';
}
/*
* if numeric host name then try to parse it as such; do the number
* first because some systems return garbage instead of INVALID_INETADDR
*/
} else {
}
/*
* try numeric
*/
if (hostinetaddr == INVALID_INETADDR) {
/* No such host! */
return -1;
}
/* Not an Internet host! */
return -1;
}
/* Set up the socket data. */
/* Only Cray UNICOS3 and UNICOS4 will define this */
{
long t;
}
#else
#endif /* CRAY and OLDTCP */
} else {
/* Only Cray UNICOS3 and UNICOS4 will define this */
#else
#endif /* CRAY and OLDTCP */
}
addrlen = sizeof (struct sockaddr_in);
/*
* Open the network connection.
*/
do {
return -1;
}
/*
* turn off TCP coalescence
*/
#ifdef TCP_NODELAY
{
}
#endif
if (gNXSndBufSize > 0)
/*
* connect to the socket; if there is no X server or if the backlog has
* been reached, then ECONNREFUSED will be returned.
*/
return -1;
}
sleep (1);
} else {
break;
}
} while (retries-- > 0);
/*
* Success! So, save the auth information
*/
#ifdef CRAY
#ifdef OLDTCP
#else
#endif /* OLDTCP */
#else /* else not CRAY */
#endif /* CRAY */
/*
* We are special casing the BSD hack localhost address
* 127.0.0.1, since this address shouldn't be copied to
* other machines. So, we simply omit generating the auth info
* since we set it to the local machine before calling this routine!
*/
if (*saddrp) {
} else {
*saddrlenp = 0;
}
}
return fd;
}
#endif /* TCPCONN */
/*****************************************************************************
* *
* Connection Utility Routines *
* *
*****************************************************************************/
/*
* Disconnect from server.
*/
{
return 0;
}
#include <stddef.h>
/*
* This is an OS dependent routine which:
* 1) returns as soon as the connection can be written on....
* 2) if the connection can be read, must enqueue events and handle errors,
* until the connection is writable.
*/
{
int nfound;
while (1) {
do {
} while (nfound <= 0);
long pend_not_register;
register long pend;
/* find out how much data can be read */
/* must read at least one xEvent; if none is pending, then
we'll just block waiting for it */
/* but we won't read more than the max buffer size */
/* round down to an integral number of XReps */
/* no space between comma and type or else macro will die */
else /* it's an event packet; die */
}
}
return;
}
}
{
int result;
do {
} while (result <= 0);
}
#ifdef XXX
char *auth_proto, /* NOT null-terminated */
char char *auth_string) /* NOT null-terminated */
{
int pad;
int niov = 0;
#define add_to_iov(b,l) \
/*
* write authorization protocol name and data
*/
if (auth_length > 0) {
}
if (auth_strlen > 0) {
}
return;
}
#endif /* XXX */