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