FreeWRL / FreeX3D 4.3.0
PluginSocket.c
1/*
2
3
4Common 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
48OLDCODE #ifdef F_SETSIG
49OLDCODE #define FSIGOK
50OLDCODE #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
62typedef 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
69void *PluginSocket_constructor(){
70 void *v = MALLOCV(sizeof(struct pPluginSocket));
71 memset(v,0,sizeof(struct pPluginSocket));
72 return v;
73}
74void PluginSocket_init(struct tPluginSocket *t){
75 //public
76 //private
77 t->prv = PluginSocket_constructor();
78 {
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;
89double TickTime();
90
91#ifdef PLUGINSOCKETVERBOSE
92/* prints to a log file if we are running as a plugin */
93static 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. */
107int 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
158void 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
177char * 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
308void 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}