diff options
Diffstat (limited to 'common.c')
-rw-r--r-- | common.c | 313 |
1 files changed, 240 insertions, 73 deletions
@@ -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 */ |