1 /*
2  *  Copyright (C) 1997, 1998 Olivetti & Oracle Research Laboratory
3  *
4  *  This is free software; you can redistribute it and/or modify
5  *  it under the terms of the GNU General Public License as published by
6  *  the Free Software Foundation; either version 2 of the License, or
7  *  (at your option) any later version.
8  *
9  *  This software is distributed in the hope that it will be useful,
10  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  *  GNU General Public License for more details.
13  *
14  *  You should have received a copy of the GNU General Public License
15  *  along with this software; if not, write to the Free Software
16  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
17  *  USA.
18  *
19  *  Seriously modified by Fredrik H�binette <hubbe@hubbe.net>
20  */
21 
22 /*
23  * x2vnc - control VNC displays without showing them
24  */
25 
26 #include <unistd.h>
27 #include <errno.h>
28 #include <sys/types.h>
29 #include <sys/wait.h>
30 #include <sys/time.h>
31 #include <sys/stat.h>
32 #include <fcntl.h>
33 #include <x2vnc.h>
34 
35 int temp_file_fd=0;
36 
main(int argc,char ** argv)37 int main(int argc, char **argv)
38 {
39   fd_set fds;
40   struct timeval tv, *tvp;
41   int msWait;
42 
43   processArgs(argc, argv);
44 
45   if (listenSpecified) {
46 
47     listenForIncomingConnections();
48     /* returns only with a succesful connection */
49 
50   }
51   else
52   {
53     if(reconnect)
54     {
55       long last_fork=0;
56       char *tmpdir="/tmp";
57       char tmpfile[1024];
58       if(getenv("TMPDIR") && strlen(tmpdir) < 900)
59 	tmpdir=getenv("TMPDIR");
60 
61       sprintf(tmpfile, "%s/x2vnc-%d-%d",
62 	      tmpdir,
63 	      getpid(),
64 	      time(0));
65 
66       temp_file_fd=open(tmpfile, O_RDWR | O_CREAT | O_EXCL, 0600);
67       unlink(tmpfile);
68 
69       while(1)
70       {
71 	int status, pid;
72 
73 	/* limit how often we restart */
74 	if(time(0) - last_fork < 1) sleep(2);
75 
76 	last_fork=time(0);
77 	switch (pid=fork())
78 	{
79 	  case -1:
80 	    perror("fork");
81 	    exit(1);
82 
83 	  case 0:
84 	    break;
85 
86 	  default:
87 	    while(waitpid(pid, &status, 0) < 0 && errno==EINTR);
88             if(debug)
89               fprintf(stderr,"Child exited with status %d\n",status);
90 	    continue;
91 	}
92 	break;
93       }
94     }
95 
96     if (!ConnectToRFBServer(hostname, port)) exit(1);
97   }
98 
99   if (!InitialiseRFBConnection(rfbsock)) exit(1);
100 
101   if (!CreateXWindow()) exit(1);
102 
103   if (!SetFormatAndEncodings()) {
104     exit(1);
105   }
106 
107 
108   while (1)
109   {
110     /*
111      * Always handle all X events before doing select.  This is the
112      * simplest way of ensuring that we don't block in select while
113      * Xlib has some events on its queue.
114      */
115 
116     if (!HandleXEvents()) {
117       exit(1);
118     }
119 
120     tv.tv_sec = 5;
121     tv.tv_usec = 0;
122 
123     FD_ZERO(&fds);
124     FD_SET(ConnectionNumber(dpy),&fds);
125     FD_SET(rfbsock,&fds);
126 
127     if (select(FD_SETSIZE, &fds, NULL, NULL, &tv) < 0) {
128       perror("select");
129       exit(1);
130     }
131 
132     if (FD_ISSET(rfbsock, &fds)) {
133       if (!HandleRFBServerMessage()) {
134 		exit(1);
135 	    }
136 	}
137     }
138 
139     return 0;
140 }
141