1 /*
2 * Author: William Chia-Wei Cheng (bill.cheng@acm.org)
3 *
4 * Copyright (C) 2001-2009, William Chia-Wei Cheng.
5 *
6 * This file may be distributed under the terms of the Q Public License
7 * as defined by Trolltech AS of Norway and appearing in the file
8 * LICENSE.QPL included in the packaging of this file.
9 *
10 * THIS FILE IS PROVIDED AS IS WITH NO WARRANTY OF ANY KIND, INCLUDING
11 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
12 * PURPOSE. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL,
13 * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
14 * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
15 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
16 * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 *
18 * @(#)$Header: /mm2/home/cvs/bc-src/tgif/remote.c,v 1.9 2011/05/16 16:21:59 william Exp $
19 */
20
21 #define _INCLUDE_FROM_REMOTE_C_
22
23 #include "tgifdefs.h"
24 #include "patchlvl.h"
25
26 #include "cmd.e"
27 #include "cutpaste.e"
28 #include "dialog.e"
29 #include "drawing.e"
30 #include "file.e"
31 #include "ftp.e"
32 #include "http.e"
33 #include "mainloop.e"
34 #include "markup.e"
35 #include "menu.e"
36 #include "msg.e"
37 #include "names.e"
38 #include "navigate.e"
39 #include "page.e"
40 #include "remote.e"
41 #include "setup.e"
42 #include "stream.e"
43 #include "strtbl.e"
44 #include "tcp.e"
45 #include "util.e"
46 #include "version.e"
47
48 int postingCGIQuery=FALSE;
49 int gettingHttpHeaderOnly=FALSE;
50 char *fnameForPostingCGIQuery=NULL;
51 char gszLocalPID[MAXSTRING];
52 char gzipCmd[MAXPATHLENGTH+1];
53 char gunzipCmd[MAXPATHLENGTH+1];
54
55 static int debugRemote=FALSE;
56 static char uncompressCmd[MAXPATHLENGTH+1];
57 static char httpProxy[MAXPATHLENGTH+1];
58 static char ftpProxy[MAXPATHLENGTH+1];
59
60 typedef struct DownloadStatRec {
61 int timestamp;
62 int cumulative_bytes;
63 struct DownloadStatRec *next, *prev;
64 } *DownloadStatRecPtr;
65
66 static struct DownloadStatRec *gpFirstDLS=NULL, *gpLastDLS=NULL;
67 static int gnDownloadStartTime=0;
68
CleanUpDownloadStats()69 void CleanUpDownloadStats()
70 {
71 struct DownloadStatRec *pdls=NULL, *next_pdls=NULL;
72
73 for (pdls=gpFirstDLS; pdls != NULL; pdls=next_pdls) {
74 next_pdls = pdls->next;
75 free(pdls);
76 }
77 gpFirstDLS = gpLastDLS = NULL;
78 gnDownloadStartTime = 0;
79 }
80
81 #define THROUGHPUT_WINDOW 10
82
UpdateDownloadStats(bytes,psz_buf)83 int UpdateDownloadStats(bytes, psz_buf)
84 int bytes;
85 char *psz_buf;
86 {
87 struct DownloadStatRec *pdls=NULL;
88 time_t tloc;
89 int curtime=0, count=0, elapsetime=0, interval=0;
90 float bps=(float)0;
91
92 *psz_buf = '\0';
93 time(&tloc);
94 curtime = (int)tloc;
95 if (gpFirstDLS == NULL) gnDownloadStartTime = curtime;
96 pdls = gpLastDLS;
97 if (pdls != NULL) {
98 if (curtime == pdls->timestamp) {
99 pdls->cumulative_bytes += bytes;
100 } else {
101 pdls = NULL;
102 }
103 }
104 if (pdls == NULL) {
105 pdls = (struct DownloadStatRec *)malloc(sizeof(struct DownloadStatRec));
106 if (pdls == NULL) FailAllocMessage();
107 memset(pdls, 0, sizeof(struct DownloadStatRec));
108 pdls->timestamp = curtime;
109 pdls->cumulative_bytes = (gpLastDLS==NULL ? 0 :
110 gpLastDLS->cumulative_bytes);
111 pdls->cumulative_bytes += bytes;
112 pdls->prev = gpLastDLS;
113 pdls->next = NULL;
114 if (gpLastDLS == NULL) {
115 gpFirstDLS = pdls;
116 } else {
117 gpLastDLS->next = pdls;
118 }
119 gpLastDLS = pdls;
120 }
121 if (gnDownloadStartTime == curtime) {
122 return FALSE;
123 }
124 for (pdls=gpLastDLS, count=0; pdls != NULL && count < THROUGHPUT_WINDOW;
125 pdls=pdls->prev, count++) {
126 }
127 elapsetime = gpLastDLS->timestamp - gnDownloadStartTime;
128 if (pdls == NULL) {
129 interval = elapsetime;
130 bps = ((float)(gpLastDLS->cumulative_bytes)) / ((float)interval);
131 } else {
132 interval = gpLastDLS->timestamp - pdls->timestamp;
133 bps = ((float)(gpLastDLS->cumulative_bytes - pdls->cumulative_bytes)) /
134 ((float)interval);
135 }
136 bps /= (float)1000;
137 sprintf(psz_buf, TgLoadCachedString(CSTID_PARANED_SEC_ELAPSED_AVG_SPEED),
138 elapsetime, bps);
139 return TRUE;
140 }
141
142 static int gnUserAgentInitialized=FALSE;
143 static char gszUserAgentName[MAXSTRING];
144
145 static
InitUserAgentName()146 void InitUserAgentName()
147 {
148 char *c_ptr=NULL;
149
150 if (!gnUserAgentInitialized) {
151 gnUserAgentInitialized = TRUE;
152 *gszUserAgentName = '\0';
153 if (!(PRTGIF && !cmdLineOpenDisplay) &&
154 (c_ptr=XGetDefault(mainDisplay, TOOL_NAME, "UserAgentName")) !=
155 NULL) {
156 strcpy(gszUserAgentName, c_ptr);
157 UtilTrimBlanks(gszUserAgentName);
158 }
159 }
160 }
161
GetClientID(psz_buf,buf_sz)162 int GetClientID(psz_buf, buf_sz)
163 char *psz_buf;
164 int buf_sz;
165 {
166 char agent_name[128];
167
168 *agent_name = '\0';
169 InitUserAgentName();
170 if (*gszUserAgentName != '\0') strcpy(agent_name, gszUserAgentName);
171
172 if (*agent_name == '\0') {
173 if (*specialBuild == '\0') {
174 sprintf(agent_name, "%s/%s.%1d", TOOL_NAME, versionString,
175 TGIF_PATCHLEVEL);
176 } else {
177 sprintf(agent_name, "%s/%s.%1d-%s", TOOL_NAME, versionString,
178 TGIF_PATCHLEVEL, specialBuild);
179 }
180 }
181 return UtilStrCpyN(psz_buf, buf_sz, agent_name);
182 }
183
GetUserAgent(buf,buf_sz)184 void GetUserAgent(buf, buf_sz)
185 char *buf;
186 int buf_sz;
187 {
188 InitUserAgentName();
189 if (buf == NULL || buf_sz <= 0) return;
190 *buf = '\0';
191 UtilStrCpyN(buf, buf_sz, gszUserAgentName);
192 }
193
SetUserAgent(buf)194 void SetUserAgent(buf)
195 char *buf;
196 {
197 InitUserAgentName();
198 if (buf == NULL || *buf == '\0') {
199 *gszUserAgentName = '\0';
200 } else {
201 UtilStrCpyN(gszUserAgentName, sizeof(gszUserAgentName), buf);
202 UtilTrimBlanks(gszUserAgentName);
203 }
204 }
205
GetUserID(psz_buf,buf_sz)206 int GetUserID(psz_buf, buf_sz)
207 char *psz_buf;
208 int buf_sz;
209 {
210 char user_name[MAXSTRING+1];
211 int total=0;
212
213 sprintf(user_name, "%s@", TOOL_NAME);
214 total = strlen(user_name);
215 if (gethostname(&user_name[total], sizeof(user_name)-1-total) < 0) {
216 sprintf(&user_name[total], "UNKNOWN");
217 } else {
218 struct hostent *p_hostent=gethostbyname(&user_name[total]);
219
220 if (p_hostent != NULL && p_hostent->h_name != NULL &&
221 *p_hostent->h_name != '\0') {
222 if (strchr(p_hostent->h_name, '.') == NULL &&
223 strchr(&user_name[total], '.') != NULL) {
224 } else {
225 strcpy(&user_name[total], p_hostent->h_name);
226 }
227 }
228 }
229 return UtilStrCpyN(psz_buf, buf_sz, user_name);
230 }
231
UserAbortComm()232 int UserAbortComm()
233 {
234 return CheckInterrupt(TRUE);
235 }
236
OtherAbortComm()237 int OtherAbortComm()
238 {
239 XEvent ev;
240
241 if (initializingMain || PRTGIF) return FALSE;
242
243 while (XCheckMaskEvent(mainDisplay, StructureNotifyMask, &ev)) {
244 if (iconWindowShown) {
245 if ((ev.xany.window == iconBaseWindow && ev.type == UnmapNotify) ||
246 (ev.xany.window == mainWindow && ev.type == MapNotify)) {
247 XPutBackEvent(mainDisplay, &ev);
248 return TRUE;
249 }
250 } else if ((ev.xany.window == iconBaseWindow && ev.type == MapNotify) ||
251 (ev.xany.window == mainWindow && ev.type == UnmapNotify)) {
252 XPutBackEvent(mainDisplay, &ev);
253 return TRUE;
254 } else if (ev.type == ConfigureNotify) {
255 Reconfigure(FALSE);
256 }
257 }
258 while (XCheckMaskEvent(mainDisplay, VisibilityChangeMask, &ev)) {
259 if (iconWindowShown) {
260 if (ev.xany.window == mainWindow && ev.type == VisibilityNotify &&
261 ev.xvisibility.state == VisibilityUnobscured) {
262 XPutBackEvent(mainDisplay, &ev);
263 return TRUE;
264 } else {
265 ExposeEventHandler(&ev, TRUE);
266 }
267 } else {
268 if (ev.xany.window == iconBaseWindow && ev.type == VisibilityNotify &&
269 ev.xvisibility.state == VisibilityUnobscured) {
270 XPutBackEvent(mainDisplay, &ev);
271 return TRUE;
272 } else {
273 ExposeEventHandler(&ev, TRUE);
274 }
275 }
276 }
277 if (XCheckMaskEvent(mainDisplay, ExposureMask, &ev)) {
278 ExposeEventHandler(&ev, TRUE);
279 while (XCheckMaskEvent(mainDisplay, ExposureMask, &ev)) ;
280 }
281 return FALSE;
282 }
283
GetPageNumFromPageSpec(psz_spec,pn_page_num)284 int GetPageNumFromPageSpec(psz_spec, pn_page_num)
285 char *psz_spec;
286 int *pn_page_num;
287 {
288 if (*psz_spec == '#') {
289 int i=atoi(&psz_spec[1]);
290
291 if (i >= 1 && i <= lastPageNum) {
292 if (pn_page_num != NULL) *pn_page_num = i;
293 return TRUE;
294 }
295 } else {
296 struct PageRec *page_ptr;
297 int i;
298
299 if (pn_page_num != NULL) *pn_page_num = (-1);
300 for (i=1, page_ptr=firstPage; i <= lastPageNum; i++,
301 page_ptr=page_ptr->next) {
302 if (page_ptr->name != NULL && strcmp(psz_spec,page_ptr->name) == 0) {
303 if (pn_page_num != NULL) *pn_page_num = i;
304 return TRUE;
305 }
306 }
307 }
308 if (pn_page_num != NULL) *pn_page_num = (-1);
309 return FALSE;
310 }
311
FreeRemoteBuf(psz_buf)312 void FreeRemoteBuf(psz_buf)
313 char *psz_buf;
314 {
315 TcpFreeBuf(psz_buf);
316 }
317
318 static
ParseURL(url,protocol,host,port,path)319 int ParseURL(url, protocol, host, port, path)
320 char *url, **protocol, **host, **path;
321 int *port;
322 {
323 char *c_ptr=strchr(url, ':');
324
325 *protocol = *host = *path = 0;
326 if (c_ptr == NULL) return TG_REMOTE_STATUS_FORMAT;
327
328 *c_ptr = '\0';
329 *protocol = UtilStrDup(url);
330 *c_ptr++ = ':';
331 if (strncmp(c_ptr, "//", 2) == 0) {
332 char *tmp_host=(&c_ptr[2]), *port_ptr;
333
334 if ((c_ptr=strchr(tmp_host, '/')) == NULL) {
335 *path = UtilStrDup("");
336 } else {
337 *path = UtilStrDup(c_ptr);
338 *c_ptr = '\0';
339 }
340 if ((port_ptr=strchr(tmp_host, ':')) != NULL) {
341 *port_ptr = '\0';
342 *port = (int)atoi(&port_ptr[1]);
343 *host = UtilStrDup(tmp_host);
344 *port_ptr = ':';
345 if (*port <= 0) {
346 return TG_REMOTE_STATUS_FORMAT;
347 }
348 } else {
349 *host = UtilStrDup(tmp_host);
350 }
351 if (c_ptr != NULL) *c_ptr = '/';
352 } else {
353 *host = UtilStrDup("localhost");
354 *path = UtilStrDup(c_ptr);
355 }
356 return TG_REMOTE_STATUS_OK;
357 }
358
359 static
DumpURL(host,port,path)360 void DumpURL(host, port, path)
361 char *host, *path;
362 int port;
363 {
364 /* debug, do not translate */
365 fprintf(stderr, "\thost = %s\n", host);
366 fprintf(stderr, "\tport = %1d\n", port);
367 fprintf(stderr, "\tpath = %s\n", path);
368 fprintf(stderr, "\n");
369 }
370
DirIsRemote(psz_dir)371 int DirIsRemote(psz_dir)
372 char *psz_dir;
373 {
374 int port=0;
375 char *protocol=NULL, *host=NULL, *path=NULL;
376 int status=ParseURL(psz_dir, &protocol, &host, &port, &path), rc=FALSE;
377
378 if (status == TG_REMOTE_STATUS_OK && protocol != NULL) {
379 if (UtilStrICmp(protocol, "http") == 0 ||
380 UtilStrICmp(protocol, "ftp") == 0) {
381 rc = TRUE;
382 }
383 }
384 if (protocol != NULL) free(protocol);
385 if (host != NULL) free(host);
386 if (path != NULL) free(path);
387 return rc;
388 }
389
FileIsRemote(psz_file)390 int FileIsRemote(psz_file)
391 char *psz_file;
392 {
393 return DirIsRemote(psz_file);
394 }
395
UrlIsHtml(psz_url)396 int UrlIsHtml(psz_url)
397 char *psz_url;
398 {
399 char *ext_str=UtilStrRChr(psz_url, (int)'/');
400
401 if (ext_str == NULL) return FALSE;
402 if ((ext_str=strchr(ext_str, '.')) == NULL) return FALSE;
403 ext_str++;
404 return (UtilStrICmp(ext_str,"html")==0 || UtilStrICmp(ext_str,"htm")==0);
405 }
406
407 static
FormLocalName(psz_file,psz_def_ext,psz_return)408 int FormLocalName(psz_file, psz_def_ext, psz_return)
409 char *psz_file, *psz_def_ext, *psz_return;
410 {
411 if (psz_def_ext != NULL) {
412 char *slash_ptr=UtilStrRChr(psz_file, (int)DIR_SEP), *dot_ptr=NULL;
413
414 if (slash_ptr == NULL) {
415 dot_ptr = strchr(psz_file, '.');
416 } else {
417 dot_ptr = strchr(slash_ptr, '.');
418 }
419 if (dot_ptr == NULL) {
420 if (slash_ptr != NULL && slash_ptr[1] == '\0') {
421 sprintf(psz_return, "%s/index.%s", psz_file, psz_def_ext);
422 } else {
423 sprintf(psz_return, "%s.%s", psz_file, psz_def_ext);
424 }
425 } else {
426 strcpy(psz_return, psz_file);
427 }
428 } else {
429 strcpy(psz_return, psz_file);
430 }
431 return UtilShrinkName(psz_return);
432 }
433
FormRemoteName(psz_file,psz_def_ext,psz_return)434 int FormRemoteName(psz_file, psz_def_ext, psz_return)
435 char *psz_file, *psz_def_ext, *psz_return;
436 {
437 char *c_ptr=strstr(psz_file, "//"), *path;
438
439 if (c_ptr == NULL) return FALSE;
440 if ((c_ptr=strchr(&c_ptr[2], '/')) == NULL) {
441 if (!FormLocalName("/", psz_def_ext, psz_return)) return FALSE;
442 path = UtilStrDup(psz_return);
443 sprintf(psz_return, "%s%s", psz_file, path);
444 free(path);
445 } else {
446 if (!FormLocalName(c_ptr, psz_def_ext, psz_return)) return FALSE;
447 path = UtilStrDup(psz_return);
448 *c_ptr = '\0';
449 sprintf(psz_return, "%s%s", psz_file, path);
450 free(path);
451 *c_ptr = '/';
452 }
453 return TRUE;
454 }
455
FormNewFileName(psz_dir,psz_file,psz_def_ext,psz_return,ppsz_page_spec)456 int FormNewFileName(psz_dir, psz_file, psz_def_ext, psz_return, ppsz_page_spec)
457 char *psz_dir, *psz_file, *psz_def_ext, *psz_return, **ppsz_page_spec;
458 {
459 int rc=TRUE;
460
461 if (ppsz_page_spec != NULL) *ppsz_page_spec = NULL;
462 if (DirIsRemote(psz_dir)) {
463 if (*psz_file == '/') {
464 int len;
465 char *c_ptr=strstr(psz_dir, "//"), *fname=NULL;
466
467 if (c_ptr == NULL) return FALSE;
468 if ((c_ptr=strchr(&c_ptr[2], '/')) == NULL) return FALSE;
469 *c_ptr = '\0';
470 len = strlen(psz_dir)+strlen(psz_file);
471 fname = (char*)malloc((len+1)*sizeof(char));
472 if (fname == NULL) {
473 *c_ptr = '/';
474 return FailAllocMessage();
475 }
476 sprintf(fname, "%s%s", psz_dir, psz_file);
477 *c_ptr = '/';
478 if (!FormRemoteName(fname, psz_def_ext, psz_return)) rc = FALSE;
479 free(fname);
480 } else if (FileIsRemote(psz_file)) {
481 if (!FormRemoteName(psz_file, psz_def_ext, psz_return)) rc = FALSE;
482 } else {
483 int len=strlen(psz_dir)+1+strlen(psz_file);
484 char *fname=(char*)malloc((len+1)*sizeof(char));
485
486 if (fname == NULL) return FailAllocMessage();
487
488 sprintf(fname, "%s/%s", psz_dir, psz_file);
489 if (!FormRemoteName(fname, psz_def_ext, psz_return)) rc = FALSE;
490 free(fname);
491 }
492 } else {
493 if (*psz_file == DIR_SEP) {
494 if (!FormLocalName(psz_file, psz_def_ext, psz_return)) rc = FALSE;
495 } else if (FileIsRemote(psz_file)) {
496 if (!FormRemoteName(psz_file, psz_def_ext, psz_return)) rc = FALSE;
497 } else {
498 int len=strlen(psz_dir)+1+strlen(psz_file);
499 char *fname=(char*)malloc((len+1)*sizeof(char));
500
501 if (fname == NULL) return FailAllocMessage();
502
503 sprintf(fname, "%s%c%s", psz_dir, DIR_SEP, psz_file);
504 if (!FormLocalName(fname, psz_def_ext, psz_return)) rc = FALSE;
505 free(fname);
506 }
507 }
508 if (rc && ppsz_page_spec != NULL && psz_return != NULL &&
509 *psz_return != '\0') {
510 char *c_ptr=UtilStrRChr(psz_return, (int)'/');
511
512 if (c_ptr != NULL) {
513 for (++c_ptr; *c_ptr != '\0'; c_ptr++) {
514 if (*c_ptr == '#') {
515 *c_ptr++ = '\0';
516 *ppsz_page_spec = UtilStrDup(c_ptr);
517 } else if (*c_ptr == '?') {
518 break;
519 }
520 }
521 }
522 }
523 return rc;
524 }
525
ShowRemoteStatus(psz_msg)526 void ShowRemoteStatus(psz_msg)
527 char *psz_msg;
528 {
529 if (PRTGIF) return;
530 if (serializingFile || deserializingFile) return;
531
532 SetStringStatus(psz_msg);
533 XSync(mainDisplay, False);
534 }
535
WriteRemoteFileIntoTemp(psz_buf,buf_sz,psz_ext)536 char *WriteRemoteFileIntoTemp(psz_buf, buf_sz, psz_ext)
537 char *psz_buf, *psz_ext;
538 int buf_sz;
539 {
540 char *tmp_fname=NULL;
541 int fd=(-1);
542 mode_t mode=((tmpFileMode == 0) ? 0700 : tmpFileMode);
543
544 tmp_fname = (char*)malloc((strlen(tmpDir)+20)*sizeof(char));
545 if (tmp_fname == NULL) {
546 FailAllocMessage();
547 return NULL;
548 }
549 if (MkTempFile(tmp_fname, (strlen(tmpDir)+19)*sizeof(char), tmpDir,
550 TOOL_NAME) == NULL) {
551 free(tmp_fname);
552 return NULL;
553 }
554 if (psz_ext != NULL) strcat(tmp_fname, psz_ext);
555 unlink(tmp_fname);
556 if ((fd=open(tmp_fname, O_WRONLY|O_CREAT|O_TRUNC, mode)) == (-1)) {
557 sprintf(gszMsgBox, TgLoadString(STID_CANT_CREATE_NAMED_TMP_FILE),
558 tmp_fname);
559 MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
560 free(tmp_fname);
561 return NULL;
562 } else {
563 int ok=TRUE;
564
565 if (write(fd, psz_buf, buf_sz) != buf_sz) {
566 sprintf(gszMsgBox, TgLoadString(STID_FAIL_TO_WRITE_TO_FILE),
567 tmp_fname);
568 MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
569 ok = FALSE;
570 }
571 close(fd);
572 if (!ok) {
573 unlink(tmp_fname);
574 free(tmp_fname);
575 return NULL;
576 }
577 if (tmpFileMode != 0 && chmod(tmp_fname, tmpFileMode)) {
578 sprintf(gszMsgBox, TgLoadString(STID_CANNOT_CHMOD), tmp_fname,
579 tmpFileMode);
580 MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
581 }
582 return tmp_fname;
583 }
584 }
585
586 #define USE_GUNZIP 0
587 #define USE_UNCOMPRESS 1
588
589 static
TgifCompressedUrl(url)590 int TgifCompressedUrl(url)
591 char *url;
592 {
593 char *ext_ptr=NULL;
594 int len, count=0, obj_len, sym_len, pin_len, uncompress_method=INVALID;
595
596 if (url == NULL) return uncompress_method;
597 len = strlen(url);
598 for (ext_ptr=(&url[len-1]); ext_ptr != url; ext_ptr--) {
599 if (*ext_ptr == '.') {
600 if (++count == 2) break;
601 }
602 }
603 if (count != 2) return uncompress_method;
604 ext_ptr++;
605 obj_len = strlen(OBJ_FILE_EXT);
606 sym_len = strlen(SYM_FILE_EXT);
607 pin_len = strlen(PIN_FILE_EXT);
608
609 if (strcmp(ext_ptr,"obj.gz")==0 || strcmp(ext_ptr,"sym.gz")==0 ||
610 strcmp(ext_ptr,"pin.gz")==0) {
611 uncompress_method = USE_GUNZIP;
612 } else if (strcmp(ext_ptr,"obj.Z")==0 || strcmp(ext_ptr,"sym.Z")==0 ||
613 strcmp(ext_ptr,"pin.Z")==0) {
614 uncompress_method = USE_UNCOMPRESS;
615 } else if ((strncmp(ext_ptr,OBJ_FILE_EXT,obj_len)==0 &&
616 strcmp(&ext_ptr[obj_len],".gz")==0) ||
617 (strncmp(ext_ptr,SYM_FILE_EXT,sym_len)==0 &&
618 strcmp(&ext_ptr[sym_len],".gz")==0) ||
619 (strncmp(ext_ptr,PIN_FILE_EXT,pin_len)==0 &&
620 strcmp(&ext_ptr[pin_len],".gz")==0)) {
621 uncompress_method = USE_GUNZIP;
622 } else if ((strncmp(ext_ptr,OBJ_FILE_EXT,obj_len)==0 &&
623 strcmp(&ext_ptr[obj_len],".Z")==0) ||
624 (strncmp(ext_ptr,SYM_FILE_EXT,sym_len)==0 &&
625 strcmp(&ext_ptr[sym_len],".Z")==0) ||
626 (strncmp(ext_ptr,PIN_FILE_EXT,pin_len)==0 &&
627 strcmp(&ext_ptr[pin_len],".Z")==0)) {
628 uncompress_method = USE_UNCOMPRESS;
629 }
630 return uncompress_method;
631 }
632
633 static
UncompressTgifFile(url,ppsz_buf,pn_buf_sz,pn_html)634 void UncompressTgifFile(url, ppsz_buf, pn_buf_sz, pn_html)
635 char *url, **ppsz_buf;
636 int *pn_buf_sz, *pn_html;
637 {
638 FILE *pfp=NULL;
639 char *uncompress_cmd=NULL, *tmp_fname=NULL, *cmd=NULL;
640 int uncompress_method;
641
642 if (ppsz_buf == NULL || *ppsz_buf == NULL || pn_buf_sz == NULL ||
643 *pn_buf_sz <= 0) {
644 return;
645 }
646 uncompress_method = TgifCompressedUrl(url);
647
648 switch (uncompress_method) {
649 case USE_GUNZIP:
650 uncompress_cmd = gunzipCmd;
651 sprintf(gszMsgBox, TgLoadCachedString(CSTID_UNZIPPING_WITH_CMD_DOTS),
652 gunzipCmd);
653 ShowRemoteStatus(gszMsgBox);
654 break;
655 case USE_UNCOMPRESS:
656 uncompress_cmd = uncompressCmd;
657 sprintf(gszMsgBox, TgLoadCachedString(CSTID_UNCOMPRESSING_WITH_CMD_DOTS),
658 uncompressCmd);
659 ShowRemoteStatus(gszMsgBox);
660 break;
661 default: return;
662 }
663 if ((tmp_fname=WriteRemoteFileIntoTemp(*ppsz_buf, *pn_buf_sz,
664 (uncompress_method==USE_UNCOMPRESS ? ".Z" : NULL))) == NULL) {
665 return;
666 }
667 cmd = (char*)malloc((strlen(tmp_fname)+strlen(uncompress_cmd)+20) *
668 sizeof(char));
669 if (cmd == NULL) FailAllocMessage();
670
671 if (strstr(uncompress_cmd, "%s") == NULL) {
672 sprintf(cmd, "%s %s", uncompress_cmd, tmp_fname);
673 } else {
674 sprintf(cmd, uncompress_cmd, tmp_fname);
675 }
676 if (!FindProgramInPath(cmd, NULL, FALSE)) {
677 free(cmd);
678 unlink(tmp_fname);
679 free(tmp_fname);
680 return;
681 }
682 if ((pfp=(FILE*)popen(cmd, "r")) == NULL) {
683 sprintf(gszMsgBox, TgLoadString(STID_CANNOT_EXECUTE_GIVEN_CMD), cmd);
684 MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
685 } else {
686 int buf_sz=0x1000, total=0, chunk_sz=0x1000, bytes_read;
687 char *buf=(char*)malloc((buf_sz+1)*sizeof(char));
688
689 if (buf == NULL) FailAllocMessage();
690 while (buf != NULL && (bytes_read=fread(&buf[total], sizeof(char),
691 chunk_sz, pfp)) > 0) {
692 total += bytes_read;
693 buf_sz += chunk_sz;
694 buf = (char*)realloc(buf, buf_sz+1);
695 }
696 buf[total] = '\0';
697 pclose(pfp);
698 if (buf != NULL && total > 0) {
699 free(*ppsz_buf);
700 *ppsz_buf = buf;
701 *pn_buf_sz = total;
702 } else if (buf != NULL) {
703 free(buf);
704 }
705 }
706 unlink(tmp_fname);
707 free(tmp_fname);
708 if (cmd != NULL) free(cmd);
709 }
710
711 static
GetProxyHostAndPort(proxy_spec,def_port,pn_port)712 char *GetProxyHostAndPort(proxy_spec, def_port, pn_port)
713 char *proxy_spec;
714 int def_port, *pn_port;
715 {
716 char *colon_ptr=strchr(proxy_spec, ':'), *return_buf=NULL;
717 int len=(-1);
718
719 if (colon_ptr == NULL) {
720 len = strlen(proxy_spec);
721 if (len > 0 && proxy_spec[len-1] == '/') {
722 proxy_spec[len-1] = '\0';
723 } else {
724 len = (-1);
725 }
726 *pn_port = def_port;
727 return_buf = UtilStrDup(proxy_spec);
728 } else {
729 *colon_ptr = '\0';
730 len = strlen(proxy_spec);
731 if (len > 0 && proxy_spec[len-1] == '/') {
732 proxy_spec[len-1] = '\0';
733 } else {
734 len = (-1);
735 }
736 *pn_port = atoi(&colon_ptr[1]);
737 return_buf = UtilStrDup(proxy_spec);
738 *colon_ptr = ':';
739 }
740 if (len != (-1)) proxy_spec[len-1] = '/';
741 return return_buf;
742 }
743
744 static
LoadHttpIntoMem(url,host,port,path,ppsz_buf,ppsz_content_type,pn_buf_sz,pn_html,pn_http_extracted_text)745 int LoadHttpIntoMem(url, host, port, path, ppsz_buf, ppsz_content_type,
746 pn_buf_sz, pn_html, pn_http_extracted_text)
747 char *url, *host, *path, **ppsz_buf, **ppsz_content_type;
748 int port, *pn_buf_sz, *pn_html, *pn_http_extracted_text;
749 {
750 int status=TG_REMOTE_STATUS_OK, n_socket=0, proxy_port=0;
751 char *proxy_host=NULL, port_str[20];
752
753 if (pn_http_extracted_text != NULL) *pn_http_extracted_text=FALSE;
754 if (port == 0) port = 80;
755 if (debugRemote) DumpURL(host, port, path);
756
757 ShowInterrupt(1);
758 if (*httpProxy == '\0') {
759 sprintf(port_str, "%1d", port);
760 status = HttpDoConnect(host, port, &n_socket);
761 } else {
762 proxy_host = GetProxyHostAndPort(httpProxy, 80, &proxy_port);
763 sprintf(port_str, "%1d", proxy_port);
764 if (proxy_host == NULL) {
765 status = INVALID;
766 } else {
767 status = HttpDoConnect(proxy_host, proxy_port, &n_socket);
768 }
769 }
770 if (status == TG_REMOTE_STATUS_HOST) {
771 sprintf(gszMsgBox, TgLoadString(STID_CANT_LOCATE_NAMED_SERVER_TRY),
772 "HTTP", (*httpProxy == '\0' ? host : proxy_host));
773 if (PRTGIF) {
774 fprintf(stderr, "%s\n", gszMsgBox);
775 } else {
776 MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
777 }
778 } else if (status == TG_REMOTE_STATUS_INTR) {
779 sprintf(gszMsgBox, TgLoadString(STID_CONNECTION_INTERRUPTED), "HTTP");
780 MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
781 close(n_socket);
782 } else if (status < 0) {
783 /* n_socket already closed in TcpDoDonnect() */
784 if (*httpProxy == '\0') {
785 sprintf(gszMsgBox, TgLoadString(STID_CANT_CONN_TO_HOST_PORT), "HTTP",
786 host, port==80 ? "" : ":", port==80 ? "" : port_str);
787 } else {
788 sprintf(gszMsgBox, TgLoadString(STID_CANT_CONN_TO_HOST_PORT), "HTTP",
789 proxy_host, proxy_port==80 ? "" : ":",
790 proxy_port==80 ? "" : port_str);
791 }
792 MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
793 } else if (status == TG_REMOTE_STATUS_OK) {
794 status = HttpDoWrite(n_socket, (*httpProxy=='\0' ? path : url),
795 host, port);
796 if (status == TG_REMOTE_STATUS_OK) {
797 char *buf=NULL;
798 int buf_sz=0;
799
800 if ((status=HttpDoRead(n_socket, &buf, &buf_sz)) ==
801 TG_REMOTE_STATUS_OK && buf != NULL && *buf != '\0') {
802 *ppsz_buf = HttpExtractText(buf, pn_buf_sz, pn_html,
803 ppsz_content_type);
804 if (*ppsz_buf != NULL && pn_buf_sz != NULL &&
805 ppsz_content_type != NULL) {
806 if (!ParseMarkUpFile(*ppsz_buf, *pn_buf_sz, pn_html,
807 *ppsz_content_type)) {
808 }
809 }
810 if (*ppsz_buf != NULL && debugHttp > 0) {
811 if ((debugHttp % 100) == 99) {
812 /*
813 * Because of the way HttpExtractText() is coded,
814 * if *ppsz_buf != NULL, (*ppsz_buf)[*pn_buf_sz] is '\0'
815 * no matter what kind of file it is!
816 */
817 if (cmdLineDumpURL) {
818 (void)fwrite(*ppsz_buf, sizeof(char), (*pn_buf_sz),
819 stdout);
820 }
821 }
822 }
823 if (pn_http_extracted_text != NULL) *pn_http_extracted_text = TRUE;
824 FreeRemoteBuf(buf);
825 } else if (status == TG_REMOTE_STATUS_INTR) {
826 sprintf(gszMsgBox, TgLoadString(STID_CONNECTION_INTERRUPTED),
827 "HTTP");
828 MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
829 } else if (buf == NULL || *buf == '\0') {
830 sprintf(gszMsgBox, TgLoadString(STID_FAIL_TO_GET_DATA_FROM_URL),
831 "HTTP", url);
832 MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
833 } else {
834 if (*httpProxy == '\0') {
835 sprintf(gszMsgBox,
836 TgLoadString(STID_NETWORK_ERR_TALK_TO_HOST_PORT),
837 "HTTP", host, port==80 ? "" : ":",
838 port==80 ? "" : port_str);
839 } else {
840 sprintf(gszMsgBox,
841 TgLoadString(STID_NETWORK_ERR_TALK_TO_HOST_PORT),
842 "HTTP", proxy_host, proxy_port==80 ? "" : ":",
843 proxy_port==80 ? "" : port_str);
844 }
845 MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
846 }
847 }
848 close(n_socket);
849 } else {
850 if (*httpProxy == '\0') {
851 sprintf(gszMsgBox, TgLoadString(STID_CANT_CONN_TO_HOST_PORT),
852 "HTTP", host, port==80 ? "" : ":", port==80 ? "" : port_str);
853 } else {
854 sprintf(gszMsgBox, TgLoadString(STID_CANT_CONN_TO_HOST_PORT),
855 "HTTP", proxy_host, proxy_port==80 ? "" : ":",
856 proxy_port==80 ? "" : port_str);
857 }
858 MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
859 }
860 HideInterrupt();
861 return status;
862 }
863
864 static
LoadFtpIntoMem(url,host,port,path,ppsz_buf,ppsz_content_type,pn_buf_sz,pn_html)865 int LoadFtpIntoMem(url, host, port, path, ppsz_buf, ppsz_content_type,
866 pn_buf_sz, pn_html)
867 char *url, *host, *path, **ppsz_buf, **ppsz_content_type;
868 int port, *pn_buf_sz, *pn_html;
869 {
870 int status=TG_REMOTE_STATUS_OK, n_socket=0, proxy_port=0;
871 char *proxy_host=NULL, port_str[20];
872
873 if (port == 0) port = 21;
874 if (debugRemote) DumpURL(host, port, path);
875
876 ShowInterrupt(1);
877 if (*ftpProxy == '\0') {
878 sprintf(port_str, "%1d", port);
879 status = FtpDoConnect(host, port, &n_socket);
880 } else {
881 proxy_host = GetProxyHostAndPort(ftpProxy, 21, &proxy_port);
882 sprintf(port_str, "%1d", proxy_port);
883 if (proxy_host == NULL) {
884 status = INVALID;
885 } else {
886 status = FtpDoConnect(proxy_host, proxy_port, &n_socket);
887 }
888 }
889 if (status == TG_REMOTE_STATUS_HOST) {
890 sprintf(gszMsgBox, TgLoadString(STID_CANT_LOCATE_NAMED_SERVER_TRY),
891 "FTP", (*ftpProxy == '\0' ? host : proxy_host));
892 if (PRTGIF) {
893 fprintf(stderr, "%s\n", gszMsgBox);
894 } else {
895 MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
896 }
897 } else if (status == TG_REMOTE_STATUS_INTR) {
898 sprintf(gszMsgBox, TgLoadString(STID_CONNECTION_INTERRUPTED), "FTP");
899 MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
900 close(n_socket);
901 } else if (status < 0) {
902 /* n_socket already closed in TcpDoDonnect() */
903 if (*ftpProxy == '\0') {
904 sprintf(gszMsgBox, TgLoadString(STID_CANT_CONN_TO_HOST_PORT),
905 "FTP", host, port==21 ? "" : ":", port==21 ? "" : port_str);
906 } else {
907 sprintf(gszMsgBox, TgLoadString(STID_CANT_CONN_TO_HOST_PORT),
908 "FTP", proxy_host, proxy_port==21 ? "" : ":",
909 proxy_port==21 ? "" : port_str);
910 }
911 MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
912 } else if (status == TG_REMOTE_STATUS_OK) {
913 char *buf=NULL;
914 int buf_sz=0;
915
916 sprintf(gszMsgBox, TgLoadCachedString(CSTID_SENDING_REQUESTS_DOTS),
917 "FTP");
918 ShowRemoteStatus(gszMsgBox);
919 if (((status=FtpDoTalk(n_socket, (*ftpProxy=='\0' ? path : url),
920 &buf, &buf_sz))&(~FTP_LOGGED_IN)) == TG_REMOTE_STATUS_OK &&
921 buf != NULL && *buf != '\0') {
922 *ppsz_buf = buf;
923 if (pn_buf_sz != NULL) *pn_buf_sz = buf_sz;
924 if (*ppsz_buf != NULL && pn_buf_sz != NULL && debugFtp == -99) {
925 /*
926 * Because of the way FtpDoTalk() is coded,
927 * if *ppsz_buf != NULL, (*ppsz_buf)[*pn_buf_sz] is '\0'
928 * no matter what kind of file it is!
929 */
930 if (cmdLineDumpURL) {
931 (void)fwrite(*ppsz_buf, sizeof(char), (*pn_buf_sz), stdout);
932 }
933 }
934 sprintf(gszMsgBox, TgLoadCachedString(CSTID_DATA_RECEIVED), "FTP");
935 ShowRemoteStatus(gszMsgBox);
936 } else if ((status & (~FTP_LOGGED_IN)) == TG_REMOTE_STATUS_INTR) {
937 sprintf(gszMsgBox, TgLoadString(STID_CONNECTION_INTERRUPTED), "FTP");
938 MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
939 } else if (status & FTP_LOGGED_IN) {
940 sprintf(gszMsgBox, TgLoadString(STID_FAIL_TO_GET_DATA_FROM_URL),
941 "FTP", url);
942 MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
943 } else {
944 if (*ftpProxy == '\0') {
945 sprintf(gszMsgBox, TgLoadString(STID_FAILED_TO_LOGIN_TO_HOST_PORT),
946 "FTP", host, port==21 ? "" : ":", port==21 ? "" : port_str);
947 } else {
948 sprintf(gszMsgBox, TgLoadString(STID_FAILED_TO_LOGIN_TO_HOST_PORT),
949 "FTP", proxy_host, proxy_port==21 ? "" : ":",
950 proxy_port==21 ? "" : port_str);
951 }
952 MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
953 }
954 close(n_socket);
955 } else {
956 if (*ftpProxy == '\0') {
957 sprintf(gszMsgBox, TgLoadString(STID_CANT_CONN_TO_HOST_PORT),
958 "FTP", host, port==21 ? "" : ":", port==21 ? "" : port_str);
959 } else {
960 sprintf(gszMsgBox, TgLoadString(STID_CANT_CONN_TO_HOST_PORT),
961 "FTP", proxy_host, proxy_port==21 ? "" : ":",
962 proxy_port==21 ? "" : port_str);
963 }
964 MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
965 }
966 HideInterrupt();
967 return status;
968 }
969
970 static
ResetRemoteBuf(ppsz_buf,ppsz_content_type,pn_buf_sz,pn_html)971 void ResetRemoteBuf(ppsz_buf, ppsz_content_type, pn_buf_sz, pn_html)
972 char **ppsz_buf, **ppsz_content_type;
973 int *pn_buf_sz, *pn_html;
974 {
975 if (ppsz_buf != NULL && *ppsz_buf != NULL) {
976 free(*ppsz_buf);
977 *ppsz_buf = NULL;
978 }
979 if (ppsz_content_type != NULL && *ppsz_content_type != NULL) {
980 free(*ppsz_content_type);
981 *ppsz_content_type = NULL;
982 }
983 if (pn_buf_sz != NULL) *pn_buf_sz = 0;
984 if (pn_html != NULL) *pn_html = FALSE;
985 }
986
987 static int gnForwardCount=0;
988 static int gnAuthCount=0;
989
990 static
LoadForwardedFileInMem(url,ppsz_buf,ppsz_content_type,pn_buf_sz,pn_html,force_load,psz_final_url,cb_final_url)991 int LoadForwardedFileInMem(url, ppsz_buf, ppsz_content_type, pn_buf_sz,
992 pn_html, force_load, psz_final_url, cb_final_url)
993 char *url, **ppsz_buf, **ppsz_content_type, *psz_final_url;
994 int *pn_buf_sz, *pn_html, force_load, cb_final_url;
995 {
996 char *location=HttpHeaderGetLocation(), *dup_location;
997 int rc=TRUE;
998
999 if (location == NULL) {
1000 sprintf(gszMsgBox, TgLoadString(STID_CANT_FIND_LOCATION_IN_HDR),
1001 "HTTP", url);
1002 MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
1003 return TRUE;
1004 }
1005
1006 if (gnForwardCount >= 5) {
1007 sprintf(gszMsgBox, TgLoadString(STID_LNK_FWD_5_TIMES_LOAD_ABORT),
1008 "HTTP", url);
1009 MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
1010 return TRUE;
1011 }
1012 dup_location = UtilStrDup(location);
1013 if (dup_location == NULL) {
1014 FailAllocMessage();
1015 return TRUE;
1016 }
1017 if (psz_final_url != NULL && cb_final_url > 0) {
1018 UtilStrCpyN(psz_final_url, cb_final_url, dup_location);
1019 }
1020 sprintf(gszMsgBox, TgLoadCachedString(CSTID_FORWARDING_URL_TO_URL),
1021 "HTTP", url, location);
1022 Msg(gszMsgBox);
1023 ShowRemoteStatus(gszMsgBox);
1024 /*
1025 * After calling ResetRemoteBuf(),
1026 * can only return TRUE if buffer is filled.
1027 */
1028 ResetRemoteBuf(ppsz_buf, ppsz_content_type, pn_buf_sz, pn_html);
1029 gnForwardCount++;
1030 rc = LoadRemoteFileInMem(dup_location, ppsz_buf, ppsz_content_type,
1031 pn_buf_sz, pn_html, force_load, psz_final_url, cb_final_url);
1032 gnForwardCount--;
1033 free(dup_location);
1034 return rc;
1035 }
1036
1037 static
ParseAuthFields(psz_scheme)1038 char *ParseAuthFields(psz_scheme)
1039 char *psz_scheme;
1040 {
1041 char *realm_ptr, *realm_value;
1042
1043 UtilTrimBlanks(psz_scheme);
1044 realm_ptr = strchr(psz_scheme, ' ');
1045 if (realm_ptr != NULL) {
1046 *realm_ptr++ = '\0';
1047 while (*realm_ptr == ' ') {
1048 realm_ptr++;
1049 }
1050 if (*realm_ptr == '\0') {
1051 return NULL;
1052 } else if ((realm_value=strchr(realm_ptr, '=')) != NULL) {
1053 return ++realm_value;
1054 }
1055 }
1056 return NULL;
1057 }
1058
1059 static
LoadAuthenticatedFileInMem(url,host,port,ppsz_buf,ppsz_content_type,pn_buf_sz,pn_html,force_load)1060 int LoadAuthenticatedFileInMem(url, host, port, ppsz_buf, ppsz_content_type,
1061 pn_buf_sz, pn_html, force_load)
1062 char *url, *host, **ppsz_buf, **ppsz_content_type;
1063 int port, *pn_buf_sz, *pn_html, force_load;
1064 {
1065 char *www_authenticate=HttpHeaderGetWWWAuthentication();
1066 char *scheme=NULL, *realm=NULL, *encoded_auth=NULL;
1067 int rc=TRUE;
1068
1069 if (www_authenticate == NULL) {
1070 sprintf(gszMsgBox, TgLoadString(STID_CANT_FIND_WWW_AUTHEN_IN_HDR),
1071 "HTTP", url);
1072 MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
1073 return TRUE;
1074 }
1075 scheme = UtilStrDup(www_authenticate);
1076 if (scheme == NULL) {
1077 FailAllocMessage();
1078 return TRUE;
1079 }
1080 if ((realm=ParseAuthFields(scheme)) == NULL) {
1081 free(scheme);
1082 return TRUE;
1083 }
1084 /* realm has double-quotes around it */
1085 if ((encoded_auth=FindAuthorization(host, port, scheme, realm)) != NULL) {
1086 /* committed authorization is cached */
1087 /*
1088 * After calling ResetRemoteBuf(),
1089 * can only return TRUE if buffer is filled.
1090 */
1091 ResetRemoteBuf(ppsz_buf, ppsz_content_type, pn_buf_sz, pn_html);
1092 SetAuthorization(host, port, scheme, realm, encoded_auth);
1093 gnAuthCount++;
1094 rc = LoadRemoteFileInMem(url, ppsz_buf, ppsz_content_type, pn_buf_sz,
1095 pn_html, force_load, NULL, 0);
1096 gnAuthCount--;
1097 ResetAuthorization();
1098 } else {
1099 char *psz=NULL, user_name[MAXSTRING+1], password[MAXSTRING+1];
1100
1101 *user_name = *password = '\0';
1102 sprintf(gszMsgBox, TgLoadString(STID_AUTHEN_REQ_FOR_REALM),
1103 "HTTP", realm);
1104 ShowRemoteStatus(gszMsgBox);
1105 sprintf(gszMsgBox, TgLoadString(STID_ENTER_USERNAME_FOR_REALM), realm);
1106 if (mainDisplay == NULL) {
1107 fprintf(stdout, "%s ", gszMsgBox);
1108 fflush(stdout);
1109 psz = UtilGetALine(stdin);
1110 if (psz != NULL) {
1111 UtilStrCpyN(user_name, sizeof(user_name), psz);
1112 UtilFree(psz);
1113 }
1114 } else {
1115 Dialog(gszMsgBox, TgLoadCachedString(CSTID_DLG_ACCEPT_CANCEL),
1116 user_name);
1117 }
1118 UtilTrimBlanks(user_name);
1119 if (*user_name != '\0') {
1120 *password = '\0';
1121 sprintf(gszMsgBox, TgLoadString(STID_ENTER_PASSWORD_FOR_REALM), realm);
1122 doPassword = TRUE;
1123 if (mainDisplay == NULL) {
1124 fprintf(stdout, "%s ", gszMsgBox);
1125 fflush(stdout);
1126 psz = UtilGetALine(stdin);
1127 if (psz != NULL) {
1128 UtilStrCpyN(password, sizeof(password), psz);
1129 UtilFree(psz);
1130 }
1131 } else {
1132 Dialog(gszMsgBox, NULL, password);
1133 }
1134 doPassword = FALSE;
1135 }
1136 if (*user_name != '\0' && *password != '\0') {
1137 char *tmp_auth;
1138
1139 sprintf(gszMsgBox, "%s:%s", user_name, password);
1140 if ((tmp_auth=UtilStrDup(gszMsgBox)) == NULL) FailAllocMessage();
1141 if ((encoded_auth=Base64Encode(tmp_auth)) == NULL) FailAllocMessage();
1142 free(tmp_auth);
1143 if (!SetAuthorization(host, port, scheme, realm, encoded_auth)) {
1144 FailAllocMessage();
1145 } else {
1146 /*
1147 * After calling ResetRemoteBuf(),
1148 * can only return TRUE if buffer is filled.
1149 */
1150 ResetRemoteBuf(ppsz_buf, ppsz_content_type, pn_buf_sz, pn_html);
1151 SetAuthorization(host, port, scheme, realm, encoded_auth);
1152 gnAuthCount++;
1153 rc = LoadRemoteFileInMem(url, ppsz_buf, ppsz_content_type,
1154 pn_buf_sz, pn_html, force_load, NULL, 0);
1155 gnAuthCount--;
1156 ResetAuthorization();
1157 }
1158 free(encoded_auth);
1159 }
1160 }
1161 free(scheme);
1162 return rc;
1163 }
1164
LoadRemoteFileInMem(url,ppsz_buf,ppsz_content_type,pn_buf_sz,pn_html,force_load,psz_final_url,cb_final_url)1165 int LoadRemoteFileInMem(url, ppsz_buf, ppsz_content_type, pn_buf_sz, pn_html,
1166 force_load, psz_final_url, cb_final_url)
1167 char *url, **ppsz_buf, **ppsz_content_type, *psz_final_url;
1168 int *pn_buf_sz, *pn_html, force_load, cb_final_url;
1169 /* if the remote type is http, the url has an extension and it */
1170 /* is not html but the retrieved file is html, then it's */
1171 /* probably an error */
1172 {
1173 int status=0, rc;
1174 int port=0, protocol_is_http=FALSE, http_extracted_text=FALSE;
1175 char *protocol=NULL, *host=NULL, *path=NULL, *proxy_host=NULL;
1176 char port_str[20];
1177 struct URLCacheRec *url_cache=NULL;
1178
1179 *port_str = '\0';
1180 if (pn_buf_sz != NULL) *pn_buf_sz = 0;
1181 if (pn_html != NULL) *pn_html = FALSE;
1182 *ppsz_buf = NULL;
1183
1184 if (!force_load) url_cache = FindURLCache(url, TRUE);
1185 if (url_cache != NULL && url_cache->remote_buf_sz > 0 &&
1186 url_cache->remote_buf != NULL) {
1187 *ppsz_buf = (char*)malloc((url_cache->remote_buf_sz)*sizeof(char));
1188 if (*ppsz_buf == NULL) FailAllocMessage();
1189 memcpy(*ppsz_buf, url_cache->remote_buf, url_cache->remote_buf_sz);
1190 *pn_buf_sz = url_cache->remote_buf_sz;
1191 if (ppsz_content_type != NULL) {
1192 *ppsz_content_type = UtilStrDup(url_cache->content_type);
1193 }
1194 *pn_html = url_cache->is_html;
1195 return TRUE;
1196 }
1197 status = ParseURL(url, &protocol, &host, &port, &path);
1198 if (status != TG_REMOTE_STATUS_OK) {
1199 if (protocol != NULL) free(protocol);
1200 if (host != NULL) free(host);
1201 if (path != NULL) free(path);
1202 sprintf(gszMsgBox, TgLoadString(STID_FAIL_TO_PARSE_GIVEN_URL), url);
1203 if (PRTGIF) {
1204 fprintf(stderr, "%s\n", gszMsgBox);
1205 } else {
1206 MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
1207 }
1208 return FALSE;
1209 }
1210 if (UtilStrICmp(protocol, "http") == 0) {
1211 protocol_is_http = TRUE;
1212 status = LoadHttpIntoMem(url, host, port, path, ppsz_buf,
1213 ppsz_content_type, pn_buf_sz, pn_html, &http_extracted_text);
1214 } else if (UtilStrICmp(protocol, "ftp") == 0) {
1215 status = LoadFtpIntoMem(url, host, port, path, ppsz_buf,
1216 ppsz_content_type, pn_buf_sz, pn_html);
1217 } else {
1218 if (debugRemote) DumpURL(host, port, path);
1219 sprintf(gszMsgBox, TgLoadString(STID_TOOL_NOT_KNOW_HOW_TALK_PROTO),
1220 protocol);
1221 if (PRTGIF) {
1222 fprintf(stderr, "%s\n", gszMsgBox);
1223 } else {
1224 MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
1225 }
1226 status = TG_REMOTE_STATUS_FORMAT;
1227 }
1228 rc = TRUE;
1229 if (status==TG_REMOTE_STATUS_OK && protocol_is_http && http_extracted_text) {
1230 int resp_code=HttpHeaderGetResponseCode();
1231
1232 switch (resp_code) {
1233 case 301:
1234 case 302:
1235 rc = LoadForwardedFileInMem(url, ppsz_buf, ppsz_content_type,
1236 pn_buf_sz, pn_html, force_load, psz_final_url, cb_final_url);
1237 break;
1238 case 401:
1239 rc = LoadAuthenticatedFileInMem(url, host, port,
1240 ppsz_buf, ppsz_content_type, pn_buf_sz, pn_html, force_load);
1241 break;
1242 default:
1243 if (gnAuthCount > 0) {
1244 /* password verified? */
1245 CommitAuthorization();
1246 }
1247 break;
1248 }
1249 }
1250 if (status == TG_REMOTE_STATUS_OK) {
1251 UncompressTgifFile(url, ppsz_buf, pn_buf_sz, pn_html);
1252 UpdateURLCache(url, *ppsz_buf,
1253 (ppsz_content_type==NULL ? NULL : *ppsz_content_type),
1254 *pn_buf_sz, *pn_html);
1255 }
1256 if (protocol != NULL) free(protocol);
1257 if (host != NULL) free(host);
1258 if (path != NULL) free(path);
1259 if (proxy_host != NULL) free(proxy_host);
1260 return rc;
1261 }
1262
1263 static
LaunchViewer(launch_remote_file,psz_viewer,psz_url,psz_new_fname)1264 void LaunchViewer(launch_remote_file, psz_viewer, psz_url,
1265 psz_new_fname)
1266 int launch_remote_file;
1267 char *psz_viewer, *psz_url, *psz_new_fname;
1268 {
1269 if (strcmp(psz_viewer, "NONE") != 0) {
1270 #ifndef _BACKGROUND_DONT_FORK
1271 int pid=0;
1272 #endif /* ~_BACKGROUND_DONT_FORK */
1273 char cmd[MAXSTRING<<2];
1274
1275 if (launch_remote_file) {
1276 sprintf(cmd, psz_viewer, psz_url);
1277 } else {
1278 sprintf(cmd, psz_viewer, psz_new_fname);
1279 }
1280 sprintf(gszMsgBox, TgLoadString(STID_LAUNCH_GIVEN_VIEWER), cmd);
1281 Msg(gszMsgBox);
1282 ShowRemoteStatus(gszMsgBox);
1283
1284 #ifdef _BACKGROUND_DONT_FORK
1285 strcat(cmd, " &");
1286 (void)system(cmd);
1287 #else /* ~_BACKGROUND_DONT_FORK */
1288 pid = fork();
1289 if (pid == 0) {
1290 (void)system(cmd);
1291 exit(0);
1292 }
1293 #endif /* _BACKGROUND_DONT_FORK */
1294 } else {
1295 sprintf(gszMsgBox, TgLoadString(STID_FILE_SAVED), psz_new_fname);
1296 Msg(gszMsgBox);
1297 }
1298 }
1299
1300 struct MimeTypeRec {
1301 char *main_type, *sub_type;
1302 struct MimeTypeRec *next;
1303 };
1304
1305 struct MailCapRec {
1306 char *main_type, *sub_type;
1307 char *cmd, *params;
1308 struct MailCapRec *next, *prev;
1309 };
1310
1311 static struct MimeTypeRec *topMimeTypesInfo=NULL;
1312 static struct MailCapRec *topMailCapInfo=NULL, *botMailCapInfo=NULL;
1313
1314 static
AddAMimeType(main_type,sub_type)1315 void AddAMimeType(main_type, sub_type)
1316 char *main_type, *sub_type;
1317 {
1318 struct MimeTypeRec *mime_type_ptr;
1319
1320 mime_type_ptr = (struct MimeTypeRec *)malloc(sizeof(struct MimeTypeRec));
1321 if (mime_type_ptr == NULL) { FailAllocMessage(); return; }
1322 memset(mime_type_ptr, 0, sizeof(struct MimeTypeRec));
1323 mime_type_ptr->main_type = UtilStrDup(main_type);
1324 mime_type_ptr->sub_type = UtilStrDup(sub_type);
1325 mime_type_ptr->next = topMimeTypesInfo;
1326 topMimeTypesInfo = mime_type_ptr;
1327 }
1328
1329 static
AddAMailCap(main_type,sub_type,cmd,params)1330 void AddAMailCap(main_type, sub_type, cmd, params)
1331 char *main_type, *sub_type, *cmd, *params;
1332 {
1333 struct MailCapRec *mail_cap_ptr;
1334
1335 mail_cap_ptr = (struct MailCapRec *)malloc(sizeof(struct MailCapRec));
1336 if (mail_cap_ptr == NULL) { FailAllocMessage(); return; }
1337 memset(mail_cap_ptr, 0, sizeof(struct MailCapRec));
1338 mail_cap_ptr->main_type = UtilStrDup(main_type);
1339 mail_cap_ptr->sub_type = UtilStrDup(sub_type);
1340 mail_cap_ptr->cmd = UtilStrDup(cmd);
1341 mail_cap_ptr->params = (params==NULL ? NULL : UtilStrDup(params));
1342 mail_cap_ptr->prev = botMailCapInfo;
1343 mail_cap_ptr->next = NULL;
1344 if (botMailCapInfo == NULL) {
1345 topMailCapInfo = mail_cap_ptr;
1346 } else {
1347 botMailCapInfo->next = mail_cap_ptr;
1348 }
1349 botMailCapInfo = mail_cap_ptr;
1350 }
1351
1352 static
FreeMimeTypesInfo()1353 void FreeMimeTypesInfo()
1354 {
1355 struct MimeTypeRec *next_mime_type_ptr;
1356
1357 for ( ; topMimeTypesInfo != NULL; topMimeTypesInfo=next_mime_type_ptr) {
1358 next_mime_type_ptr = topMimeTypesInfo->next;
1359 if (topMimeTypesInfo->main_type!=NULL) free(topMimeTypesInfo->main_type);
1360 if (topMimeTypesInfo->sub_type!=NULL) free(topMimeTypesInfo->sub_type);
1361 free(topMimeTypesInfo);
1362 }
1363 }
1364
1365 static
FreeMailCapInfo()1366 void FreeMailCapInfo()
1367 {
1368 struct MailCapRec *next_mail_cap_ptr;
1369
1370 for ( ; topMailCapInfo != NULL; topMailCapInfo=next_mail_cap_ptr) {
1371 next_mail_cap_ptr = topMailCapInfo->next;
1372 if (topMailCapInfo->main_type != NULL) free(topMailCapInfo->main_type);
1373 if (topMailCapInfo->sub_type != NULL) free(topMailCapInfo->sub_type);
1374 if (topMailCapInfo->cmd != NULL) free(topMailCapInfo->cmd);
1375 if (topMailCapInfo->params != NULL) free(topMailCapInfo->params);
1376 free(topMailCapInfo);
1377 }
1378 botMailCapInfo = NULL;
1379 }
1380
1381 static
DumpMimeTypesInfo()1382 void DumpMimeTypesInfo()
1383 {
1384 struct MimeTypeRec *mime_type_ptr;
1385
1386 /* do not translate -- program constants */
1387 fprintf(stderr, "*** Mime Types ***\n");
1388 for (mime_type_ptr=topMimeTypesInfo; mime_type_ptr != NULL;
1389 mime_type_ptr=mime_type_ptr->next) {
1390 fprintf(stderr, "%s/%s\n",
1391 mime_type_ptr->main_type != NULL ? mime_type_ptr->main_type : "",
1392 mime_type_ptr->sub_type != NULL ? mime_type_ptr->sub_type : "");
1393 }
1394 fprintf(stderr, "\n");
1395 }
1396
1397 static
DumpMailCapInfo()1398 void DumpMailCapInfo()
1399 {
1400 struct MailCapRec *mail_cap_ptr;
1401
1402 /* do not translate -- program constants */
1403 fprintf(stderr, "*** Mail Capabilities ***\n");
1404 for (mail_cap_ptr=topMailCapInfo; mail_cap_ptr != NULL;
1405 mail_cap_ptr=mail_cap_ptr->next) {
1406 fprintf(stderr, "%s/%s; %s; %s\n",
1407 mail_cap_ptr->main_type != NULL ? mail_cap_ptr->main_type : "",
1408 mail_cap_ptr->sub_type != NULL ? mail_cap_ptr->sub_type : "",
1409 mail_cap_ptr->cmd != NULL ? mail_cap_ptr->cmd : "",
1410 mail_cap_ptr->params != NULL ? mail_cap_ptr->params : "");
1411 }
1412 fprintf(stderr, "\n");
1413 }
1414
1415 static
FillMimeTypesInfo()1416 void FillMimeTypesInfo()
1417 {
1418 char *c_ptr, *buf, fname[MAXPATHLENGTH+1];
1419 FILE *fp;
1420 int line_num=0;
1421
1422 if ((c_ptr=XGetDefault(mainDisplay,TOOL_NAME,"MimeTypesFile")) != NULL) {
1423 strcpy(fname, c_ptr);
1424 } else {
1425 sprintf(fname, "%s%c.mime.types", homeDir, DIR_SEP);
1426 }
1427 if ((fp=fopen(fname, "r")) == NULL) return;
1428 while ((buf=UtilGetALine(fp)) != NULL) {
1429 line_num++;
1430 if (*buf != '#') {
1431 char *c_ptr1=strtok(buf, " \t\n\r");
1432
1433 if (c_ptr1 != NULL && *c_ptr1 != '\0') {
1434 int ok=TRUE;
1435 char *sub_type=NULL;
1436
1437 if ((sub_type=strchr(c_ptr1, '/')) == NULL) {
1438 ok = FALSE;
1439 } else {
1440 *sub_type++ = '\0';
1441 if (*sub_type == '\0') ok = FALSE;
1442 if (*c_ptr1 == '*') ok = FALSE;
1443 }
1444 if (!ok) {
1445 sprintf(gszMsgBox,
1446 TgLoadCachedString(CSTID_MALFORMED_LINE_NUM_IN_FILE),
1447 line_num, fname);
1448 Msg(gszMsgBox);
1449 } else {
1450 AddAMimeType(c_ptr1, sub_type);
1451 }
1452 }
1453 }
1454 free(buf);
1455 }
1456 fclose(fp);
1457 if (debugRemote) DumpMimeTypesInfo();
1458 }
1459
1460 static
FillMailCapInfo()1461 void FillMailCapInfo()
1462 {
1463 char *spec=NULL, *fname=NULL, *colon_ptr=NULL, *c_ptr=NULL;
1464
1465 if ((c_ptr=getenv("MAILCAPS")) != NULL) {
1466 spec = UtilStrDup(c_ptr);
1467 } else {
1468 sprintf(gszMsgBox, "%s%c.mailcap", homeDir, DIR_SEP);
1469 spec = UtilStrDup(gszMsgBox);
1470 }
1471 if (spec == NULL) FailAllocMessage();
1472
1473 fname = spec;
1474 colon_ptr = strchr(fname, ':');
1475 while (fname != NULL) {
1476 if (colon_ptr != NULL) *colon_ptr = '\0';
1477 if (*fname != '\0') {
1478 FILE *fp=NULL;
1479
1480 if ((fp=fopen(fname, "r")) == NULL) {
1481 sprintf(gszMsgBox, TgLoadString(STID_CANT_OPEN_GIVEN_MAILCAP_FILE),
1482 fname);
1483 Msg(gszMsgBox);
1484 } else {
1485 int line_num=0;
1486 char *buf=NULL;
1487
1488 while ((buf=UtilGetAContinuedLine(fp)) != NULL) {
1489 line_num++;
1490 UtilTrimBlanks(buf);
1491 if (*buf != '\0' && *buf != '#') {
1492 char *first_semi_ptr=strchr(buf, ';');
1493 char *second_semi_ptr=NULL, *sub_type=NULL;
1494 int ok=TRUE;
1495
1496 if (first_semi_ptr == NULL) {
1497 ok = FALSE;
1498 } else {
1499 *first_semi_ptr++ = '\0';
1500 while (*first_semi_ptr == ' ' && *first_semi_ptr == '\t') {
1501 first_semi_ptr++;
1502 }
1503 second_semi_ptr = strchr(first_semi_ptr, ';');
1504 if (second_semi_ptr != NULL) {
1505 *second_semi_ptr++ = '\0';
1506 }
1507 if ((sub_type=strchr(buf, '/')) == NULL) {
1508 ok = FALSE;
1509 } else {
1510 *sub_type++ = '\0';
1511 }
1512 }
1513 if (!ok) {
1514 sprintf(gszMsgBox,
1515 TgLoadCachedString(CSTID_MALFORMED_LINE_NUM_IN_FILE),
1516 line_num, fname);
1517 Msg(gszMsgBox);
1518 } else {
1519 if (first_semi_ptr!=NULL) UtilTrimBlanks(first_semi_ptr);
1520 if (second_semi_ptr!=NULL) UtilTrimBlanks(second_semi_ptr);
1521 AddAMailCap(buf, sub_type, first_semi_ptr,
1522 second_semi_ptr);
1523 }
1524 }
1525 free(buf);
1526 }
1527 fclose(fp);
1528 }
1529 }
1530 if (colon_ptr == NULL) break;
1531 *colon_ptr++ = ':';
1532 fname = colon_ptr;
1533 colon_ptr = strchr(fname, ':');
1534 }
1535 UtilFree(spec);
1536 if (debugRemote) DumpMailCapInfo();
1537 }
1538
1539 static
MalformedMailCapEntryMessage(mail_cap_ptr)1540 void MalformedMailCapEntryMessage(mail_cap_ptr)
1541 struct MailCapRec *mail_cap_ptr;
1542 {
1543 if (mail_cap_ptr->params == NULL) {
1544 sprintf(gszMsgBox, TgLoadString(STID_MALFORMED_MAILCAP_ENTRY),
1545 mail_cap_ptr->main_type, mail_cap_ptr->sub_type, mail_cap_ptr->cmd);
1546 } else {
1547 sprintf(gszMsgBox, TgLoadString(STID_MALFORMED_MAILCAP_ENTRY_PARAM),
1548 mail_cap_ptr->main_type, mail_cap_ptr->sub_type, mail_cap_ptr->cmd,
1549 mail_cap_ptr->params);
1550 }
1551 MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
1552 }
1553
1554 static
GetContentValue(name,params)1555 char *GetContentValue(name, params)
1556 char *name, *params;
1557 {
1558 char *buf, *c_ptr;
1559
1560 if (params == NULL) return NULL;
1561
1562 buf = UtilStrDup(params);
1563 if (buf == NULL) { FailAllocMessage(); return NULL; }
1564 for (c_ptr=strtok(buf, ";"); c_ptr != NULL; c_ptr=strtok(NULL, ";")) {
1565 char *equal_ptr=strchr(c_ptr, '-');
1566
1567 if (equal_ptr != NULL) {
1568 char *c_ptr1=c_ptr;
1569
1570 while (*c_ptr1 == ' ' || *c_ptr1 == '\t') c_ptr1++;
1571 *equal_ptr = '\0';
1572 if (UtilStrICmp(c_ptr1, name) == 0) {
1573 char *return_buf=UtilStrDup(&equal_ptr[1]);
1574
1575 free(buf);
1576 return return_buf;
1577 }
1578 *equal_ptr = '=';
1579 }
1580 }
1581 free(buf);
1582 return NULL;
1583 }
1584
1585 static int mimeViewerInitialized=FALSE;
1586
1587 static
GetMimeViewer(psz_content_type)1588 char *GetMimeViewer(psz_content_type)
1589 char *psz_content_type;
1590 {
1591 struct MailCapRec *mail_cap_ptr;
1592 struct MimeTypeRec *mime_type_ptr;
1593 char *main_type=UtilStrDup(psz_content_type), *sub_type=NULL;
1594 char *params=NULL, *buf=NULL, *c_ptr;
1595 int buf_sz=0, buf_index=0;
1596
1597 if (main_type == NULL) { FailAllocMessage(); return NULL; }
1598 UtilTrimBlanks(main_type);
1599 params = strchr(main_type, ';');
1600 if (params != NULL) *params++ = '\0';
1601
1602 if (UtilStrICmp(main_type, "application/x-tgif") == 0) {
1603 free(main_type);
1604 return NULL;
1605 }
1606 sub_type = strchr(main_type, '/');
1607 if (sub_type == NULL) { free(main_type); return NULL; }
1608 *sub_type++ = '\0';
1609 if (UtilStrICmp(main_type, "multipart") == 0) {
1610 free(main_type);
1611 sprintf(gszMsgBox, TgLoadString(STID_TOOL_CANT_HANDLE_MP_MIME),
1612 TOOL_NAME);
1613 MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
1614 return NULL;
1615 }
1616
1617 if (!mimeViewerInitialized) {
1618 mimeViewerInitialized = TRUE;
1619 FillMimeTypesInfo();
1620 FillMailCapInfo();
1621 }
1622 for (mime_type_ptr=topMimeTypesInfo; mime_type_ptr != NULL;
1623 mime_type_ptr=mime_type_ptr->next) {
1624 if (UtilStrICmp(main_type, mime_type_ptr->main_type) == 0) {
1625 if (strcmp(mime_type_ptr->sub_type, "*") == 0) {
1626 break;
1627 } else if (UtilStrICmp(sub_type, mime_type_ptr->sub_type) == 0) {
1628 break;
1629 }
1630 }
1631 }
1632 if (mime_type_ptr == NULL) { free(main_type); return NULL; }
1633
1634 for (mail_cap_ptr=topMailCapInfo; mail_cap_ptr != NULL;
1635 mail_cap_ptr=mail_cap_ptr->next) {
1636 if (UtilStrICmp(main_type, mail_cap_ptr->main_type) == 0) {
1637 if (strcmp(mail_cap_ptr->sub_type, "*") == 0) {
1638 break;
1639 } else if (UtilStrICmp(sub_type, mail_cap_ptr->sub_type) == 0) {
1640 break;
1641 }
1642 }
1643 }
1644 free(main_type);
1645 if (mail_cap_ptr == NULL) return NULL;
1646
1647 buf_sz = 0x100;
1648 buf = (char*)malloc((buf_sz+1)*sizeof(char));
1649 if (buf == NULL) { FailAllocMessage(); return NULL; }
1650 c_ptr = mail_cap_ptr->cmd;
1651 while (*c_ptr != '\0') {
1652 if (*c_ptr == '\\' && c_ptr[1] == '\0') {
1653 MalformedMailCapEntryMessage(mail_cap_ptr);
1654 free(buf);
1655 return NULL;
1656 }
1657 if (*c_ptr == '%') {
1658 char *tmp_buf=NULL, *right_bracket;
1659 int num_ch_to_skip=(-1), len;
1660
1661 switch (c_ptr[1]) {
1662 case 's': tmp_buf=UtilStrDup("%s"); num_ch_to_skip=2; break;
1663 case 'S': tmp_buf=UtilStrDup("%S"); num_ch_to_skip=2; break;
1664 case 't':
1665 len = strlen(main_type)+strlen(sub_type)+1;
1666 tmp_buf = (char*)malloc((len+1)*sizeof(char));
1667 if (tmp_buf == NULL) FailAllocMessage();
1668 sprintf(tmp_buf, "%s/%s", main_type, sub_type);
1669 num_ch_to_skip = 2;
1670 break;
1671 case '{':
1672 if ((right_bracket=strchr(&c_ptr[2], '}')) == NULL) {
1673 if (mail_cap_ptr->params == NULL) {
1674 sprintf(gszMsgBox, TgLoadString(STID_CANT_FIND_RT_BRACK_MC),
1675 mail_cap_ptr->main_type, mail_cap_ptr->sub_type,
1676 mail_cap_ptr->cmd);
1677 } else {
1678 sprintf(gszMsgBox,
1679 TgLoadString(STID_CANT_FIND_RT_BRACK_MC_PARAM),
1680 mail_cap_ptr->main_type, mail_cap_ptr->sub_type,
1681 mail_cap_ptr->cmd, mail_cap_ptr->params);
1682 }
1683 MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
1684 free(buf);
1685 return NULL;
1686 }
1687 num_ch_to_skip = right_bracket-c_ptr+1;
1688 *right_bracket = '\0';
1689 if ((tmp_buf=GetContentValue(&c_ptr[2], params)) == NULL) {
1690 sprintf(gszMsgBox, TgLoadString(STID_CANT_FIND_NAMED_INFO_IN_CT),
1691 "HTTP", &c_ptr[2]);
1692 MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
1693 *right_bracket = '}';
1694 free(buf);
1695 return NULL;
1696 }
1697 *right_bracket = '}';
1698 break;
1699 default:
1700 MalformedMailCapEntryMessage(mail_cap_ptr);
1701 free(buf);
1702 return NULL;
1703 }
1704 if (num_ch_to_skip < 0 || tmp_buf == NULL) {
1705 free(buf);
1706 FailAllocMessage();
1707 return NULL;
1708 }
1709 len = strlen(tmp_buf);
1710 while (buf_index+len+1 >= buf_sz) {
1711 buf_sz += 0x100;
1712 if ((buf=(char*)realloc(buf, buf_sz+1)) == NULL) return NULL;
1713 }
1714 strcpy(&buf[buf_index], tmp_buf);
1715 buf_index += len;
1716
1717 free(tmp_buf);
1718 c_ptr += num_ch_to_skip;
1719 } else {
1720 if (buf_index+1 >= buf_sz) {
1721 buf_sz += 0x100;
1722 if ((buf=(char*)realloc(buf, buf_sz+1)) == NULL) return NULL;
1723 }
1724 if (*c_ptr == '\\') c_ptr++;
1725 buf[buf_index++] = *c_ptr++;
1726 }
1727 }
1728 buf[buf_index] = '\0';
1729 return buf;
1730 }
1731
1732 static
SaveTmpURLToFile(psz_url,no_viewer_found,tmp_fname,new_file_name)1733 int SaveTmpURLToFile(psz_url, no_viewer_found, tmp_fname, new_file_name)
1734 char *psz_url, *tmp_fname, *new_file_name;
1735 int no_viewer_found;
1736 {
1737 char msg[MAXSTRING<<2];
1738 char *msg1=(char*)malloc((strlen(curDirIsLocal ? curDir : curLocalDir)+30) *
1739 sizeof(char));
1740 int rc=TG_REMOTE_STATUS_OK;
1741
1742 if (msg1 == NULL) { FailAllocMessage(); return INVALID; }
1743
1744 if (no_viewer_found) {
1745 sprintf(msg, TgLoadString(STID_NO_VIEWER_SAVE_GIVEN_STR_AS), psz_url);
1746 } else {
1747 sprintf(msg, TgLoadString(STID_SAVE_GIVEN_STR_AS), psz_url);
1748 }
1749 sprintf(msg1, TgLoadString(STID_WORKING_DIRECTORY_IS),
1750 (curDirIsLocal ? curDir : curLocalDir));
1751 *new_file_name = '\0';
1752 Dialog(msg, msg1, new_file_name);
1753 free(msg1);
1754 UtilTrimBlanks(new_file_name);
1755
1756 if (*new_file_name == '\0') return INVALID;
1757 if (!OkayToCreateFile(new_file_name)) return INVALID;
1758
1759 rc = UtilCopyFile(tmp_fname, new_file_name);
1760 if (rc != TG_REMOTE_STATUS_OK) {
1761 switch (rc) {
1762 case TG_REMOTE_STATUS_READ:
1763 sprintf(gszMsgBox, TgLoadString(STID_CANNOT_OPEN_FILE_FOR_READING),
1764 tmp_fname);
1765 break;
1766 case TG_REMOTE_STATUS_WRITE:
1767 sprintf(gszMsgBox, TgLoadString(STID_CANNOT_OPEN_FILE_FOR_WRITING),
1768 new_file_name);
1769 break;
1770 case TG_REMOTE_STATUS_FILE:
1771 sprintf(gszMsgBox, TgLoadString(STID_FAIL_TO_WRITE_TO_FILE),
1772 new_file_name);
1773 break;
1774 default:
1775 strcpy(gszMsgBox, TgLoadString(STID_UNKNOWN_ERR_IN_COPYING_FILES));
1776 break;
1777 }
1778 MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
1779 return INVALID;
1780 }
1781 return rc;
1782 }
1783
1784 static
UseMimeViewer(psz_url,psz_content_type,tmp_fname)1785 int UseMimeViewer(psz_url, psz_content_type, tmp_fname)
1786 char *psz_url, *psz_content_type, *tmp_fname;
1787 /* returns FALSE if psz_url is to be interpreted as a tgif file or text */
1788 /* returns TRUE if external viewer is launched */
1789 /* returns INVALID if there's an error or if the user canceled */
1790 {
1791 char new_file_name[MAXPATHLENGTH+1];
1792 char *viewer=NULL, *cmd=NULL, *big_s=NULL;
1793 int launch_remote_file=FALSE;
1794
1795 if (psz_content_type == NULL ||
1796 UtilStrICmp(psz_content_type, "application/x-tgif") == 0 ||
1797 strncmp(psz_url, "http:", 5) != 0) {
1798 return FALSE;
1799 }
1800 sprintf(gszMsgBox, "%s", psz_url);
1801 Msg(gszMsgBox);
1802 sprintf(gszMsgBox, " Content-type: %s", psz_content_type);
1803 Msg(gszMsgBox);
1804 /*
1805 * fprintf(stderr, "URL: %s\n", psz_url);
1806 * fprintf(stderr, "Content-Type: %s\n", psz_content_type);
1807 * fprintf(stderr, "tmp_fname: %s\n", tmp_fname);
1808 */
1809 viewer = GetMimeViewer(psz_content_type);
1810
1811 if (viewer == NULL) {
1812 char *slash_ptr=(psz_content_type == NULL ? NULL :
1813 strchr(psz_content_type, '/'));
1814
1815 if (slash_ptr != NULL) {
1816 *slash_ptr = '\0';
1817 if (UtilStrICmp(psz_content_type, "application") == 0 ||
1818 UtilStrICmp(psz_content_type, "audio") == 0 ||
1819 UtilStrICmp(psz_content_type, "image") == 0 ||
1820 UtilStrICmp(psz_content_type, "video") == 0 ||
1821 ((*psz_content_type == 'X' || *psz_content_type == 'x') &&
1822 psz_content_type[1] == '-')) {
1823 *slash_ptr = '/';
1824 SaveTmpURLToFile(psz_url, TRUE, tmp_fname, new_file_name);
1825 return TRUE;
1826 }
1827 *slash_ptr = '/';
1828 }
1829 return FALSE;
1830 }
1831 /*
1832 * fprintf(stderr, "Launch viewer: %s\n", viewer);
1833 */
1834 if ((big_s=strstr(viewer, "%S")) == NULL) {
1835 if (SaveTmpURLToFile(psz_url, FALSE, tmp_fname, new_file_name) ==
1836 INVALID) {
1837 free(viewer);
1838 return INVALID;
1839 }
1840 cmd = (char*)malloc((strlen(viewer)+strlen(new_file_name)+40) *
1841 sizeof(char));
1842 } else {
1843 big_s[1] = 's';
1844 launch_remote_file = TRUE;
1845 cmd = (char*)malloc((strlen(viewer)+strlen(psz_url)+40)*sizeof(char));
1846 }
1847 if (cmd == NULL) {
1848 FailAllocMessage();
1849 free(viewer);
1850 return INVALID;
1851 }
1852 LaunchViewer(launch_remote_file, viewer, psz_url, new_file_name);
1853 free(viewer);
1854 free(cmd);
1855 return TRUE;
1856 }
1857
1858 static char *gpszViewerInfo=NULL;
1859
1860 static
GetViewer(ext_str)1861 char *GetViewer(ext_str)
1862 char *ext_str;
1863 /* caller needs to call free() if not return NULL */
1864 {
1865 int ext_len=strlen(ext_str), value_len, orig_len;
1866 char resource_str[MAXSTRING+1];
1867 char *value=NULL, *c_ptr;
1868
1869 for (c_ptr=gpszViewerInfo; c_ptr != NULL && *c_ptr != '\0'; ) {
1870 char *cr=strchr(c_ptr, '\n'), *next_cr=NULL;
1871 int cmp_result;
1872
1873 if (cr == NULL) {
1874 free(gpszViewerInfo);
1875 gpszViewerInfo = NULL;
1876 return NULL;
1877 }
1878 *cr = '\0';
1879 cmp_result = UtilStrICmp(c_ptr, ext_str);
1880 *cr++ = '\n';
1881 next_cr = strchr(cr, '\n');
1882 if (next_cr == NULL) {
1883 free(gpszViewerInfo);
1884 gpszViewerInfo = NULL;
1885 return NULL;
1886 }
1887 if (cmp_result == 0) {
1888 char *return_str;
1889
1890 *next_cr = '\0';
1891 return_str = (*cr == '\0' ? NULL : UtilStrDup(cr));
1892 *next_cr = '\n';
1893 return return_str;
1894 }
1895 c_ptr = &next_cr[1];
1896 }
1897 sprintf(resource_str, "%sViewer", ext_str);
1898 if ((c_ptr=XGetDefault(mainDisplay,TOOL_NAME,resource_str)) != NULL) {
1899 int count=0;
1900
1901 value = (char*)malloc((strlen(c_ptr)+2)*sizeof(char));
1902 if (value == NULL) {
1903 FailAllocMessage();
1904 return NULL;
1905 }
1906 sprintf(value, "%s\n", c_ptr);
1907 for (c_ptr=strstr(value,"%s"); c_ptr != NULL;
1908 c_ptr=strstr(&c_ptr[2],"%s")) {
1909 count++;
1910 }
1911 for (c_ptr=strstr(value,"%S"); c_ptr != NULL;
1912 c_ptr=strstr(&c_ptr[2],"%S")) {
1913 count++;
1914 }
1915 if (count > 1) {
1916 sprintf(gszMsgBox, TgLoadString(STID_INVALID_XDEF), TOOL_NAME,
1917 resource_str, value);
1918 MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
1919 strcpy(value, "\n");
1920 }
1921 } else {
1922 if ((value=UtilStrDup("\n")) == NULL) return NULL;
1923 }
1924 value_len = strlen(value);
1925 orig_len = (gpszViewerInfo == NULL ? 0 : strlen(gpszViewerInfo));
1926 if ((gpszViewerInfo=(gpszViewerInfo == NULL ?
1927 (char*)malloc((orig_len+ext_len+1+value_len+2)*sizeof(char)) :
1928 (char*)realloc(gpszViewerInfo, orig_len+ext_len+1+value_len+2))) ==
1929 NULL) {
1930 FailAllocMessage();
1931 return NULL;
1932 }
1933 sprintf(&gpszViewerInfo[orig_len], "%s\n%s", ext_str, value);
1934 if (value[value_len-1] == '\n') value[--value_len] = '\0';
1935 if (*value == '\0') {
1936 free(value);
1937 return NULL;
1938 }
1939 return value;
1940 }
1941
1942 static
UseViewer(psz_url,psz_content_type,tmp_fname)1943 int UseViewer(psz_url, psz_content_type, tmp_fname)
1944 char *psz_url, *psz_content_type, *tmp_fname;
1945 /* returns FALSE if psz_url is to be interpreted as a tgif file or text */
1946 /* returns TRUE if external viewer is launched */
1947 /* returns INVALID if there's an error or if the user canceled */
1948 {
1949 char *ext_str=UtilStrRChr(psz_url, (int)'/');
1950 char new_file_name[MAXPATHLENGTH+1];
1951 char *viewer=NULL, *cmd=NULL, *big_s=NULL, *separator, saved_ch='\0';
1952 int launch_remote_file=FALSE;
1953
1954 if (ext_str == NULL) {
1955 return UseMimeViewer(psz_url, psz_content_type, tmp_fname);
1956 }
1957 for (separator=(&ext_str[1]); *separator != '\0'; separator++) {
1958 if (*separator == '#' || *separator == '?') {
1959 saved_ch = *separator;
1960 *separator = '\0';
1961 break;
1962 }
1963 }
1964 if ((ext_str=strchr(ext_str, '.')) == NULL) {
1965 if (separator != NULL) *separator = saved_ch;
1966 return UseMimeViewer(psz_url, psz_content_type, tmp_fname);
1967 }
1968 ext_str++;
1969 viewer = GetViewer(ext_str);
1970 if (separator != NULL) *separator = saved_ch;
1971 if (viewer == NULL) {
1972 return UseMimeViewer(psz_url, psz_content_type, tmp_fname);
1973 }
1974 if ((big_s=strstr(viewer, "%S")) == NULL) {
1975 if (SaveTmpURLToFile(psz_url, FALSE, tmp_fname, new_file_name) ==
1976 INVALID) {
1977 free(viewer);
1978 return INVALID;
1979 }
1980 cmd = (char*)malloc((strlen(viewer)+strlen(new_file_name)+40) *
1981 sizeof(char));
1982 } else {
1983 big_s[1] = 's';
1984 launch_remote_file = TRUE;
1985 cmd = (char*)malloc((strlen(viewer)+strlen(psz_url)+40)*sizeof(char));
1986 }
1987 if (cmd == NULL) {
1988 FailAllocMessage();
1989 free(viewer);
1990 return INVALID;
1991 }
1992 LaunchViewer(launch_remote_file, viewer, psz_url, new_file_name);
1993 free(viewer);
1994 free(cmd);
1995 return TRUE;
1996 }
1997
UseExternalViewer(is_html,psz_url,psz_content_type,tmp_fname)1998 int UseExternalViewer(is_html, psz_url, psz_content_type, tmp_fname)
1999 int is_html;
2000 char *psz_url, *psz_content_type, *tmp_fname;
2001 /* returns FALSE if psz_url is to be interpreted as a tgif file or text */
2002 /* returns TRUE if external viewer is launched */
2003 /* returns INVALID if there's an error or if the user canceled */
2004 {
2005 char *viewer=NULL;
2006 int rc=FALSE;
2007 int url_is_html=UrlIsHtml(psz_url);
2008
2009 if (url_is_html || !is_html) {
2010 if (UseViewer(psz_url, psz_content_type, tmp_fname) != FALSE) {
2011 rc = TRUE;
2012 }
2013 } else if (is_html && (viewer=GetViewer("html")) != NULL) {
2014 char new_file_name[MAXPATHLENGTH+1], *cmd=NULL, *big_s=NULL;
2015 int launch_remote_file=FALSE;
2016
2017 if ((big_s=strstr(viewer, "%S")) == NULL) {
2018 if (SaveTmpURLToFile(psz_url, FALSE, tmp_fname, new_file_name) ==
2019 INVALID) {
2020 free(viewer);
2021 return INVALID;
2022 }
2023 cmd = (char*)malloc((strlen(viewer)+strlen(new_file_name)+40) *
2024 sizeof(char));
2025 } else {
2026 big_s[1] = 's';
2027 launch_remote_file = TRUE;
2028 cmd = (char*)malloc((strlen(viewer)+strlen(psz_url)+40)*sizeof(char));
2029 }
2030 if (cmd == NULL) {
2031 FailAllocMessage();
2032 free(viewer);
2033 rc = INVALID;
2034 } else {
2035 LaunchViewer(launch_remote_file, viewer, psz_url, new_file_name);
2036 free(viewer);
2037 free(cmd);
2038 rc = TRUE;
2039 }
2040 } else if (UseMimeViewer(psz_url, psz_content_type, tmp_fname) != FALSE) {
2041 rc = TRUE;
2042 }
2043 return rc;
2044 }
2045
LoadRemoteFileFromMem(psz_url,psz_buf,psz_content_type,buf_sz,is_html)2046 int LoadRemoteFileFromMem(psz_url, psz_buf, psz_content_type, buf_sz, is_html)
2047 char *psz_url, *psz_buf, *psz_content_type;
2048 int buf_sz, is_html;
2049 {
2050 char *tmp_fname=WriteRemoteFileIntoTemp(psz_buf, buf_sz, NULL);
2051 int navigating=navigatingBackAndForth, rc_loadfile;
2052
2053 if (tmp_fname == NULL) return FALSE;
2054
2055 if (UseExternalViewer(is_html, psz_url, psz_content_type, tmp_fname) !=
2056 FALSE) {
2057 unlink(tmp_fname);
2058 free(tmp_fname);
2059 return FALSE;
2060 }
2061 if (!navigating) {
2062 BeforeNavigate();
2063 navigatingBackAndForth = TRUE;
2064 }
2065 rc_loadfile = LoadFile(tmp_fname, (-1), FALSE);
2066 if (!navigating) navigatingBackAndForth = FALSE;
2067
2068 if (!rc_loadfile) {
2069 NewProc();
2070 PasteString(psz_buf, TRUE, TRUE);
2071 }
2072 SetCurDir(psz_url);
2073 curFileDefined = TRUE;
2074 RedrawTitleWindow();
2075 sprintf(gszMsgBox, TgLoadCachedString(CSTID_CUR_FILE_IS), psz_url);
2076 Msg(gszMsgBox);
2077 unlink(tmp_fname);
2078 free(tmp_fname);
2079 if (!navigating) CommitNavigate();
2080 return TRUE;
2081 }
2082
2083 static
ModifyProxy(proxy_host)2084 void ModifyProxy(proxy_host)
2085 char *proxy_host;
2086 {
2087 char *c_ptr, *host=NULL, *port;
2088
2089 if ((c_ptr=strstr(proxy_host, "//")) == NULL) {
2090 if ((host=UtilStrDup(proxy_host)) == NULL) return;
2091 } else {
2092 if ((host=UtilStrDup(&c_ptr[2])) == NULL) return;
2093 }
2094 port = strchr(host, ':');
2095 if (port != NULL) *port++ = '\0';
2096 sprintf(proxy_host, "%s%s%s",
2097 host, port==NULL ? "" : ":", port==NULL ? "" : port);
2098 free(host);
2099 }
2100
InitLocalPID()2101 void InitLocalPID()
2102 {
2103 static int stInitialized=FALSE;
2104
2105 if (!stInitialized) {
2106 int pid=(int)getpid();
2107 char sz_host_name[MAXSTRING];
2108
2109 *gszLocalPID = *sz_host_name = '\0';
2110 if (gethostname(sz_host_name, sizeof(sz_host_name)) < 0) {
2111 fprintf(stderr, "%s\n",
2112 TgLoadString(STID_CANT_GETHOSTNAME_USE_LOCALH));
2113 strcpy(sz_host_name, "localhost");
2114 }
2115 sprintf(gszLocalPID, "%1d:%s", pid, sz_host_name);
2116
2117 stInitialized = TRUE;
2118 }
2119 }
2120
InitRemote()2121 void InitRemote()
2122 {
2123 char *c_ptr=NULL;
2124 int val=0;
2125
2126 InitLocalPID();
2127
2128 autoHyperSpaceOnRemote = TRUE;
2129 if ((c_ptr=XGetDefault(mainDisplay,TOOL_NAME,"AutoHyperSpaceOnRemote")) !=
2130 NULL && UtilStrICmp(c_ptr, "false") == 0) {
2131 autoHyperSpaceOnRemote = FALSE;
2132 }
2133 allowLaunchInHyperSpace = FALSE;
2134 if ((c_ptr=XGetDefault(mainDisplay,TOOL_NAME,"AllowLaunchInHyperSpace")) !=
2135 NULL && UtilStrICmp(c_ptr, "true") == 0) {
2136 allowLaunchInHyperSpace = TRUE;
2137 }
2138 *gzipCmd = '\0';
2139 if ((c_ptr=XGetDefault(mainDisplay,TOOL_NAME,"GZipCmd")) == NULL) {
2140 strcpy(gzipCmd, "gzip -c");
2141 } else {
2142 strcpy(gzipCmd, c_ptr);
2143 }
2144 *gunzipCmd = '\0';
2145 if ((c_ptr=XGetDefault(mainDisplay,TOOL_NAME,"GUnZipCmd")) == NULL) {
2146 strcpy(gunzipCmd, "gunzip -c");
2147 } else {
2148 strcpy(gunzipCmd, c_ptr);
2149 }
2150 *uncompressCmd = '\0';
2151 if ((c_ptr=XGetDefault(mainDisplay,TOOL_NAME,"UncompressCmd")) == NULL) {
2152 strcpy(uncompressCmd, "uncompress -c");
2153 } else {
2154 strcpy(uncompressCmd, c_ptr);
2155 }
2156 *httpProxy = '\0';
2157 if ((c_ptr=getenv("http_proxy")) != NULL) {
2158 strcpy(httpProxy, c_ptr);
2159 ModifyProxy(httpProxy);
2160 } else if ((c_ptr=XGetDefault(mainDisplay,TOOL_NAME,"HttpProxy")) != NULL) {
2161 strcpy(httpProxy, c_ptr);
2162 ModifyProxy(httpProxy);
2163 } else {
2164 *httpProxy = '\0';
2165 }
2166 *ftpProxy = '\0';
2167 if ((c_ptr=getenv("ftp_proxy")) != NULL) {
2168 strcpy(ftpProxy, c_ptr);
2169 ModifyProxy(ftpProxy);
2170 } else if ((c_ptr=XGetDefault(mainDisplay,TOOL_NAME,"FtpProxy")) != NULL) {
2171 strcpy(ftpProxy, c_ptr);
2172 ModifyProxy(ftpProxy);
2173 } else {
2174 *ftpProxy = '\0';
2175 }
2176 if ((c_ptr=XGetDefault(mainDisplay,TOOL_NAME,"DebugHttp")) != NULL &&
2177 sscanf(c_ptr, "%d", &val) == 1 && val >= 0) {
2178 HttpDebug(val);
2179 }
2180 if ((c_ptr=XGetDefault(mainDisplay,TOOL_NAME,"DebugFtp")) != NULL &&
2181 sscanf(c_ptr, "%d", &val) == 1 && val >= 0) {
2182 FtpDebug(val);
2183 }
2184 gnHttpKeepAlive = FALSE;
2185 if ((c_ptr=XGetDefault(mainDisplay,TOOL_NAME,"HttpKeepAlive")) != NULL &&
2186 UtilStrICmp(c_ptr, "true") == 0) {
2187 gnHttpKeepAlive = TRUE;
2188 }
2189 if ((c_ptr=XGetDefault(mainDisplay,TOOL_NAME,"FakedReferer")) != NULL) {
2190 HttpFakeReferer(c_ptr);
2191 }
2192 InitHttp();
2193 InitMime();
2194 }
2195
CleanUpRemote()2196 void CleanUpRemote()
2197 {
2198 gnUserAgentInitialized = FALSE;
2199 *gszUserAgentName = '\0';
2200 CleanUpDownloadStats();
2201 CleanUpMime();
2202 CleanUpHttp();
2203 if (gpszViewerInfo != NULL) {
2204 free(gpszViewerInfo);
2205 gpszViewerInfo = NULL;
2206 }
2207 FreeMimeTypesInfo();
2208 FreeMailCapInfo();
2209 }
2210