#include "scope.h"
#include <fcntl.h>
#include <unistd.h>
void
enterprocedure (char *s)
{
debug(2,(stderr, "-> %s\n", s));
}
void
warn (char *s)
{
fprintf(stderr, "####### %s\n", s);
}
void
panic (char *s)
{
fprintf(stderr, "%s\n", s);
exit(1);
}
void *
Malloc (long n)
{
void *p;
p = malloc(n);
debug(64,(stderr, "%lx = malloc(%ld)\n", (unsigned long) p, n));
if (p == NULL)
panic("no more malloc space");
return(p);
}
void
Free(void *p)
{
debug(64,(stderr, "%lx = free\n", (unsigned long) p));
free(p);
}
#define __USE_BSD_SIGNAL
#include <signal.h>
static void SignalURG(int sig)
{
debug(1,(stderr, "==> SIGURG received\n"));
}
static void SignalPIPE(int sig)
{
signal (SIGPIPE, SignalPIPE);
debug(1,(stderr, "==> SIGPIPE received\n"));
}
static void SignalINT(int sig)
{
signal (SIGINT, SignalINT);
debug(1,(stderr, "==> SIGINT received\n"));
Interrupt = 1;
}
static void SignalQUIT(int sig)
{
debug(1,(stderr, "==> SIGQUIT received\n"));
exit(1);
}
static void SignalTERM(int sig)
{
debug(1,(stderr, "==> SIGTERM received\n"));
exit(1);
}
static void SignalTSTP(int sig)
{
debug(1,(stderr, "==> SIGTSTP received\n"));
}
static void SignalCONT(int sig)
{
debug(1,(stderr, "==> SIGCONT received\n"));
}
static void SignalUSR1(int sig)
{
debug(1,(stderr, "==> SIGUSR1 received\n"));
ScopeEnabled = ! ScopeEnabled;
}
void
SetSignalHandling(void)
{
enterprocedure("SetSignalHandling");
(void)signal(SIGURG, SignalURG);
(void)signal(SIGPIPE, SignalPIPE);
(void)signal(SIGINT, SignalINT);
(void)signal(SIGQUIT, SignalQUIT);
(void)signal(SIGTERM, SignalTERM);
(void)signal(SIGTSTP, SignalTSTP);
(void)signal(SIGCONT, SignalCONT);
if (HandleSIGUSR1)
(void)signal(SIGUSR1, SignalUSR1);
}
#ifdef USE_XTRANS
#define TRANS_CLIENT
#define TRANS_SERVER
#define X11_t
#include <X11/Xtrans/Xtrans.h>
static XtransConnInfo *ListenTransConns = NULL;
static int *ListenTransFds = NULL;
static int ListenTransCount;
#else
#include <sys/types.h>
#include <sys/uio.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <sys/fcntl.h>
#if !defined(FIOCLEX) && defined(HAVE_SYS_FILIO_H)
#include <sys/filio.h>
#endif
#include <netinet/in.h>
#include <netdb.h>
static int ON = 1 ;
#define BACKLOG 5
#endif
void
SetUpConnectionSocket(
int iport,
void (*connectionFunc)(int))
{
#ifdef USE_XTRANS
char port[20];
int partial;
int i;
#else
FD ConnectionSocket;
struct sockaddr_in sin;
short port;
int one = 1;
#ifndef SO_DONTLINGER
struct linger linger;
#endif
#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, NULL, ListenTransConns[i]);
}
} else {
panic("Could not open any listening connections");
}
#else
ConnectionSocket = socket(AF_INET, SOCK_STREAM, 0);
if (ConnectionSocket < 0)
{
perror("socket");
exit(-1);
}
(void)setsockopt(ConnectionSocket, SOL_SOCKET, SO_REUSEADDR, (char *)&one, sizeof (int));
#ifdef SO_USELOOPBACK
(void)setsockopt(ConnectionSocket, SOL_SOCKET, SO_USELOOPBACK, (char *)NULL, 0);
#endif
#ifdef SO_DONTLINGER
(void)setsockopt(ConnectionSocket, SOL_SOCKET, SO_DONTLINGER, (char *)NULL, 0);
#else
linger.l_onoff = 0;
linger.l_linger = 0;
(void)setsockopt(ConnectionSocket, SOL_SOCKET, SO_LINGER, (char *)&linger, sizeof linger);
#endif
bzero((char *)&sin, sizeof(sin));
sin.sin_family = AF_INET;
{
char MyHostName[256];
struct hostent *hp;
(void) gethostname(MyHostName, sizeof(MyHostName));
ScopeHost = (char *) Malloc((long)(1+strlen(MyHostName)));
strcpy(ScopeHost, MyHostName);
hp = gethostbyname(MyHostName);
if (hp == NULL)
panic("No address for our host");
bcopy((char *)hp->h_addr, (char*)&sin.sin_addr, hp->h_length);
}
sin.sin_addr.s_addr = INADDR_ANY;
port = iport;
sin.sin_port = htons (port);
ScopePort = port;
if (bind(ConnectionSocket, (struct sockaddr *)&sin, sizeof(sin)) < 0)
{
perror("bind");
exit(-1);
}
debug(4,(stderr, "Socket is FD %d for %s,%d\n",
ConnectionSocket, ScopeHost, ScopePort));
if (listen(ConnectionSocket, BACKLOG) < 0)
{
perror("listen");
exit(-1);
};
#ifdef FD_CLOEXEC
(void)fcntl(ConnectionSocket, F_SETFD, FD_CLOEXEC);
#else
(void)ioctl(ConnectionSocket, FIOCLEX, 0);
#endif
#if defined(O_NONBLOCK) && (!defined(ultrix) && !defined(hpux))
(void) fcntl (ConnectionSocket, F_SETFL, O_NONBLOCK);
#else
#ifdef FIOSNBIO
(void) ioctl (ConnectionSocket, FIOSNBIO, &ON);
#else
(void) fcntl (ConnectionSocket, F_SETFL, FNDELAY);
#endif
#endif
debug(4,(stderr, "Listening on FD %d\n", ConnectionSocket));
UsingFD(ConnectionSocket, connectionFunc, NULL, NULL);
#endif
}