Annotation of Amaya/amaya/query.c, revision 1.141
1.14 cvs 1: /*
2: *
3: * (c) COPYRIGHT MIT and INRIA, 1996.
4: * Please first read the full copyright statement in file COPYRIGHT.
5: *
6: */
1.4 cvs 7:
1.19 cvs 8: /*
1.83 cvs 9: * query.c : contains all the functions for requesting and publishing
1.19 cvs 10: * URLs via libwww. It handles any eventual HTTP error code
11: * (redirection, authentication needed, not found, etc.)
12: *
1.69 cvs 13: * Author: J. Kahan
1.92 cvs 14: * J. Kahan/R. Guetari Windows 95/NT routines
1.19 cvs 15: */
1.17 cvs 16:
1.44 cvs 17: #ifndef AMAYA_JAVA
18:
1.116 cvs 19: /* defines to include elsewhere
20: *********************************/
21:
1.124 cvs 22: #ifndef _WINDOWS
1.130 cvs 23: #endif /* !_WINDOWS */
1.116 cvs 24: #define AMAYA_WWW_CACHE
25:
1.128 cvs 26: #define CACHE_DIR_NAME DIR_STR"libwww-cache"
1.116 cvs 27: #define DEFAULT_CACHE_SIZE 5
28:
1.12 cvs 29: /* Amaya includes */
1.25 cvs 30: #define THOT_EXPORT extern
1.4 cvs 31: #include "amaya.h"
1.130 cvs 32: #include <sys/types.h>
1.70 cvs 33: #include <fcntl.h>
1.140 cvs 34: #include "HTEvtLst.h"
1.7 cvs 35:
1.141 ! cvs 36: #if defined(__svr4__) || defined (_AIX)
1.4 cvs 37: #define CATCH_SIG
38: #endif
39:
40: /* local structures coming from libwww and which are
1.17 cvs 41: not found in any .h file
1.7 cvs 42: */
1.68 cvs 43:
1.7 cvs 44: struct _HTStream
45: {
1.15 cvs 46: const HTStreamClass *isa;
47: FILE *fp;
1.45 cvs 48: BOOL leave_open; /* Close file when TtaFreeMemory? */
1.15 cvs 49: char *end_command; /* Command to execute */
50: BOOL remove_on_close; /* Remove file? */
51: char *filename; /* Name of file */
52: HTRequest *request; /* saved for callback */
53: HTRequestCallback *callback;
1.7 cvs 54: };
55:
1.15 cvs 56:
1.7 cvs 57: struct _HTError
58: {
59: HTErrorElement element; /* Index number into HTError */
60: HTSeverity severity; /* A la VMS */
61: BOOL ignore; /* YES if msg should not go to user */
62: void *par; /* Explanation, e.g. filename */
63: int length; /* For copying by generic routine */
64: char *where; /* Which function */
65: };
66:
1.4 cvs 67: /* Type definitions and global variables etc. local to this module */
68:
1.17 cvs 69: /*----------------------------------------------------------------------*/
70:
1.4 cvs 71: /*** private variables ***/
1.17 cvs 72:
1.4 cvs 73: static HTList *converters = NULL; /* List of global converters */
1.27 cvs 74: static HTList *acceptTypes = NULL; /* List of types for the Accept header */
1.4 cvs 75: static HTList *encodings = NULL;
1.16 cvs 76: static int object_counter = 0; /* loaded objects counter */
1.140 cvs 77: static boolean AmayaAlive_flag; /* set to 1 if the application is active;
78: 0 if we have killed */
79: static boolean CanDoStop_flag; /* set to 1 if we can do a stop, 0
80: if we're inside a critical section */
1.128 cvs 81: #ifdef AMAYA_WWW_CACHE
1.130 cvs 82: static int fd_cachelock; /* open handle to the .lock cache file */
83: #endif /* AMAYA_WWW_CACHE */
1.4 cvs 84:
1.15 cvs 85: #include "answer_f.h"
86: #include "query_f.h"
87: #include "AHTURLTools_f.h"
88: #include "AHTBridge_f.h"
89: #include "AHTMemConv_f.h"
90: #include "AHTFWrite_f.h"
1.4 cvs 91:
1.116 cvs 92: /* prototypes */
93:
94: #ifdef __STDC__
1.128 cvs 95: static void RecCleanCache (char *dirname);
1.123 cvs 96: #ifdef _WINDOWS
1.70 cvs 97: int WIN_Activate_Request (HTRequest* , HTAlertOpcode, int, const char*, void*, HTAlertPar*);
1.116 cvs 98: #endif /* _WINDOWS */
1.70 cvs 99: #else
1.128 cvs 100: static void RecCleanCache (/* char *dirname */);
1.123 cvs 101: #ifdef _WINDOWS
1.128 cvs 102: int WIN_Activate_Request (/* HTRequest* , HTAlertOpcode, int, const char*, void*, HTAlertPar* */);
1.116 cvs 103: #endif /* _WINDOWS */
1.70 cvs 104: #endif /* __STDC__ */
1.116 cvs 105:
1.15 cvs 106:
1.130 cvs 107: #ifdef AMAYA_WWW_CACHE
108: /***************************************************************
109: lock functions, used to avoid concurrent use of the cache
110: Mostly based on W. Richard Stevens' APUE book.
111: ***************************************************************/
112: /*----------------------------------------------------------------------
113: set_cachelock
114: sets a write lock on filename.
115: Returns -1 in case of failure, otherwise, it'll open a handle on
116: filename and fd_cachelock will take its value.
117: ----------------------------------------------------------------------*/
118: #ifdef __STDC__
119: static int set_cachelock (char *filename)
120: #else
121: static int set_cachelock (filename)
122: char *filename;
123: #endif /* __STDC__ */
124: {
125: #ifdef _WINDOWS
126: return 0;
127: #else
128: int status;
129: struct flock lock;
130:
131: lock.l_type = F_WRLCK;
132: lock.l_start = 0;
133: lock.l_whence = SEEK_SET;
134: lock.l_len = 0;
135:
136: fd_cachelock = open (filename, O_WRONLY);
137:
138: if (fd_cachelock == -1)
139: status = -1;
140: else
141: status = fcntl(fd_cachelock, F_SETLK, &lock);
142:
143: if (status == -1)
144: fd_cachelock = 0;
145:
146: return (status);
147: #endif /* _WINDOWS */
148: }
149:
150: /*----------------------------------------------------------------------
151: clear_cachelock
152: remove the write lock set on a filename.
153: It'll close the fd handle on filename and reset *fd to 0.
154: ----------------------------------------------------------------------*/
155: #ifdef __STDC__
156: static int clear_cachelock (void)
157: #else
158: static int clear_cachelock ()
159: int *fd;
160: #endif /* __STDC__ */
161: {
162: #ifdef _WINDOWS
163: return 0;
164: #else
165: int status;
166: struct flock lock;
167:
168: if (fd_cachelock)
169: return (-1);
170:
171: lock.l_type = F_UNLCK;
172: lock.l_start = 0;
173: lock.l_whence = SEEK_SET;
174: lock.l_len = 0;
175:
176: status = fcntl(fd_cachelock, F_SETLK, &lock);
177: close (fd_cachelock);
178: fd_cachelock = 0;
179:
180: return (status);
181: #endif /* _WINDOWS */
182: }
183:
184: /*----------------------------------------------------------------------
185: test_cachelock
186: returns 0 if a fd is not locked by other process, otherwise
187: returns the pid of the process who has the lock
188: ----------------------------------------------------------------------*/
189: #ifdef __STDC__
190: static int test_cachelock (char *filename)
191: #else
192: static int test_cachelock (filename)
193: char *filename;
194: #endif __STDC__
195: {
196: #ifdef _WINDOWS
197: int fd;
1.137 cvs 198: fd = _open (filename, _O_WRONLY | _O_BINARY);
1.130 cvs 199: if (fd != -1)
200: {
1.137 cvs 201: _close (fd);
1.130 cvs 202: return 0;
203: }
204: else
205: return -1;
206: #else
207: struct flock lock;
208: int fd, status;
209:
210: lock.l_type = F_WRLCK;
211: lock.l_start = 0;
212: lock.l_whence = SEEK_SET;
213: lock.l_len = 0;
214:
215: fd = open (filename, O_WRONLY);
216:
217: if (fd < 0)
218: return (-1);
219: /* is this file locked ? */
220: status = fcntl (fd, F_GETLK, &lock);
221: close (fd);
222:
223: if (status < 0)
224: return (-1);
225:
226: if (lock.l_type == F_UNLCK)
227: return (0); /* false, region is not locked by another proc */
228: return (lock.l_pid); /* true, return pid of lock owner */
229: #endif /* _WINDOWS */
230: }
231:
232: #endif /* AMAYA_WWW_CACHE */
233:
1.15 cvs 234: /*----------------------------------------------------------------------
1.17 cvs 235: GetDocIdStatus
236: gets the status associated to a docid
1.15 cvs 237: ----------------------------------------------------------------------*/
238: #ifdef __STDC__
239: AHTDocId_Status *GetDocIdStatus (int docid, HTList * documents)
240: #else
241: AHTDocID_Status *GetDocIdStatus (docid, documents)
242: int docid;
243: HTList *documents;
244:
245: #endif
246: {
247: AHTDocId_Status *me;
248: HTList *cur;
249:
250: if (documents)
251: {
252: cur = documents;
253:
254: while ((me = (AHTDocId_Status *) HTList_nextObject (cur)))
255: {
256: if (me->docid == docid)
257: return (me);
1.18 cvs 258: }
259: }
1.15 cvs 260: return (AHTDocId_Status *) NULL;
261:
262: }
263:
1.5 cvs 264: /*----------------------------------------------------------------------
1.27 cvs 265: AHTGuessAtom_for
266: Converts an Amaya type descriptor into the equivalent MIME type.
267: ----------------------------------------------------------------------*/
268: #ifdef __STDC__
269: static HTAtom *AHTGuessAtom_for (char *urlName, PicType contentType)
270: #else
271: static HTAtom *AHTGuessAtom_for (urlName, contentType)
272: char *urlName;
273: PicType contentType;
274: #endif
275: {
276: HTAtom *atom;
277: char *filename;
278: HTEncoding enc;
279: HTEncoding cte;
280: HTLanguage lang;
1.50 cvs 281: double quality = 1.0;
1.27 cvs 282:
283: switch (contentType)
284: {
285: case xbm_type:
286: atom = HTAtom_for("image/xbm");
287: break;
288: case eps_type:
1.35 cvs 289: atom = HTAtom_for("application/postscript");
1.27 cvs 290: break;
291: case xpm_type:
292: atom = HTAtom_for("image/xpm");
293: break;
294: case gif_type:
295: atom = HTAtom_for("image/gif");
296: break;
297: case jpeg_type:
298: atom = HTAtom_for("image/jpeg");
299: break;
300: case png_type:
301: atom = HTAtom_for("image/png");
302: break;
303: case unknown_type:
304: default:
305: /*
306: ** Amaya could not detect the type, so
307: ** we try to use the filename's suffix to do so.
308: */
1.45 cvs 309: filename = AmayaParseUrl (urlName, "", AMAYA_PARSE_PATH | AMAYA_PARSE_PUNCTUATION);
1.27 cvs 310: HTBind_getFormat (filename, &atom, &enc, &cte, &lang, &quality);
1.45 cvs 311: TtaFreeMemory (filename);
1.27 cvs 312: if (atom == WWW_UNKNOWN)
313: /*
314: ** we could not identify the suffix, so we assign it
315: ** a default type
316: */
317: atom = HTAtom_for ("text/html");
318: break;
319: }
320:
321: return atom;
322: }
323:
324: /*----------------------------------------------------------------------
1.17 cvs 325: AHTReqContext_new
326: create a new Amaya Context Object and update the global Amaya
327: request status.
1.5 cvs 328: ----------------------------------------------------------------------*/
1.4 cvs 329: #ifdef __STDC__
330: static AHTReqContext *AHTReqContext_new (int docid)
331: #else
332: static AHTReqContext *AHTReqContext_new (docid)
333: int docid;
334:
335: #endif
336: {
337: AHTReqContext *me;
338: AHTDocId_Status *docid_status;
339:
340: if ((me = (AHTReqContext *) TtaGetMemory (sizeof (AHTReqContext))) == NULL)
1.116 cvs 341: outofmem (__FILE__, "AHTReqContext_new");
342:
343: /* clear the structure */
344: memset ((void *) me, 0, sizeof (AHTReqContext));
1.4 cvs 345:
1.81 cvs 346: /* Bind the Context object together with the Request Object */
347: me->request = HTRequest_new ();
348:
1.116 cvs 349: /*
350: ** Make sure that the first request is flushed immediately and not
351: ** buffered in the output buffer
352: */
353: HTRequest_setFlush(me->request, YES);
354:
1.80 cvs 355: /* clean the associated file structure) */
1.79 cvs 356: HTRequest_setOutputStream (me->request, NULL);
1.81 cvs 357:
1.4 cvs 358: /* Initialize the other members of the structure */
1.17 cvs 359: me->reqStatus = HT_NEW; /* initial status of a request */
1.4 cvs 360: me->docid = docid;
361: HTRequest_setMethod (me->request, METHOD_GET);
362: HTRequest_setOutputFormat (me->request, WWW_SOURCE);
363: HTRequest_setContext (me->request, me);
1.116 cvs 364:
1.36 cvs 365: /* experimental */
366: me->read_sock = INVSOC;
367: me->write_sock = INVSOC;
368: me->except_sock = INVSOC;
1.4 cvs 369:
370: /* Update the global context */
371: HTList_appendObject (Amaya->reqlist, (void *) me);
372:
373: docid_status = GetDocIdStatus (docid, Amaya->docid_status);
374:
1.7 cvs 375: if (docid_status == NULL)
376: {
1.116 cvs 377: docid_status = (AHTDocId_Status *)
378: TtaGetMemory (sizeof (AHTDocId_Status));
1.7 cvs 379: docid_status->docid = docid;
380: docid_status->counter = 1;
381: HTList_addObject (Amaya->docid_status, (void *) docid_status);
382: }
383: else
1.4 cvs 384: docid_status->counter++;
385:
386: Amaya->open_requests++;
387:
1.74 cvs 388: #ifdef DEBUG_LIBWWW
389: fprintf (stderr, "AHTReqContext_new: Created object %p\n", me);
390: #endif
1.116 cvs 391:
1.4 cvs 392: return me;
393: }
394:
1.5 cvs 395: /*----------------------------------------------------------------------
1.17 cvs 396: AHTReqContext_delete
397: Delete an Amaya Context Object and update the global Amaya request
398: status.
1.5 cvs 399: ----------------------------------------------------------------------*/
1.4 cvs 400:
401: #ifdef __STDC__
1.15 cvs 402: boolean AHTReqContext_delete (AHTReqContext * me)
1.4 cvs 403: #else
1.15 cvs 404: boolean AHTReqContext_delete (me)
1.4 cvs 405: AHTReqContext *me;
406:
407: #endif
408: {
409: AHTDocId_Status *docid_status;
410:
1.7 cvs 411: if (me)
412: {
1.4 cvs 413:
1.74 cvs 414: #ifdef DEBUG_LIBWWW
1.138 cvs 415: fprintf (stderr, "AHTReqContext_delete: Deleting object %p\n", me);
1.74 cvs 416: #endif
1.138 cvs 417: if (Amaya->reqlist)
418: HTList_removeObject (Amaya->reqlist, (void *) me);
419:
420: docid_status = GetDocIdStatus (me->docid, Amaya->docid_status);
421: if (docid_status)
422: {
423: docid_status->counter--;
424:
425: if (docid_status->counter == 0)
426: {
427: HTList_removeObject (Amaya->docid_status, (void *) docid_status);
428: TtaFreeMemory ((void *) docid_status);
429: }
430: }
431: if (me->method != METHOD_PUT && HTRequest_outputStream (me->request))
432: AHTFWriter_FREE (me->request->output_stream);
433:
434: HTRequest_delete (me->request);
435:
436: if (me->output && me->output != stdout)
437: {
1.85 cvs 438: #ifdef DEBUG_LIBWWW
1.138 cvs 439: fprintf (stderr, "AHTReqContext_delete: URL is %s, closing "
440: "FILE %p\n", me->urlName, me->output);
1.85 cvs 441: #endif
1.138 cvs 442: fclose (me->output);
443: me->output = NULL;
444: }
1.79 cvs 445:
1.138 cvs 446: if (me->error_stream != (char *) NULL)
447: HT_FREE (me->error_stream);
448: #ifndef _WINDOWS
449: #ifdef WWW_XWINDOWS
450: if (me->read_xtinput_id || me->write_xtinput_id ||
451: me->except_xtinput_id)
452: RequestKillAllXtevents(me);
453: #endif /* WWW_XWINDOWS */
454: #endif /* !_WINDOWS */
455:
456: if (me->reqStatus == HT_ABORT)
457: {
458: if (me->outputfile && me->outputfile[0] != EOS)
459: {
460: TtaFileUnlink (me->outputfile);
461: me->outputfile[0] = EOS;
462: }
463: }
464:
465: if ((me->mode & AMAYA_ASYNC) || (me->mode & AMAYA_IASYNC))
466: /* for the ASYNC mode, free the memory we allocated in GetObjectWWW
467: or in PutObjectWWW */
468: {
469: if (me->urlName)
470: TtaFreeMemory (me->urlName);
471: if (me->outputfile)
472: TtaFreeMemory (me->outputfile);
473: }
474:
475: if (me->content_type)
476: TtaFreeMemory (me->content_type);
477:
478: if (me->formdata)
479: HTAssocList_delete (me->formdata);
480:
481: /* to trace bugs */
482: memset ((void *) me, 0, sizeof (AHTReqContext));
483:
484: TtaFreeMemory ((void *) me);
485:
486: Amaya->open_requests--;
487:
488: return TRUE;
1.7 cvs 489: }
1.15 cvs 490: return FALSE;
1.4 cvs 491: }
492:
493:
1.15 cvs 494: /*----------------------------------------------------------------------
1.17 cvs 495: Thread_deleteAll
496: this function deletes the whole list of active threads.
1.5 cvs 497: ----------------------------------------------------------------------*/
1.4 cvs 498: #ifdef __STDC__
499: static void Thread_deleteAll (void)
500: #else
501: static void Thread_deleteAll ()
502: #endif
503: {
1.21 cvs 504: HTList *cur;
505: AHTReqContext *me;
506: AHTDocId_Status *docid_status;
507:
1.74 cvs 508: if (Amaya && Amaya->reqlist)
509: {
510: if (Amaya->open_requests > 0)
511: #ifdef DEBUG_LIBWWW
512: fprintf (stderr, "Thread_deleteAll: Killing %d outstanding "
513: "requests\n", Amaya->open_requests);
514: #endif
515: {
516: cur = Amaya->reqlist;
517:
518: /* erase the requests */
519: while ((me = (AHTReqContext *) HTList_removeLastObject (cur)))
520: {
521: if (me->request)
522: {
1.138 cvs 523: #ifndef _WINDOWS
1.74 cvs 524: RequestKillAllXtevents (me);
1.138 cvs 525: #endif /* !_WINDOWS */
1.92 cvs 526:
1.140 cvs 527: if (!HTRequest_kill (me->request))
528: AHTReqContext_delete (me);
1.74 cvs 529: }
530: } /* while */
531:
532: /* erase the docid_status entities */
533: while ((docid_status = (AHTDocId_Status *) HTList_removeLastObject ((void *) Amaya->docid_status)))
534: TtaFreeMemory ((void *) docid_status);
535:
536: } /* if */
1.84 cvs 537:
1.74 cvs 538: }
1.4 cvs 539: }
540:
1.5 cvs 541: /*----------------------------------------------------------------------
1.83 cvs 542: AHTOpen_file
543: ----------------------------------------------------------------------*/
544: #ifdef __STDC__
1.85 cvs 545: int AHTOpen_file (HTRequest * request)
1.83 cvs 546: #else
1.85 cvs 547: int AHTOpen_file (request)
1.83 cvs 548: HTRequest *request;
549:
550: #endif /* __STDC__ */
551: {
552: AHTReqContext *me; /* current request */
553:
554: me = HTRequest_context (request);
555:
1.93 cvs 556: if (!me)
557: return HT_ERROR;
558:
1.83 cvs 559: #ifdef DEBUG_LIBWWW
1.116 cvs 560: fprintf(stderr, "AHTOpen_file: start for object : %p\n", me);
1.85 cvs 561: #endif /* DEBUG_LIBWWW */
562:
563: if (me->reqStatus == HT_ABORT)
564: {
565: #ifdef DEBUG_LIBWWW
566: fprintf(stderr, "AHTOpen_file: caught an abort request, skipping it\n");
1.83 cvs 567: #endif /* DEBUG_LIBWWW */
568:
1.85 cvs 569: return HT_OK;
570: }
571:
1.136 cvs 572: if (me->method == METHOD_PUT)
573: {
574: me->reqStatus = HT_WAITING;
575: return HT_OK;
576: }
577:
1.85 cvs 578: if (HTRequest_outputStream (me->request))
579: {
580:
581: #ifdef DEBUG_LIBWWW
582: fprintf(stderr, "AHTOpen_file: output stream already existed for url %s\n", me->urlName);
583: #endif /* DEBUG_LIBWWW */
584: return HT_OK;
585: }
586:
587: #ifdef DEBUG_LIBWWW
588: fprintf(stderr, "AHTOpen_file: opening output stream for url %s\n", me->urlName);
589: #endif /* DEBUG_LIBWWW */
590:
1.83 cvs 591: if (!(me->output) &&
592: (me->output != stdout) &&
593: #ifndef _WINDOWS
594: (me->output = fopen (me->outputfile, "w")) == NULL)
595: {
1.116 cvs 596: #else /* !_WINDOWS */
1.83 cvs 597: (me->output = fopen (me->outputfile, "wb")) == NULL)
598: {
599: #endif /* !_WINDOWS */
600:
1.131 cvs 601: me->outputfile[0] = EOS; /* file could not be opened */
1.85 cvs 602: #ifdef DEBUG_LIBWWW
603: fprintf(stderr, "AHTOpen_file: couldn't open output stream for url %s\n", me->urlName);
604: #endif
1.83 cvs 605: TtaSetStatus (me->docid, 1,
606: TtaGetMessage (AMAYA, AM_CANNOT_CREATE_FILE),
607: me->outputfile);
608: me->reqStatus = HT_ERR;
609: return (HT_ERROR);
610: }
611:
612: HTRequest_setOutputStream (me->request,
613: AHTFWriter_new (me->request,
614: me->output, YES));
615: me->reqStatus = HT_WAITING;
616:
617: return HT_OK;
618: }
619:
620: /*----------------------------------------------------------------------
1.17 cvs 621: redirection_handler
622: this function is registered to handle permanent and temporary
623: redirections.
624: ----------------------------------------------------------------------*/
1.4 cvs 625: #ifdef __STDC__
1.7 cvs 626: static int redirection_handler (HTRequest * request, HTResponse * response, void *param, int status)
1.4 cvs 627: #else
628: static int redirection_handler (request, context, status)
629: HTRequest *request;
630: HTResponse *response;
631: void *param;
632: int status;
633:
634: #endif
635: {
636:
637: HTAnchor *new_anchor = HTResponse_redirection (response);
1.7 cvs 638: AHTReqContext *me = HTRequest_context (request);
1.4 cvs 639: HTMethod method = HTRequest_method (request);
1.98 cvs 640: char *ref;
641: char *tmp;
1.4 cvs 642:
1.7 cvs 643: if (!new_anchor)
644: {
645: if (PROT_TRACE)
646: HTTrace ("Redirection. No destination\n");
647: return HT_OK;
648: }
1.4 cvs 649:
650: /*
651: ** Only do redirect on GET and HEAD
652: */
1.7 cvs 653: if (!HTMethod_isSafe (method))
654: {
1.130 cvs 655: /*
656: ** If we got a 303 See Other then change the method to GET.
657: ** Otherwise ask the user whether we should continue.
658: */
659: if (status == HT_SEE_OTHER)
660: {
661: if (PROT_TRACE)
662: HTTrace("Redirection. Changing method from %s to GET\n",
663: HTMethod_name(method));
664: HTRequest_setMethod(request, METHOD_GET);
665: }
666: else
667: {
668: HTAlertCallback *prompt = HTAlert_find (HT_A_CONFIRM);
669: if (prompt)
670: {
671: if ((*prompt) (request, HT_A_CONFIRM, HT_MSG_REDIRECTION,
672: NULL, NULL, NULL) != YES)
673: return HT_ERROR;
674: }
675: }
1.7 cvs 676: }
1.4 cvs 677: /*
678: ** Start new request with the redirect anchor found in the headers.
679: ** Note that we reuse the same request object which means that we must
680: ** keep this around until the redirected request has terminated. It also
681: ** allows us in an easy way to keep track of the number of redirections
682: ** so that we can detect endless loops.
683: */
1.17 cvs 684:
1.7 cvs 685: if (HTRequest_doRetry (request))
686: {
687: /* do we need to normalize the URL? */
688: if (strncmp (new_anchor->parent->address, "http:", 5))
689: {
690: /* Yes, so we use the pre-redirection anchor as a base name */
1.74 cvs 691: ref = AmayaParseUrl (new_anchor->parent->address,
692: me->urlName, AMAYA_PARSE_ALL);
1.7 cvs 693: if (ref)
694: {
1.98 cvs 695: HT_FREE (new_anchor->parent->address);
696: tmp = NULL;
697: HTSACopy (&tmp, ref);
698: new_anchor->parent->address = tmp;
699: TtaFreeMemory (ref);
1.7 cvs 700: }
1.98 cvs 701: else
702: return HT_ERROR; /* We can't redirect anymore */
1.7 cvs 703: }
704:
705: /* update the current file name */
1.130 cvs 706: if ((me->mode & AMAYA_ASYNC) || (me->mode & AMAYA_IASYNC))
1.7 cvs 707: {
1.130 cvs 708: TtaFreeMemory (me->urlName);
709: me->urlName = TtaStrdup (new_anchor->parent->address);
1.7 cvs 710: }
711: else
1.130 cvs 712: /* it's a SYNC mode, so we should keep the urlName */
713: {
714: strncpy (me->urlName, new_anchor->parent->address,
715: MAX_LENGTH - 1);
716: me->urlName[MAX_LENGTH - 1] = EOS;
717: }
1.7 cvs 718:
1.38 cvs 719: ChopURL (me->status_urlName, me->urlName);
1.116 cvs 720:
1.7 cvs 721: TtaSetStatus (me->docid, 1, TtaGetMessage (AMAYA, AM_RED_FETCHING),
1.38 cvs 722: me->status_urlName);
1.7 cvs 723:
724: /* Start request with new credentials */
1.79 cvs 725: if (HTRequest_outputStream (me->request) != NULL) {
1.85 cvs 726: AHTFWriter_FREE (request->output_stream);
727: if (me->output != stdout) { /* Are we writing to a file? */
1.74 cvs 728: #ifdef DEBUG_LIBWWW
1.130 cvs 729: fprintf (stderr, "redirection_handler: New URL is %s, closing "
730: "FILE %p\n", me->urlName, me->output);
1.74 cvs 731: #endif
1.79 cvs 732: fclose (me->output);
733: me->output = NULL;
734: }
1.64 cvs 735: }
1.68 cvs 736:
1.105 cvs 737: /* reset the status */
1.116 cvs 738: me->reqStatus = HT_NEW;
1.105 cvs 739: /* clear the errors */
1.116 cvs 740: HTError_deleteAll (HTRequest_error (request));
1.105 cvs 741: HTRequest_setError (request, NULL);
1.116 cvs 742:
1.130 cvs 743: if (me->method == METHOD_PUT
744: || me->method == METHOD_POST) /* PUT, POST etc. */
1.74 cvs 745: status = HTLoadAbsolute (me->urlName, request);
1.7 cvs 746: else
1.74 cvs 747: HTLoadAnchor (new_anchor, request);
1.7 cvs 748: }
749: else
1.68 cvs 750: {
1.74 cvs 751: HTRequest_addError (request, ERR_FATAL, NO, HTERR_MAX_REDIRECT,
752: NULL, 0, "HTRedirectFilter");
753: TtaSetStatus (me->docid, 1, TtaGetMessage (AMAYA, AM_REDIRECTIONS_LIMIT),
754: NULL);
755: if (me->error_html)
756: DocNetworkStatus[me->docid] |= AMAYA_NET_ERROR;
757: /* so that we can show the error message */
1.68 cvs 758: }
759:
1.4 cvs 760: /*
1.74 cvs 761: ** By returning HT_ERROR we make sure that this is the last handler to be
762: ** called. We do this as we don't want any other filter to delete the
763: ** request object now when we have just started a new one ourselves
764: */
1.4 cvs 765: return HT_ERROR;
766: }
767:
1.5 cvs 768: /*----------------------------------------------------------------------
1.17 cvs 769: terminate_handler
770: this function is registered to handle the result of the request
1.5 cvs 771: ----------------------------------------------------------------------*/
1.4 cvs 772: #if __STDC__
1.7 cvs 773: static int terminate_handler (HTRequest * request, HTResponse * response, void *context, int status)
1.4 cvs 774: #else
775: static int terminate_handler (request, response, context, status)
776: HTRequest *request;
777: HTResponse *response;
778: void *context;
779: int status;
1.123 cvs 780: #endif /* __STDC__ */
1.4 cvs 781: {
1.116 cvs 782: AHTReqContext *me = (AHTReqContext *) HTRequest_context (request);
783: boolean error_flag;
784: char *content_type;
785:
786: if (!me)
787: return HT_OK; /* not an Amaya request */
788:
789: if (me->reqStatus == HT_END)
790: /* we have already processed this request! */
791: return HT_OK;
792:
793: /* if Amaya was killed, treat with this request as if it were
794: issued by a Stop button event */
795:
796: if (!AmayaIsAlive ())
1.80 cvs 797: me->reqStatus = HT_ABORT;
1.74 cvs 798:
1.77 cvs 799: if (status == HT_LOADED ||
800: status == HT_CREATED ||
1.79 cvs 801: status == HT_NO_DATA ||
1.116 cvs 802: #ifdef AMAYA_WWW_CACHE
803: /* what status to use to know we're downloading from a cache? */
804: status == HT_NOT_MODIFIED ||
805: #endif /* AMAYA_WWW_CACHE */
1.79 cvs 806: me->reqStatus == HT_ABORT)
1.74 cvs 807: error_flag = FALSE;
1.13 cvs 808: else
1.74 cvs 809: error_flag = TRUE;
1.130 cvs 810:
1.4 cvs 811: /* output any errors from the server */
1.130 cvs 812:
1.77 cvs 813: /*
1.74 cvs 814: ** me->output = output file which will receive an html file
815: ** me->error_html = yes, output HTML errors in the screen
816: ** request->error_stack == if there are any errors, they will be here
817: ** me->error_stream_size If it's != 0 means an error message has already
818: ** been written to the stack
819: */
820:
1.4 cvs 821: /* First, we verify if there are any errors and if they are not
1.17 cvs 822: ** yet written to the error stack. If no, then let's try to write them
823: ** ourselves
824: */
1.74 cvs 825:
826: #ifdef DEBUG_LIBWWW
827: fprintf (stderr, "terminate_handler: URL is "
828: "%s, closing FILE %p status is %d\n", me->urlName, me->output,
829: status);
1.69 cvs 830: #endif
1.74 cvs 831:
1.69 cvs 832: if (me->output && me->output != stdout)
833: {
1.74 cvs 834: /* we are writing to a file */
835: if (me->reqStatus != HT_ABORT)
836: { /* if the request was not aborted and */
1.80 cvs 837: if (error_flag &&
838: me->error_html == TRUE)
839: /* there were some errors and we want to print them */
840: {
841: if (me->error_stream_size == 0)/* and the stream is empty */
842: AHTError_MemPrint (request); /* copy errors from
1.74 cvs 843: **the error stack
1.77 cvs 844: ** into the error stream */
1.80 cvs 845: if (me->error_stream)
846: { /* if the stream is non-empty */
847: fprintf (me->output, me->error_stream);/* output the errors */
1.85 cvs 848: /* Clear the error context, so that we can deal with
849: this answer as if it were a normal reply */
850: HTError_deleteAll( HTRequest_error (request));
851: HTRequest_setError (request, NULL);
852: error_flag = 0;
1.74 cvs 853: }
854: } /* if error_stack */
1.85 cvs 855: }
856:
857: /* if != HT_ABORT */
858:
859: #ifdef DEBUG_LIBWWW
860: fprintf (stderr, "terminate_handler: URL is %s, closing "
861: "FILE %p\n", me->urlName, me->output);
862: #endif
1.74 cvs 863: fclose (me->output);
864: me->output = NULL;
1.69 cvs 865: }
1.80 cvs 866:
867: if (error_flag)
868: me->reqStatus = HT_ERR;
869: else if (me->reqStatus != HT_ABORT)
870: me->reqStatus = HT_END;
1.116 cvs 871:
872: /* copy the content_type */
873: content_type = request->anchor->content_type->name;
1.114 cvs 874: if (content_type && content_type [0] != EOS)
1.88 cvs 875: {
1.114 cvs 876: /* libwww gives www/unknown when it gets an error. As this is
877: an HTML test, we force the type to text/html */
878: if (!strcmp (content_type, "www/unknown"))
879: me->content_type = TtaStrdup ("text/html");
880: else
881: me->content_type = TtaStrdup (content_type);
882:
883: /* Content-Type can be specified by an httpd server's admin. To be on
884: the safe side, we normalize its case */
885: ConvertToLowerCase (me->content_type);
886:
1.88 cvs 887: #ifdef DEBUG_LIBWWW
888: fprintf (stderr, "content type is: %s\n", me->content_type);
889: #endif /* DEBUG_LIBWWW */
1.114 cvs 890: }
891:
1.115 cvs 892: /* to avoid a hangup while downloading css files */
1.140 cvs 893: if (AmayaAlive_flag && (me->mode & AMAYA_LOAD_CSS))
1.116 cvs 894: TtaSetStatus (me->docid, 1,
895: TtaGetMessage (AMAYA, AM_ELEMENT_LOADED),
896: me->status_urlName);
897:
898: /* don't remove or Xt will hang up during the PUT */
899: if (AmayaIsAlive () && ((me->method == METHOD_POST) ||
900: (me->method == METHOD_PUT)))
1.7 cvs 901: {
1.80 cvs 902: PrintTerminateStatus (me, status);
903: }
1.114 cvs 904:
1.111 cvs 905: ProcessTerminateRequest (request, response, context, status);
1.116 cvs 906:
1.111 cvs 907: return HT_OK;
1.4 cvs 908: }
909:
1.5 cvs 910: /*----------------------------------------------------------------------
1.17 cvs 911: AHTLoadTerminate_handler
1.74 cvs 912: this is an application "AFTER" Callback. It's called by the library
913: when a request has ended, so that we can setup the correct status.
1.5 cvs 914: ----------------------------------------------------------------------*/
1.4 cvs 915:
916: #ifdef __STDC__
1.111 cvs 917: int AHTLoadTerminate_handler (HTRequest * request, HTResponse * response, void *param, int status)
1.4 cvs 918: #else
1.111 cvs 919: int AHTLoadTerminate_handler (request, response, param, status)
1.4 cvs 920: HTRequest *request;
921: HTResponse *response;
922: void *param;
923: int status;
1.69 cvs 924:
1.4 cvs 925: #endif
926: {
1.116 cvs 927:
928: /** @@@@ use this with printstatus ?? */
929:
1.4 cvs 930: AHTReqContext *me = HTRequest_context (request);
931: HTAlertCallback *cbf;
932: AHTDocId_Status *docid_status;
933:
1.7 cvs 934: switch (status)
1.116 cvs 935: {
936: case HT_LOADED:
937: if (PROT_TRACE)
938: HTTrace ("Load End.... OK: `%s\' has been accessed\n",
939: me->status_urlName);
1.4 cvs 940:
1.116 cvs 941: docid_status = GetDocIdStatus (me->docid,
942: Amaya->docid_status);
1.7 cvs 943:
1.116 cvs 944: if (docid_status != NULL && docid_status->counter > 1)
945: TtaSetStatus (me->docid, 1,
946: TtaGetMessage (AMAYA, AM_ELEMENT_LOADED),
1.74 cvs 947: me->status_urlName);
1.7 cvs 948: break;
1.116 cvs 949:
950: case HT_NO_DATA:
951: if (PROT_TRACE)
952: HTTrace ("Load End.... OK BUT NO DATA: `%s\'\n",
953: me->status_urlName);
954: TtaSetStatus (me->docid, 1,
955: TtaGetMessage (AMAYA, AM_LOADED_NO_DATA),
956: me->status_urlName);
957: break;
958:
959: case HT_INTERRUPTED:
960: if (PROT_TRACE)
961: HTTrace ("Load End.... INTERRUPTED: `%s\'\n",
962: me->status_urlName);
963: TtaSetStatus (me->docid, 1,
964: TtaGetMessage (AMAYA, AM_LOAD_ABORT),
965: NULL);
966: break;
1.7 cvs 967:
1.116 cvs 968: case HT_RETRY:
969: if (PROT_TRACE)
970: HTTrace ("Load End.... NOT AVAILABLE, RETRY AT %ld\n",
971: HTResponse_retryTime (response));
972: TtaSetStatus (me->docid, 1,
973: TtaGetMessage (AMAYA, AM_NOT_AVAILABLE_RETRY),
974: me->status_urlName);
975: break;
1.7 cvs 976:
1.116 cvs 977: case HT_ERROR:
978: cbf = HTAlert_find (HT_A_MESSAGE);
979: if (cbf)
980: (*cbf) (request, HT_A_MESSAGE, HT_MSG_NULL, NULL,
981: HTRequest_error (request), NULL);
982: break;
983:
984: if (PROT_TRACE)
985: HTTrace ("Load End.... ERROR: Can't access `%s\'\n",
986: me->status_urlName ? me->status_urlName :"<UNKNOWN>");
987: TtaSetStatus (me->docid, 1,
988: TtaGetMessage (AMAYA, AM_CANNOT_LOAD),
989: me->status_urlName ? me->status_urlName : "<UNKNOWN>");
990: break;
991: default:
992: if (PROT_TRACE)
993: HTTrace ("Load End.... UNKNOWN RETURN CODE %d\n", status);
994: break;
995: }
996:
997: return HT_OK;
998: }
1.7 cvs 999:
1.116 cvs 1000: #ifdef DEBUG_LIBWWW
1001: static int LineTrace (const char * fmt, va_list pArgs)
1002: {
1003: return (vfprintf(stderr, fmt, pArgs));
1.4 cvs 1004: }
1.116 cvs 1005: #endif DEBUG_LIBWWW
1.4 cvs 1006:
1.27 cvs 1007: /*----------------------------------------------------------------------
1008: AHTAcceptTypesInit
1.74 cvs 1009: This function prepares the Accept header used by Amaya during
1010: the HTTP content negotiation phase
1.27 cvs 1011: ----------------------------------------------------------------------*/
1012: #ifdef __STDC__
1013: static void AHTAcceptTypesInit (HTList *c)
1014: #else /* __STDC__ */
1015: static void AHTAcceptTypesInit (c)
1016: HTList *c;
1017: #endif /* __STDC__ */
1018: {
1019: if (c == (HTList *) NULL)
1020: return;
1021:
1022: /* define here all the mime types that Amaya can accept */
1023:
1.74 cvs 1024: HTConversion_add (c, "image/png", "www/present",
1025: HTThroughLine, 1.0, 0.0, 0.0);
1026: HTConversion_add (c, "image/jpeg", "www/present",
1027: HTThroughLine, 1.0, 0.0, 0.0);
1028: HTConversion_add (c, "image/gif", "www/present",
1029: HTThroughLine, 1.0, 0.0, 0.0);
1030: HTConversion_add (c, "image/xbm", "www/present",
1031: HTThroughLine, 1.0, 0.0, 0.0);
1032: HTConversion_add (c, "image/xpm", "www/present",
1033: HTThroughLine, 1.0, 0.0, 0.0);
1034: HTConversion_add (c, "application/postscript",
1035: "www/present", HTThroughLine, 1.0, 0.0, 0.0);
1.4 cvs 1036:
1.27 cvs 1037: /* Define here the equivalences between MIME types and file extensions for
1038: the types that Amaya can display */
1039:
1040: /* Register the default set of file suffix bindings */
1041: HTFileInit ();
1042:
1043: /* Don't do any case distinction */
1044: HTBind_caseSensitive (FALSE);
1045: }
1.4 cvs 1046:
1.5 cvs 1047: /*----------------------------------------------------------------------
1.17 cvs 1048: AHTConverterInit
1049: Bindings between a source media type and a destination media type
1050: (conversion).
1.5 cvs 1051: ----------------------------------------------------------------------*/
1.15 cvs 1052: #ifdef __STDC__
1053: static void AHTConverterInit (HTList *c)
1054: #else /* __STDC__ */
1055: static void AHTConverterInit (c)
1056: HTList *c;
1057: #endif /* __STDC__ */
1.4 cvs 1058: {
1059:
1060: /* Handler for custom http error messages */
1.7 cvs 1061: HTConversion_add (c, "*/*", "www/debug", AHTMemConverter, 1.0, 0.0, 0.0);
1.4 cvs 1062:
1063: /*
1064: ** These are converters that converts to something other than www/present,
1065: ** that is not directly outputting someting to the user on the screen
1066: */
1067:
1.116 cvs 1068: HTConversion_add (c, "message/rfc822", "*/*", HTMIMEConvert,
1069: 1.0, 0.0, 0.0);
1.4 cvs 1070: HTConversion_add (c, "message/x-rfc822-foot", "*/*", HTMIMEFooter,
1071: 1.0, 0.0, 0.0);
1072: HTConversion_add (c, "message/x-rfc822-head", "*/*", HTMIMEHeader,
1073: 1.0, 0.0, 0.0);
1.116 cvs 1074: HTConversion_add(c,"message/x-rfc822-cont", "*/*", HTMIMEContinue,
1075: 1.0, 0.0, 0.0);
1076: HTConversion_add(c,"message/x-rfc822-partial","*/*", HTMIMEPartial,
1077: 1.0, 0.0, 0.0);
1.4 cvs 1078: HTConversion_add (c, "multipart/*", "*/*", HTBoundary,
1079: 1.0, 0.0, 0.0);
1080: HTConversion_add (c, "text/plain", "text/html", HTPlainToHTML,
1081: 1.0, 0.0, 0.0);
1082:
1083: /*
1.116 cvs 1084: ** The following conversions are converting ASCII output from various
1085: ** protocols to HTML objects.
1086: */
1.4 cvs 1087: HTConversion_add (c, "text/x-http", "*/*", HTTPStatus_new,
1088: 1.0, 0.0, 0.0);
1089:
1090: /*
1.116 cvs 1091: ** We also register a special content type guess stream that can figure out
1092: ** the content type by reading the first bytes of the stream
1093: */
1.4 cvs 1094: HTConversion_add (c, "www/unknown", "*/*", HTGuess_new,
1095: 1.0, 0.0, 0.0);
1096:
1.116 cvs 1097: #ifdef AMAYA_WWW_CACHE
1.4 cvs 1098: /*
1.116 cvs 1099: ** Register a persistent cache stream which can save an object to local
1100: ** file
1101: */
1.4 cvs 1102: HTConversion_add (c, "www/cache", "*/*", HTCacheWriter,
1103: 1.0, 0.0, 0.0);
1.116 cvs 1104: HTConversion_add(c,"www/cache-append", "*/*", HTCacheAppend,
1105: 1.0, 0.0, 0.0);
1106: #endif AMAYA_WWW_CACHE
1.4 cvs 1107:
1108: /*
1.116 cvs 1109: ** This dumps all other formats to local disk without any further
1110: ** action taken
1111: */
1.4 cvs 1112: HTConversion_add (c, "*/*", "www/present", HTSaveLocally,
1113: 0.3, 0.0, 0.0);
1.116 cvs 1114:
1.4 cvs 1115: }
1116:
1.27 cvs 1117:
1.15 cvs 1118: /*----------------------------------------------------------------------
1.17 cvs 1119: AHTProtocolInit
1120: Registers all amaya supported protocols.
1.15 cvs 1121: ----------------------------------------------------------------------*/
1.4 cvs 1122: static void AHTProtocolInit (void)
1123: {
1.116 cvs 1124: char *strptr;
1.4 cvs 1125:
1.116 cvs 1126: /*
1127: NB. Preemptive == YES means Blocking requests
1128: Non-preemptive == NO means Non-blocking requests
1129: */
1130: HTTransport_add("tcp", HT_TP_SINGLE, HTReader_new, HTWriter_new);
1131: HTTransport_add("buffered_tcp", HT_TP_SINGLE, HTReader_new,
1132: HTBufferWriter_new);
1133: HTProtocol_add ("http", "buffered_tcp", HTTP_PORT, NO, HTLoadHTTP, NULL);
1.136 cvs 1134: #ifdef _WINDOWS
1135: HTProtocol_add ("file", "local", 0, YES, HTLoadFile, NULL);
1136: #else
1.116 cvs 1137: HTProtocol_add ("file", "local", 0, NO, HTLoadFile, NULL);
1.136 cvs 1138: #endif _WINDOWS
1.116 cvs 1139: #ifdef AMAYA_WWW_CACHE
1140: HTProtocol_add("cache", "local", 0, YES, HTLoadCache, NULL);
1141: #endif /* AMAYA_WWW_CACHE */
1.103 cvs 1142: #if 0 /* experimental code */
1.116 cvs 1143: HTProtocol_add ("ftp", "tcp", FTP_PORT, NO, HTLoadFTP, NULL);
1.17 cvs 1144: #endif
1.116 cvs 1145:
1146: /* initialize pipelining */
1.121 cvs 1147: strptr = (char *) TtaGetEnvString ("ENABLE_PIPELINING");
1.116 cvs 1148: if (strptr && *strptr && strcasecmp (strptr,"yes" ))
1149: HTTP_setConnectionMode (HTTP_11_NO_PIPELINING);
1.4 cvs 1150: }
1151:
1.15 cvs 1152: /*----------------------------------------------------------------------
1.17 cvs 1153: AHTNetInit
1154: Reegisters "before" and "after" request filters.
1.15 cvs 1155: ----------------------------------------------------------------------*/
1.4 cvs 1156: static void AHTNetInit (void)
1157: {
1158:
1159: /* Register BEFORE filters
1.74 cvs 1160: ** The BEFORE filters handle proxies, caches, rule files etc.
1161: ** The filters are called in the order by which the are registered
1162: ** Not done automaticly - may be done by application!
1163: */
1.4 cvs 1164:
1.116 cvs 1165: #ifdef AMAYA_WWW_CACHE
1166: HTNet_addBefore (HTCacheFilter, "http://*", NULL, HT_FILTER_MIDDLE);
1167: #endif /* AMAYA_WWW_CACHE */
1168: HTNet_addBefore (HTCredentialsFilter, "http://*", NULL, HT_FILTER_LATE);
1169: HTNet_addBefore (HTProxyFilter, NULL, NULL, HT_FILTER_LATE);
1.85 cvs 1170: HTHost_setActivateRequestCallback (AHTOpen_file);
1.4 cvs 1171:
1172: /* register AFTER filters
1.74 cvs 1173: ** The AFTER filters handle error messages, logging, redirection,
1174: ** authentication etc.
1175: ** The filters are called in the order by which the are registered
1176: ** Not done automaticly - may be done by application!
1177: */
1.4 cvs 1178:
1.116 cvs 1179: HTNet_addAfter (HTAuthFilter, "http://*", NULL, HT_NO_ACCESS,
1180: HT_FILTER_MIDDLE);
1181: HTNet_addAfter(HTAuthFilter, "http://*", NULL, HT_REAUTH,
1182: HT_FILTER_MIDDLE);
1183: HTNet_addAfter (redirection_handler, "http://*", NULL, HT_PERM_REDIRECT,
1184: HT_FILTER_MIDDLE);
1185: HTNet_addAfter (redirection_handler, "http://*", NULL, HT_FOUND,
1186: HT_FILTER_MIDDLE);
1187: HTNet_addAfter (redirection_handler, "http://*", NULL, HT_SEE_OTHER,
1188: HT_FILTER_MIDDLE);
1189: HTNet_addAfter (redirection_handler, "http://*", NULL, HT_TEMP_REDIRECT,
1190: HT_FILTER_MIDDLE);
1191: HTNet_addAfter (HTUseProxyFilter, "http://*", NULL, HT_USE_PROXY,
1192: HT_FILTER_MIDDLE);
1193: #ifdef AMAYA_WWW_CACHE
1194: HTNet_addAfter (HTCacheUpdateFilter, "http://*", NULL, HT_NOT_MODIFIED,
1195: HT_FILTER_MIDDLE);
1196: #endif /* AMAYA_WWW_CACHE */
1.111 cvs 1197: #ifndef _WINDOWS
1.116 cvs 1198: HTNet_addAfter (AHTLoadTerminate_handler, NULL, NULL, HT_ALL,
1199: HT_FILTER_LAST);
1.111 cvs 1200: #endif /* !_WINDOWS */
1.116 cvs 1201: /**** for later ?? ****/
1202: /* HTNet_addAfter(HTInfoFilter, NULL, NULL, HT_ALL, HT_FILTER_LATE); */
1.51 cvs 1203: /* handles all errors */
1.116 cvs 1204: HTNet_addAfter (terminate_handler, NULL, NULL, HT_ALL, HT_FILTER_LAST);
1.4 cvs 1205: }
1206:
1.15 cvs 1207: /*----------------------------------------------------------------------
1.17 cvs 1208: AHTAlertInit
1209: Register alert messages and their callbacks.
1.15 cvs 1210: ----------------------------------------------------------------------*/
1211: #ifdef __STDC__
1212: static void AHTAlertInit (void)
1213: #else
1214: static void AHTAlertInit ()
1215: #endif
1216: {
1217: HTAlert_add (AHTProgress, HT_A_PROGRESS);
1.120 cvs 1218: #ifdef __WINDOWS
1.70 cvs 1219: HTAlert_add ((HTAlertCallback *) WIN_Activate_Request, HT_PROG_CONNECT);
1.116 cvs 1220: #endif /* _WINDOWS */
1.15 cvs 1221: HTAlert_add (AHTError_print, HT_A_MESSAGE);
1.48 cvs 1222: HTError_setShow (~((unsigned int) 0 ) & ~((unsigned int) HT_ERR_SHOW_DEBUG)); /* process all messages except debug ones*/
1.15 cvs 1223: HTAlert_add (AHTConfirm, HT_A_CONFIRM);
1224: HTAlert_add (AHTPrompt, HT_A_PROMPT);
1225: HTAlert_add (AHTPromptPassword, HT_A_SECRET);
1226: HTAlert_add (AHTPromptUsernameAndPassword, HT_A_USER_PW);
1.116 cvs 1227: }
1228:
1.128 cvs 1229: /*----------------------------------------------------------------------
1230: libwww_CleanCache
1231: frontend to the recursive cache cleaning function
1232: ----------------------------------------------------------------------*/
1233: #ifdef __STDC__
1234: void libwww_CleanCache (void)
1235: #else
1236: void libwww_CleanCache ()
1237: Document doc;
1238: View view;
1239: #endif /* __STDC__ */
1240: {
1.130 cvs 1241: #ifdef AMAYA_WWW_CACHE
1.128 cvs 1242: char *strptr;
1243: char *cache_dir;
1244: int cache_size;
1.130 cvs 1245:
1.128 cvs 1246: if (!HTCacheMode_enabled ())
1247: /* don't do anything if we're not using a cache */
1248: return;
1249: /* temporarily close down the cache, purge it, then restart */
1.130 cvs 1250: cache_dir = TtaStrdup ( (char *) HTCacheMode_getRoot ());
1.128 cvs 1251: cache_size = HTCacheMode_maxSize ();
1.130 cvs 1252: /* remove the concurrent cache lock */
1253: #ifdef DEBUG_LIBWWW
1254: fprintf (stderr, "Clearing the cache lock\n");
1255: #endif /* DEBUG_LIBWWW */
1256: clear_cachelock ();
1.128 cvs 1257: HTCacheTerminate ();
1.130 cvs 1258: HTCacheMode_setEnabled (NO);
1259: strptr = TtaGetMemory (strlen (cache_dir) + 20);
1.128 cvs 1260: strcpy (strptr, cache_dir);
1261: strcat (strptr, DIR_STR);
1262:
1263: RecCleanCache (strptr);
1264:
1265: HTCacheMode_setExpires(HT_EXPIRES_AUTO);
1266: HTCacheInit (cache_dir, cache_size);
1.130 cvs 1267: /* set a new concurrent cache lock */
1.132 cvs 1268: strcat (strptr, ".lock");
1.130 cvs 1269: if (set_cachelock (strptr) == -1)
1270: /* couldn't open the .lock file, so, we close the cache to
1271: be in the safe side */
1272: {
1273: #ifdef DEBUG_LIBWWW
1274: fprintf (stderr, "couldnt set the cache lock\n");
1275: #endif /* DEBUG_LIBWWW */
1276: HTCacheTerminate ();
1277: HTCacheMode_setEnabled (NO);
1278: }
1279: #ifdef DEBUG_LIBWWW
1280: fprintf (stderr, "set a cache lock\n");
1281: #endif /* DEBUG_LIBWWW */
1282: TtaFreeMemory (strptr);
1.128 cvs 1283: TtaFreeMemory (cache_dir);
1284: #endif /* AMAYA_WWW_CACHE */
1285: }
1286:
1.118 cvs 1287: #ifdef AMAYA_WWW_CACHE
1288: /*----------------------------------------------------------------------
1.128 cvs 1289: RecCleanCache
1.118 cvs 1290: Clears an existing cache directory
1291: ----------------------------------------------------------------------*/
1292: #ifdef __STDC__
1.128 cvs 1293: static void RecCleanCache (char *dirname)
1.118 cvs 1294: #else
1.128 cvs 1295: static void RecCleanCache (char *dirname)
1296: Document doc;
1297: View view;
1.118 cvs 1298: #endif /* __STDC__ */
1.128 cvs 1299:
1300: #ifdef _WINDOWS
1301: {
1302: HANDLE hFindFile;
1303: boolean status;
1304: WIN32_FIND_DATA ffd;
1305:
1306: char t_dir [MAX_LENGTH];
1.130 cvs 1307: char *ptr;
1.128 cvs 1308:
1.130 cvs 1309: /* create a t_dir name to start searching for files */
1.128 cvs 1310: if ((strlen (dirname) + 10) > MAX_LENGTH)
1311: /* ERROR: directory name is too big */
1312: return;
1313:
1314: strcpy (t_dir, dirname);
1.130 cvs 1315: /* save the end of the dirname. We'll use it to make
1316: a complete pathname when erasing files */
1317: ptr = &t_dir[strlen (t_dir)];
1318: strcat (t_dir, "*");
1.128 cvs 1319:
1.130 cvs 1320: hFindFile = FindFirstFile (t_dir, &ffd);
1.128 cvs 1321:
1322: if (hFindFile == INVALID_HANDLE_VALUE)
1323: /* nothing to erase? */
1324: return;
1325:
1326: status = TRUE;
1.130 cvs 1327: while (status)
1328: {
1329: if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
1.133 cvs 1330: {
1331: /* it's a directory, erase it recursively */
1332: if (strcmp (ffd.cFileName, "..") && strcmp (ffd.cFileName, "."))
1333: {
1334: strcpy (ptr, ffd.cFileName);
1335: strcat (ptr, DIR_STR);
1336: RecCleanCache (t_dir);
1.137 cvs 1337: # ifdef _WINDOWS
1338: _rmdir (t_dir);
1339: # else /* !_WINDOWS */
1.133 cvs 1340: rmdir (t_dir);
1.137 cvs 1341: # endif /* _WINDOWS */
1.133 cvs 1342: }
1343: }
1344: else
1.130 cvs 1345: {
1.133 cvs 1346: /* it's a file, erase it */
1.130 cvs 1347: strcpy (ptr, ffd.cFileName);
1.133 cvs 1348: TtaFileUnlink (t_dir);
1.130 cvs 1349: }
1350: status = FindNextFile (hFindFile, &ffd);
1351: }
1.128 cvs 1352: FindClose (hFindFile);
1353: }
1354:
1355: #else /* _WINDOWS */
1.118 cvs 1356: {
1357: DIR *dp;
1358: struct stat st;
1359: #ifdef HAVE_DIRENT_H
1360: struct dirent *d;
1361: #else
1362: struct direct *d;
1363: #endif /* HAVE_DIRENT_H */
1.128 cvs 1364: char filename[BUFSIZ+1];
1.118 cvs 1365:
1366: if ((dp = opendir (dirname)) == NULL)
1367: {
1368: /* @@@ we couldn't open the directory ... we need some msg */
1369: perror (dirname);
1370: exit;
1371: }
1372:
1373: while ((d = readdir (dp)) != NULL)
1374: {
1375: /* skip the UNIX . and .. links */
1376: if (!strcmp (d->d_name, "..")
1377: || !strcmp (d->d_name, "."))
1378: continue;
1379:
1.128 cvs 1380: sprintf (filename, "%s"DIR_STR"%s", dirname, d->d_name);
1.118 cvs 1381: if (lstat (filename, &st) < 0 )
1382: {
1383: /* @@2 need some error message */
1384: perror (filename);
1385: continue;
1386: }
1387:
1388: switch (st.st_mode & S_IFMT)
1389: {
1390: case S_IFDIR:
1391: /* if we find a directory, we erase it, recursively */
1.128 cvs 1392: strcat (filename, DIR_STR);
1393: RecCleanCache (filename);
1394: rmdir (filename);
1.118 cvs 1395: break;
1396: case S_IFLNK:
1397: /* skip any links we find */
1398: continue;
1399: break;
1400: default:
1401: /* erase the filename */
1402: TtaFileUnlink (filename);
1403: break;
1404: }
1405: }
1406: closedir (dp);
1407: }
1.128 cvs 1408: #endif /* _WINDOWS */
1.118 cvs 1409: #endif /* AMAYA_WWW_CACHE */
1410:
1.116 cvs 1411: /*----------------------------------------------------------------------
1412: CacheInit
1413: Reads the cache settings from the thot.ini file.
1414: ----------------------------------------------------------------------*/
1.118 cvs 1415: #ifdef __STDC__
1.116 cvs 1416: static void CacheInit (void)
1.118 cvs 1417: #else
1418: static void Cacheinit ()
1419: #endif
1420:
1.116 cvs 1421: {
1422: #ifndef AMAYA_WWW_CACHE
1423: HTCacheMode_setEnabled (NO);
1424:
1425: #else /* AMAYA_WWW_CACHE */
1426: char *strptr;
1427: char *cache_dir = NULL;
1.130 cvs 1428: char *cache_lockfile;
1429: int cache_size;
1430: boolean cache_enabled;
1431: boolean cache_locked;
1432:
1.116 cvs 1433: /* activate cache? */
1434: strptr = (char *) TtaGetEnvString ("ENABLE_CACHE");
1435: if (strptr && *strptr && strcasecmp (strptr,"yes" ))
1.130 cvs 1436: cache_enabled = NO;
1.116 cvs 1437: else
1.130 cvs 1438: cache_enabled = YES;
1.116 cvs 1439:
1440: /* get the cache dir (or use a default one) */
1441: strptr = (char *) TtaGetEnvString ("CACHE_DIR");
1442: if (strptr && *strptr)
1443: {
1444: cache_dir = TtaGetMemory (strlen (strptr) + strlen (CACHE_DIR_NAME) + 1);
1445: strcpy (cache_dir, strptr);
1446: }
1447: else
1448: {
1.122 cvs 1449: cache_dir = TtaGetMemory (strlen (TempFileDirectory)
1.116 cvs 1450: + strlen (CACHE_DIR_NAME) + 1);
1.122 cvs 1451: strcpy (cache_dir, TempFileDirectory);
1.116 cvs 1452: }
1453: strcat (cache_dir, CACHE_DIR_NAME);
1454:
1455: /* get the cache size (or use a default one) */
1456: strptr = (char *) TtaGetEnvString ("CACHE_SIZE");
1457: if (strptr && *strptr)
1458: cache_size = atoi (strptr);
1459: else
1460: cache_size = DEFAULT_CACHE_SIZE;
1461:
1.130 cvs 1462: if (cache_enabled)
1.116 cvs 1463: {
1464: /* how to remove the lock? force remove it? */
1.130 cvs 1465: cache_lockfile = TtaGetMemory (strlen (cache_dir) + 20);
1466: strcpy (cache_lockfile, cache_dir);
1467: strcat (cache_lockfile, DIR_STR".lock");
1468: cache_locked = FALSE;
1469: if (TtaFileExist (cache_lockfile)
1470: && !(cache_locked = test_cachelock (cache_lockfile)))
1.116 cvs 1471: {
1.130 cvs 1472: #ifdef DEBUG_LIBWWW
1473: fprintf (stderr, "found a stale cache, removing it\n");
1474: #endif /* DEBUG_LIBWWW */
1475: /* remove the lock and clean the cache (the clean cache
1476: will remove all, making the following call unnecessary */
1477: /* little trick to win some memory */
1478: strptr = strrchr (cache_lockfile, '.');
1479: *strptr = EOS;
1480: RecCleanCache (cache_lockfile);
1481: *strptr = '.';
1.116 cvs 1482: }
1483:
1.130 cvs 1484: if (!cache_locked)
1485: {
1486: /* initialize the cache if there's no other amaya
1487: instance running */
1488: HTCacheInit (cache_dir, cache_size);
1489: HTCacheMode_setExpires(HT_EXPIRES_AUTO);
1490: if (set_cachelock (cache_lockfile) == -1)
1491: /* couldn't open the .lock file, so, we close the cache to
1492: be in the safe side */
1493: {
1494: HTCacheTerminate ();
1495: HTCacheMode_setEnabled (NO);
1496: #ifdef DEBUG_LIBWWW
1497: fprintf (stderr, "couldnt set the cache lock\n");
1498: #endif /* DEBUG_LIBWWW */
1499: }
1500: #ifdef DEBUG_LIBWWW
1501: else
1502:
1503: fprintf (stderr, "created the cache lock\n");
1504: #endif /* DEBUG_LIBWWW */
1505: }
1506: else
1507: {
1508: HTCacheMode_setEnabled (NO);
1509: #ifdef DEBUG_LIBWWW
1510: fprintf (stderr, "lock detected, starting libwww without a cache/n");
1511: #endif /* DEBUG_LIBWWW */
1512: }
1513: TtaFreeMemory (cache_lockfile);
1.116 cvs 1514: }
1515: else
1516: HTCacheMode_setEnabled (NO);
1517:
1518: if (cache_dir)
1519: TtaFreeMemory (cache_dir);
1520: #endif /* AMAYA_WWW_CACHE */
1.15 cvs 1521: }
1522:
1523: /*----------------------------------------------------------------------
1.97 cvs 1524: ProxyInit
1525: Reads any proxies settings which may be declared as environmental
1526: variables or in the thot.ini file. The former overrides the latter.
1527: ----------------------------------------------------------------------*/
1.118 cvs 1528: #ifdef __STDC__
1.97 cvs 1529: static void ProxyInit (void)
1.118 cvs 1530: #else
1531: static void ProxyInit ()
1532: #endif /* __STDC__ */
1.97 cvs 1533: {
1534: char *strptr;
1535: char *str = NULL;
1536: char *name;
1537:
1538: /* get the proxy settings from the thot.ini file */
1539: strptr = (char *) TtaGetEnvString ("HTTP_PROXY");
1540: if (strptr && *strptr)
1541: HTProxy_add ("http", strptr);
1542: /* get the no_proxy settings from the thot.ini file */
1543: strptr = (char *) TtaGetEnvString ("NO_PROXY");
1544: if (strptr && *strptr)
1545: {
1546: str = TtaStrdup (strptr); /* Get copy we can mutilate */
1547: strptr = str;
1548: while ((name = HTNextField (&strptr)) != NULL) {
1549: char *portstr = strchr (name, ':');
1550: unsigned port=0;
1551: if (portstr) {
1552: *portstr++ = '\0';
1.116 cvs 1553: if (*portstr) port = (unsigned) atoi (portstr);
1.97 cvs 1554: }
1555: /* Register it for all access methods */
1556: HTNoProxy_add (name, NULL, port);
1557: }
1558: TtaFreeMemory (str);
1559: }
1560:
1561: /* use libw3's routine to get all proxy settings from the environment */
1562: HTProxy_getEnvVar ();
1563: }
1564:
1565:
1566: /*----------------------------------------------------------------------
1.17 cvs 1567: AHTProfile_newAmaya
1568: creates the Amaya client profile for libwww.
1.15 cvs 1569: ----------------------------------------------------------------------*/
1570: #ifdef __STDC__
1571: static void AHTProfile_newAmaya (char *AppName, char *AppVersion)
1572: #else /* __STDC__ */
1573: static void AHTProfile_newAmaya (AppName, AppVersion)
1574: char *AppName;
1575: char *AppVersion;
1576: #endif /* __STDC__ */
1.4 cvs 1577: {
1578: /* If the Library is not already initialized then do it */
1579: if (!HTLib_isInitialized ())
1580: HTLibInit (AppName, AppVersion);
1581:
1582: if (!converters)
1583: converters = HTList_new ();
1.27 cvs 1584: if (!acceptTypes)
1585: acceptTypes = HTList_new ();
1.4 cvs 1586: if (!encodings)
1587: encodings = HTList_new ();
1588:
1589: /* Register the default set of transport protocols */
1590: HTTransportInit ();
1591:
1592: /* Register the default set of application protocol modules */
1593: AHTProtocolInit ();
1594:
1.116 cvs 1595: /* Register the default set of messages and dialog functions */
1596: AHTAlertInit ();
1597: HTAlert_setInteractive (YES);
1598:
1599: #ifdef AMAYA_WWW_CACHE
1600: /* Enable the persistent cache */
1601: CacheInit ();
1602: #else
1603: HTCacheMode_setEnabled (NO);
1604: #endif /* AMAYA_WWW_CACHE */
1.4 cvs 1605:
1606: /* Register the default set of BEFORE and AFTER filters */
1607: AHTNetInit ();
1608:
1609: /* Set up the default set of Authentication schemes */
1610: HTAAInit ();
1611:
1.97 cvs 1612: /* Get any proxy settings */
1613: ProxyInit ();
1.4 cvs 1614:
1615: /* Register the default set of converters */
1616: AHTConverterInit (converters);
1.27 cvs 1617: AHTAcceptTypesInit (acceptTypes);
1.4 cvs 1618: HTFormat_setConversion (converters);
1619:
1620: /* Register the default set of transfer encoders and decoders */
1.116 cvs 1621: HTTransferEncoderInit (encodings); /* chunks ??? */
1.4 cvs 1622: HTFormat_setTransferCoding (encodings);
1623:
1624: /* Register the default set of MIME header parsers */
1.74 cvs 1625: HTMIMEInit (); /* must be called again for language selector */
1.4 cvs 1626:
1627: /* Register the default set of Icons for directory listings */
1.27 cvs 1628: /*HTIconInit(NULL); *//* experimental */
1.4 cvs 1629:
1630: }
1631:
1.5 cvs 1632: /*----------------------------------------------------------------------
1.17 cvs 1633: AHTProfile_delete
1634: deletes the Amaya client profile.
1.5 cvs 1635: ----------------------------------------------------------------------*/
1.4 cvs 1636: #ifdef __STDC__
1637: static void AHTProfile_delete (void)
1638: #else
1639: static void AHTProfile_delete ()
1.7 cvs 1640: #endif /* __STDC__ */
1.4 cvs 1641: {
1.22 cvs 1642:
1643: /* free the Amaya global context */
1.74 cvs 1644: if (!converters)
1645: HTConversion_deleteAll (converters);
1646: if (!acceptTypes)
1647: HTConversion_deleteAll (acceptTypes);
1648: if (!encodings)
1649: HTCoding_deleteAll (encodings);
1650:
1651: HTList_delete (Amaya->docid_status);
1652: HTList_delete (Amaya->reqlist);
1653: TtaFreeMemory (Amaya);
1654: {
1.61 cvs 1655:
1.74 cvs 1656: if (HTLib_isInitialized ())
1657:
1.120 cvs 1658: #ifdef _WINDOWS
1.61 cvs 1659: HTEventTerminate ();
1.120 cvs 1660: #endif _WINDOWS;
1.74 cvs 1661:
1662: /* Clean up the persistent cache (if any) */
1.116 cvs 1663: #ifdef AMAYA_WWW_CACHE
1.130 cvs 1664: clear_cachelock ();
1.116 cvs 1665: HTCacheTerminate ();
1666: #endif /* AMAYA_WWW_CACHE */
1.74 cvs 1667:
1668: /* Clean up all the global preferences */
1669: HTFormat_deleteAll ();
1670:
1671: /* Terminate libwww */
1672: HTLibTerminate ();
1673: }
1.4 cvs 1674: }
1675:
1.5 cvs 1676: /*----------------------------------------------------------------------
1.116 cvs 1677: AmayacontextInit
1678: initializes an internal Amaya context for our libwww interface
1679: ----------------------------------------------------------------------*/
1680: #ifdef __STDC__
1681: static void AmayaContextInit ()
1682: #else
1683: static void AmayaContextInit ()
1684: #endif
1685:
1686: {
1.140 cvs 1687: AmayaAlive_flag = TRUE;
1.116 cvs 1688: /* Initialization of the global context */
1689: Amaya = (AmayaContext *) TtaGetMemory (sizeof (AmayaContext));
1690: Amaya->reqlist = HTList_new ();
1691: Amaya->docid_status = HTList_new ();
1692: Amaya->open_requests = 0;
1693: }
1694:
1695: /*----------------------------------------------------------------------
1.17 cvs 1696: QueryInit
1697: initializes the libwww interface
1.5 cvs 1698: ----------------------------------------------------------------------*/
1.4 cvs 1699: #ifdef __STDC__
1700: void QueryInit ()
1701: #else
1702: void QueryInit ()
1703: #endif
1704: {
1705:
1.116 cvs 1706: AmayaContextInit ();
1.4 cvs 1707: AHTProfile_newAmaya (HTAppName, HTAppVersion);
1.140 cvs 1708: CanDoStop_set (TRUE);
1.4 cvs 1709:
1.116 cvs 1710: #ifdef _WINDOWS
1.120 cvs 1711: /*** AHTEventInit (); this was the call to my AHTEvent module HTEvtLst today***/
1.125 cvs 1712: HTEventInit ();
1.116 cvs 1713: #endif /* _WINDOWS */
1.72 cvs 1714:
1.123 cvs 1715: #ifndef _WINDOWS
1.116 cvs 1716: HTEvent_setRegisterCallback ((void *) AHTEvent_register);
1717: HTEvent_setUnregisterCallback ((void *) AHTEvent_unregister);
1.120 cvs 1718: HTTimer_registerSetTimerCallback ((void *) AMAYA_SetTimer);
1719: HTTimer_registerDeleteTimerCallback ((void *) AMAYA_DeleteTimer);
1.116 cvs 1720: #endif /* !_WINDOWS */
1721:
1.74 cvs 1722: #ifdef DEBUG_LIBWWW
1.116 cvs 1723: /* forwards error messages to our own function */
1724: WWW_TraceFlag = THD_TRACE;
1.138 cvs 1725: HTTrace_setCallback(LineTrace);
1.74 cvs 1726: #endif
1.4 cvs 1727:
1728: /* Trace activation (for debugging) */
1.138 cvs 1729: /***
1730: WWW_TraceFlag = SHOW_CORE_TRACE | SHOW_THREAD_TRACE | SHOW_PROTOCOL_TRACE;
1731: WWW_TraceFlag |= 0xFFFFFFFFl;
1732: ***/
1733:
1734: /* Setting up other user interfaces */
1735:
1736: /* Setting up different network parameters */
1737: /* Maximum number of simultaneous open sockets */
1738: HTNet_setMaxSocket (8);
1739: /* different network services timeouts */
1740: HTDNS_setTimeout (60);
1741: HTHost_setPersistTimeout (60L);
1742: /* default timeout in ms */
1743: HTHost_setEventTimeout (20000);
1744:
1.4 cvs 1745: #ifdef CATCH_SIG
1.138 cvs 1746: signal (SIGPIPE, SIG_IGN);
1.4 cvs 1747: #endif
1.15 cvs 1748: }
1749:
1750: /*----------------------------------------------------------------------
1.17 cvs 1751: LoopForStop
1.136 cvs 1752: a copy of the Thop event loop so we can handle the stop button in Unix
1753: and preemptive requests under Windows
1.15 cvs 1754: ----------------------------------------------------------------------*/
1755: #ifdef __STDC__
1756: static int LoopForStop (AHTReqContext * me)
1757: #else
1758: static int LoopForStop (AHTReqContext * me)
1759: #endif
1760: {
1.136 cvs 1761: #ifdef _WINDOWS
1762: MSG msg;
1763: unsigned long libwww_msg;
1764: HWND old_active_window, libwww_window;
1765: int status_req = HT_OK;
1766:
1767: old_active_window = GetActiveWindow ();
1768: libwww_window = HTEventList_getWinHandle (&libwww_msg);
1.137 cvs 1769:
1770: while (GetMessage (&msg, NULL, 0, 0)
1.136 cvs 1771: && me->reqStatus != HT_END && me->reqStatus != HT_ERR
1772: && me->reqStatus != HT_ABORT && AmayaIsAlive ())
1773: {
1774: if (msg.message != WM_QUIT)
1775: {
1776: TranslateMessage (&msg);
1777: DispatchMessage (&msg);
1778: }
1779: else
1780: break;
1781:
1782: }
1783: if (!AmayaIsAlive ())
1784: /* Amaya was killed by one of the callback handlers */
1785: exit (0);
1786: #else /* _WINDOWS */
1.25 cvs 1787: extern ThotAppContext app_cont;
1.51 cvs 1788: XEvent ev;
1789: XtInputMask status;
1.17 cvs 1790: int status_req = HT_OK;
1.15 cvs 1791:
1792: /* to test the async calls */
1.17 cvs 1793: /* Loop while waiting for new events, exists when the request is over */
1.15 cvs 1794: while (me->reqStatus != HT_ABORT &&
1795: me->reqStatus != HT_END &&
1.69 cvs 1796: me->reqStatus != HT_ERR) {
1.116 cvs 1797: if (!AmayaIsAlive ())
1.69 cvs 1798: /* Amaya was killed by one of the callback handlers */
1799: exit (0);
1800:
1801: status = XtAppPending (app_cont);
1802: if (status & XtIMXEvent) {
1803: XtAppNextEvent (app_cont, &ev);
1804: TtaHandleOneEvent (&ev);
1805: } else if (status & (XtIMAll & (~XtIMXEvent))) {
1806: XtAppProcessEvent (app_cont, (XtIMAll & (~XtIMXEvent)));
1807: } else {
1808: XtAppNextEvent (app_cont, &ev);
1809: TtaHandleOneEvent (&ev);
1810: }
1811: }
1.136 cvs 1812: #endif /* _WINDOWS */
1.69 cvs 1813: switch (me->reqStatus) {
1814: case HT_ERR:
1815: case HT_ABORT:
1.130 cvs 1816: status_req = NO;
1.15 cvs 1817: break;
1818:
1.69 cvs 1819: case HT_END:
1.130 cvs 1820: status_req = YES;
1.15 cvs 1821: break;
1822:
1.69 cvs 1823: default:
1.15 cvs 1824: break;
1.69 cvs 1825: }
1.15 cvs 1826: return (status_req);
1.4 cvs 1827: }
1828:
1.5 cvs 1829: /*----------------------------------------------------------------------
1.15 cvs 1830: QueryClose
1.21 cvs 1831: closes all existing threads, frees all non-automatically deallocated
1832: memory and then ends libwww.
1.5 cvs 1833: ----------------------------------------------------------------------*/
1.116 cvs 1834: void QueryClose ()
1.4 cvs 1835: {
1.24 cvs 1836:
1.140 cvs 1837: AmayaAlive_flag = FALSE;
1.24 cvs 1838:
1.116 cvs 1839: /* remove all the handlers and callbacks that may output a message to
1840: a non-existent Amaya window */
1.130 cvs 1841: #ifndef _WINDOWS
1.116 cvs 1842: HTNet_deleteAfter (AHTLoadTerminate_handler);
1.130 cvs 1843: #endif _WINDOWS
1.116 cvs 1844: HTNet_deleteAfter (redirection_handler);
1845: HTAlertCall_deleteAll (HTAlert_global () );
1846: HTAlert_setGlobal ((HTList *) NULL);
1847: HTEvent_setRegisterCallback ((HTEvent_registerCallback *) NULL);
1848: HTEvent_setUnregisterCallback ((HTEvent_unregisterCallback *) NULL);
1849: #ifndef _WINDOWS
1850: /** need to erase all existing timers too **/
1851: HTTimer_registerSetTimerCallback (NULL);
1852: HTTimer_registerDeleteTimerCallback (NULL);
1853: #endif /* !_WINDOWS */
1854: HTHost_setActivateRequestCallback (NULL);
1855: Thread_deleteAll ();
1.21 cvs 1856:
1.116 cvs 1857: HTProxy_deleteAll ();
1858: HTNoProxy_deleteAll ();
1859: HTGateway_deleteAll ();
1860: AHTProfile_delete ();
1861: }
1862:
1863: /*----------------------------------------------------------------------
1864: NextNameValue
1865: ---------------------------------------------------------------------*/
1866: #ifdef __STDC__
1867: static char * NextNameValue (char ** pstr, char **name, char **value)
1868: #else
1869: static char * NextNameValue (pstr, name, value);
1870: char ** pstr;
1871: char **name;
1872: char **value;
1873: #endif /* __STDC__ */
1874: {
1875: char * p = *pstr;
1876: char * start = NULL;
1877: if (!pstr || !*pstr) return NULL;
1878:
1879: if (!*p) {
1880: *pstr = p;
1881: *name = NULL;
1882: *value = NULL;
1883: return NULL; /* No field */
1884: }
1885:
1886: /* Now search for the next '&' and ';' delimitators */
1887: start = p;
1888: while (*p && *p != '&' && *p != ';') p++;
1889: if (*p)
1890: *p++ = '\0';
1891: *pstr = p;
1892:
1893: /* Search for the name and value */
1894: *name = start;
1895: p = start;
1896:
1897: while(*p && *p != '=')
1898: p++;
1899: if (*p)
1900: *p++ = '\0';
1901: *value = p;
1902:
1903: return start;
1904: }
1905:
1906: /*----------------------------------------------------------------------
1907: PrepareFormdata
1908: ---------------------------------------------------------------------*/
1909: #ifdef __STDC__
1910: static HTAssocList * PrepareFormdata (char *string)
1911: #else
1912: static HTAssocList * PrepareFormdata (string)
1913: char *string;
1914: #endif /* __STDC__ */
1915: {
1916: char * tmp_string, * tmp_string_ptr;
1917: char * name;
1918: char * value;
1919: HTAssocList * formdata;
1920:
1921: if (!string)
1922: return NULL;
1923:
1924: /* store the ptr in another variable, as the original address will
1925: change
1926: */
1927:
1928: tmp_string_ptr = tmp_string = TtaStrdup (string);
1929: formdata = HTAssocList_new();
1930:
1931: while (*tmp_string)
1932: {
1933: NextNameValue (&tmp_string, &name, &value);
1934: HTAssocList_addObject(formdata,
1935: name, value);
1936: }
1937:
1938: TtaFreeMemory (tmp_string_ptr);
1939: return formdata;
1.4 cvs 1940: }
1941:
1.99 cvs 1942:
1943: /*----------------------------------------------------------------------
1944: InvokeGetObjectWWW_callback
1945: A simple function to invoke a callback function whenever there's an error
1946: in GetObjectWWW
1947: ---------------------------------------------------------------------*/
1948:
1.116 cvs 1949: #ifdef __STDC__
1950: void InvokeGetObjectWWW_callback (int docid, char *urlName, char *outputfile, TTcbf *terminate_cbf, void *context_tcbf, int status)
1.99 cvs 1951: #else
1.111 cvs 1952: void InvokeGetObjectWWW_callback (docid, urlName, outputfile, terminate_cbf, context_tcbf, status)
1.99 cvs 1953: int docid;
1954: char *urlName;
1955: char *outputfile;
1956: TTcbf *terminate_cbf;
1957: void *context_tcbf;
1.116 cvs 1958: #endif /* __STDC__ */
1.99 cvs 1959: {
1960: if (!terminate_cbf)
1961: return;
1962:
1.116 cvs 1963: (*terminate_cbf) (docid, status, urlName, outputfile,
1.99 cvs 1964: NULL, context_tcbf);
1965: }
1966:
1967:
1968:
1.5 cvs 1969: /*----------------------------------------------------------------------
1.15 cvs 1970: GetObjectWWW
1.17 cvs 1971: this function requests a resource designated by a URLname into a
1972: temporary filename. The download can come from a simple GET operation,
1973: or can come from POSTING/GETTING a form. In the latter
1974: case, the function receives a query string to send to the server.
1975:
1.5 cvs 1976: 4 file retrieval modes are proposed:
1977: AMAYA_SYNC : blocking mode
1978: AMAYA_ISYNC : incremental, blocking mode
1979: AMAYA_ASYNC : non-blocking mode
1980: AMAYA_IASYNC : incremental, non-blocking mode
1981:
1982: In the incremental mode, each time a package arrives, it will be
1983: stored in the temporary file. In addition, if an
1984: incremental_callback function is defined, this function will be
1985: called and handled a copy of the newly received data package.
1986: Finally, if a terminate_callback function is defined, it will be
1987: invoked when the request terminates. The caller of this function
1.4 cvs 1988: can define two different contexts to be passed to the callback
1989: functions.
1990:
1991: When the function is called with the SYNC mode, the function will
1992: return only when the requested file has been loaded.
1993: The ASYNC mode will immediately return after setting up the
1994: call.
1995:
1996: Notes:
1997: At the end of a succesful request, the urlName string contains the
1998: name of the actually retrieved URL. As a URL can change over the time,
1999: (e.g., be redirected elsewhere), it is advised that the function
1.17 cvs 2000: caller verify the value of the urlName variable at the end of
1.4 cvs 2001: a request.
2002:
2003: Inputs:
2004: - docid Document identifier for the set of objects being
2005: retrieved.
2006: - urlName The URL to be retrieved (MAX_URL_LENGTH chars length)
2007: - outputfile A pointer to an empty string of MAX_URL_LENGTH.
2008: - mode The retrieval mode.
2009: - incremental_cbf
2010: - context_icbf
2011: Callback and context for the incremental modes
2012: - terminate_cbf
2013: - context_icbf
2014: Callback and context for a terminate handler
1.17 cvs 2015: -error_html if TRUE, then display any server error message as an
2016: HTML document.
1.88 cvs 2017: - content_type a string
2018:
1.4 cvs 2019: Outputs:
2020: - urlName The URL that was retrieved
2021: - outputfile The name of the temporary file which holds the
2022: retrieved data. (Only in case of success)
1.88 cvs 2023: - if content_type wasn't NULL, it will contain a copy of the parameter
2024: sent in the HTTP answer
1.4 cvs 2025: Returns:
2026: HT_ERROR
2027: HT_OK
1.5 cvs 2028:
2029: ----------------------------------------------------------------------*/
1.4 cvs 2030: #ifdef __STDC__
1.127 cvs 2031: int GetObjectWWW (int docid, char* urlName, char* formdata,
1.116 cvs 2032: char* outputfile, int mode, TIcbf* incremental_cbf,
2033: void* context_icbf, TTcbf* terminate_cbf,
1.88 cvs 2034: void* context_tcbf, boolean error_html, char *content_type)
1.4 cvs 2035: #else
1.127 cvs 2036: int GetObjectWWW (docid, urlName, formdata, outputfile, mode,
1.116 cvs 2037: incremental_cbf, context_icbf,
1.88 cvs 2038: terminate_cbf, context_tcbf, error_html, content_type)
1.73 cvs 2039: int docid;
2040: char *urlName;
1.127 cvs 2041: char *formdata;
1.73 cvs 2042: char *outputfile;
2043: int mode;
2044: TIcbf *incremental_cbf;
2045: void *context_icbf;
2046: TTcbf *terminate_cbf;
2047: void *context_tcbf;
2048: boolean error_html;
1.88 cvs 2049: char *content_type;
1.4 cvs 2050: #endif
2051: {
2052: AHTReqContext *me;
2053: char *ref;
1.107 cvs 2054: int status, l;
1.114 cvs 2055: int tempsubdir;
1.7 cvs 2056:
1.116 cvs 2057: if (urlName == NULL || docid == 0 || outputfile == NULL)
2058: {
2059: /* no file to be loaded */
2060: TtaSetStatus (docid, 1, TtaGetMessage (AMAYA, AM_BAD_URL), urlName);
1.69 cvs 2061:
1.116 cvs 2062: if (error_html)
1.69 cvs 2063: /* so we can show the error message */
2064: DocNetworkStatus[docid] |= AMAYA_NET_ERROR;
1.116 cvs 2065: InvokeGetObjectWWW_callback (docid, urlName, outputfile, terminate_cbf,
2066: context_tcbf, HT_ERROR);
2067: return HT_ERROR;
2068: }
1.7 cvs 2069:
1.4 cvs 2070: /* do we support this protocol? */
1.116 cvs 2071: if (IsValidProtocol (urlName) == NO)
2072: {
2073: /* return error */
2074: outputfile[0] = EOS; /* file could not be opened */
2075: TtaSetStatus (docid, 1,
2076: TtaGetMessage (AMAYA, AM_GET_UNSUPPORTED_PROTOCOL),
2077: urlName);
2078:
2079: if (error_html)
1.69 cvs 2080: /* so we can show the error message */
2081: DocNetworkStatus[docid] |= AMAYA_NET_ERROR;
1.116 cvs 2082: InvokeGetObjectWWW_callback (docid, urlName, outputfile, terminate_cbf,
2083: context_tcbf, HT_ERROR);
2084: return HT_ERROR;
2085: }
1.4 cvs 2086:
1.114 cvs 2087: /* we store CSS in subdir named 0; all the other files go to a subidr
2088: named after their own docid */
2089:
2090: tempsubdir = (mode & AMAYA_LOAD_CSS) ? 0 : docid;
2091:
1.116 cvs 2092: /* create a tempfilename */
2093: sprintf (outputfile, "%s%c%d%c%04dAM",
2094: TempFileDirectory, DIR_SEP, tempsubdir, DIR_SEP, object_counter);
2095: /* update the object_counter (used for the tempfilename) */
1.4 cvs 2096: object_counter++;
1.116 cvs 2097:
1.4 cvs 2098: /* normalize the URL */
1.45 cvs 2099: ref = AmayaParseUrl (urlName, "", AMAYA_PARSE_ALL);
1.4 cvs 2100: /* should we abort the request if we could not normalize the url? */
1.69 cvs 2101: if (ref == (char*) NULL || ref[0] == EOS) {
2102: /*error */
2103: outputfile[0] = EOS;
2104: TtaSetStatus (docid, 1, TtaGetMessage (AMAYA, AM_BAD_URL), urlName);
2105:
2106: if (error_html)
1.116 cvs 2107: /* so we can show the error message */
2108: DocNetworkStatus[docid] |= AMAYA_NET_ERROR;
1.99 cvs 2109: InvokeGetObjectWWW_callback (docid, urlName, outputfile, terminate_cbf,
1.116 cvs 2110: context_tcbf, HT_ERROR);
1.69 cvs 2111: return HT_ERROR;
2112: }
1.116 cvs 2113:
1.4 cvs 2114: /* verify if that file name existed */
1.9 cvs 2115: if (TtaFileExist (outputfile))
1.77 cvs 2116: TtaFileUnlink (outputfile);
1.116 cvs 2117:
1.4 cvs 2118: /* Initialize the request structure */
2119: me = AHTReqContext_new (docid);
1.116 cvs 2120: if (me == NULL)
2121: {
2122: outputfile[0] = EOS;
2123: /* need an error message here */
2124: TtaFreeMemory (ref);
2125: InvokeGetObjectWWW_callback (docid, urlName, outputfile, terminate_cbf,
2126: context_tcbf, HT_ERROR);
2127: return HT_ERROR;
2128: }
2129:
1.4 cvs 2130: /* Specific initializations for POST and GET */
1.116 cvs 2131: if (mode & AMAYA_FORM_POST)
2132: {
2133: me->method = METHOD_POST;
2134: HTRequest_setMethod (me->request, METHOD_POST);
2135: }
2136: else
2137: {
2138: me->method = METHOD_GET;
2139: if (!HasKnownFileSuffix (ref))
2140: HTRequest_setConversion(me->request, acceptTypes, TRUE);
2141: }
1.93 cvs 2142:
1.116 cvs 2143: /* Common initialization for all HTML methods */
1.4 cvs 2144: me->mode = mode;
2145: me->error_html = error_html;
2146: me->incremental_cbf = incremental_cbf;
2147: me->context_icbf = context_icbf;
2148: me->terminate_cbf = terminate_cbf;
2149: me->context_tcbf = context_tcbf;
1.64 cvs 2150:
1.69 cvs 2151: /* for the async. request modes, we need to have our
1.4 cvs 2152: own copy of outputfile and urlname
1.116 cvs 2153: */
1.4 cvs 2154:
1.116 cvs 2155: if ((mode & AMAYA_ASYNC) || (mode & AMAYA_IASYNC))
2156: {
2157: l = strlen (outputfile);
2158: if (l > MAX_LENGTH)
2159: me->outputfile = TtaGetMemory (l + 2);
2160: else
2161: me->outputfile = TtaGetMemory (MAX_LENGTH + 2);
2162: strcpy (me->outputfile, outputfile);
2163: l = strlen (urlName);
2164: if (l > MAX_LENGTH)
2165: me->urlName = TtaGetMemory (l + 2);
2166: else
2167: me->urlName = TtaGetMemory (MAX_LENGTH + 2);
2168: strcpy (me->urlName, urlName);
2169: #ifdef _WINDOWS
2170: /* force windows ASYNC requests to always be non preemptive */
2171: HTRequest_setPreemptive (me->request, NO);
2172: #endif /*_WINDOWS */
2173: } /* AMAYA_ASYNC mode */
2174: else
2175: #ifdef _WINDOWS
2176: {
2177: me->outputfile = outputfile;
2178: me->urlName = urlName;
2179: /* force windows SYNC requests to always be non preemptive */
2180: HTRequest_setPreemptive (me->request, YES);
2181: }
2182: #else /* !_WINDOWS */
2183: {
2184: me->outputfile = outputfile;
2185: me->urlName = urlName;
2186: }
2187: /***
1.136 cvs 2188: In order to take into account the stop button,
2189: the requests will be always asynchronous, however, if mode=AMAYA_SYNC,
1.57 cvs 2190: we will loop until the document has been received or a stop signal
2191: generated
1.77 cvs 2192: ****/
1.116 cvs 2193: HTRequest_setPreemptive (me->request, NO);
2194: #endif /* _WINDOWS */
1.61 cvs 2195:
2196: /* prepare the URLname that will be displayed in teh status bar */
2197: ChopURL (me->status_urlName, me->urlName);
1.77 cvs 2198: TtaSetStatus (me->docid, 1,
2199: TtaGetMessage (AMAYA, AM_FETCHING),
2200: me->status_urlName);
1.4 cvs 2201:
2202: me->anchor = (HTParentAnchor *) HTAnchor_findAddress (ref);
1.45 cvs 2203: TtaFreeMemory (ref);
1.4 cvs 2204:
1.114 cvs 2205: if (mode & AMAYA_NOCACHE)
1.116 cvs 2206: HTRequest_setReloadMode (me->request, HT_CACHE_FLUSH);
2207:
2208: /* prepare the query string and format for POST */
2209: if (mode & AMAYA_FORM_POST)
1.114 cvs 2210: {
1.116 cvs 2211: HTAnchor_setFormat ((HTParentAnchor *) me->anchor,
2212: HTAtom_for ("application/x-www-form-urlencoded"));
2213: HTAnchor_setLength ((HTParentAnchor *) me->anchor, me->block_size);
2214: HTRequest_setEntityAnchor (me->request, me->anchor);
2215: }
1.114 cvs 2216:
1.127 cvs 2217: /* create the formdata element for libwww */
2218: if (formdata)
2219: me->formdata = PrepareFormdata (formdata);
2220:
1.116 cvs 2221: /* do the request */
2222: if (mode & AMAYA_FORM_POST)
1.119 cvs 2223: {
2224: /* this call doesn't give back a boolean */
2225: HTParentAnchor * posted = NULL;
2226:
2227: posted = HTPostFormAnchor (me->formdata, (HTAnchor *) me->anchor,
2228: me->request);
2229: status = posted ? YES : NO;
2230: }
1.127 cvs 2231: else if (formdata)
2232: status = HTGetFormAnchor(me->formdata, (HTAnchor *) me->anchor,
2233: me->request);
1.116 cvs 2234: else
1.77 cvs 2235: status = HTLoadAnchor ((HTAnchor *) me->anchor, me->request);
1.69 cvs 2236:
1.123 cvs 2237: /* @@@ may need some special windows error msg here */
1.116 cvs 2238: /* control the errors */
1.4 cvs 2239:
1.130 cvs 2240: if (status == NO)
1.116 cvs 2241: /* the request invocation failed */
2242: {
2243: /* show an error message on the status bar */
2244: DocNetworkStatus[docid] |= AMAYA_NET_ERROR;
2245: TtaSetStatus (docid, 1,
2246: TtaGetMessage (AMAYA, AM_CANNOT_LOAD),
2247: urlName);
2248: if (me->reqStatus == HT_NEW)
2249: /* manually invoke the last processing that usually gets done
2250: in a succesful request */
2251: InvokeGetObjectWWW_callback (docid, urlName, outputfile,
2252: terminate_cbf, context_tcbf, HT_ERROR);
2253: /* terminate_handler wasn't called */
1.136 cvs 2254: AHTReqContext_delete (me);
1.116 cvs 2255: }
2256: else
1.136 cvs 2257: /* end treatment for SYNC requests */
1.120 cvs 2258: if ((mode & AMAYA_SYNC) || (mode & AMAYA_ISYNC))
2259: {
1.136 cvs 2260: /* wait here untilt the asynchronous request finishes */
1.130 cvs 2261: status = LoopForStop (me);
1.136 cvs 2262: /* if status returns HT_ERROR, should we invoke the callback? */
1.120 cvs 2263: if (!HTRequest_kill (me->request))
2264: AHTReqContext_delete (me);
2265: }
1.130 cvs 2266:
1.136 cvs 2267: /* an interface problem!!! */
2268: return (status == YES ? 0 : -1);
1.4 cvs 2269: }
2270:
1.5 cvs 2271: /*----------------------------------------------------------------------
1.17 cvs 2272: PutObjectWWW
2273: frontend for uploading a resource to a URL. This function downloads
2274: a file to be uploaded into memory, it then calls UploadMemWWW to
2275: finish the job.
2276:
1.5 cvs 2277: 2 upload modes are proposed:
2278: AMAYA_SYNC : blocking mode
2279: AMAYA_ASYNC : non-blocking mode
2280:
1.4 cvs 2281: When the function is called with the SYNC mode, the function will
2282: return only when the file has been uploaded.
2283: The ASYNC mode will immediately return after setting up the
2284: call. Furthermore, at the end of an upload, the ASYNC mode will
2285: call back terminate_cbf, handling it the context defined in
2286: context_tcbf.
2287:
2288: Notes:
2289: At the end of a succesful request, the urlName string contains the
2290: name of the actually uploaded URL. As a URL can change over the time,
2291: (e.g., be redirected elsewhere), it is advised that the function
2292: caller verifies the value of the urlName variable at the end of
2293: a request.
2294:
2295: Inputs:
2296: - docid Document identifier for the set of objects being
2297: retrieved.
2298: - fileName A pointer to the local file to upload
2299: - urlName The URL to be uploaded (MAX_URL_LENGTH chars length)
2300: - mode The retrieval mode.
2301: - terminate_cbf
2302: - context_icbf
2303: Callback and context for a terminate handler
2304:
2305: Outputs:
2306: - urlName The URL that was uploaded
2307:
2308: Returns:
2309: HT_ERROR
2310: HT_OK
1.5 cvs 2311: ----------------------------------------------------------------------*/
1.4 cvs 2312: #ifdef __STDC__
1.27 cvs 2313: int PutObjectWWW (int docid, char *fileName, char *urlName, int mode, PicType contentType,
1.4 cvs 2314: TTcbf * terminate_cbf, void *context_tcbf)
2315: #else
1.26 cvs 2316: int PutObjectWWW (docid, urlName, fileName, mode, contentType,
1.4 cvs 2317: ,terminate_cbf, context_tcbf)
2318: int docid;
2319: char *urlName;
2320: char *fileName;
2321: int mode;
1.27 cvs 2322: PicType contentType;
1.4 cvs 2323: TTcbf *terminate_cbf;
2324: void *context_tcbf;
2325:
1.116 cvs 2326: #endif /* __STDC__ */
1.4 cvs 2327: {
1.116 cvs 2328: AHTReqContext *me;
1.4 cvs 2329: int status;
2330: int fd;
2331: struct stat file_stat;
1.116 cvs 2332: char *fileURL;
1.4 cvs 2333:
1.33 cvs 2334: AmayaLastHTTPErrorMsg [0] = EOS;
2335:
1.116 cvs 2336: if (urlName == NULL || docid == 0 || fileName == NULL
2337: || !TtaFileExist (fileName))
1.4 cvs 2338: /* no file to be uploaded */
2339: return HT_ERROR;
2340:
2341: /* do we support this protocol? */
1.7 cvs 2342: if (IsValidProtocol (urlName) == NO)
2343: {
2344: /* return error */
1.77 cvs 2345: TtaSetStatus (docid, 1,
2346: TtaGetMessage (AMAYA, AM_PUT_UNSUPPORTED_PROTOCOL),
1.7 cvs 2347: urlName);
2348: return HT_ERROR;
2349: }
1.116 cvs 2350:
2351: /* verify the file's size */
2352: #ifndef _WINDOWS
1.7 cvs 2353: if ((fd = open (fileName, O_RDONLY)) == -1)
1.116 cvs 2354: #else
1.137 cvs 2355: if ((fd = _open (fileName, _O_RDONLY | _O_BINARY)) == -1)
1.116 cvs 2356: #endif /* _WINDOWS */
1.7 cvs 2357: {
2358: /* if we could not open the file, exit */
2359: /*error msg here */
2360: return (HT_ERROR);
2361: }
1.4 cvs 2362:
2363: fstat (fd, &file_stat);
1.137 cvs 2364: # ifdef _WINDOWS
2365: _close (fd);
2366: # else /* _WINDOWS */
1.116 cvs 2367: close (fd);
1.137 cvs 2368: # endif /* _WINDOWS */
1.4 cvs 2369:
1.7 cvs 2370: if (file_stat.st_size == 0)
2371: {
2372: /* file was empty */
2373: /*errmsg here */
2374: return (HT_ERROR);
2375: }
1.116 cvs 2376:
2377: /* prepare the request context */
1.4 cvs 2378:
2379: if (THD_TRACE)
1.116 cvs 2380: fprintf (stderr, "file size == %u\n", (unsigned) file_stat.st_size);
1.4 cvs 2381:
2382: me = AHTReqContext_new (docid);
2383:
1.7 cvs 2384: if (me == NULL)
2385: {
1.131 cvs 2386: /* @@ need an error message here */
1.7 cvs 2387: TtaHandlePendingEvents ();
2388: return (HT_ERROR);
2389: }
1.116 cvs 2390:
1.4 cvs 2391: me->mode = mode;
2392: me->incremental_cbf = (TIcbf *) NULL;
2393: me->context_icbf = (void *) NULL;
2394: me->terminate_cbf = terminate_cbf;
2395: me->context_tcbf = context_tcbf;
2396: me->urlName = urlName;
1.116 cvs 2397: me->block_size = file_stat.st_size;
1.17 cvs 2398: /* select the parameters that distinguish a PUT from a GET/POST */
1.4 cvs 2399: me->method = METHOD_PUT;
2400: HTRequest_setMethod (me->request, METHOD_PUT);
2401: me->output = stdout;
1.17 cvs 2402: /* we are not expecting to receive any input from the server */
2403: me->outputfile = (char *) NULL;
1.4 cvs 2404:
1.134 cvs 2405: #ifdef _WINDOWS
2406: /* libwww's HTParse function doesn't take into account the drive name;
2407: so we sidestep it */
2408: fileURL = NULL;
2409: StrAllocCopy (fileURL, "file:");
2410: StrAllocCat (fileURL, fileName);
2411: #else
1.116 cvs 2412: fileURL = HTParse (fileName, "file:/", PARSE_ALL);
1.134 cvs 2413: #endif /* _WINDOWS */
1.116 cvs 2414: me->anchor = (HTParentAnchor *) HTAnchor_findAddress (fileURL);
2415: HT_FREE (fileURL);
1.114 cvs 2416:
1.28 cvs 2417: /* Set the Content-Type of the file we are uploading */
1.77 cvs 2418: HTAnchor_setFormat ((HTParentAnchor *) me->anchor,
2419: AHTGuessAtom_for (me->urlName, contentType));
1.17 cvs 2420:
1.134 cvs 2421: /* associate the anchor to the request */
1.4 cvs 2422: HTRequest_setEntityAnchor (me->request, me->anchor);
1.134 cvs 2423:
2424: /* define other request characteristics */
1.116 cvs 2425: #ifdef _WINDOWS
1.136 cvs 2426: HTRequest_setPreemptive (me->request, NO);
1.116 cvs 2427: #else
1.134 cvs 2428: HTRequest_setPreemptive (me->request, NO);
1.116 cvs 2429: #endif /* _WINDOWS */
2430:
1.136 cvs 2431: /* don't use the cache while saving a document */
2432: HTRequest_setReloadMode (me->request, HT_CACHE_FLUSH);
1.116 cvs 2433:
1.74 cvs 2434: /* prepare the URLname that will be displayed in teh status bar */
2435: ChopURL (me->status_urlName, me->urlName);
2436: TtaSetStatus (me->docid, 1, TtaGetMessage (AMAYA, AM_REMOTE_SAVING),
2437: me->status_urlName);
1.114 cvs 2438:
1.116 cvs 2439: status = HTPutDocumentAbsolute (me->anchor, urlName, me->request);
1.4 cvs 2440:
1.130 cvs 2441: if (status == YES && me->reqStatus != HT_ERR)
1.7 cvs 2442: {
2443: /* part of the stop button handler */
2444: if ((mode & AMAYA_SYNC) || (mode & AMAYA_ISYNC))
1.136 cvs 2445: status = LoopForStop (me);
1.15 cvs 2446: }
1.136 cvs 2447: if (!HTRequest_kill (me->request))
2448: AHTReqContext_delete (me);
2449:
1.116 cvs 2450: TtaHandlePendingEvents ();
1.90 cvs 2451:
1.130 cvs 2452: return (status == YES ? 0 : -1);
1.28 cvs 2453: }
1.4 cvs 2454:
1.5 cvs 2455: /*----------------------------------------------------------------------
1.138 cvs 2456: StopRequest
1.17 cvs 2457: stops (kills) all active requests associated with a docid
1.5 cvs 2458: ----------------------------------------------------------------------*/
1.4 cvs 2459: #ifdef __STDC__
2460: void StopRequest (int docid)
2461: #else
2462: void StopRequest (docid)
2463: int docid;
2464: #endif
2465: {
1.140 cvs 2466: if (Amaya && CanDoStop ())
1.138 cvs 2467: {
1.139 cvs 2468: #if 0 /* for later */
1.140 cvs 2469: AHTDocId_Status *docid_status;
2470: /* verify if there are any requests at all associated with docid */
1.138 cvs 2471: docid_status = (AHTDocId_Status *) GetDocIdStatus (docid,
2472: Amaya->docid_status);
2473: if (docid_status == (AHTDocId_Status *) NULL)
2474: return;
1.139 cvs 2475: #endif /* 0 */
1.138 cvs 2476: /* temporary call to stop all requests, as libwww changed its API */
2477: StopAllRequests (docid);
2478: }
2479: }
2480:
2481: /*----------------------------------------------------------------------
2482: StopAllRequests
2483: stops (kills) all active requests. We use the docid
2484: ----------------------------------------------------------------------*/
2485: #ifdef __STDC__
2486: void StopAllRequests (int docid)
2487: #else
1.140 cvs 2488: void StopAllRequests (docid)
1.138 cvs 2489: int docid;
2490: #endif
2491: {
1.4 cvs 2492: HTList *cur;
2493: AHTReqContext *me;
1.116 cvs 2494:
1.138 cvs 2495: /* only do the stop if we're not being called while processing a
2496: request */
1.140 cvs 2497: if (Amaya && CanDoStop ())
1.7 cvs 2498: {
1.138 cvs 2499:
1.100 cvs 2500: #ifdef DEBUG_LIBWWW
1.138 cvs 2501: fprintf (stderr, "StopRequest: number of Amaya requests "
2502: "before kill: %d\n", Amaya->open_requests);
1.100 cvs 2503: #endif /* DEBUG_LIBWWW */
1.116 cvs 2504:
1.138 cvs 2505: HTNet_killAll();
2506: EventOrder_deleteAll();
1.4 cvs 2507:
1.116 cvs 2508: cur = Amaya->reqlist;
2509: while ((me = (AHTReqContext *) HTList_nextObject (cur)))
2510: {
1.140 cvs 2511: if (AmayaIsAlive ())
2512: if (me->reqStatus != HT_END)
2513: {
2514: if (me->terminate_cbf)
2515: (*me->terminate_cbf) (me->docid, -1, me->urlName,
2516: me->outputfile,
2517: me->content_type, me->context_tcbf);
2518: fprintf (stderr,"StopRequest: killing req %p, url %s, status %d\n", me, me->urlName, me->reqStatus);
2519: AHTReqContext_delete (me);
2520: }
2521: /* to be on the safe side, remove all outstanding X events */
2522: else ( RequestKillAllXtevents (me));
1.116 cvs 2523: }
1.138 cvs 2524: /* Delete remaining channels */
1.140 cvs 2525: HTChannel_deleteAll();
1.116 cvs 2526:
1.100 cvs 2527: #ifdef DEBUG_LIBWWW
1.138 cvs 2528: fprintf (stderr, "StopRequest: number of Amaya requests "
2529: "after kill: %d\n", Amaya->open_requests);
1.100 cvs 2530: #endif /* DEBUG_LIBWWW */
1.138 cvs 2531: }
2532: } /* StopAllRequests */
1.17 cvs 2533:
2534:
1.105 cvs 2535: /*----------------------------------------------------------------------
2536: AmayaIsAlive
1.140 cvs 2537: returns the value of the AmayaAlive_flag
1.105 cvs 2538: ----------------------------------------------------------------------*/
2539: #ifdef __STDC__
2540: boolean AmayaIsAlive (void)
2541: #else
2542: boolean AmayaIsAlive ()
2543: #endif /* _STDC_ */
2544: {
1.140 cvs 2545: return AmayaAlive_flag;
2546: }
2547:
2548: /*----------------------------------------------------------------------
2549: CanDoStop
2550: returns the value of the CanDoStop flag
2551: ----------------------------------------------------------------------*/
2552: #ifdef __STDC__
2553: boolean CanDoStop (void)
2554: #else
2555: boolean CanDoStop ()
2556: #endif /* _STDC_ */
2557: {
2558: return CanDoStop_flag;
2559: }
2560:
2561: /*----------------------------------------------------------------------
2562: CanDoStop_set
2563: sets the value of the CanDoStop flag
2564: ----------------------------------------------------------------------*/
2565: #ifdef __STDC__
2566: void CanDoStop_set (boolean value)
2567: #else
2568: void CanDoStop (value)
2569: boolean value;
2570: #endif /* _STDC_ */
2571: {
2572: CanDoStop_flag = value;
1.105 cvs 2573: }
1.116 cvs 2574:
1.69 cvs 2575: #endif /* AMAYA_JAVA */
1.77 cvs 2576:
1.116 cvs 2577: /*
2578: end of Module query.c
2579: */
1.140 cvs 2580:
2581:
2582:
2583:
2584:
2585:
1.17 cvs 2586:
2587:
Webmaster