FreeWRL/FreeX3D  3.0.0
PluginSocket.c
1 /*
2 
3 
4 Common functions used by Mozilla and Netscape plugins...(maybe PluginGlue too?)
5 
6 */
7 
8 
9 /****************************************************************************
10  This file is part of the FreeWRL/FreeX3D Distribution.
11 
12  Copyright 2009 CRC Canada. (http://www.crc.gc.ca)
13 
14  FreeWRL/FreeX3D is free software: you can redistribute it and/or modify
15  it under the terms of the GNU Lesser Public License as published by
16  the Free Software Foundation, either version 3 of the License, or
17  (at your option) any later version.
18 
19  FreeWRL/FreeX3D is distributed in the hope that it will be useful,
20  but WITHOUT ANY WARRANTY; without even the implied warranty of
21  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22  GNU General Public License for more details.
23 
24  You should have received a copy of the GNU General Public License
25  along with FreeWRL/FreeX3D. If not, see <http://www.gnu.org/licenses/>.
26 ****************************************************************************/
27 
28 
29 
30 #include <config.h>
31 #include <system.h>
32 #include <system_threads.h>
33 #include <system_net.h>
34 #include <display.h>
35 #include <internal.h>
36 
37 #include <libFreeWRL.h>
38 
39 #include "../vrml_parser/Structs.h"
40 #include "../main/headers.h"
41 #include "../x3d_parser/Bindable.h"
42 
43 #include "pluginUtils.h"
44 #include "PluginSocket.h"
45 
46 
47 #ifdef OLDCODE
48 OLDCODE #ifdef F_SETSIG
49 OLDCODE #define FSIGOK
50 OLDCODE #endif
51 #endif //OLDCODE
52 
53 //pthread_mutex_t mylocker = PTHREAD_MUTEX_INITIALIZER;
54 
55 #define LOCK_PLUGIN_COMMUNICATION pthread_mutex_lock(&p->mylocker);
56 #define UNLOCK_PLUGIN_COMMUNICATION pthread_mutex_unlock(&p->mylocker);
57 
58 //fd_set rfds;
59 //struct timeval tv;
60 //char return_url[FILENAME_MAX]; /* used to be local, but was returned as a pointer */
61 
62 typedef struct pPluginSocket{
63  pthread_mutex_t mylocker;// = PTHREAD_MUTEX_INITIALIZER;
64  fd_set rfds;
65  struct timeval tv;
66  char return_url[FILENAME_MAX]; /* used to be local, but was returned as a pointer */
67 
69 void *PluginSocket_constructor(){
70  void *v = MALLOCV(sizeof(struct pPluginSocket));
71  memset(v,0,sizeof(struct pPluginSocket));
72  return v;
73 }
74 void PluginSocket_init(struct tPluginSocket *t){
75  //public
76  //private
77  t->prv = PluginSocket_constructor();
78  {
79  ppPluginSocket p = (ppPluginSocket)t->prv;
80  pthread_mutex_init(&(p->mylocker), NULL);
81  //p->rfds;
82  //p->tv;
83  //p->return_url[FILENAME_MAX]; /* used to be local, but was returned as a pointer */
84  }
85 }
86 
87 
88 //extern double TickTime;
89 double TickTime();
90 
91 #ifdef PLUGINSOCKETVERBOSE
92 /* prints to a log file if we are running as a plugin */
93 static void pluginprint (const char *m, const char *p)
94 {
95  double myt;
96  if (gglobal()->internalc.global_plugin_print) {
97  /* Set the timestamp */
98  myt = Time1970sec();
99  printf ("%f: freewrl: ",myt);
100  printf(m,p);
101  }
102 
103 }
104 #endif
105 
106 /* loop about waiting for the Browser to send us some stuff. */
107 int waitForData(int sock) {
108 
109  int retval;
110  int count;
111  int totalcount;
112  ppPluginSocket p = (ppPluginSocket)gglobal()->PluginSocket.prv;
113 
114  #ifdef PLUGINSOCKETVERBOSE
115  pluginprint ("waitForData, socket %d\n",sock);
116  #endif
117 
118  retval = FALSE;
119  count = 0;
120  totalcount = 80000;
121 
122  do {
123  /*
124  #ifdef PLUGINSOCKETVERBOSE
125  pluginprint ("waitForData on socket looping...%d\n",count);
126  #endif
127  */
128 
129  p->tv.tv_sec = 0;
130  p->tv.tv_usec = 100;
131  FD_ZERO(&p->rfds);
132  FD_SET(sock, &p->rfds);
133 
134  /* wait for the socket. We HAVE to select on "sock+1" - RTFM */
135  retval = select(sock+1, &p->rfds, NULL, NULL, &p->tv);
136 
137 
138  if (retval) {
139  #ifdef PLUGINSOCKETVERBOSE
140  pluginprint ("waitForData returns TRUE\n","");
141  #endif
142 
143  return (TRUE);
144  } else {
145  count ++;
146  if (count > totalcount) {
147  #ifdef PLUGINSOCKETVERBOSE
148  pluginprint ("waitForData, timing out\n","");
149  #endif
150 
151  return (FALSE);
152  }
153  }
154  } while (!retval);
155  return 0 ;
156 }
157 
158 void requestPluginPrint(int to_plugin, const char *msg) {
159  size_t len = 0, ulen = 0, bytes = 0;
160  urlRequest request;
161 
162  request.notifyCode = 2; /* ask for print service */
163 
164  len = FILENAME_MAX * sizeof(char);
165  memset(request.url, 0, len);
166 
167  ulen = strlen(msg) + 1;
168  memmove(request.url, msg, ulen);
169 
170  bytes = sizeof(urlRequest);
171 
172  if (write(to_plugin, (urlRequest *) &request, bytes) < 0) {
173  printf ("COULD NOT WRITE TO THE PLUGIN SOCKET!\n");
174  }
175 }
176 
177 char * requestUrlfromPlugin(int to_plugin, uintptr_t plugin_instance, const char *url) {
178  size_t len = 0, ulen = 0, bytes = 0;
179  urlRequest request;
180  FILE *infile;
181  int linecount;
182  int linelen;
183  char buf[2004];
184  char encodedUrl[2000];
185  ppPluginSocket p = (ppPluginSocket)gglobal()->PluginSocket.prv;
186 
187  LOCK_PLUGIN_COMMUNICATION
188 
189  /* encode the url - if it has funny characters (eg, spaces) asciify them
190  in accordance to some HTML web standard */
191  URLencod(encodedUrl,url,2000);
192 
193  #ifdef PLUGINSOCKETVERBOSE
194  pluginprint ("NEW REQUEST\n",url);
195  pluginprint ("requestURL fromPlugin, getting %s\n",url);
196  pluginprint (" ... encoded is %s\n",encodedUrl);
197  #endif
198 
199  request.instance = (void *) plugin_instance;
200  request.notifyCode = 0; /* get a file */
201 
202  len = FILENAME_MAX * sizeof(char);
203  memset(request.url, 0, len);
204  memset(p->return_url, 0, len);
205 
206  ulen = strlen(encodedUrl) + 1;
207  memmove(request.url, encodedUrl, ulen);
208 
209  bytes = sizeof(urlRequest);
210 
211  #ifdef PLUGINSOCKETVERBOSE
212  pluginprint ("requestURL fromPlugin, step 1\n","");
213  pluginprint ("sending url request to socket %d\n",to_plugin);
214  #endif
215 
216  if (write(to_plugin, (urlRequest *) &request, bytes) < 0) {
217  #ifdef PLUGINSOCKETVERBOSE
218  pluginprint ("write failed in requestUrlfromPlugin","");
219  #endif
220  return NULL;
221  }
222 
223  #ifdef PLUGINSOCKETVERBOSE
224  pluginprint ("requestURL fromPlugin, step 2\n","");
225  #endif
226 
227 
228 
229  /* wait around for a bit to see if this is going to pass or fail */
230  if (!waitForData(to_plugin)) {
231  request.notifyCode = -99; /* destroy stream */
232  if (write(to_plugin, (urlRequest *) &request, bytes) < 0) {
233  #ifdef PLUGINSOCKETVERBOSE
234  pluginprint ("write failed in requestUrlfromPlugin","");
235  #endif
236  UNLOCK_PLUGIN_COMMUNICATION
237  return NULL;
238  }
239 
240  ConsoleMessage ("failed to find URL %s\n",url);
241  UNLOCK_PLUGIN_COMMUNICATION
242 
243  return NULL;
244  }
245 
246  if (read(to_plugin, (char *) p->return_url, len) < 0) {
247  #ifdef PLUGINSOCKETVERBOSE
248  pluginprint("read failed in requestUrlfromPlugin","");
249  pluginprint("Testing: error from read -- returned url is %s.\n", return_url);
250  #endif
251  UNLOCK_PLUGIN_COMMUNICATION
252  return NULL;
253  }
254 
255  #ifdef PLUGINSOCKETVERBOSE
256  pluginprint ("requestURL fromPlugin, returning %s\n",return_url);
257  pluginprint ("REQUEST FINISHED\n",return_url);
258  #endif
259 
260  /* is this a string from URLNotify? (see plugin code for this "special" string) */
261  #define returnErrorString "this file is not to be found on the internet"
262  if (strncmp(p->return_url,returnErrorString,strlen(returnErrorString)) == 0) return NULL;
263 
264  /* now, did this request return a text file with a html page indicating 404- not found? */
265  infile = fopen (p->return_url,"r");
266  if (infile == NULL) {
267  #ifdef PLUGINSOCKETVERBOSE
268  pluginprint ("requestUrlFromPlugin, file %s could not be opened",return_url);
269  #endif
270  /* hmmm - I think that this file should exist, why did it not open? */
271  UNLOCK_PLUGIN_COMMUNICATION
272  return NULL;
273  }
274 
275  linecount = 0;
276  linelen = (int) fread (buf,1,2000,infile);
277  /* pluginprint ("verify read, read in %d characters\n",linelen);*/
278  while ((linelen > 0) && (linecount < 5)){
279  /* pluginprint ("verify read, read in %d characters\n",linelen);*/
280 
281  /* did we find a "404 file not found" message? */
282  /* some, all??? will eventually return a 404 html text in
283  place of whatever you requested */
284  if (strstr(buf,"<TITLE>404 Not Found</TITLE>") != NULL) {
285  #ifdef PLUGINSOCKETVERBOSE
286  pluginprint ("found a 404 in :%s:\n",buf);
287  #endif
288  fclose (infile);
289  UNLOCK_PLUGIN_COMMUNICATION
290  return NULL;
291  }
292  linecount ++;
293  linelen = (int) fread (buf,1,2000,infile);
294  }
295  fclose (infile);
296 
297 
298  UNLOCK_PLUGIN_COMMUNICATION
299 
300  /* we must be returning something here */
301  return p->return_url;
302 }
303 
304 
305 /* tell Netscape that a new window is required (eg, Anchor
306  * clicked and it is an HTML page */
307 
308 void requestNewWindowfromPlugin(int sockDesc,
309  uintptr_t plugin_instance,
310  const char *url)
311 {
312  size_t len = 0, ulen = 0, bytes = 0;
313  urlRequest request;
314  ppPluginSocket p = (ppPluginSocket)gglobal()->PluginSocket.prv;
315 
316  #ifdef PLUGINSOCKETVERBOSE
317  pluginprint ("requestNewWindow fromPlugin, getting %s\n",url);
318  #endif
319 
320  request.instance = (void *) plugin_instance;
321  request.notifyCode = 1; /* tell plugin that we want a new window */
322 
323  len = FILENAME_MAX * sizeof(char);
324  memset(request.url, 0, len);
325  memset(p->return_url, 0, len);
326 
327  ulen = strlen(url) + 1;
328  memmove(request.url, url, ulen);
329  bytes = sizeof(urlRequest);
330 
331  #ifdef PLUGINSOCKETVERBOSE
332  pluginprint ("requestNewWindow fromPlugin, step 1\n","");
333  #endif
334 
335  if (write(sockDesc, (urlRequest *) &request, bytes) < 0) {
336  #ifdef PLUGINSOCKETVERBOSE
337  pluginprint ("write failed in requestUrlfromPlugin","");
338  #endif
339  return;
340  }
341 }