summaryrefslogtreecommitdiff
path: root/common.c
diff options
context:
space:
mode:
Diffstat (limited to 'common.c')
-rw-r--r--common.c313
1 files changed, 240 insertions, 73 deletions
diff --git a/common.c b/common.c
index 7ce37a5..2a3f984 100644
--- a/common.c
+++ b/common.c
@@ -23,28 +23,66 @@
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
* *
+ * *
+ * Copyright 2002 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, and/or sell copies of the Software, and to permit persons
+ * to whom the Software is furnished to do so, provided that the above
+ * copyright notice(s) and this permission notice appear in all copies of
+ * the Software and that both the above copyright notice(s) and this
+ * permission notice appear in supporting documentation.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
+ * OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL
+ * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING
+ * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Except as contained in this notice, the name of a copyright holder
+ * shall not be used in advertising or otherwise to promote the sale, use
+ * or other dealings in this Software without prior written authorization
+ * of the copyright holder.
+ * *
\* *********************************************************** */
#include "scope.h"
+#ifdef SYSV
+#define bzero(s,l) memset(s, 0, l)
+#define bcopy(s,d,l) memmove(d,s,l)
+#endif
+
+#include <unistd.h>
+
/* ********************************************** */
/* */
/* Debugging support routines */
/* */
/* ********************************************** */
+void
enterprocedure(s)
char *s;
{
debug(2,(stderr, "-> %s\n", s));
}
+void
warn(s)
char *s;
{
fprintf(stderr, "####### %s\n", s);
}
+void
panic(s)
char *s;
{
@@ -58,21 +96,18 @@ panic(s)
/* */
/* ********************************************** */
-extern char *malloc();
-
-char *Malloc (n)
- long n;
+void *Malloc (long n)
{
- char *p;
- p = (char *)malloc((unsigned int)n);
+ void *p;
+ p = malloc(n);
debug(64,(stderr, "%x = malloc(%d)\n", p, n));
if (p == NULL)
panic("no more malloc space");
return(p);
}
-Free(p)
- char *p;
+void
+Free(void *p)
{
debug(64,(stderr, "%x = free\n", p));
free(p);
@@ -88,82 +123,55 @@ Free(p)
#include <signal.h>
-#ifdef SIGURG
-void SignalURG(int dummy)
+static void SignalURG(int sig)
{
debug(1,(stderr, "==> SIGURG received\n"));
}
-#endif /* #ifdef SIGURG */
-#ifdef SIGPIPE
-void SignalPIPE(int dummy)
+static void SignalPIPE(int sig)
{
debug(1,(stderr, "==> SIGPIPE received\n"));
}
-#endif /* #ifdef SIGPIPE */
-#ifdef SIGINT
-void SignalINT(int dummy)
+static void SignalINT(int sig)
{
debug(1,(stderr, "==> SIGINT received\n"));
exit(1);
-#endif /* #ifdef SIGINT */
}
-#ifdef SIGQUIT
-void SignalQUIT(int dummy)
+static void SignalQUIT(int sig)
{
debug(1,(stderr, "==> SIGQUIT received\n"));
exit(1);
-#endif /* #ifdef SIGQUIT */
}
-#ifdef SIGTERM
-void SignalTERM(int dummy)
+static void SignalTERM(int sig)
{
debug(1,(stderr, "==> SIGTERM received\n"));
exit(1);
-#endif /* #ifdef SIGTERM */
}
-#ifdef SIGTSTP
-void SignalTSTP(int dummy)
+static void SignalTSTP(int sig)
{
debug(1,(stderr, "==> SIGTSTP received\n"));
}
-#endif /* #ifdef SIGTSTP */
-#ifdef SIGCONT
-void SignalCONT(int dummy)
+static void SignalCONT(int sig)
{
debug(1,(stderr, "==> SIGCONT received\n"));
}
-#endif /* #ifdef SIGCONT */
+void
SetSignalHandling()
{
enterprocedure("SetSignalHandling");
-#ifdef SIGURG
- (void)signal(SIGURG, SignalURG);
-#endif /* #ifdef SIGURG */
-#ifdef SIGPIPE
- (void)signal(SIGPIPE, SignalPIPE);
-#endif /* #ifdef SIGPIPE */
-#ifdef SIGINT
- (void)signal(SIGINT, SignalINT);
-#endif /* #ifdef SIGINT */
-#ifdef SIGQUIT
- (void)signal(SIGQUIT, SignalQUIT);
-#endif /* #ifdef SIGQUIT */
-#ifdef SIGTERM
- (void)signal(SIGTERM, SignalTERM);
-#endif /* #ifdef SIGTERM */
-#ifdef SIGTSTP
- (void)signal(SIGTSTP, SignalTSTP);
-#endif /* #ifdef SIGTSTP */
-#ifdef SIGCONT
- (void)signal(SIGCONT, SignalCONT);
-#endif /* #ifdef SIGCONT */
+ signal(SIGURG, SignalURG);
+ signal(SIGPIPE, SignalPIPE);
+ signal(SIGINT, SignalINT);
+ signal(SIGQUIT, SignalQUIT);
+ signal(SIGTERM, SignalTERM);
+ signal(SIGTSTP, SignalTSTP);
+ signal(SIGCONT, SignalCONT);
}
@@ -174,31 +182,79 @@ SetSignalHandling()
/* */
/* ************************************************************ */
+#ifdef USE_XTRANS
+
+#include <X11/Xtrans/Xtrans.h>
+static XtransConnInfo *ListenTransConns = NULL;
+static int *ListenTransFds = NULL;
+static int ListenTransCount;
+
+#else
+
#include <sys/types.h> /* needed by sys/socket.h and netinet/in.h */
#include <sys/uio.h> /* for struct iovec, used by socket.h */
#include <sys/socket.h> /* for AF_INET, SOCK_STREAM, ... */
#include <sys/ioctl.h> /* for FIONCLEX, FIONBIO, ... */
+#include <sys/fcntl.h> /* for FIONCLEX, FIONBIO, ... */
#include <netinet/in.h> /* struct sockaddr_in */
#include <netdb.h> /* struct servent * and struct hostent * */
+#ifdef DNETCONN
+#include <X11/dni.h>
+#endif
+#ifdef DNETSVR4
+#include <X11/dni8.h>
+#include <dlfcn.h>
+struct hostent *(*dnet_gethostbyname)();
+int (*dnet_gethostname)();
+short initialize_libdni();
+#endif
static int ON = 1 /* used in ioctl */ ;
-#define BACKLOG 5
-
-/* for use in the UsingFD call -- defined later */
-extern int NewConnection ();
-
+#define BACKLOG 5
+#endif
-SetUpConnectionSocket(port)
- int port;
+void
+SetUpConnectionSocket(iport)
+ int iport;
{
+#ifdef USE_XTRANS
+ char port[20];
+ int partial;
+ int i;
+ extern long ServerBasePort;
+#else
FD ConnectionSocket;
struct sockaddr_in sin;
-#ifndef SO_DONTLINGER
- struct linger linger;
-#endif /* #ifndef SO_DONTLINGER */
+ short port;
+#endif
enterprocedure("SetUpConnectionSocket");
+#ifdef USE_XTRANS
+ ScopePort = iport - ServerBasePort;
+ sprintf (port, "%d", ScopePort);
+ if ((_X11TransMakeAllCOTSServerListeners (port, &partial,
+ &ListenTransCount, &ListenTransConns) >= 0) &&
+ (ListenTransCount >= 1)) {
+ if (partial) {
+ debug(4,(stderr,
+ "Warning: Failed to establish listening connections on some transports\n"));
+ }
+ ListenTransFds = (int *) malloc (ListenTransCount * sizeof (int));
+
+ for (i = 0; i < ListenTransCount; i++)
+ {
+ int fd = _X11TransGetConnectionNumber (ListenTransConns[i]);
+
+ ListenTransFds[i] = fd;
+ debug(4,(stderr, "Listening on FD %d\n", fd));
+ UsingFD(fd, NewConnection, ListenTransConns[i]);
+ }
+ } else {
+ panic("Could not open any listening connections");
+ }
+#else
+
/* create the connection socket and set its parameters of use */
ConnectionSocket = socket(AF_INET, SOCK_STREAM, 0);
if (ConnectionSocket < 0)
@@ -207,16 +263,10 @@ SetUpConnectionSocket(port)
exit(-1);
}
(void)setsockopt(ConnectionSocket, SOL_SOCKET, SO_REUSEADDR, (char *)NULL, 0);
-#ifdef SO_USELOOPBACK
(void)setsockopt(ConnectionSocket, SOL_SOCKET, SO_USELOOPBACK, (char *)NULL, 0);
-#endif /* #ifdef SO_USELOOPBACK */
#ifdef SO_DONTLINGER
(void)setsockopt(ConnectionSocket, SOL_SOCKET, SO_DONTLINGER, (char *)NULL, 0);
-#else /* #ifdef SO_DONTLINGER */
- linger.l_onoff = 0;
- linger.l_linger = 0;
- (void)setsockopt(ConnectionSocket, SOL_SOCKET, SO_LINGER, (char *)&linger, sizeof linger);
-#endif /* #ifdef SO_DONTLINGER */
+#endif
/* define the name and port to be used with the connection socket */
bzero((char *)&sin, sizeof(sin));
@@ -232,7 +282,7 @@ SetUpConnectionSocket(port)
(void) gethostname(MyHostName, sizeof(MyHostName));
ScopeHost = (char *) Malloc((long)(1+strlen(MyHostName)));
- (void)strcpy(ScopeHost, MyHostName);
+ strcpy(ScopeHost, MyHostName);
hp = gethostbyname(MyHostName);
if (hp == NULL)
panic("No address for our host");
@@ -243,7 +293,8 @@ SetUpConnectionSocket(port)
addresses. INADDR_ANY should work with all of them at once. */
sin.sin_addr.s_addr = INADDR_ANY;
- sin.sin_port = htons(port);
+ port = iport;
+ sin.sin_port = htons (port);
ScopePort = port;
/* bind the name and port number to the connection socket */
@@ -264,13 +315,129 @@ SetUpConnectionSocket(port)
};
/* a few more parameter settings */
-#ifdef FIOCLEX
- (void)ioctl(ConnectionSocket, FIOCLEX, 0);
-#endif /* #ifdef FIOCLEX */
- (void)ioctl(ConnectionSocket, FIONBIO, &ON);
+ ioctl(ConnectionSocket, FIOCLEX, 0);
+ ioctl(ConnectionSocket, FIONBIO, &ON);
debug(4,(stderr, "Listening on FD %d\n", ConnectionSocket));
UsingFD(ConnectionSocket, NewConnection);
+#endif
+
+}
+
+#ifndef USE_XTRANS
+#ifdef DNETSVR4
+SetUpDECnetConnection(display)
+int display;
+{
+ struct sockaddr_dn *sdn,sdnn; /* DECnet socket */
+ struct hostent *hp;
+ int sock;
+ char hostname[6];
+
+ if (!initialize_libdni()) {
+ fprintf(stderr,"Unable to open libdni.so\n");
+ exit(0);
+ }
+ sdn = &sdnn;
+ if (!(dnet_gethostname)(hostname)) {
+ fprintf(stderr,"Can't get DECnet local host name\n");
+ exit(0);
+ }
+ if ((hp = (struct hostent *)(dnet_gethostbyname)(hostname)) == NULL) {
+ fprintf(stderr,"xhost: can't get name %s\n",hostname);
+ exit(0);
+ }
+ sdn->sdn_family = AF_DECnet;
+ sdn->sdn_format = DNADDR_FMT1;
+ sdn->sdn_port = 0;
+ sprintf ((char *)sdn->sdn_name, "X$X%d", display);
+ sdn->sdn_namelen = strlen((char *)sdn->sdn_name);
+ sdn->sdn_addr = *(u_short *)hp->h_addr_list[0];
+
+ if ((sock = socket (AF_DECnet, SOCK_STREAM, 0)) < 0) {
+ perror("socket");
+ exit(0);
+ }
+ (void)setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *)NULL, 0);
+ (void)setsockopt(sock, SOL_SOCKET, SO_USELOOPBACK, (char *)NULL, 0);
+
+ if (bind(sock, (struct sockaddr_dn *)sdn,
+ sizeof(struct sockaddr_dn)) < 0) {
+ perror("DNI Bind");
+ exit(0);
+ }
+ if (listen(sock, 100) < 0) {
+ perror("DNI Listen");
+ exit(0);
+ }
+
+ UsingFD(sock, NewConnection);
}
+#endif
+#ifdef DNETCONN
+SetUpDECnetConnection(display)
+int display;
+{
+ struct ses_io_type sesopts;
+ char objname[6];
+ FD fd;
+
+ enterprocedure("SetUpDECnetConnection");
+ sprintf (objname, "X$X%d", display);
+ if ((fd = open("/dev/dni", O_RDWR)) < 0) {
+ fprintf(stderr,"xscope: dni: open failed\n");
+ exit(-1);
+ }
+ if (ioctl(fd, SES_GET_LINK, 0)) {
+ fprintf(stderr,"xscope: dni: can't get link\n");
+ exit(-1);
+ }
+ /* set nonblocking here since dni ignores fcntls */
+ /* set asyncronous to avoid blocking on SES_GET_AI */
+ sesopts.io_flags = SES_IO_NBIO + SES_IO_ASYNCH_MODE;
+ sesopts.io_io_signal = SIGIO;
+ sesopts.io_int_signal = 0;
+
+ if (ioctl(fd, SES_IO_TYPE, &sesopts) < 0) {
+ fprintf(stderr,"xscope: dni: ioctl failed\n");
+ exit(-1);
+ }
+
+ /* register as server */
+ if (ioctl(fd, SES_NAME_SERVER, objname) < 0) {
+ fprintf(stderr,"xscope: dni: ioctl failed\n");
+ exit(-1);
+ }
+ debug(4,(stderr, "Listening on DECnet FD %d\n", fd));
+ UsingFD(fd, NewConnection);
+}
+#endif
+#ifdef DNETSVR4
+short
+initialize_libdni()
+{
+ void *handle;
+ char *home;
+ char *path;
+
+ if (dnet_gethostname && dnet_gethostbyname)
+ return(1);
+ if (!(handle = dlopen("/etc/openwin/lib/libdni.so",RTLD_NOW))) {
+ if ((home = (char *)getenv("DNI_X_ENABLE")) == NULL)
+ return(0);
+ path = (char *)malloc(strlen(home) + 12);
+ sprintf(path, "%s%s",home, "/libdni.so");
+ if (!(handle = dlopen(path,RTLD_NOW)))
+ return(0);
+ free(path);
+ }
+ if (!(dnet_gethostbyname = (struct hostent *(*)())dlsym(handle,"dni_gethostbyname")))
+ return(0);
+ if (!(dnet_gethostname = (int (*)())dlsym(handle,"dni_gethostname")))
+ return(0);
+ return(1);
+}
+#endif
+#endif /* USE_XTRANS */