#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/time.h>
#include <sys/utsname.h>
#include <vncviewer.h>
Bool listenSpecified = False;
int listenPort = 0;
static Bool AllXEventsPredicate(Display *d, XEvent *ev, char *arg);
void
listenForIncomingConnections(int *argc, char **argv, int listenArgIndex)
{
Display *d;
XEvent ev;
int listenSocket, sock;
fd_set fds;
int n;
int i;
char *displayname = NULL;
listenSpecified = True;
for (i = 1; i < *argc; i++) {
if (strcmp(argv[i], "-display") == 0 && i+1 < *argc) {
displayname = argv[i+1];
}
}
if (listenArgIndex+1 < *argc && argv[listenArgIndex+1][0] >= '0' &&
argv[listenArgIndex+1][0] <= '9') {
listenPort = (LISTEN_PORT_OFFSET + atoi(argv[listenArgIndex+1])) & 0xFFFF;
removeArgs(argc, argv, listenArgIndex, 2);
} else {
char *display;
char *colonPos;
struct utsname hostinfo;
removeArgs(argc, argv, listenArgIndex, 1);
display = XDisplayName(displayname);
colonPos = strchr(display, ':');
uname(&hostinfo);
if (colonPos && ((colonPos == display) ||
(strncmp(hostinfo.nodename, display,
strlen(hostinfo.nodename)) == 0))) {
listenPort = LISTEN_PORT_OFFSET + atoi(colonPos+1);
} else {
fprintf(stderr,"%s: cannot work out which display number to "
"listen on.\n", programName);
fprintf(stderr,"Please specify explicitly with -listen <num>\n");
exit(1);
}
}
if (!(d = XOpenDisplay(displayname))) {
fprintf(stderr,"%s: unable to open display %s\n",
programName, XDisplayName(displayname));
exit(1);
}
listenSocket = ListenAtTcpPort(listenPort);
if (listenSocket < 0) exit(1);
fprintf(stderr,"%s -listen: Listening on port %d\n",
programName, listenPort);
fprintf(stderr,"%s -listen: Command line errors are not reported until "
"a connection comes in.\n", programName);
while (True) {
int status, pid;
while ((pid= wait3(&status, WNOHANG, (struct rusage *)0))>0);
while (XCheckIfEvent(d, &ev, AllXEventsPredicate, NULL))
;
FD_ZERO(&fds);
FD_SET(listenSocket, &fds);
FD_SET(ConnectionNumber(d), &fds);
select(FD_SETSIZE, &fds, NULL, NULL, NULL);
if (FD_ISSET(listenSocket, &fds)) {
rfbsock = AcceptTcpConnection(listenSocket);
if (rfbsock < 0) exit(1);
if (!SetNonBlocking(rfbsock)) exit(1);
XCloseDisplay(d);
switch (fork()) {
case -1:
perror("fork");
exit(1);
case 0:
close(listenSocket);
return;
default:
close(rfbsock);
if (!(d = XOpenDisplay(displayname))) {
fprintf(stderr,"%s: unable to open display %s\n",
programName, XDisplayName(displayname));
exit(1);
}
break;
}
}
}
}
static Bool
AllXEventsPredicate(Display *d, XEvent *ev, char *arg)
{
return True;
}