Annotation of Amaya/amaya/query.c, revision 1.311
1.14 cvs 1: /*
2: *
1.265 cvs 3: * (c) COPYRIGHT MIT and INRIA, 1996-2001.
1.14 cvs 4: * Please first read the full copyright statement in file COPYRIGHT.
1.156 cvs 5: *
1.14 cvs 6: */
1.243 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.116 cvs 17: /* defines to include elsewhere
18: *********************************/
19:
1.185 cvs 20: #ifdef _WINDOWS
21: #include <string.h>
1.130 cvs 22: #endif /* !_WINDOWS */
1.116 cvs 23: #define AMAYA_WWW_CACHE
1.168 cvs 24: #define AMAYA_LOST_UPDATE
1.116 cvs 25:
1.12 cvs 26: /* Amaya includes */
1.25 cvs 27: #define THOT_EXPORT extern
1.4 cvs 28: #include "amaya.h"
1.214 cvs 29: #include "init_f.h"
1.130 cvs 30: #include <sys/types.h>
1.309 cvs 31: #ifndef _WINDOWS
1.308 kahan 32: #include <unistd.h>
1.309 cvs 33: #endif
1.70 cvs 34: #include <fcntl.h>
1.140 cvs 35: #include "HTEvtLst.h"
1.157 cvs 36: #include "HTAABrow.h"
1.272 cvs 37: #include "string.h"
1.279 cvs 38: #include "interface.h"
1.7 cvs 39:
1.141 cvs 40: #if defined(__svr4__) || defined (_AIX)
1.4 cvs 41: #define CATCH_SIG
42: #endif
43:
44: /* local structures coming from libwww and which are
1.17 cvs 45: not found in any .h file
1.7 cvs 46: */
1.68 cvs 47:
1.7 cvs 48: struct _HTStream
49: {
1.15 cvs 50: const HTStreamClass *isa;
51: FILE *fp;
1.45 cvs 52: BOOL leave_open; /* Close file when TtaFreeMemory? */
1.15 cvs 53: char *end_command; /* Command to execute */
54: BOOL remove_on_close; /* Remove file? */
55: char *filename; /* Name of file */
56: HTRequest *request; /* saved for callback */
57: HTRequestCallback *callback;
1.7 cvs 58: };
59:
1.15 cvs 60:
1.7 cvs 61: struct _HTError
62: {
63: HTErrorElement element; /* Index number into HTError */
64: HTSeverity severity; /* A la VMS */
65: BOOL ignore; /* YES if msg should not go to user */
66: void *par; /* Explanation, e.g. filename */
67: int length; /* For copying by generic routine */
68: char *where; /* Which function */
69: };
70:
1.4 cvs 71: /* Type definitions and global variables etc. local to this module */
72:
1.17 cvs 73: /*----------------------------------------------------------------------*/
1.293 kahan 74:
75: /* libwww default parameters */
76: #ifdef _WINDOWS
77: #define CACHE_DIR_NAME "\\libwww-cache\\"
78: #else
79: #define CACHE_DIR_NAME "/libwww-cache/"
80: #endif
81:
82: #define DEFAULT_CACHE_SIZE 10
83: #define DEFAULT_MAX_CACHE_ENTRY_SIZE 3
84: #define DEFAULT_MAX_SOCKET 32
85: #define DEFAULT_DNS_TIMEOUT 1800L
86: #define DEFAULT_PERSIST_TIMEOUT 60L
87: #define DEFAULT_NET_EVENT_TIMEOUT 60000
1.294 kahan 88: /* defines the priority for general content negotiation */
89: #define GENERAL_ACCEPT_NEGOTIATION "*/*;q=0.1,"AM_SVG_MIME_TYPE","AM_MATHML_MIME_TYPE","AM_XHTML_MIME_TYPE
1.293 kahan 90: /* defines the priority for image content negotiation */
91: #define IMAGE_ACCEPT_NEGOTIATION "*/*;q=0.1,image/*,image/gif,image/jpeg,image/png,image/svg+xml,"AM_SVG_MIME_TYPE
92:
1.4 cvs 93: /*** private variables ***/
1.17 cvs 94:
1.4 cvs 95: static HTList *converters = NULL; /* List of global converters */
1.27 cvs 96: static HTList *acceptTypes = NULL; /* List of types for the Accept header */
1.193 cvs 97: static HTList *acceptLanguages = NULL; /* List of language priorities for the Accept header */
1.151 cvs 98: static HTList *transfer_encodings = NULL;
99: static HTList *content_encodings = NULL;
1.207 cvs 100: /* List of domains where we can do a safe PUT redirect */
101: static HTList *safeput_list = NULL;
102:
1.16 cvs 103: static int object_counter = 0; /* loaded objects counter */
1.191 cvs 104: static ThotBool AmayaAlive_flag; /* set to 1 if the application is active;
1.140 cvs 105: 0 if we have killed */
1.191 cvs 106: static ThotBool CanDoStop_flag; /* set to 1 if we can do a stop, 0
1.140 cvs 107: if we're inside a critical section */
1.214 cvs 108: static ThotBool UserAborted_flag; /* set to 1 if we're processing a user
109: induced stop request operation */
1.128 cvs 110: #ifdef AMAYA_WWW_CACHE
1.130 cvs 111: static int fd_cachelock; /* open handle to the .lock cache file */
112: #endif /* AMAYA_WWW_CACHE */
1.4 cvs 113:
1.246 kahan 114: static ThotBool FTPURL_flag; /* if set to true, we can browse FTP URLs */
115:
1.248 kahan 116: static FILE *trace_fp = NULL; /* file pointer to the trace logs */
117:
1.15 cvs 118: #include "answer_f.h"
119: #include "query_f.h"
120: #include "AHTURLTools_f.h"
121: #include "AHTBridge_f.h"
122: #include "AHTMemConv_f.h"
123: #include "AHTFWrite_f.h"
1.4 cvs 124:
1.298 cvs 125: #ifdef DAV
126: #include "davlib.h"
127: #include "davlib_f.h"
128: #include "davlibCommon_f.h"
1.302 kirschpi 129: #endif /* DAV */
1.298 cvs 130:
1.116 cvs 131: /* prototypes */
132:
1.123 cvs 133: #ifdef _WINDOWS
1.70 cvs 134: int WIN_Activate_Request (HTRequest* , HTAlertOpcode, int, const char*, void*, HTAlertPar*);
1.116 cvs 135: #endif /* _WINDOWS */
1.297 kirschpi 136:
1.130 cvs 137: #ifdef AMAYA_WWW_CACHE
138: /***************************************************************
139: lock functions, used to avoid concurrent use of the cache
140: Mostly based on W. Richard Stevens' APUE book.
141: ***************************************************************/
142: /*----------------------------------------------------------------------
143: set_cachelock
144: sets a write lock on filename.
145: Returns -1 in case of failure, otherwise, it'll open a handle on
146: filename and fd_cachelock will take its value.
147: ----------------------------------------------------------------------*/
1.265 cvs 148: static int set_cachelock (char *filename)
1.130 cvs 149: {
1.188 cvs 150: int status;
1.130 cvs 151: #ifdef _WINDOWS
1.188 cvs 152:
153: status = TtaFileExist (filename);
154: return ((status) ? 0 : -1);
1.130 cvs 155: #else
156: struct flock lock;
157:
158: lock.l_type = F_WRLCK;
159: lock.l_start = 0;
160: lock.l_whence = SEEK_SET;
161: lock.l_len = 0;
162:
163: fd_cachelock = open (filename, O_WRONLY);
164:
165: if (fd_cachelock == -1)
166: status = -1;
167: else
168: status = fcntl(fd_cachelock, F_SETLK, &lock);
169:
170: if (status == -1)
1.190 cvs 171: {
1.179 cvs 172: if (fd_cachelock > 0)
1.190 cvs 173: close (fd_cachelock);
1.179 cvs 174: fd_cachelock = 0;
1.178 cvs 175: }
1.130 cvs 176: return (status);
177: #endif /* _WINDOWS */
178: }
179:
180: /*----------------------------------------------------------------------
181: clear_cachelock
182: remove the write lock set on a filename.
183: It'll close the fd handle on filename and reset *fd to 0.
184: ----------------------------------------------------------------------*/
185: static int clear_cachelock (void)
186: {
187: #ifdef _WINDOWS
188: return 0;
189: #else
190: int status;
191:
1.178 cvs 192: if (!fd_cachelock)
1.130 cvs 193: return (-1);
194:
1.178 cvs 195: status = close (fd_cachelock);
1.130 cvs 196: fd_cachelock = 0;
197:
198: return (status);
199: #endif /* _WINDOWS */
200: }
201:
202: /*----------------------------------------------------------------------
203: test_cachelock
204: returns 0 if a fd is not locked by other process, otherwise
205: returns the pid of the process who has the lock
206: ----------------------------------------------------------------------*/
1.265 cvs 207: static int test_cachelock (char *filename)
1.130 cvs 208: {
209: #ifdef _WINDOWS
1.185 cvs 210: /* if the lock is set, we can't unlink the file under Windows */
1.188 cvs 211: if (!TtaFileUnlink (filename))
212: return 0;
213: else
1.185 cvs 214: return -1;
1.130 cvs 215: #else
216: struct flock lock;
217: int fd, status;
218:
219: lock.l_type = F_WRLCK;
220: lock.l_start = 0;
221: lock.l_whence = SEEK_SET;
222: lock.l_len = 0;
223:
224: fd = open (filename, O_WRONLY);
225:
226: if (fd < 0)
227: return (-1);
228: /* is this file locked ? */
229: status = fcntl (fd, F_GETLK, &lock);
230: close (fd);
231:
232: if (status < 0)
233: return (-1);
234:
235: if (lock.l_type == F_UNLCK)
236: return (0); /* false, region is not locked by another proc */
237: return (lock.l_pid); /* true, return pid of lock owner */
238: #endif /* _WINDOWS */
239: }
240:
241: #endif /* AMAYA_WWW_CACHE */
242:
1.15 cvs 243: /*----------------------------------------------------------------------
1.17 cvs 244: GetDocIdStatus
245: gets the status associated to a docid
1.15 cvs 246: ----------------------------------------------------------------------*/
247: AHTDocId_Status *GetDocIdStatus (int docid, HTList * documents)
248: {
249: AHTDocId_Status *me;
250: HTList *cur;
251:
252: if (documents)
253: {
254: cur = documents;
255:
256: while ((me = (AHTDocId_Status *) HTList_nextObject (cur)))
257: {
258: if (me->docid == docid)
259: return (me);
1.18 cvs 260: }
261: }
1.15 cvs 262: return (AHTDocId_Status *) NULL;
263:
264: }
265:
1.5 cvs 266: /*----------------------------------------------------------------------
1.27 cvs 267: AHTGuessAtom_for
268: Converts an Amaya type descriptor into the equivalent MIME type.
269: ----------------------------------------------------------------------*/
1.276 kahan 270: static HTAtom *AHTGuessAtom_for (char *urlName, char *contentType)
1.27 cvs 271: {
272: HTAtom *atom;
1.265 cvs 273: char * filename;
1.160 cvs 274: HTEncoding enc = NULL;
275: HTEncoding cte = NULL;
276: HTLanguage lang = NULL;
1.50 cvs 277: double quality = 1.0;
1.27 cvs 278:
1.276 kahan 279: /* we already have a MIME type, we jsut return the atom */
280: if (contentType && *contentType)
281: atom = HTAtom_for (contentType);
282: else
1.27 cvs 283: {
1.276 kahan 284: /* we don't have the MIME type, so
285: we try to use the filename's suffix to infer it */
1.265 cvs 286: filename = AmayaParseUrl (urlName, "",
287: AMAYA_PARSE_PATH | AMAYA_PARSE_PUNCTUATION);
288: HTBind_getFormat (filename, &atom, &enc, &cte, &lang, &quality);
1.45 cvs 289: TtaFreeMemory (filename);
1.27 cvs 290: if (atom == WWW_UNKNOWN)
1.276 kahan 291: {
1.27 cvs 292: /*
1.276 kahan 293: ** we could not identify the suffix, so we give it a default type.
294: ** (we should ask the user, but we're not ready for that yet).
1.27 cvs 295: */
296: atom = HTAtom_for ("text/html");
1.276 kahan 297: }
1.27 cvs 298: }
299: return atom;
300: }
301:
302: /*----------------------------------------------------------------------
1.238 cvs 303: HTTP_Headers_set
304: Copies the headers in which the application is interested, doing
305: any in-between conversions as needed.
306: ----------------------------------------------------------------------*/
307: void HTTP_headers_set (HTRequest * request, HTResponse * response, void *context, int status)
308: {
1.267 kahan 309: AHTReqContext *me;
1.283 cvs 310: HTAtom *tmp_atom = NULL;
1.267 kahan 311: char *tmp_char;
1.285 kahan 312: char *tmp_char2;
1.284 kahan 313: char tmp_string[20];
1.267 kahan 314: HTParentAnchor *anchor;
1.287 kahan 315: ThotBool use_anchor;
1.307 vatton 316: HTError *pres;
1.267 kahan 317:
318: me = (AHTReqContext *) HTRequest_context (request);
1.282 kahan 319:
1.267 kahan 320: anchor = HTRequest_anchor (request);
1.238 cvs 321:
1.287 kahan 322: /* if we get a cached answer, we should get all the header information
323: from the anchor, instead of from the response object */
324: tmp_char = HTAnchor_physical (anchor);
325: if (tmp_char && !strncmp (tmp_char, "cache:", sizeof ("cache:") - 1))
326: use_anchor = TRUE;
327: else
328: use_anchor = FALSE;
329:
1.263 kahan 330: /* @@@ JK: we need a function here to specify which headers we
1.238 cvs 331: want to copy */
332:
1.267 kahan 333: /* copy the content_type if we didn't force it before */
334: if (me->http_headers.content_type == NULL)
1.260 kahan 335: {
1.267 kahan 336: /* trying to use the info in the anchor, rather than in the response.
337: Seems it's more recent */
1.282 kahan 338:
339: /* @@ JK: trying to use the content type stored in the response object */
1.287 kahan 340: if (!use_anchor && response)
1.282 kahan 341: tmp_atom = HTResponse_format (response);
342: if (!tmp_atom)
343: tmp_atom = HTAnchor_format (anchor);
1.260 kahan 344:
1.267 kahan 345: if (tmp_atom)
346: tmp_char = HTAtom_name (tmp_atom);
347: else
348: tmp_char = "www/unknown";
349:
350: if (tmp_char && tmp_char[0] != EOS)
1.238 cvs 351: {
1.267 kahan 352: /* libwww gives www/unknown when it gets an error. As this is
353: an HTML test, we force the type to text/html */
354: if (!strcmp (tmp_char, "www/unknown"))
355: {
356: /* if it's not a file downloaded from FTP, initialize the
357: content type to text/html by default */
358: me->http_headers.content_type = NULL;
359: }
360: else
1.284 kahan 361: me->http_headers.content_type = TtaStrdup (tmp_char);
1.267 kahan 362:
1.238 cvs 363: #ifdef DEBUG_LIBWWW
1.267 kahan 364: fprintf (stderr, "Set content type to: %s\n",
365: me->http_headers.content_type);
1.238 cvs 366: #endif /* DEBUG_LIBWWW */
1.267 kahan 367: }
1.238 cvs 368: }
1.267 kahan 369:
1.238 cvs 370: /* copy the charset */
1.267 kahan 371:
372: /* @@ JK I think there was a problem when using info directly from
373: the anchor... but what it was? The response object doesn't have
374: it anyway */
375: tmp_atom = HTAnchor_charset (anchor);
376: #if 0
1.260 kahan 377: if (use_anchor)
378: tmp_atom = HTAnchor_charset (anchor);
379: else
380: tmp_atom = HTResponse_charset (response);
1.267 kahan 381: #endif
382:
1.238 cvs 383: if (tmp_atom)
384: {
1.284 kahan 385: tmp_char = HTAtom_name (tmp_atom);
386: if (tmp_char)
387: me->http_headers.charset = TtaStrdup (tmp_char);
1.238 cvs 388: }
1.256 kahan 389:
1.268 kahan 390: /* copy the content length */
1.284 kahan 391: snprintf (tmp_string, sizeof (tmp_string), "%ld", HTAnchor_length (anchor));
392: me->http_headers.content_length = TtaStrdup (tmp_string);
1.268 kahan 393:
1.256 kahan 394: /* copy the reason */
395: tmp_char = HTResponse_reason (response);
396: if (tmp_char)
1.284 kahan 397: me->http_headers.reason = TtaStrdup (tmp_char);
398:
399: /* copy the content-location */
400: tmp_char = HTAnchor_location (anchor);
1.285 kahan 401: if (tmp_char && *tmp_char)
1.304 kahan 402: {
403: /* make a copy of the full location_header, for computing the base url */
1.305 kahan 404: if (HTURL_isAbsolute (tmp_char))
405: me->http_headers.full_content_location = TtaStrdup (tmp_char);
406: else
407: me->http_headers.full_content_location = AmayaParseUrl (me->urlName, tmp_char,
408: AMAYA_PARSE_ALL);
409: tmp_char = me->http_headers.full_content_location;
1.285 kahan 410: /* only include the filename. We suppose we have either a
411: relative or an absolute URL and that everything after the last
1.304 kahan 412: slash is the doc name + ext */
1.285 kahan 413: if (HTURL_isAbsolute (tmp_char))
414: {
415: tmp_char2 = tmp_char + strlen (tmp_char) -1;
416: while (*tmp_char2 != URL_SEP && tmp_char2 != tmp_char)
417: tmp_char2--;
418: if (tmp_char2 != tmp_char && *(tmp_char2 + 1))
419: tmp_char = tmp_char2 + 1;
420: }
421: me->http_headers.content_location = TtaStrdup (tmp_char);
422: }
1.307 vatton 423:
424: /* copy the status */
425: pres = (HTError *) HTList_nextObject (request->error_stack);
426: if (pres)
427: me->http_headers.status = HTError_index (pres);
428: else
429: me->http_headers.status = 0;
430:
1.238 cvs 431: }
432:
433: /*----------------------------------------------------------------------
434: HTTP_headers_delete
435: Deletes all the paramaters that were assigned to the response type
436: ----------------------------------------------------------------------*/
437: static void HTTP_headers_delete (AHTHeaders me)
438: {
439: if (me.content_type)
440: TtaFreeMemory (me.content_type);
441:
442: if (me.charset)
443: TtaFreeMemory (me.charset);
1.268 kahan 444:
445: if (me.content_length)
446: TtaFreeMemory (me.content_length);
1.256 kahan 447:
448: if (me.reason)
449: TtaFreeMemory (me.reason);
1.284 kahan 450:
451: if (me.content_location)
452: TtaFreeMemory (me.content_location);
1.304 kahan 453:
454: if (me.full_content_location)
455: TtaFreeMemory (me.full_content_location);
1.238 cvs 456: }
457:
458: /*----------------------------------------------------------------------
459: HTTP_headers
460: Returns the value of a parameter in the HTTP response structure.
461: Returns null if this structure is empty.
462: ----------------------------------------------------------------------*/
1.265 cvs 463: char *HTTP_headers (AHTHeaders *me, AHTHeaderName param)
1.238 cvs 464: {
1.265 cvs 465: char *result;
1.238 cvs 466:
467: if (!me)
468: return NULL;
469:
470: switch (param)
471: {
472: case AM_HTTP_CONTENT_TYPE:
473: result = me->content_type;
474: break;
475: case AM_HTTP_CHARSET:
476: result = me->charset;
1.268 kahan 477: break;
478: case AM_HTTP_CONTENT_LENGTH:
479: result = me->content_length;
1.238 cvs 480: break;
1.256 kahan 481: case AM_HTTP_REASON:
482: result = me->reason;
1.284 kahan 483: break;
484: case AM_HTTP_CONTENT_LOCATION:
485: result = me->content_location;
1.304 kahan 486: break;
487: case AM_HTTP_FULL_CONTENT_LOCATION:
488: result = me->full_content_location;
1.256 kahan 489: break;
1.238 cvs 490: default:
491: result = NULL;
492: }
493:
494: return result;
495: }
496:
497: /*----------------------------------------------------------------------
1.17 cvs 498: AHTReqContext_new
499: create a new Amaya Context Object and update the global Amaya
500: request status.
1.297 kirschpi 501:
502: ----------------------------------------------------------------------
503: MKP: this function is now used in davlib.c file for the WebDAV requests
1.299 kirschpi 504:
1.297 kirschpi 505: ---------------------------------------------------------------------- */
506: AHTReqContext *AHTReqContext_new (int docid)
1.4 cvs 507: {
508: AHTReqContext *me;
509: AHTDocId_Status *docid_status;
510:
511: if ((me = (AHTReqContext *) TtaGetMemory (sizeof (AHTReqContext))) == NULL)
1.116 cvs 512: outofmem (__FILE__, "AHTReqContext_new");
513:
514: /* clear the structure */
515: memset ((void *) me, 0, sizeof (AHTReqContext));
1.4 cvs 516:
1.81 cvs 517: /* Bind the Context object together with the Request Object */
518: me->request = HTRequest_new ();
519:
1.80 cvs 520: /* clean the associated file structure) */
1.79 cvs 521: HTRequest_setOutputStream (me->request, NULL);
1.81 cvs 522:
1.4 cvs 523: /* Initialize the other members of the structure */
1.17 cvs 524: me->reqStatus = HT_NEW; /* initial status of a request */
1.4 cvs 525: me->docid = docid;
526: HTRequest_setMethod (me->request, METHOD_GET);
527: HTRequest_setOutputFormat (me->request, WWW_SOURCE);
528: HTRequest_setContext (me->request, me);
1.116 cvs 529:
1.36 cvs 530: /* experimental */
531: me->read_sock = INVSOC;
532: me->write_sock = INVSOC;
533: me->except_sock = INVSOC;
1.4 cvs 534:
535: /* Update the global context */
536: HTList_appendObject (Amaya->reqlist, (void *) me);
537:
538: docid_status = GetDocIdStatus (docid, Amaya->docid_status);
539:
1.7 cvs 540: if (docid_status == NULL)
541: {
1.116 cvs 542: docid_status = (AHTDocId_Status *)
543: TtaGetMemory (sizeof (AHTDocId_Status));
1.7 cvs 544: docid_status->docid = docid;
545: docid_status->counter = 1;
546: HTList_addObject (Amaya->docid_status, (void *) docid_status);
547: }
548: else
1.4 cvs 549: docid_status->counter++;
550:
1.297 kirschpi 551: #ifdef DAV /* clean the DAV request context */
552: me->dav_context = NULL; /* it should be create only when doing a DAV request */
1.302 kirschpi 553: #endif /* DAV */
1.297 kirschpi 554:
1.4 cvs 555: Amaya->open_requests++;
556:
1.74 cvs 557: #ifdef DEBUG_LIBWWW
558: fprintf (stderr, "AHTReqContext_new: Created object %p\n", me);
559: #endif
1.116 cvs 560:
1.4 cvs 561: return me;
562: }
563:
1.5 cvs 564: /*----------------------------------------------------------------------
1.17 cvs 565: AHTReqContext_delete
566: Delete an Amaya Context Object and update the global Amaya request
567: status.
1.5 cvs 568: ----------------------------------------------------------------------*/
1.191 cvs 569: ThotBool AHTReqContext_delete (AHTReqContext * me)
1.4 cvs 570: {
571: AHTDocId_Status *docid_status;
572:
1.7 cvs 573: if (me)
574: {
1.74 cvs 575: #ifdef DEBUG_LIBWWW
1.138 cvs 576: fprintf (stderr, "AHTReqContext_delete: Deleting object %p\n", me);
1.74 cvs 577: #endif
1.297 kirschpi 578:
579: #ifdef DAV /* if there is a DAV context object, delete it */
1.303 kirschpi 580: if (me->dav_context) AHTDAVContext_delete (me->dav_context);
1.297 kirschpi 581: #endif /* DAV */
582:
1.138 cvs 583: if (Amaya->reqlist)
584: HTList_removeObject (Amaya->reqlist, (void *) me);
585:
586: docid_status = GetDocIdStatus (me->docid, Amaya->docid_status);
587: if (docid_status)
588: {
589: docid_status->counter--;
590:
591: if (docid_status->counter == 0)
592: {
593: HTList_removeObject (Amaya->docid_status, (void *) docid_status);
594: TtaFreeMemory ((void *) docid_status);
595: }
596: }
1.215 cvs 597:
598: HTNoFreeStream_delete (HTRequest_outputStream (me->request));
599: HTRequest_setOutputStream (me->request, NULL);
1.190 cvs 600: /* JK: no longer needed in libwww 5.2.3
601: if (me->method != METHOD_PUT && HTRequest_outputStream (me->request))
602: AHTFWriter_FREE (HTRequest_outputStream (me->request));
603: */
1.138 cvs 604: HTRequest_delete (me->request);
605:
606: if (me->output && me->output != stdout)
607: {
1.85 cvs 608: #ifdef DEBUG_LIBWWW
1.138 cvs 609: fprintf (stderr, "AHTReqContext_delete: URL is %s, closing "
610: "FILE %p\n", me->urlName, me->output);
1.85 cvs 611: #endif
1.138 cvs 612: fclose (me->output);
613: me->output = NULL;
614: }
1.79 cvs 615:
1.138 cvs 616: if (me->error_stream != (char *) NULL)
617: HT_FREE (me->error_stream);
618: #ifndef _WINDOWS
619: #ifdef WWW_XWINDOWS
620: if (me->read_xtinput_id || me->write_xtinput_id ||
621: me->except_xtinput_id)
622: RequestKillAllXtevents(me);
623: #endif /* WWW_XWINDOWS */
624: #endif /* !_WINDOWS */
625:
626: if (me->reqStatus == HT_ABORT)
627: {
628: if (me->outputfile && me->outputfile[0] != EOS)
629: {
1.233 cvs 630: TtaFileUnlink (me->outputfile);
1.138 cvs 631: me->outputfile[0] = EOS;
632: }
633: }
634:
635: if ((me->mode & AMAYA_ASYNC) || (me->mode & AMAYA_IASYNC))
636: /* for the ASYNC mode, free the memory we allocated in GetObjectWWW
637: or in PutObjectWWW */
638: {
639: if (me->urlName)
640: TtaFreeMemory (me->urlName);
641: if (me->outputfile)
642: TtaFreeMemory (me->outputfile);
643: }
1.206 cvs 644:
1.208 cvs 645: /* the real name to which we are publishing */
646: if (me->default_put_name)
647: TtaFreeMemory (me->default_put_name);
648:
1.206 cvs 649: /* @@ temp change for the %esc conversion */
650: if (me->method == METHOD_PUT && me->urlName)
651: TtaFreeMemory (me->urlName);
652:
1.138 cvs 653: if (me->formdata)
654: HTAssocList_delete (me->formdata);
1.238 cvs 655:
656: /* erase the response headers */
657: HTTP_headers_delete (me->http_headers);
1.138 cvs 658:
1.228 cvs 659: #ifdef ANNOTATIONS
660: if (me->document)
661: TtaFreeMemory (me->document);
662: #endif /* ANNOTATIONS */
663:
1.138 cvs 664: /* to trace bugs */
665: memset ((void *) me, 0, sizeof (AHTReqContext));
666:
667: TtaFreeMemory ((void *) me);
668:
669: Amaya->open_requests--;
670:
671: return TRUE;
1.7 cvs 672: }
1.15 cvs 673: return FALSE;
1.4 cvs 674: }
675:
676:
1.15 cvs 677: /*----------------------------------------------------------------------
1.17 cvs 678: Thread_deleteAll
679: this function deletes the whole list of active threads.
1.5 cvs 680: ----------------------------------------------------------------------*/
1.4 cvs 681: static void Thread_deleteAll (void)
682: {
1.21 cvs 683: HTList *cur;
684: AHTReqContext *me;
685: AHTDocId_Status *docid_status;
686:
1.74 cvs 687: if (Amaya && Amaya->reqlist)
688: {
689: if (Amaya->open_requests > 0)
690: #ifdef DEBUG_LIBWWW
691: fprintf (stderr, "Thread_deleteAll: Killing %d outstanding "
692: "requests\n", Amaya->open_requests);
693: #endif
694: {
695: cur = Amaya->reqlist;
696:
697: /* erase the requests */
698: while ((me = (AHTReqContext *) HTList_removeLastObject (cur)))
699: {
700: if (me->request)
701: {
1.142 cvs 702: #ifndef _WINDOWS
703: #ifdef WWW_XWINDOWS
1.74 cvs 704: RequestKillAllXtevents (me);
1.142 cvs 705: #endif /* WWW_XWINDOWS */
1.138 cvs 706: #endif /* !_WINDOWS */
1.140 cvs 707: if (!HTRequest_kill (me->request))
708: AHTReqContext_delete (me);
1.74 cvs 709: }
710: } /* while */
711:
712: /* erase the docid_status entities */
713: while ((docid_status = (AHTDocId_Status *) HTList_removeLastObject ((void *) Amaya->docid_status)))
714: TtaFreeMemory ((void *) docid_status);
715:
716: } /* if */
1.84 cvs 717:
1.74 cvs 718: }
1.4 cvs 719: }
1.198 cvs 720:
1.5 cvs 721: /*----------------------------------------------------------------------
1.83 cvs 722: AHTOpen_file
723: ----------------------------------------------------------------------*/
1.85 cvs 724: int AHTOpen_file (HTRequest * request)
1.83 cvs 725: {
726: AHTReqContext *me; /* current request */
727:
728: me = HTRequest_context (request);
1.93 cvs 729: if (!me)
730: return HT_ERROR;
1.83 cvs 731: #ifdef DEBUG_LIBWWW
1.116 cvs 732: fprintf(stderr, "AHTOpen_file: start for object : %p\n", me);
1.85 cvs 733: #endif /* DEBUG_LIBWWW */
734: if (me->reqStatus == HT_ABORT)
735: {
736: #ifdef DEBUG_LIBWWW
737: fprintf(stderr, "AHTOpen_file: caught an abort request, skipping it\n");
1.83 cvs 738: #endif /* DEBUG_LIBWWW */
1.85 cvs 739: return HT_OK;
740: }
741:
1.136 cvs 742: if (me->method == METHOD_PUT)
743: {
744: me->reqStatus = HT_WAITING;
745: return HT_OK;
746: }
747:
1.85 cvs 748: if (HTRequest_outputStream (me->request))
749: {
750: #ifdef DEBUG_LIBWWW
751: fprintf(stderr, "AHTOpen_file: output stream already existed for url %s\n", me->urlName);
752: #endif /* DEBUG_LIBWWW */
753: return HT_OK;
754: }
755:
756: #ifdef DEBUG_LIBWWW
1.265 cvs 757: fprintf(stderr, "AHTOpen_file: opening output stream for url %s\n", me->urlName);
1.85 cvs 758: #endif /* DEBUG_LIBWWW */
759:
1.83 cvs 760: if (!(me->output) &&
761: (me->output != stdout) &&
762: #ifndef _WINDOWS
1.265 cvs 763: (me->output = fopen (me->outputfile, "w")) == NULL)
1.116 cvs 764: #else /* !_WINDOWS */
1.265 cvs 765: (me->output = fopen (me->outputfile, "wb")) == NULL)
766: #endif /* !_WINDOWS */
1.83 cvs 767: {
1.131 cvs 768: me->outputfile[0] = EOS; /* file could not be opened */
1.85 cvs 769: #ifdef DEBUG_LIBWWW
770: fprintf(stderr, "AHTOpen_file: couldn't open output stream for url %s\n", me->urlName);
771: #endif
1.265 cvs 772: TtaSetStatus (me->docid, 1,
773: TtaGetMessage (AMAYA, AM_CANNOT_CREATE_FILE),
774: me->outputfile);
1.83 cvs 775: me->reqStatus = HT_ERR;
776: return (HT_ERROR);
777: }
778:
779: HTRequest_setOutputStream (me->request,
1.265 cvs 780: AHTFWriter_new (me->request, me->output, YES));
1.83 cvs 781: me->reqStatus = HT_WAITING;
782: return HT_OK;
783: }
784:
785: /*----------------------------------------------------------------------
1.265 cvs 786: SafePut_init
787: Sets up the domains which are authorized to make a redirect on
788: a PUT.
789: ----------------------------------------------------------------------*/
790: static void SafePut_init (void)
791: {
792: char *strptr;
1.266 cvs 793: char *ptr, *ptr2;
794: char *domain;
1.265 cvs 795:
796: /* get the proxy settings from the thot.ini file */
797: strptr = TtaGetEnvString ("SAFE_PUT_REDIRECT");
798: if (strptr && *strptr)
799: {
800: /* Get copy we can mutilate */
1.266 cvs 801: ptr2 = TtaStrdup (strptr);
1.265 cvs 802: /* convert to lowercase */
1.266 cvs 803: ptr = ptr2;
1.265 cvs 804: while (*ptr)
805: {
806: *ptr = tolower (*ptr);
807: ptr++;
808: }
809:
810: /* create the list container */
1.266 cvs 811: safeput_list = HTList_new ();
812:
1.265 cvs 813: /* store the domain list */
1.266 cvs 814: ptr = ptr2;
815: while ((domain = HTNextField (&ptr)) != NULL)
1.265 cvs 816: HTList_addObject (safeput_list, TtaStrdup (domain));
817:
818: TtaFreeMemory (ptr2);
819: }
820: }
821:
822: /*----------------------------------------------------------------------
823: SafePut_delete
824: Deletes the safeput_list variable
825: ----------------------------------------------------------------------*/
826: static void SafePut_delete (void)
827: {
828: HTList *cur = safeput_list;
829: char *domain;
830:
831: if (!safeput_list)
832: return;
833:
834: while ((domain = (char *) HTList_nextObject (cur)))
835: TtaFreeMemory (domain);
836: HTList_delete (safeput_list);
837: safeput_list = NULL;
838: }
839:
840: /*----------------------------------------------------------------------
841: SafePut_query
842: returns true if the domain to which belongs the URL accepts an automatic
843: PUT redirect.
844: ----------------------------------------------------------------------*/
845: static ThotBool SafePut_query (char *url)
846: {
1.266 cvs 847: HTList *cur;
848: char *me;
849: ThotBool found;
850: char tmp[MAX_LENGTH];
1.265 cvs 851:
852: /* extract the domain path of the url and normalize it */
853: /* domain = url; */
854: cur = safeput_list;
855: found = FALSE;
856:
1.266 cvs 857: while ((me = (char *) HTList_nextObject (cur)))
858: {
1.273 cvs 859: strcpy (tmp, me);
1.266 cvs 860: if (strstr (url, tmp))
861: {
862: found = TRUE;
863: break;
864: }
865: }
1.265 cvs 866:
867: return (found);
868: }
869:
870: /*----------------------------------------------------------------------
1.17 cvs 871: redirection_handler
872: this function is registered to handle permanent and temporary
873: redirections.
874: ----------------------------------------------------------------------*/
1.265 cvs 875: static int redirection_handler (HTRequest *request, HTResponse *response,
876: void *param, int status)
1.4 cvs 877: {
1.265 cvs 878: HTAnchor *new_anchor = HTResponse_redirection (response);
879: AHTReqContext *me = HTRequest_context (request);
880: HTMethod method = HTRequest_method (request);
881: char *ref;
882: char *escape_src, *dst;
883: char urlAdr[MAX_LENGTH];
884:
885: if (!me)
886: /* if the redirect doesn't come from Amaya, we call libwww's standard redirect filter */
887: return (HTRedirectFilter (request, response, param, status));
888:
889: if (!new_anchor)
890: {
891: if (PROT_TRACE)
1.235 cvs 892: HTTrace ("Redirection. No destination\n");
1.265 cvs 893: return HT_OK;
894: }
1.4 cvs 895:
896: /*
1.207 cvs 897: ** Only do redirect on GET, HEAD, and authorized domains for PUT
1.265 cvs 898: */
899: if ((me->method == METHOD_PUT && !SafePut_query (me->urlName)) ||
900: (me->method != METHOD_PUT && !HTMethod_isSafe (method)))
901: {
902: /*
903: ** If we got a 303 See Other then change the method to GET.
904: ** Otherwise ask the user whether we should continue.
905: */
906: if (status == HT_SEE_OTHER)
907: {
1.235 cvs 908: if (PROT_TRACE)
1.265 cvs 909: HTTrace("Redirection. Changing method from %s to GET\n", HTMethod_name(method));
910: HTRequest_setMethod(request, METHOD_GET);
911: }
912: else
913: {
914: HTAlertCallback *prompt = HTAlert_find (HT_A_CONFIRM);
915: if (prompt)
916: {
917: if ((*prompt) (request, HT_A_CONFIRM, HT_MSG_REDIRECTION, NULL, NULL, NULL) != YES)
918: {
919: /* the user didn't agree on the redirection, so
920: we consider it's an abort */
921: me->reqStatus = HT_ABORT;
922: /* and we return HT_OK so that the terminate_handler
923: will be called */
924: return HT_OK;
925: }
926: }
927: }
928: }
929:
1.4 cvs 930: /*
1.265 cvs 931: ** Start new request with the redirect anchor found in the headers.
932: ** Note that we reuse the same request object which means that we must
933: ** keep this around until the redirected request has terminated. It also
934: ** allows us in an easy way to keep track of the number of redirections
935: ** so that we can detect endless loops.
936: */
937: if (HTRequest_doRetry (request))
938: {
939: /*
940: ** Start request with new credentials
941: */
942: /* only do a redirect using a network protocol understood by Amaya */
1.273 cvs 943: strcpy (urlAdr, new_anchor->parent->address);
1.265 cvs 944: if (IsValidProtocol (urlAdr))
945: {
946: /* if it's a valid URL, we try to normalize it */
947: /* We use the pre-redirection anchor as a base name */
948: /* @@ how to obtain this address here? */
949: dst = urlAdr;
950: escape_src = EscapeURL (me->urlName);
951: if (escape_src)
952: {
953: ref = AmayaParseUrl (dst, escape_src, AMAYA_PARSE_ALL);
954: TtaFreeMemory (escape_src);
955: }
956: else
957: ref = NULL;
958:
959: if (ref)
960: {
961: HTAnchor_setPhysical (HTAnchor_parent (new_anchor), ref);
962: TtaFreeMemory (ref);
963: }
964: else
965: return HT_OK; /* We can't redirect anymore */
966: }
967: else
968: return HT_OK; /* We can't redirect anymore */
969:
970: /* update the current file name */
971: if ((me->mode & AMAYA_ASYNC) || (me->mode & AMAYA_IASYNC) ||
972: (me->method == METHOD_PUT))
973: {
974: TtaFreeMemory (me->urlName);
1.272 cvs 975: me->urlName = TtaStrdup (urlAdr);
1.265 cvs 976: }
977: else
978: {
979: /* it's a SYNC mode, so we should keep the urlName */
980: strncpy (me->urlName, urlAdr, MAX_LENGTH - 1);
981: me->urlName[MAX_LENGTH - 1] = EOS;
982: }
983: ChopURL (me->status_urlName, me->urlName);
1.166 cvs 984:
1.265 cvs 985: /* @@ verify if this is important */
986: /* @@@ new libwww doesn't need this free stream while making
987: a PUT. Is it the case everywhere or just for PUT? */
988: if (me->method != METHOD_PUT &&
989: me->request->orig_output_stream != NULL)
990: {
991: AHTFWriter_FREE (me->request->orig_output_stream);
992: me->request->orig_output_stream = NULL;
993: if (me->output != stdout)
994: {
995: /* Are we writing to a file? */
1.257 kahan 996: #ifdef DEBUG_LIBWWW
1.265 cvs 997: fprintf (stderr, "redirection_handler: New URL is %s, closing FILE %p\n", me->urlName, me->output);
1.257 kahan 998: #endif
1.265 cvs 999: fclose (me->output);
1000: me->output = NULL;
1001: }
1002: }
1003:
1004: /* tell the user what we're doing */
1005: TtaSetStatus (me->docid, 1,
1006: TtaGetMessage (AMAYA, AM_RED_FETCHING), me->status_urlName);
1007: /*
1008: ** launch the request
1009: */
1010: /* add a link relationship? */
1011: /* reset the request status */
1012: me->reqStatus = HT_NEW;
1013: /* clear the errors */
1014: HTError_deleteAll (HTRequest_error (request));
1015: HTRequest_setError (request, NULL);
1016: /* clear the authentication credentials, as they get regenerated */
1017: HTRequest_deleteCredentialsAll (request);
1.297 kirschpi 1018:
1019: #ifdef DAV
1.299 kirschpi 1020: /* remove the old header "If" (WebDAV lock information) */
1.297 kirschpi 1021: DAVRemoveIfHeader (me);
1022:
1023: /* search lock information for the new url */
1024: if (me->method == METHOD_POST || me->method == METHOD_PUT)
1025: DAVAddIfHeader (me,me->urlName);
1.302 kirschpi 1026: #endif /* DAV */
1.265 cvs 1027:
1028: if (me->method == METHOD_POST || me->method == METHOD_PUT)
1.285 kahan 1029: {
1030: /* PUT, POST etc. */
1031: /* for PUT, we memorize there was a redirection, so that we
1032: can clear the original cache entry in the terminate_handler */
1033: if (me->method == METHOD_PUT)
1034: me->put_redirection = TRUE;
1035: status = HTLoadAbsolute (me->urlName, request);
1036: }
1.265 cvs 1037: else
1038: HTLoadAnchor (new_anchor, request);
1039: }
1040: else
1041: {
1042: HTRequest_addError (request, ERR_FATAL, NO, HTERR_MAX_REDIRECT, NULL, 0, "HTRedirectFilter");
1043: /* so that we can show the error message */
1044: if (me->error_html)
1045: DocNetworkStatus[me->docid] |= AMAYA_NET_ERROR;
1046: me->reqStatus = HT_ERR;
1047: TtaSetStatus (me->docid, 1, TtaGetMessage (AMAYA, AM_REDIRECTIONS_LIMIT), NULL);
1048: }
1049:
1.4 cvs 1050: /*
1.74 cvs 1051: ** By returning HT_ERROR we make sure that this is the last handler to be
1052: ** called. We do this as we don't want any other filter to delete the
1053: ** request object now when we have just started a new one ourselves
1054: */
1.4 cvs 1055: return HT_ERROR;
1056: }
1057:
1.151 cvs 1058: #ifdef AMAYA_LOST_UPDATE
1059: /*----------------------------------------------------------------------
1060: precondition_handler
1061: 412 "Precondition failed" handler
1062: ----------------------------------------------------------------------*/
1.265 cvs 1063: static int precondition_handler (HTRequest *request, HTResponse *response,
1064: void *context, int status)
1.151 cvs 1065: {
1.168 cvs 1066: AHTReqContext *me = (AHTReqContext *) HTRequest_context (request);
1067: HTAlertCallback *prompt = HTAlert_find (HT_A_CONFIRM);
1.191 cvs 1068: ThotBool force_put;
1.151 cvs 1069:
1070: if (!me)
1071: return HT_OK; /* not an Amaya request */
1072:
1.168 cvs 1073: if (prompt)
1074: force_put = (*prompt) (request, HT_A_CONFIRM, HT_MSG_RULES,
1075: NULL, NULL, NULL);
1076: else
1077: force_put = NO;
1078:
1079: if (force_put)
1080: {
1.297 kirschpi 1081: #ifdef DAV
1082: BOOL noIf = NO;
1083:
1084: /* MKP: if the old request has preconditions, *
1085: * then, we supose that these preconditions *
1086: * caused the 412 Precondition Failed status *
1087: * code, otherwise we supose that the cause *
1088: * was an eventual If header. */
1089: if (HTRequest_preconditions(me->request)!=HT_NO_MATCH)
1090: noIf = NO;
1091: else
1092: noIf = YES;
1.302 kirschpi 1093: #endif /* DAV */
1.297 kirschpi 1094:
1095:
1.168 cvs 1096: /* start a new PUT request without preconditions */
1097: /* @@ do we need to kill the request? */
1098: if (me->output && me->output != stdout)
1099: {
1100: fclose (me->output);
1101: me->output = NULL;
1102: }
1103: /*
1104: ** reset the Amaya and libwww request status
1105: */
1.176 cvs 1106:
1107: /* start with a new, clean request structure */
1108: HTRequest_delete (me->request);
1109: me->request = HTRequest_new ();
1110: /* clean the associated file structure) */
1111: HTRequest_setOutputStream (me->request, NULL);
1112: /* Initialize the other members of the structure */
1.171 cvs 1113: HTRequest_setMethod (me->request, METHOD_GET);
1.176 cvs 1114: HTRequest_setOutputFormat (me->request, WWW_SOURCE);
1115: HTRequest_setContext (me->request, me);
1116: HTRequest_setPreemptive (me->request, NO);
1117: /*
1118: ** Make sure that the first request is flushed immediately and not
1119: ** buffered in the output buffer
1120: */
1121: if (me->mode & AMAYA_FLUSH_REQUEST)
1122: HTRequest_setFlush(me->request, YES);
1123:
1.171 cvs 1124: /* turn off preconditions */
1125: HTRequest_setPreconditions(me->request, HT_NO_MATCH);
1126: me->reqStatus = HT_NEW;
1.297 kirschpi 1127:
1128:
1129: #ifdef DAV
1.302 kirschpi 1130: /* MKP: add an If header (lock information) only
1131: * if there wasn't preconditions */
1.297 kirschpi 1132: if (noIf!=YES) DAVAddIfHeader (me,HTAnchor_address(me->dest));
1133: #endif /* DAV */
1134:
1135:
1.171 cvs 1136: /* make the request */
1.176 cvs 1137: status = HTPutDocumentAnchor (HTAnchor_parent (me->source),
1138: me->dest, me->request);
1.168 cvs 1139: /* stop here */
1140: return HT_ERROR;
1141: }
1142: else
1143: {
1144: /* abort the request */
1145: /* @@ should we call StopRequest here? */
1146: me->reqStatus = HT_ABORT;
1147: /* stop here */
1148: return HT_ERROR;
1149: }
1150: }
1.151 cvs 1151:
1.168 cvs 1152: /*----------------------------------------------------------------------
1153: check_handler
1154: Request HEAD checker filter
1155: ----------------------------------------------------------------------*/
1156: static int check_handler (HTRequest * request, HTResponse * response,
1.151 cvs 1157: void * param, int status)
1158: {
1.168 cvs 1159: AHTReqContext *me = (AHTReqContext *) HTRequest_context (request);
1160: HTAlertCallback *prompt = HTAlert_find (HT_A_CONFIRM);
1.191 cvs 1161: ThotBool force_put;
1.168 cvs 1162:
1163: if (!me)
1164: return HT_OK; /* not an Amaya request */
1165:
1166: HTRequest_deleteAfter(me->request, check_handler);
1167: /*
1168: ** If head request showed that the document doesn't exist
1169: ** then just go ahead and PUT it. Otherwise ask for help
1170: */
1171: if (status == HT_ERROR || status == HT_INTERRUPTED || status == HT_TIMEOUT)
1172: {
1173: /* we'd need to call terminate_handler, to free the resources */
1174: /* abort the request */
1175: /* @@ should we call StopRequest here? */
1176: me->reqStatus = HT_ABORT;
1177: /* stop here */
1178: return HT_ERROR;
1179: }
1180: else if (status == HT_NO_ACCESS || status == HT_NO_PROXY_ACCESS)
1181: {
1182: /* we'd need to call terminate_handler, to free the resources */
1183: /* abort the request */
1184: /* @@ should we call StopRequest here? */
1185: me->reqStatus = HT_ABORT;
1186: /* stop here */
1187: return HT_ERROR;
1188: }
1189: else if ( (abs(status)/100) != 2)
1190: {
1.176 cvs 1191: /* start with a new, clean request structure */
1192: HTRequest_delete (me->request);
1193: me->request = HTRequest_new ();
1.208 cvs 1194: /* add the default PUT name */
1195: HTRequest_setDefaultPutName (me->request, me->default_put_name);
1.176 cvs 1196: /* clean the associated file structure) */
1197: HTRequest_setOutputStream (me->request, NULL);
1198: /* Initialize the other members of the structure */
1.171 cvs 1199: HTRequest_setMethod (me->request, METHOD_GET);
1.176 cvs 1200: HTRequest_setOutputFormat (me->request, WWW_SOURCE);
1201: HTRequest_setContext (me->request, me);
1202: HTRequest_setPreemptive (me->request, NO);
1203: /*
1204: ** Make sure that the first request is flushed immediately and not
1205: ** buffered in the output buffer
1206: */
1207: if (me->mode & AMAYA_FLUSH_REQUEST)
1208: HTRequest_setFlush(me->request, YES);
1.297 kirschpi 1209:
1210: #ifdef DAV
1.302 kirschpi 1211: /* MKP: try to add an "If" header (lock information)
1212: * Such header will be added only if there is a
1213: * lock information in the local base. */
1.297 kirschpi 1214: DAVAddIfHeader (me,me->urlName);
1.302 kirschpi 1215: #endif /* DAV */
1.297 kirschpi 1216:
1.176 cvs 1217:
1218: /* turn on the special preconditions, to avoid having this
1219: ressource appear before we do the PUT */
1.168 cvs 1220: HTRequest_setPreconditions(me->request, HT_DONT_MATCH_ANY);
1.171 cvs 1221: me->reqStatus = HT_NEW;
1.168 cvs 1222: status = HTPutDocumentAnchor (HTAnchor_parent (me->source), me->dest, me->request);
1223: return HT_ERROR; /* stop here */
1.176 cvs 1224: }
1.168 cvs 1225: else
1226: {
1227: if (prompt)
1228: force_put = (*prompt) (request, HT_A_CONFIRM, HT_MSG_FILE_REPLACE,
1229: NULL, NULL, NULL);
1230: else
1231: force_put = FALSE;
1232:
1233: if (force_put)
1.151 cvs 1234: {
1235: /* Start a new PUT request without preconditions */
1.176 cvs 1236:
1237: /* get a new, clean request structure */
1238: HTRequest_delete (me->request);
1239: me->request = HTRequest_new ();
1.208 cvs 1240: /* add the default PUT name */
1241: HTRequest_setDefaultPutName (me->request, me->default_put_name);
1.176 cvs 1242: /* clean the associated file structure) */
1243: HTRequest_setOutputStream (me->request, NULL);
1244: /* Initialize the other members of the structure */
1.171 cvs 1245: HTRequest_setMethod (me->request, METHOD_GET);
1.176 cvs 1246: HTRequest_setOutputFormat (me->request, WWW_SOURCE);
1247: HTRequest_setContext (me->request, me);
1248: HTRequest_setPreemptive (me->request, NO);
1.297 kirschpi 1249:
1250: #ifdef DAV
1.302 kirschpi 1251: /* MKP: try to add an "If" header (lock information)
1252: * Such header will be added only if there is a
1253: * lock information in the local base. */
1.297 kirschpi 1254: DAVAddIfHeader (me,HTAnchor_address(me->dest));
1.302 kirschpi 1255: #endif /* DAV */
1256:
1.297 kirschpi 1257:
1.176 cvs 1258: /*
1259: ** Make sure that the first request is flushed immediately and not
1260: ** buffered in the output buffer
1261: */
1262: if (me->mode & AMAYA_FLUSH_REQUEST)
1263: HTRequest_setFlush(me->request, YES);
1264: /* remove the preconditions */
1.168 cvs 1265: HTRequest_setPreconditions(me->request, HT_NO_MATCH);
1.171 cvs 1266: me->reqStatus = HT_NEW;
1.176 cvs 1267: status = HTPutDocumentAnchor (HTAnchor_parent (me->source),
1268: me->dest, me->request);
1.168 cvs 1269: return HT_ERROR; /* stop here */
1.151 cvs 1270: }
1.168 cvs 1271: else
1272: {
1273: /* we'd need to call terminate_handler, to free the resources */
1274: /* abort the request */
1275: /* @@ should we call StopRequest here? */
1276: me->reqStatus = HT_ABORT;
1277: /* stop here */
1278: return HT_ERROR;
1279: }
1280: }
1281: return HT_ERROR;
1.151 cvs 1282: }
1283: #endif /* AMAYA_LOST_UPDATE */
1284:
1.5 cvs 1285: /*----------------------------------------------------------------------
1.17 cvs 1286: terminate_handler
1287: this function is registered to handle the result of the request
1.5 cvs 1288: ----------------------------------------------------------------------*/
1.265 cvs 1289: static int terminate_handler (HTRequest *request, HTResponse *response,
1290: void *context, int status)
1.4 cvs 1291: {
1.116 cvs 1292: AHTReqContext *me = (AHTReqContext *) HTRequest_context (request);
1.191 cvs 1293: ThotBool error_flag;
1.116 cvs 1294:
1295: if (!me)
1.214 cvs 1296: return HT_ERROR; /* not an Amaya request */
1.116 cvs 1297:
1298: if (me->reqStatus == HT_END)
1299: /* we have already processed this request! */
1300: return HT_OK;
1301:
1302: /* if Amaya was killed, treat with this request as if it were
1303: issued by a Stop button event */
1304:
1305: if (!AmayaIsAlive ())
1.80 cvs 1306: me->reqStatus = HT_ABORT;
1.220 cvs 1307:
1308: /* trying to protect against this problem... hard to place
1309: the detection elsewhere :-/ */
1.240 cvs 1310: /* @@ JK: Is this still needed? */
1.220 cvs 1311: if (IsHTTP09Error (request))
1312: status = -1;
1313:
1.238 cvs 1314: if (status == HT_LOADED
1315: || status == HT_CREATED
1316: || status == HT_NO_DATA
1.249 kahan 1317: /* JK: removed it as the kludge doesn't seem useful anymore */
1.160 cvs 1318: /* kludge for work around libwww problem */
1.249 kahan 1319: /* || (status == HT_INTERRUPTED && me->method == METHOD_PUT) */
1.116 cvs 1320: #ifdef AMAYA_WWW_CACHE
1321: /* what status to use to know we're downloading from a cache? */
1.238 cvs 1322: || status == HT_NOT_MODIFIED
1323: || status == HT_PARTIAL_CONTENT
1.116 cvs 1324: #endif /* AMAYA_WWW_CACHE */
1.238 cvs 1325: || me->reqStatus == HT_ABORT)
1.74 cvs 1326: error_flag = FALSE;
1.297 kirschpi 1327: #ifdef DAV
1328: else if (status == HT_LOCKED
1329: || status == HT_FAILED_DEPENDENCY
1.302 kirschpi 1330: || status == HT_MULTI_STATUS)
1331: {
1.297 kirschpi 1332: /* WebDAV return codes - they are handled in
1333: * specific filters. We don't need to deal
1334: * with them anymore
1335: */
1336: error_flag = FALSE;
1.302 kirschpi 1337: }
1338: #endif /* DAV */
1.256 kahan 1339: else
1.74 cvs 1340: error_flag = TRUE;
1.130 cvs 1341:
1.285 kahan 1342: /* If we did a PUT that was redirected, clean the original
1343: cache entry */
1344: if (status == 204 && me->method == METHOD_PUT && me->put_redirection)
1345: {
1346: HTCache * cache;
1347: HTParentAnchor * anchor = HTAnchor_parent (me->dest);
1348: cache = HTCache_find (anchor, NULL);
1349: if (cache)
1350: {
1351: /* what a problem... we update the cache with the wrong data
1352: from the response... after the redirection */
1353: HTCache_resetMeta (cache, request, response);
1354: }
1355: else
1356: /* If entry doesn't already exist then create a new entry */
1357: HTCache_touch(request, response, HTAnchor_parent (me->dest));
1358: }
1359:
1.4 cvs 1360: /* output any errors from the server */
1.130 cvs 1361:
1.77 cvs 1362: /*
1.74 cvs 1363: ** me->output = output file which will receive an html file
1364: ** me->error_html = yes, output HTML errors in the screen
1365: ** request->error_stack == if there are any errors, they will be here
1366: ** me->error_stream_size If it's != 0 means an error message has already
1367: ** been written to the stack
1368: */
1369:
1.4 cvs 1370: /* First, we verify if there are any errors and if they are not
1.17 cvs 1371: ** yet written to the error stack. If no, then let's try to write them
1372: ** ourselves
1373: */
1.74 cvs 1374:
1375: #ifdef DEBUG_LIBWWW
1376: fprintf (stderr, "terminate_handler: URL is "
1377: "%s, closing FILE %p status is %d\n", me->urlName, me->output,
1378: status);
1.69 cvs 1379: #endif
1.74 cvs 1380:
1.69 cvs 1381: if (me->output && me->output != stdout)
1382: {
1.214 cvs 1383: /* we are writing to a local file */
1.74 cvs 1384: if (me->reqStatus != HT_ABORT)
1385: { /* if the request was not aborted and */
1.80 cvs 1386: if (error_flag &&
1387: me->error_html == TRUE)
1388: /* there were some errors and we want to print them */
1389: {
1390: if (me->error_stream_size == 0)/* and the stream is empty */
1.210 cvs 1391: {
1392: /* if the transfer was interrupted, the file may not be
1393: empty. So, we erase it */
1394: fflush (me->output);
1395: rewind (me->output);
1396: AHTError_MemPrint (request); /* copy errors from
1397: **the error stack
1398: ** into the error stream */
1399: }
1.80 cvs 1400: if (me->error_stream)
1401: { /* if the stream is non-empty */
1402: fprintf (me->output, me->error_stream);/* output the errors */
1.85 cvs 1403: /* Clear the error context, so that we can deal with
1404: this answer as if it were a normal reply */
1405: HTError_deleteAll( HTRequest_error (request));
1406: HTRequest_setError (request, NULL);
1407: error_flag = 0;
1.74 cvs 1408: }
1409: } /* if error_stack */
1.85 cvs 1410: }
1411:
1412: /* if != HT_ABORT */
1413:
1414: #ifdef DEBUG_LIBWWW
1415: fprintf (stderr, "terminate_handler: URL is %s, closing "
1416: "FILE %p\n", me->urlName, me->output);
1417: #endif
1.74 cvs 1418: fclose (me->output);
1419: me->output = NULL;
1.69 cvs 1420: }
1.80 cvs 1421:
1.214 cvs 1422: /* a very special handling so that we can put a message box
1423: to tell the user WHAT he has just done... */
1424: if (UserAborted_flag && me->method == METHOD_PUT)
1425: {
1426: HTRequest_addError (request, ERR_FATAL, NO, HTERR_INTERRUPTED,
1427: "Operation aborted by user", 0, NULL);
1428: }
1429:
1.80 cvs 1430: if (error_flag)
1431: me->reqStatus = HT_ERR;
1.214 cvs 1432: else
1433: if (me->reqStatus != HT_ABORT)
1434: me->reqStatus = HT_END;
1.154 cvs 1435:
1.238 cvs 1436: /* copy the headers in which the application is interested */
1437: HTTP_headers_set (request, response, context, status);
1.114 cvs 1438:
1.115 cvs 1439: /* to avoid a hangup while downloading css files */
1.140 cvs 1440: if (AmayaAlive_flag && (me->mode & AMAYA_LOAD_CSS))
1.265 cvs 1441: TtaSetStatus (me->docid, 1,
1442: TtaGetMessage (AMAYA, AM_ELEMENT_LOADED),
1443: me->status_urlName);
1.116 cvs 1444:
1445: /* don't remove or Xt will hang up during the PUT */
1446: if (AmayaIsAlive () && ((me->method == METHOD_POST) ||
1447: (me->method == METHOD_PUT)))
1.7 cvs 1448: {
1.80 cvs 1449: PrintTerminateStatus (me, status);
1450: }
1.114 cvs 1451:
1.111 cvs 1452: ProcessTerminateRequest (request, response, context, status);
1.116 cvs 1453:
1.151 cvs 1454: /* stop here */
1.150 cvs 1455: return HT_ERROR;
1.4 cvs 1456: }
1457:
1.5 cvs 1458: /*----------------------------------------------------------------------
1.17 cvs 1459: AHTLoadTerminate_handler
1.74 cvs 1460: this is an application "AFTER" Callback. It's called by the library
1461: when a request has ended, so that we can setup the correct status.
1.5 cvs 1462: ----------------------------------------------------------------------*/
1.265 cvs 1463: int AHTLoadTerminate_handler (HTRequest *request, HTResponse *response,
1464: void *param, int status)
1.4 cvs 1465: {
1.116 cvs 1466: /** @@@@ use this with printstatus ?? */
1.4 cvs 1467: AHTReqContext *me = HTRequest_context (request);
1468: HTAlertCallback *cbf;
1469: AHTDocId_Status *docid_status;
1470:
1.7 cvs 1471: switch (status)
1.116 cvs 1472: {
1473: case HT_LOADED:
1474: if (PROT_TRACE)
1475: HTTrace ("Load End.... OK: `%s\' has been accessed\n",
1476: me->status_urlName);
1.4 cvs 1477:
1.116 cvs 1478: docid_status = GetDocIdStatus (me->docid,
1479: Amaya->docid_status);
1.7 cvs 1480:
1.116 cvs 1481: if (docid_status != NULL && docid_status->counter > 1)
1482: TtaSetStatus (me->docid, 1,
1483: TtaGetMessage (AMAYA, AM_ELEMENT_LOADED),
1.233 cvs 1484: me->status_urlName);
1.7 cvs 1485: break;
1.116 cvs 1486:
1487: case HT_NO_DATA:
1488: if (PROT_TRACE)
1489: HTTrace ("Load End.... OK BUT NO DATA: `%s\'\n",
1490: me->status_urlName);
1.297 kirschpi 1491: #ifdef DAV
1.302 kirschpi 1492: if (me->method==METHOD_UNLOCK)
1493: {
1494: /* MKP: set an appropriate status message */
1.297 kirschpi 1495: TtaSetStatus (me->docid, 1,
1496: TtaGetMessage (AMAYA, AM_UNLOCK_SUCCEED),
1497: NULL);
1.302 kirschpi 1498: }
1.297 kirschpi 1499: else
1.302 kirschpi 1500: #endif /* DAV */
1.297 kirschpi 1501: TtaSetStatus (me->docid, 1,
1.116 cvs 1502: TtaGetMessage (AMAYA, AM_LOADED_NO_DATA),
1.233 cvs 1503: me->status_urlName);
1.116 cvs 1504: break;
1505:
1506: case HT_INTERRUPTED:
1507: if (PROT_TRACE)
1508: HTTrace ("Load End.... INTERRUPTED: `%s\'\n",
1509: me->status_urlName);
1510: TtaSetStatus (me->docid, 1,
1511: TtaGetMessage (AMAYA, AM_LOAD_ABORT),
1512: NULL);
1513: break;
1.7 cvs 1514:
1.116 cvs 1515: case HT_RETRY:
1516: if (PROT_TRACE)
1517: HTTrace ("Load End.... NOT AVAILABLE, RETRY AT %ld\n",
1518: HTResponse_retryTime (response));
1519: TtaSetStatus (me->docid, 1,
1520: TtaGetMessage (AMAYA, AM_NOT_AVAILABLE_RETRY),
1.233 cvs 1521: me->status_urlName);
1.116 cvs 1522: break;
1.7 cvs 1523:
1.247 kahan 1524: case HT_NOT_MODIFIED:
1525: if (PROT_TRACE)
1.265 cvs 1526: HTTrace ("Load End.... NOT MODIFIED (%s)",
1527: me->status_urlName ? me->status_urlName :" <UNKNOWN>");
1.247 kahan 1528: break;
1529:
1.116 cvs 1530: case HT_ERROR:
1531: cbf = HTAlert_find (HT_A_MESSAGE);
1532: if (cbf)
1533: (*cbf) (request, HT_A_MESSAGE, HT_MSG_NULL, NULL,
1534: HTRequest_error (request), NULL);
1.247 kahan 1535: if (PROT_TRACE)
1.265 cvs 1536: HTTrace ("Load End.... ERROR: Can't access `%s\'\n",
1537: me->status_urlName ? me->status_urlName :"<UNKNOWN>");
1538: TtaSetStatus (me->docid, 1,
1539: TtaGetMessage (AMAYA, AM_CANNOT_LOAD),
1540: me->status_urlName ? me->status_urlName : "<UNKNOWN>");
1.116 cvs 1541: break;
1.247 kahan 1542:
1543: case HTERR_TIMEOUT:
1544: cbf = HTAlert_find (HT_A_MESSAGE);
1545: if (cbf)
1546: (*cbf) (request, HT_A_MESSAGE, HT_MSG_NULL, NULL,
1547: HTRequest_error (request), NULL);
1.116 cvs 1548: if (PROT_TRACE)
1.265 cvs 1549: HTTrace ("Load End.... REQUEST TIMEOUT: Can't access `%s\'\n",
1550: me->status_urlName ? me->status_urlName :"<UNKNOWN>");
1551: TtaSetStatus (me->docid, 1, TtaGetMessage (AMAYA, AM_CANNOT_LOAD),
1552: me->status_urlName ? me->status_urlName : "<UNKNOWN>");
1.116 cvs 1553: break;
1.247 kahan 1554:
1.116 cvs 1555: default:
1556: if (PROT_TRACE)
1557: HTTrace ("Load End.... UNKNOWN RETURN CODE %d\n", status);
1558: break;
1559: }
1560:
1561: return HT_OK;
1562: }
1.7 cvs 1563:
1.248 kahan 1564: /*----------------------------------------------------------------------
1565: LineTrace
1566: Makes a file copy of libwww's traces
1567: ----------------------------------------------------------------------*/
1.116 cvs 1568: static int LineTrace (const char * fmt, va_list pArgs)
1569: {
1.248 kahan 1570: vfprintf (trace_fp, fmt, pArgs);
1571: return (fflush (trace_fp));
1.4 cvs 1572: }
1573:
1.27 cvs 1574: /*----------------------------------------------------------------------
1575: AHTAcceptTypesInit
1.74 cvs 1576: This function prepares the Accept header used by Amaya during
1577: the HTTP content negotiation phase
1.27 cvs 1578: ----------------------------------------------------------------------*/
1579: static void AHTAcceptTypesInit (HTList *c)
1580: {
1.223 cvs 1581: if (c == (HTList *) NULL)
1.27 cvs 1582: return;
1583:
1.223 cvs 1584: /* define here all the mime types that Amaya can accept */
1.27 cvs 1585:
1.223 cvs 1586: HTConversion_add (c, "image/png", "www/present", HTThroughLine, 1.0, 0.0, 0.0);
1587: HTConversion_add (c, "image/jpeg", "www/present", HTThroughLine, 1.0, 0.0, 0.0);
1588: HTConversion_add (c, "image/gif", "www/present", HTThroughLine, 1.0, 0.0, 0.0);
1589: HTConversion_add (c, "image/xbm", "www/present", HTThroughLine, 1.0, 0.0, 0.0);
1590: HTConversion_add (c, "image/xpm", "www/present", HTThroughLine, 1.0, 0.0, 0.0);
1.183 cvs 1591:
1.27 cvs 1592: /* Define here the equivalences between MIME types and file extensions for
1.223 cvs 1593: the types that Amaya can display */
1.27 cvs 1594:
1.176 cvs 1595: /* Initialize suffix bindings for local files */
1596: HTBind_init();
1597:
1.27 cvs 1598: /* Register the default set of file suffix bindings */
1599: HTFileInit ();
1600:
1.257 kahan 1601: /* Register additional bindings */
1.276 kahan 1602: HTBind_add("htm", "text/html", NULL, "8bit", NULL, 1.0);
1.257 kahan 1603: HTBind_add("tgz", "application/gnutar", NULL, "binary", NULL, 1.0);
1.293 kahan 1604: HTBind_add("mml", AM_MATHML_MIME_TYPE, NULL, "8bit", NULL, 1.0);
1605: HTBind_add("svg", AM_SVG_MIME_TYPE, NULL, "8bit", NULL, 1.0);
1.260 kahan 1606: HTBind_add("xsl", "text/xml", NULL, "8bit", NULL, 1.0);
1.27 cvs 1607: /* Don't do any case distinction */
1608: HTBind_caseSensitive (FALSE);
1609: }
1.4 cvs 1610:
1.5 cvs 1611: /*----------------------------------------------------------------------
1.193 cvs 1612: AHTAcceptLanguagesInit
1613: This function prepares the Accept header used by Amaya during
1614: the HTTP content negotiation phase
1615: ----------------------------------------------------------------------*/
1.196 cvs 1616: static void AHTAcceptLanguagesInit (HTList *c)
1.193 cvs 1617: {
1.265 cvs 1618: char *ptr;
1619: char *lang_list;
1.223 cvs 1620: char s[3];
1.196 cvs 1621: int count, lg;
1622: double quality;
1623: ThotBool still;
1.193 cvs 1624:
1625: if (c == (HTList *) NULL)
1.265 cvs 1626: return;
1.193 cvs 1627:
1.203 cvs 1628: lang_list = TtaGetEnvString ("ACCEPT_LANGUAGES");
1.197 cvs 1629: s[2] = EOS;
1.272 cvs 1630: if (lang_list && *lang_list != EOS)
1.193 cvs 1631: {
1632: /* add the default language first */
1633: HTLanguage_add (c, "*", -1.0);
1634: /* how many languages do we have? */
1.196 cvs 1635: ptr = lang_list;
1636: count = 0;
1.272 cvs 1637: while (*ptr != EOS)
1.265 cvs 1638: {
1.272 cvs 1639: while (*ptr != EOS &&
1.265 cvs 1640: (*ptr < 'A' || (*ptr > 'Z' && *ptr < 'a') || *ptr > 'z'))
1641: /* skip the whole separator */
1642: ptr++;
1643: lg = 0;
1644: while ((*ptr >= 'A' &&
1645: *ptr <= 'Z') || (*ptr >= 'a' && *ptr <= 'z') || *ptr == '-')
1646: {
1647: /* it's a new language */
1648: ptr++;
1649: lg++;
1650: }
1651: if (lg >= 2)
1652: count++;
1.272 cvs 1653: if (*ptr != EOS)
1.265 cvs 1654: ptr++;
1655: }
1.193 cvs 1656:
1.196 cvs 1657: if (count > 0)
1.265 cvs 1658: quality = 1.1 - (double) count/10.0;
1.193 cvs 1659: else
1.265 cvs 1660: quality = 1.0;
1.193 cvs 1661:
1.265 cvs 1662: /* Read the languages from the registry, then inject them one, by one.
1663: The first one is the one with the highest priority.
1664: The libwww ask for the lowest priority first.
1.196 cvs 1665: */
1666: ptr--;
1667: still = TRUE;
1.265 cvs 1668: while (count)
1669: {
1670: while (still && (*ptr < 'A' || (*ptr > 'Z' && *ptr < 'a') || *ptr > 'z'))
1671: /* skip the whole separator */
1672: if (ptr > lang_list)
1673: ptr--;
1674: else
1675: still = FALSE;
1676: lg = 0;
1677: while (still &&
1678: ((*ptr >= 'A' &&
1679: *ptr <= 'Z') || (*ptr >= 'a' && *ptr <= 'z') || *ptr == '-'))
1680: {
1681: /* it's a new language */
1682: if (ptr > lang_list)
1683: ptr--;
1684: else
1685: still = FALSE;
1686: lg++;
1687: }
1688: if (lg >= 2)
1689: {
1690: if (still)
1691: strncpy (s, &ptr[1], 2);
1692: else
1693: strncpy (s, lang_list, 2);
1694: count--;
1695: HTLanguage_add (c, s, quality);
1696: quality += 0.1;
1697: }
1698: ptr--;
1699: }
1700: }
1.193 cvs 1701: }
1702:
1703: /*----------------------------------------------------------------------
1.17 cvs 1704: AHTConverterInit
1705: Bindings between a source media type and a destination media type
1706: (conversion).
1.5 cvs 1707: ----------------------------------------------------------------------*/
1.15 cvs 1708: static void AHTConverterInit (HTList *c)
1.4 cvs 1709: {
1710: /* Handler for custom http error messages */
1.7 cvs 1711: HTConversion_add (c, "*/*", "www/debug", AHTMemConverter, 1.0, 0.0, 0.0);
1.4 cvs 1712:
1713: /*
1714: ** These are converters that converts to something other than www/present,
1715: ** that is not directly outputting someting to the user on the screen
1716: */
1717:
1.223 cvs 1718: HTConversion_add (c, "message/rfc822", "*/*", HTMIMEConvert, 1.0, 0.0, 0.0);
1719: HTConversion_add (c, "message/x-rfc822-foot", "*/*", HTMIMEFooter, 1.0, 0.0, 0.0);
1720: HTConversion_add (c, "message/x-rfc822-head", "*/*", HTMIMEHeader, 1.0, 0.0, 0.0);
1721: HTConversion_add(c,"message/x-rfc822-cont", "*/*", HTMIMEContinue, 1.0, 0.0, 0.0);
1722: HTConversion_add(c,"message/x-rfc822-partial","*/*", HTMIMEPartial, 1.0, 0.0, 0.0);
1723: HTConversion_add (c, "multipart/*", "*/*", HTBoundary, 1.0, 0.0, 0.0);
1724: HTConversion_add (c, "text/plain", "text/html", HTPlainToHTML, 1.0, 0.0, 0.0);
1.4 cvs 1725:
1726: /*
1.116 cvs 1727: ** The following conversions are converting ASCII output from various
1728: ** protocols to HTML objects.
1729: */
1.223 cvs 1730: HTConversion_add (c, "text/x-http", "*/*", HTTPStatus_new, 1.0, 0.0, 0.0);
1.4 cvs 1731:
1732: /*
1.116 cvs 1733: ** We also register a special content type guess stream that can figure out
1734: ** the content type by reading the first bytes of the stream
1735: */
1.223 cvs 1736: HTConversion_add (c, "www/unknown", "*/*", HTGuess_new, 1.0, 0.0, 0.0);
1.4 cvs 1737:
1.116 cvs 1738: #ifdef AMAYA_WWW_CACHE
1.4 cvs 1739: /*
1.116 cvs 1740: ** Register a persistent cache stream which can save an object to local
1741: ** file
1742: */
1.223 cvs 1743: HTConversion_add (c, "www/cache", "*/*", HTCacheWriter, 1.0, 0.0, 0.0);
1744: HTConversion_add(c,"www/cache-append", "*/*", HTCacheAppend, 1.0, 0.0, 0.0);
1.306 cheyroul 1745: #endif /*AMAYA_WWW_CACHE*/
1.4 cvs 1746:
1747: /*
1.116 cvs 1748: ** This dumps all other formats to local disk without any further
1749: ** action taken
1750: */
1.223 cvs 1751: HTConversion_add (c, "*/*", "www/present", HTSaveLocally, 0.3, 0.0, 0.0);
1.4 cvs 1752: }
1753:
1.27 cvs 1754:
1.15 cvs 1755: /*----------------------------------------------------------------------
1.17 cvs 1756: AHTProtocolInit
1757: Registers all amaya supported protocols.
1.15 cvs 1758: ----------------------------------------------------------------------*/
1.4 cvs 1759: static void AHTProtocolInit (void)
1760: {
1.265 cvs 1761: char *strptr;
1.4 cvs 1762:
1.116 cvs 1763: /*
1764: NB. Preemptive == YES means Blocking requests
1765: Non-preemptive == NO means Non-blocking requests
1766: */
1767: HTTransport_add("tcp", HT_TP_SINGLE, HTReader_new, HTWriter_new);
1768: HTTransport_add("buffered_tcp", HT_TP_SINGLE, HTReader_new,
1769: HTBufferWriter_new);
1770: HTProtocol_add ("http", "buffered_tcp", HTTP_PORT, NO, HTLoadHTTP, NULL);
1.136 cvs 1771: #ifdef _WINDOWS
1772: HTProtocol_add ("file", "local", 0, YES, HTLoadFile, NULL);
1773: #else
1.116 cvs 1774: HTProtocol_add ("file", "local", 0, NO, HTLoadFile, NULL);
1.198 cvs 1775: #endif /* _WINDOWS */
1.116 cvs 1776: #ifdef AMAYA_WWW_CACHE
1777: HTProtocol_add("cache", "local", 0, YES, HTLoadCache, NULL);
1778: #endif /* AMAYA_WWW_CACHE */
1.103 cvs 1779: #if 0 /* experimental code */
1.245 kahan 1780: #endif
1.116 cvs 1781: HTProtocol_add ("ftp", "tcp", FTP_PORT, NO, HTLoadFTP, NULL);
1.245 kahan 1782:
1.116 cvs 1783:
1784: /* initialize pipelining */
1.223 cvs 1785: strptr = TtaGetEnvString ("ENABLE_PIPELINING");
1.265 cvs 1786: if (strptr && *strptr && strcasecmp (strptr, "yes"))
1.116 cvs 1787: HTTP_setConnectionMode (HTTP_11_NO_PIPELINING);
1.4 cvs 1788: }
1789:
1.15 cvs 1790: /*----------------------------------------------------------------------
1.17 cvs 1791: AHTNetInit
1792: Reegisters "before" and "after" request filters.
1.15 cvs 1793: ----------------------------------------------------------------------*/
1.4 cvs 1794: static void AHTNetInit (void)
1795: {
1796:
1797: /* Register BEFORE filters
1.74 cvs 1798: ** The BEFORE filters handle proxies, caches, rule files etc.
1799: ** The filters are called in the order by which the are registered
1800: ** Not done automaticly - may be done by application!
1801: */
1.4 cvs 1802:
1.116 cvs 1803: HTNet_addBefore (HTCredentialsFilter, "http://*", NULL, HT_FILTER_LATE);
1804: HTNet_addBefore (HTProxyFilter, NULL, NULL, HT_FILTER_LATE);
1.85 cvs 1805: HTHost_setActivateRequestCallback (AHTOpen_file);
1.4 cvs 1806:
1807: /* register AFTER filters
1.74 cvs 1808: ** The AFTER filters handle error messages, logging, redirection,
1809: ** authentication etc.
1810: ** The filters are called in the order by which the are registered
1811: ** Not done automaticly - may be done by application!
1812: */
1.4 cvs 1813:
1.223 cvs 1814: HTNet_addAfter (HTAuthFilter, "http://*", NULL, HT_NO_ACCESS, HT_FILTER_MIDDLE);
1815: HTNet_addAfter (HTAuthFilter, "http://*", NULL, HT_REAUTH, HT_FILTER_MIDDLE);
1816: HTNet_addAfter (redirection_handler, "http://*", NULL, HT_PERM_REDIRECT, HT_FILTER_MIDDLE);
1817: HTNet_addAfter (redirection_handler, "http://*", NULL, HT_FOUND, HT_FILTER_MIDDLE);
1818: HTNet_addAfter (redirection_handler, "http://*", NULL, HT_SEE_OTHER, HT_FILTER_MIDDLE);
1819: HTNet_addAfter (redirection_handler, "http://*", NULL, HT_TEMP_REDIRECT, HT_FILTER_MIDDLE);
1820: HTNet_addAfter (HTAuthInfoFilter, "http://*", NULL, HT_ALL, HT_FILTER_MIDDLE);
1821: HTNet_addAfter (HTUseProxyFilter, "http://*", NULL, HT_USE_PROXY, HT_FILTER_MIDDLE);
1.151 cvs 1822: #ifdef AMAYA_LOST_UPDATE
1.223 cvs 1823: HTNet_addAfter (precondition_handler, NULL, NULL, HT_PRECONDITION_FAILED, HT_FILTER_MIDDLE);
1.151 cvs 1824: #endif /* AMAYA_LOST_UPDATE */
1.111 cvs 1825: #ifndef _WINDOWS
1.223 cvs 1826: HTNet_addAfter (AHTLoadTerminate_handler, NULL, NULL, HT_ALL, HT_FILTER_LAST);
1.111 cvs 1827: #endif /* !_WINDOWS */
1.116 cvs 1828: /**** for later ?? ****/
1829: /* HTNet_addAfter(HTInfoFilter, NULL, NULL, HT_ALL, HT_FILTER_LATE); */
1.245 kahan 1830: /* @@ JK: Filters for doing ftp authentication */
1831: HTNet_addAfter (HTAuthFilter, "ftp://*", NULL, HT_NO_ACCESS, HT_FILTER_MIDDLE);
1832: HTNet_addAfter (HTAuthFilter, "ftp://*", NULL, HT_REAUTH, HT_FILTER_MIDDLE);
1.51 cvs 1833: /* handles all errors */
1.116 cvs 1834: HTNet_addAfter (terminate_handler, NULL, NULL, HT_ALL, HT_FILTER_LAST);
1.4 cvs 1835: }
1836:
1.15 cvs 1837: /*----------------------------------------------------------------------
1.17 cvs 1838: AHTAlertInit
1839: Register alert messages and their callbacks.
1.15 cvs 1840: ----------------------------------------------------------------------*/
1841: static void AHTAlertInit (void)
1842: {
1843: HTAlert_add (AHTProgress, HT_A_PROGRESS);
1.120 cvs 1844: #ifdef __WINDOWS
1.70 cvs 1845: HTAlert_add ((HTAlertCallback *) WIN_Activate_Request, HT_PROG_CONNECT);
1.116 cvs 1846: #endif /* _WINDOWS */
1.15 cvs 1847: HTAlert_add (AHTError_print, HT_A_MESSAGE);
1.48 cvs 1848: HTError_setShow (~((unsigned int) 0 ) & ~((unsigned int) HT_ERR_SHOW_DEBUG)); /* process all messages except debug ones*/
1.15 cvs 1849: HTAlert_add (AHTConfirm, HT_A_CONFIRM);
1850: HTAlert_add (AHTPrompt, HT_A_PROMPT);
1851: HTAlert_add (AHTPromptUsernameAndPassword, HT_A_USER_PW);
1.116 cvs 1852: }
1853:
1.118 cvs 1854: #ifdef AMAYA_WWW_CACHE
1855: /*----------------------------------------------------------------------
1.128 cvs 1856: RecCleanCache
1.118 cvs 1857: Clears an existing cache directory
1858: ----------------------------------------------------------------------*/
1.265 cvs 1859: static void RecCleanCache (char *dirname)
1860: {
1.128 cvs 1861: #ifdef _WINDOWS
1.223 cvs 1862: HANDLE hFindFile;
1863: ThotBool status;
1.128 cvs 1864: WIN32_FIND_DATA ffd;
1.290 vatton 1865: char t_dir [MAX_LENGTH];
1866: char *ptr;
1.128 cvs 1867:
1.130 cvs 1868: /* create a t_dir name to start searching for files */
1.265 cvs 1869: if ((strlen (dirname) + 10) > MAX_LENGTH)
1.128 cvs 1870: /* ERROR: directory name is too big */
1871: return;
1872:
1.265 cvs 1873: strcpy (t_dir, dirname);
1.130 cvs 1874: /* save the end of the dirname. We'll use it to make
1875: a complete pathname when erasing files */
1.265 cvs 1876: ptr = &t_dir[strlen (t_dir)];
1877: strcat (t_dir, "*");
1.128 cvs 1878:
1.130 cvs 1879: hFindFile = FindFirstFile (t_dir, &ffd);
1.128 cvs 1880:
1881: if (hFindFile == INVALID_HANDLE_VALUE)
1882: /* nothing to erase? */
1883: return;
1884:
1885: status = TRUE;
1.130 cvs 1886: while (status)
1887: {
1888: if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
1.133 cvs 1889: {
1890: /* it's a directory, erase it recursively */
1.265 cvs 1891: if (strcmp (ffd.cFileName, "..") && strcmp (ffd.cFileName, "."))
1.133 cvs 1892: {
1.265 cvs 1893: strcpy (ptr, ffd.cFileName);
1.272 cvs 1894: strcat (ptr, DIR_STR);
1.133 cvs 1895: RecCleanCache (t_dir);
1.274 cvs 1896: rmdir (t_dir);
1.133 cvs 1897: }
1898: }
1899: else
1.130 cvs 1900: {
1.133 cvs 1901: /* it's a file, erase it */
1.265 cvs 1902: strcpy (ptr, ffd.cFileName);
1.133 cvs 1903: TtaFileUnlink (t_dir);
1.130 cvs 1904: }
1905: status = FindNextFile (hFindFile, &ffd);
1906: }
1.128 cvs 1907: FindClose (hFindFile);
1908:
1909: #else /* _WINDOWS */
1.118 cvs 1910: DIR *dp;
1911: struct stat st;
1912: #ifdef HAVE_DIRENT_H
1913: struct dirent *d;
1914: #else
1915: struct direct *d;
1916: #endif /* HAVE_DIRENT_H */
1.128 cvs 1917: char filename[BUFSIZ+1];
1.118 cvs 1918:
1919: if ((dp = opendir (dirname)) == NULL)
1920: {
1921: /* @@@ we couldn't open the directory ... we need some msg */
1922: perror (dirname);
1.176 cvs 1923: return;
1.118 cvs 1924: }
1925:
1926: while ((d = readdir (dp)) != NULL)
1927: {
1928: /* skip the UNIX . and .. links */
1929: if (!strcmp (d->d_name, "..")
1930: || !strcmp (d->d_name, "."))
1931: continue;
1932:
1.188 cvs 1933: sprintf (filename, "%s%c%s", dirname, DIR_SEP, d->d_name);
1.118 cvs 1934: if (lstat (filename, &st) < 0 )
1935: {
1936: /* @@2 need some error message */
1937: perror (filename);
1938: continue;
1939: }
1940:
1941: switch (st.st_mode & S_IFMT)
1942: {
1943: case S_IFDIR:
1944: /* if we find a directory, we erase it, recursively */
1.128 cvs 1945: strcat (filename, DIR_STR);
1946: RecCleanCache (filename);
1947: rmdir (filename);
1.118 cvs 1948: break;
1949: case S_IFLNK:
1950: /* skip any links we find */
1951: continue;
1952: break;
1953: default:
1954: /* erase the filename */
1955: TtaFileUnlink (filename);
1956: break;
1957: }
1958: }
1959: closedir (dp);
1.265 cvs 1960: #endif /* _WINDOWS */
1.118 cvs 1961: }
1962: #endif /* AMAYA_WWW_CACHE */
1963:
1.116 cvs 1964: /*----------------------------------------------------------------------
1.265 cvs 1965: libwww_CleanCache
1966: frontend to the recursive cache cleaning function
1967: ----------------------------------------------------------------------*/
1968: void libwww_CleanCache (void)
1969: {
1970: #ifdef AMAYA_WWW_CACHE
1971: char * real_dir;
1972: char* cache_dir;
1973: char* tmp;
1974: int cache_size;
1975: int cache_expire;
1976: int cache_disconnect;
1977: ThotBool error;
1978: char * ptr;
1979:
1980: if (!HTCacheMode_enabled ())
1981: /* don't do anything if we're not using a cache */
1982: return;
1983: /* temporarily close down the cache, purge it, then restart */
1984: tmp = HTCacheMode_getRoot ();
1985: /* don't do anything if we don't have a valid cache dir */
1986: if (!tmp || *tmp == EOS)
1987: return;
1988: cache_dir = TtaStrdup (tmp);
1989: HT_FREE (tmp);
1990: cache_size = HTCacheMode_maxSize ();
1991: cache_expire = HTCacheMode_expires ();
1992: cache_disconnect = HTCacheMode_disconnected ();
1993:
1994: /* get something we can work on :) */
1995: tmp = HTWWWToLocal (cache_dir, "file:", NULL);
1996: real_dir = TtaGetMemory (strlen (tmp) + 20);
1.273 cvs 1997: strcpy (real_dir, tmp);
1.265 cvs 1998: HT_FREE (tmp);
1999:
2000: /* safeguard... abort the operation if cache_dir doesn't end with
2001: CACHE_DIR_NAME */
2002: error = TRUE;
2003: ptr = strstr (real_dir, CACHE_DIR_NAME);
2004: if (ptr && *ptr && !strcasecmp (ptr, CACHE_DIR_NAME))
2005: error = FALSE;
2006: if (error)
2007: return;
2008:
2009: /* remove the concurrent cache lock */
2010: #ifdef DEBUG_LIBWWW
2011: fprintf (stderr, "Clearing the cache lock\n");
2012: #endif /* DEBUG_LIBWWW */
2013: clear_cachelock ();
2014: HTCacheTerminate ();
2015: HTCacheMode_setEnabled (FALSE);
2016:
2017: RecCleanCache (real_dir);
2018:
2019: HTCacheMode_setExpires (cache_expire);
2020: HTCacheMode_setDisconnected (cache_disconnect);
2021: HTCacheInit (cache_dir, cache_size);
2022: /* set a new concurrent cache lock */
2023: strcat (real_dir, ".lock");
2024: if (set_cachelock (real_dir) == -1)
2025: /* couldn't open the .lock file, so, we close the cache to
2026: be in the safe side */
2027: {
2028: #ifdef DEBUG_LIBWWW
2029: fprintf (stderr, "couldnt set the cache lock\n");
2030: #endif /* DEBUG_LIBWWW */
2031: HTCacheTerminate ();
2032: HTCacheMode_setEnabled (FALSE);
2033: }
2034: #ifdef DEBUG_LIBWWW
2035: fprintf (stderr, "set a cache lock\n");
2036: #endif /* DEBUG_LIBWWW */
2037: TtaFreeMemory (real_dir);
2038: TtaFreeMemory (cache_dir);
2039: #endif /* AMAYA_WWW_CACHE */
2040: }
2041:
2042: /*----------------------------------------------------------------------
1.116 cvs 2043: CacheInit
2044: Reads the cache settings from the thot.ini file.
2045: ----------------------------------------------------------------------*/
2046: static void CacheInit (void)
2047: {
2048: #ifndef AMAYA_WWW_CACHE
2049: HTCacheMode_setEnabled (NO);
2050:
2051: #else /* AMAYA_WWW_CACHE */
1.265 cvs 2052: char *strptr;
2053: char *real_dir = NULL;
2054: char *cache_lockfile;
2055: char *cache_dir = NULL;
1.223 cvs 2056: int cache_size;
2057: int cache_entry_size;
2058: ThotBool cache_enabled;
2059: ThotBool cache_locked;
2060: ThotBool tmp_bool;
1.130 cvs 2061:
1.185 cvs 2062: int i;
2063:
1.116 cvs 2064: /* activate cache? */
1.203 cvs 2065: strptr = TtaGetEnvString ("ENABLE_CACHE");
1.265 cvs 2066: if (strptr && *strptr && strcasecmp (strptr, "yes"))
1.130 cvs 2067: cache_enabled = NO;
1.116 cvs 2068: else
1.130 cvs 2069: cache_enabled = YES;
1.116 cvs 2070:
1.151 cvs 2071: /* cache protected documents? */
1.203 cvs 2072: strptr = TtaGetEnvString ("CACHE_PROTECTED_DOCS");
1.265 cvs 2073: if (strptr && *strptr && !strcasecmp (strptr, "yes"))
1.151 cvs 2074: HTCacheMode_setProtected (YES);
2075: else
2076: HTCacheMode_setProtected (NO);
2077:
1.116 cvs 2078: /* get the cache dir (or use a default one) */
1.203 cvs 2079: strptr = TtaGetEnvString ("CACHE_DIR");
1.116 cvs 2080: if (strptr && *strptr)
2081: {
1.265 cvs 2082: real_dir = TtaGetMemory (strlen (strptr) + strlen (CACHE_DIR_NAME) + 20);
2083: strcpy (real_dir, strptr);
1.272 cvs 2084: if (*(real_dir + strlen (real_dir) - 1) != DIR_SEP)
2085: strcat (real_dir, DIR_STR);
1.116 cvs 2086: }
2087: else
2088: {
1.265 cvs 2089: real_dir = TtaGetMemory (strlen (TempFileDirectory) + strlen (CACHE_DIR_NAME) + 20);
1.272 cvs 2090: sprintf (real_dir, "%s%s", TempFileDirectory, CACHE_DIR_NAME);
1.185 cvs 2091: }
2092:
2093: /* compatiblity with previous versions of Amaya: does real_dir
2094: include CACHE_DIR_NAME? If not, add it */
1.265 cvs 2095: strptr = strstr (real_dir, CACHE_DIR_NAME);
1.185 cvs 2096: if (!strptr)
1.265 cvs 2097: strcat (real_dir, CACHE_DIR_NAME);
1.185 cvs 2098: else
2099: {
1.265 cvs 2100: i = strlen (CACHE_DIR_NAME);
1.272 cvs 2101: if (strptr[i] != EOS)
1.265 cvs 2102: strcat (real_dir, CACHE_DIR_NAME);
1.116 cvs 2103: }
1.185 cvs 2104:
1.211 cvs 2105: /* convert the local cache dir into a file URL, as expected by
2106: libwww */
1.265 cvs 2107: cache_dir = HTLocalToWWW (real_dir, "file:");
1.116 cvs 2108: /* get the cache size (or use a default one) */
1.203 cvs 2109: strptr = TtaGetEnvString ("CACHE_SIZE");
1.116 cvs 2110: if (strptr && *strptr)
1.288 vatton 2111: cache_size = atoi (strptr);
1.116 cvs 2112: else
2113: cache_size = DEFAULT_CACHE_SIZE;
1.176 cvs 2114: /* get the max cached file size (or use a default one) */
1.223 cvs 2115: if (!TtaGetEnvInt ("MAX_CACHE_ENTRY_SIZE", &cache_entry_size))
1.176 cvs 2116: cache_entry_size = DEFAULT_MAX_CACHE_ENTRY_SIZE;
1.130 cvs 2117: if (cache_enabled)
1.116 cvs 2118: {
2119: /* how to remove the lock? force remove it? */
1.265 cvs 2120: cache_lockfile = TtaGetMemory (strlen (real_dir) + 20);
2121: strcpy (cache_lockfile, real_dir);
2122: strcat (cache_lockfile, ".lock");
1.130 cvs 2123: cache_locked = FALSE;
1.223 cvs 2124: if (TtaFileExist (cache_lockfile) && !(cache_locked = test_cachelock (cache_lockfile)))
1.116 cvs 2125: {
1.130 cvs 2126: #ifdef DEBUG_LIBWWW
2127: fprintf (stderr, "found a stale cache, removing it\n");
2128: #endif /* DEBUG_LIBWWW */
2129: /* remove the lock and clean the cache (the clean cache
2130: will remove all, making the following call unnecessary */
2131: /* little trick to win some memory */
1.265 cvs 2132: strptr = strrchr (cache_lockfile, '.');
1.272 cvs 2133: *strptr = EOS;
1.130 cvs 2134: RecCleanCache (cache_lockfile);
1.265 cvs 2135: *strptr = '.';
1.116 cvs 2136: }
2137:
1.130 cvs 2138: if (!cache_locked)
2139: {
2140: /* initialize the cache if there's no other amaya
2141: instance running */
1.177 cvs 2142: HTCacheMode_setMaxCacheEntrySize (cache_entry_size);
1.223 cvs 2143: if (TtaGetEnvBoolean ("CACHE_EXPIRE_IGNORE", &tmp_bool) && tmp_bool)
1.177 cvs 2144: HTCacheMode_setExpires (HT_EXPIRES_IGNORE);
2145: else
2146: HTCacheMode_setExpires (HT_EXPIRES_AUTO);
1.223 cvs 2147: TtaGetEnvBoolean ("CACHE_DISCONNECTED_MODE", &tmp_bool);
1.177 cvs 2148: if (tmp_bool)
2149: HTCacheMode_setDisconnected (HT_DISCONNECT_NORMAL);
2150: else
2151: HTCacheMode_setDisconnected (HT_DISCONNECT_NONE);
1.211 cvs 2152: if (HTCacheInit (cache_dir, cache_size))
1.130 cvs 2153: {
1.188 cvs 2154: if (set_cachelock (cache_lockfile) == -1)
2155: /* couldn't open the .lock file, so, we close the cache to
2156: be in the safe side */
2157: {
2158: HTCacheTerminate ();
2159: HTCacheMode_setEnabled (FALSE);
2160: #ifdef DEBUG_LIBWWW
2161: fprintf (stderr, "couldnt set the cache lock\n");
2162: #endif /* DEBUG_LIBWWW */
2163: }
1.130 cvs 2164: #ifdef DEBUG_LIBWWW
1.188 cvs 2165: else
2166: fprintf (stderr, "created the cache lock\n");
1.130 cvs 2167: #endif /* DEBUG_LIBWWW */
2168: }
1.188 cvs 2169: else
2170: {
1.130 cvs 2171: #ifdef DEBUG_LIBWWW
1.188 cvs 2172: fprintf (stderr, "couldn't create the cache\n");
2173: #endif /* DEBUG_LIBWWW */
2174: HTCacheTerminate ();
2175: }
1.130 cvs 2176: }
2177: else
2178: {
1.185 cvs 2179: HTCacheMode_setEnabled (FALSE);
1.130 cvs 2180: #ifdef DEBUG_LIBWWW
2181: fprintf (stderr, "lock detected, starting libwww without a cache/n");
2182: #endif /* DEBUG_LIBWWW */
2183: }
2184: TtaFreeMemory (cache_lockfile);
1.116 cvs 2185: }
2186: else
1.185 cvs 2187: {
2188: HTCacheMode_setEnabled (FALSE);
2189: }
1.116 cvs 2190: if (cache_dir)
1.211 cvs 2191: HT_FREE (cache_dir);
1.189 cvs 2192: if (real_dir)
2193: TtaFreeMemory (real_dir);
1.185 cvs 2194: /* warn the user if the cache isn't active */
2195: if (cache_enabled && !HTCacheMode_enabled ())
1.291 kahan 2196: {
2197: ThotBool warn_user;
2198:
2199: TtaGetEnvBoolean ("WARN_NO_CACHE", &warn_user);
2200: if (warn_user)
2201: InitInfo ("Cache", TtaGetMessage (AMAYA, AM_CANT_CREATE_CACHE));
2202: }
1.116 cvs 2203: #endif /* AMAYA_WWW_CACHE */
1.15 cvs 2204: }
2205:
2206: /*----------------------------------------------------------------------
1.97 cvs 2207: ProxyInit
2208: Reads any proxies settings which may be declared as environmental
2209: variables or in the thot.ini file. The former overrides the latter.
2210: ----------------------------------------------------------------------*/
2211: static void ProxyInit (void)
2212: {
1.265 cvs 2213: char *strptr;
2214: char *name;
2215: char *tmp = NULL;
2216: char *strptrA;
1.223 cvs 2217: ThotBool proxy_is_onlyproxy;
1.97 cvs 2218:
2219: /* get the proxy settings from the thot.ini file */
1.203 cvs 2220: strptr = TtaGetEnvString ("HTTP_PROXY");
1.228 cvs 2221: if (strptr && *strptr)
2222: {
1.265 cvs 2223: tmp = (char *) TtaGetMemory (strlen (strptr) + 1);
2224: strcpy (tmp, strptr);
1.223 cvs 2225:
1.228 cvs 2226: /* does the proxy env string has an "http://" prefix? */
1.265 cvs 2227: if (!strncasecmp (strptr, "http://", 7))
1.223 cvs 2228: HTProxy_add ("http", tmp);
1.228 cvs 2229: else
2230: {
1.265 cvs 2231: strptrA = (char *) TtaGetMemory (strlen (strptr) + 9);
1.228 cvs 2232: strcpy (strptrA, "http://");
2233: strcat (strptrA, tmp);
2234: HTProxy_add ("http", strptrA);
2235: TtaFreeMemory (strptrA);
2236: }
2237: TtaFreeMemory (tmp);
2238: }
1.216 cvs 2239:
1.97 cvs 2240: /* get the no_proxy settings from the thot.ini file */
1.212 cvs 2241: strptr = TtaGetEnvString ("PROXYDOMAIN");
1.228 cvs 2242: if (strptr && *strptr)
2243: {
1.265 cvs 2244: strptrA = (char *) TtaGetMemory (strlen (strptr) + 1);
2245: tmp = strptrA;
2246: strcpy (tmp, strptr);
1.228 cvs 2247: /* as HTNextField changes the ptr we pass as an argument, we'll
1.265 cvs 2248: work with another variable, so that we can free the tmp
1.228 cvs 2249: block later on */
2250: while ((name = HTNextField (&tmp)) != NULL)
2251: {
2252: char* portstr = strchr (name, ':');
2253: unsigned port=0;
1.265 cvs 2254: if (portstr)
2255: {
2256: *portstr++ = EOS;
2257: if (*portstr)
2258: port = (unsigned) atoi (portstr);
2259: }
1.228 cvs 2260: /* Register it for all access methods */
2261: HTNoProxy_add (name, NULL, port);
2262: }
2263: TtaFreeMemory (strptrA);
2264: }
2265:
1.212 cvs 2266: /* how should we interpret the proxy domain list? */
1.291 kahan 2267:
1.212 cvs 2268: TtaGetEnvBoolean ("PROXYDOMAIN_IS_ONLYPROXY", &proxy_is_onlyproxy);
2269: HTProxy_setNoProxyIsOnlyProxy (proxy_is_onlyproxy);
2270:
2271: /* use libwww's routine to get all proxy settings from the environment */
1.97 cvs 2272: HTProxy_getEnvVar ();
2273: }
2274:
1.207 cvs 2275: /*----------------------------------------------------------------------
1.17 cvs 2276: AHTProfile_newAmaya
2277: creates the Amaya client profile for libwww.
1.15 cvs 2278: ----------------------------------------------------------------------*/
1.265 cvs 2279: static void AHTProfile_newAmaya (char *AppName, char *AppVersion)
1.4 cvs 2280: {
1.265 cvs 2281: char *strptr;
1.158 cvs 2282:
1.4 cvs 2283: /* If the Library is not already initialized then do it */
1.257 kahan 2284: if (!HTLib_isInitialized ())
1.273 cvs 2285: HTLibInit (AppName, AppVersion);
1.4 cvs 2286:
2287: if (!converters)
2288: converters = HTList_new ();
1.27 cvs 2289: if (!acceptTypes)
2290: acceptTypes = HTList_new ();
1.193 cvs 2291: if (!acceptLanguages)
2292: acceptLanguages = HTList_new ();
1.151 cvs 2293: if (!transfer_encodings)
2294: transfer_encodings = HTList_new ();
2295: if (!content_encodings)
2296: content_encodings = HTList_new ();
1.4 cvs 2297:
1.169 cvs 2298: /* inhibits libwww's automatic file_suffix_binding */
2299: HTFile_doFileSuffixBinding (FALSE);
2300:
1.4 cvs 2301: /* Register the default set of transport protocols */
2302: HTTransportInit ();
2303:
2304: /* Register the default set of application protocol modules */
2305: AHTProtocolInit ();
2306:
1.116 cvs 2307: /* Register the default set of messages and dialog functions */
2308: AHTAlertInit ();
2309: HTAlert_setInteractive (YES);
2310:
2311: #ifdef AMAYA_WWW_CACHE
2312: /* Enable the persistent cache */
2313: CacheInit ();
2314: #else
2315: HTCacheMode_setEnabled (NO);
2316: #endif /* AMAYA_WWW_CACHE */
1.4 cvs 2317:
2318: /* Register the default set of BEFORE and AFTER filters */
2319: AHTNetInit ();
2320:
2321: /* Set up the default set of Authentication schemes */
1.223 cvs 2322: HTAA_newModule ("basic", HTBasic_generate, HTBasic_parse, NULL, HTBasic_delete);
1.158 cvs 2323: /* activate MDA by defaul */
1.203 cvs 2324: strptr = TtaGetEnvString ("ENABLE_MDA");
1.265 cvs 2325: if (!strptr || (strptr && *strptr && strcasecmp (strptr, "no")))
1.223 cvs 2326: HTAA_newModule ("digest", HTDigest_generate, HTDigest_parse, HTDigest_updateInfo, HTDigest_delete);
1.257 kahan 2327:
1.97 cvs 2328: /* Get any proxy settings */
2329: ProxyInit ();
1.4 cvs 2330:
1.207 cvs 2331: /* Set up the domains where we accept a redirect on PUT */
2332: SafePut_init ();
2333:
1.4 cvs 2334: /* Register the default set of converters */
2335: AHTConverterInit (converters);
1.151 cvs 2336: HTFormat_setConversion (converters);
1.27 cvs 2337: AHTAcceptTypesInit (acceptTypes);
1.193 cvs 2338: AHTAcceptLanguagesInit (acceptLanguages);
1.4 cvs 2339:
2340: /* Register the default set of transfer encoders and decoders */
1.151 cvs 2341: HTTransferEncoderInit (transfer_encodings);
1.190 cvs 2342: HTFormat_setTransferCoding (transfer_encodings);
2343: /* Register the default set of content encoders and decoders */
1.296 kahan 2344: /* commented because we don't know yet how to handle deflate in the content enconding */
2345: /* HTContentEncoderInit (content_encodings); */
2346: HTCoding_add (content_encodings, "gzip", NULL, HTIdentityCoding, 1.0);
1.190 cvs 2347: /* ignore all other encoding formats (or libwww will send them
1.181 cvs 2348: thru a blackhole otherwise */
2349: HTCoding_add (content_encodings, "*", NULL, HTIdentityCoding, 1.0);
1.151 cvs 2350: if (HTList_count(content_encodings) > 0)
2351: HTFormat_setContentCoding(content_encodings);
2352: else
2353: {
2354: HTList_delete(content_encodings);
2355: content_encodings = NULL;
2356: }
1.4 cvs 2357:
2358: /* Register the default set of MIME header parsers */
1.74 cvs 2359: HTMIMEInit (); /* must be called again for language selector */
1.4 cvs 2360:
2361: /* Register the default set of Icons for directory listings */
1.27 cvs 2362: /*HTIconInit(NULL); *//* experimental */
1.4 cvs 2363: }
2364:
1.5 cvs 2365: /*----------------------------------------------------------------------
1.17 cvs 2366: AHTProfile_delete
2367: deletes the Amaya client profile.
1.5 cvs 2368: ----------------------------------------------------------------------*/
1.4 cvs 2369: static void AHTProfile_delete (void)
2370: {
1.22 cvs 2371: /* free the Amaya global context */
1.151 cvs 2372: /* Clean up all the registred converters */
2373: HTFormat_deleteAll ();
2374: if (acceptTypes)
1.74 cvs 2375: HTConversion_deleteAll (acceptTypes);
1.193 cvs 2376: if (acceptLanguages)
2377: HTLanguage_deleteAll (acceptLanguages);
1.151 cvs 2378:
1.209 cvs 2379: StopAllRequests (1);
1.74 cvs 2380: HTList_delete (Amaya->docid_status);
2381: HTList_delete (Amaya->reqlist);
2382: TtaFreeMemory (Amaya);
1.61 cvs 2383:
1.120 cvs 2384: #ifdef _WINDOWS
1.209 cvs 2385: if (HTLib_isInitialized ())
1.151 cvs 2386: HTEventTerminate ();
1.198 cvs 2387: #endif /* _WINDOWS; */
1.74 cvs 2388:
1.151 cvs 2389: /* Clean up the persistent cache (if any) */
1.116 cvs 2390: #ifdef AMAYA_WWW_CACHE
1.151 cvs 2391: clear_cachelock ();
2392: HTCacheTerminate ();
1.116 cvs 2393: #endif /* AMAYA_WWW_CACHE */
1.217 cvs 2394:
1.218 cvs 2395: /* call remove functions that are not called automatically by libwww */
2396: HTNetCall_deleteBeforeAll (HTNet_before ());
2397: HTNetCall_deleteAfterAll (HTNet_after ());
2398: HTAA_deleteAllModules ();
2399: HTAlertCall_deleteAll (HTAlert_global () );
2400: HTAlert_setGlobal ((HTList *) NULL);
1.259 cvs 2401: HTTimer_deleteAll ();
1.249 kahan 2402: HTEventList_unregisterAll ();
1.218 cvs 2403: /* these two functions are broken, so we can't call them right now
2404: HTHeader_deleteAll ();
2405: HTTimer_deleteAll ();
2406: */
2407: HTTransport_deleteAll ();
1.217 cvs 2408: /* remove bindings between suffixes, media types*/
2409: HTBind_deleteAll ();
1.151 cvs 2410: /* Terminate libwww */
2411: HTLibTerminate ();
1.4 cvs 2412: }
2413:
1.5 cvs 2414: /*----------------------------------------------------------------------
1.116 cvs 2415: AmayacontextInit
2416: initializes an internal Amaya context for our libwww interface
2417: ----------------------------------------------------------------------*/
1.265 cvs 2418: static void AmayaContextInit ()
1.116 cvs 2419: {
1.140 cvs 2420: AmayaAlive_flag = TRUE;
1.116 cvs 2421: /* Initialization of the global context */
2422: Amaya = (AmayaContext *) TtaGetMemory (sizeof (AmayaContext));
2423: Amaya->reqlist = HTList_new ();
2424: Amaya->docid_status = HTList_new ();
2425: Amaya->open_requests = 0;
2426: }
2427:
2428: /*----------------------------------------------------------------------
1.17 cvs 2429: QueryInit
2430: initializes the libwww interface
1.5 cvs 2431: ----------------------------------------------------------------------*/
1.265 cvs 2432: void QueryInit ()
1.4 cvs 2433: {
1.265 cvs 2434: char *strptr;
2435: int tmp_i;
2436: long tmp_l;
1.4 cvs 2437:
1.116 cvs 2438: AmayaContextInit ();
1.4 cvs 2439: AHTProfile_newAmaya (HTAppName, HTAppVersion);
1.140 cvs 2440: CanDoStop_set (TRUE);
1.214 cvs 2441: UserAborted_flag = FALSE;
1.4 cvs 2442:
1.116 cvs 2443: #ifdef _WINDOWS
1.125 cvs 2444: HTEventInit ();
1.116 cvs 2445: #endif /* _WINDOWS */
1.72 cvs 2446:
1.123 cvs 2447: #ifndef _WINDOWS
1.116 cvs 2448: HTEvent_setRegisterCallback ((void *) AHTEvent_register);
2449: HTEvent_setUnregisterCallback ((void *) AHTEvent_unregister);
1.120 cvs 2450: HTTimer_registerSetTimerCallback ((void *) AMAYA_SetTimer);
2451: HTTimer_registerDeleteTimerCallback ((void *) AMAYA_DeleteTimer);
1.116 cvs 2452: #endif /* !_WINDOWS */
1.190 cvs 2453:
1.213 cvs 2454: #ifdef HTDEBUG
1.247 kahan 2455: /* an undocumented option for being able to generate an HTTP protocol
2456: trace. The flag can take values from 1-10, which are interpreted as
2457: different kinds of debug traces. Value 99 means a complete trace.
2458: 0 or other values means No Debug.1 No Debug (default), up to Full debug, respectively. */
1.238 cvs 2459: if (TtaGetEnvInt ("ENABLE_LIBWWW_DEBUG", &tmp_i))
1.247 kahan 2460: {
2461: switch (tmp_i)
2462: {
2463: case 1:
2464: WWW_TraceFlag = SHOW_URI_TRACE;
2465: break;
2466: case 2:
2467: WWW_TraceFlag = SHOW_BIND_TRACE;
2468: break;
2469: case 3:
2470: WWW_TraceFlag = SHOW_THREAD_TRACE;
2471: break;
2472: case 4:
2473: WWW_TraceFlag = SHOW_STREAM_TRACE;
2474: break;
2475: case 5:
2476: WWW_TraceFlag = SHOW_PROTOCOL_TRACE;
2477: break;
2478: case 6:
2479: WWW_TraceFlag = SHOW_MEM_TRACE;
2480: break;
2481: case 7:
2482: WWW_TraceFlag = SHOW_URI_TRACE;
2483: break;
2484: case 8:
2485: WWW_TraceFlag = SHOW_AUTH_TRACE;
2486: break;
2487: case 9:
2488: WWW_TraceFlag = SHOW_ANCHOR_TRACE;
2489: break;
2490: case 10 :
2491: WWW_TraceFlag = SHOW_CORE_TRACE;
2492: break;
1.251 kahan 2493: case 11 :
2494: WWW_TraceFlag = SHOW_CORE_TRACE | SHOW_ANCHOR_TRACE | SHOW_AUTH_TRACE | SHOW_URI_TRACE | SHOW_THREAD_TRACE | SHOW_STREAM_TRACE;
2495: break;
1.247 kahan 2496: case 99 :
2497: WWW_TraceFlag = SHOW_ALL_TRACE;
2498: break;
2499: default:
2500: WWW_TraceFlag = 0;
2501: break;
2502: }
1.248 kahan 2503: if (WWW_TraceFlag)
2504: {
2505: /* Trace activation (for debugging) */
1.265 cvs 2506: char *s, *tmp;
1.248 kahan 2507: s = TtaGetEnvString ("APP_TMPDIR");
1.265 cvs 2508: tmp = TtaGetMemory (strlen (s) + sizeof ("/libwww.log") + 1);
2509: strcpy (tmp, s);
2510: strcat (tmp, "/libwww.log");
2511: trace_fp = fopen (tmp, "ab");
1.248 kahan 2512: TtaFreeMemory (tmp);
2513: if (trace_fp)
2514: HTTrace_setCallback(LineTrace);
2515: }
1.247 kahan 2516: }
1.208 cvs 2517: else
2518: WWW_TraceFlag = 0;
1.213 cvs 2519: #endif /* HTDEBUG */
1.208 cvs 2520:
1.74 cvs 2521: #ifdef DEBUG_LIBWWW
1.116 cvs 2522: /* forwards error messages to our own function */
2523: WWW_TraceFlag = THD_TRACE;
1.138 cvs 2524: HTTrace_setCallback(LineTrace);
1.248 kahan 2525:
1.148 cvs 2526: /***
1.138 cvs 2527: WWW_TraceFlag = SHOW_CORE_TRACE | SHOW_THREAD_TRACE | SHOW_PROTOCOL_TRACE;
2528: ***/
1.152 cvs 2529: #endif
1.247 kahan 2530:
2531: TtaGetEnvBoolean ("ENABLE_FTP", &FTPURL_flag);
1.152 cvs 2532:
1.148 cvs 2533: /* Setting up different network parameters */
1.151 cvs 2534:
1.148 cvs 2535: /* Maximum number of simultaneous open sockets */
1.203 cvs 2536: strptr = TtaGetEnvString ("MAX_SOCKET");
1.151 cvs 2537: if (strptr && *strptr)
1.288 vatton 2538: tmp_i = atoi (strptr);
1.151 cvs 2539: else
2540: tmp_i = DEFAULT_MAX_SOCKET;
2541: HTNet_setMaxSocket (tmp_i);
2542:
1.148 cvs 2543: /* different network services timeouts */
1.151 cvs 2544: /* dns timeout */
1.203 cvs 2545: strptr = TtaGetEnvString ("DNS_TIMEOUT");
1.151 cvs 2546: if (strptr && *strptr)
1.288 vatton 2547: tmp_i = atoi (strptr);
1.151 cvs 2548: else
2549: tmp_i = DEFAULT_DNS_TIMEOUT;
2550: HTDNS_setTimeout (tmp_i);
2551:
2552: /* persistent connections timeout */
1.203 cvs 2553: strptr = TtaGetEnvString ("PERSIST_CX_TIMEOUT");
1.151 cvs 2554: if (strptr && *strptr)
1.288 vatton 2555: tmp_l = atol (strptr);
1.151 cvs 2556: else
2557: tmp_l = DEFAULT_PERSIST_TIMEOUT;
2558: HTHost_setPersistTimeout (tmp_l);
2559:
1.148 cvs 2560: /* default timeout in ms */
1.203 cvs 2561: strptr = TtaGetEnvString ("NET_EVENT_TIMEOUT");
1.151 cvs 2562: if (strptr && *strptr)
1.288 vatton 2563: tmp_i = atoi (strptr);
1.151 cvs 2564: else
2565: tmp_i = DEFAULT_NET_EVENT_TIMEOUT;
2566: HTHost_setEventTimeout (tmp_i);
2567:
1.173 cvs 2568: HTRequest_setMaxRetry (8);
1.4 cvs 2569: #ifdef CATCH_SIG
1.148 cvs 2570: signal (SIGPIPE, SIG_IGN);
1.4 cvs 2571: #endif
1.15 cvs 2572: }
2573:
2574: /*----------------------------------------------------------------------
1.17 cvs 2575: LoopForStop
1.136 cvs 2576: a copy of the Thop event loop so we can handle the stop button in Unix
2577: and preemptive requests under Windows
1.15 cvs 2578: ----------------------------------------------------------------------*/
2579: static int LoopForStop (AHTReqContext * me)
2580: {
1.136 cvs 2581: #ifdef _WINDOWS
2582: MSG msg;
2583: unsigned long libwww_msg;
2584: HWND old_active_window, libwww_window;
2585: int status_req = HT_OK;
2586:
2587: old_active_window = GetActiveWindow ();
2588: libwww_window = HTEventList_getWinHandle (&libwww_msg);
1.137 cvs 2589:
1.149 cvs 2590: while (me->reqStatus != HT_END && me->reqStatus != HT_ERR
1.253 cvs 2591: && me->reqStatus != HT_ABORT && AmayaIsAlive () &&
2592: GetMessage (&msg, NULL, 0, 0))
2593: {
2594: if (msg.message != WM_QUIT)
2595: TtaHandleOneEvent (&msg);
2596: else
2597: break;
2598: }
1.136 cvs 2599: if (!AmayaIsAlive ())
2600: /* Amaya was killed by one of the callback handlers */
2601: exit (0);
2602: #else /* _WINDOWS */
1.277 kahan 2603: ThotEvent ev;
1.17 cvs 2604: int status_req = HT_OK;
1.15 cvs 2605:
2606: /* to test the async calls */
1.17 cvs 2607: /* Loop while waiting for new events, exists when the request is over */
1.15 cvs 2608: while (me->reqStatus != HT_ABORT &&
2609: me->reqStatus != HT_END &&
1.69 cvs 2610: me->reqStatus != HT_ERR) {
1.116 cvs 2611: if (!AmayaIsAlive ())
1.69 cvs 2612: /* Amaya was killed by one of the callback handlers */
2613: exit (0);
1.277 kahan 2614:
2615: if (TtaFetchOneAvailableEvent (&ev))
2616: TtaHandleOneEvent (&ev);
1.69 cvs 2617: }
1.136 cvs 2618: #endif /* _WINDOWS */
1.69 cvs 2619: switch (me->reqStatus) {
2620: case HT_ERR:
2621: case HT_ABORT:
1.130 cvs 2622: status_req = NO;
1.15 cvs 2623: break;
2624:
1.69 cvs 2625: case HT_END:
1.130 cvs 2626: status_req = YES;
1.15 cvs 2627: break;
2628:
1.69 cvs 2629: default:
1.15 cvs 2630: break;
1.69 cvs 2631: }
1.15 cvs 2632: return (status_req);
1.4 cvs 2633: }
2634:
1.5 cvs 2635: /*----------------------------------------------------------------------
1.15 cvs 2636: QueryClose
1.21 cvs 2637: closes all existing threads, frees all non-automatically deallocated
2638: memory and then ends libwww.
1.5 cvs 2639: ----------------------------------------------------------------------*/
1.116 cvs 2640: void QueryClose ()
1.4 cvs 2641: {
1.24 cvs 2642:
1.140 cvs 2643: AmayaAlive_flag = FALSE;
1.24 cvs 2644:
1.116 cvs 2645: /* remove all the handlers and callbacks that may output a message to
2646: a non-existent Amaya window */
2647: HTEvent_setRegisterCallback ((HTEvent_registerCallback *) NULL);
2648: HTEvent_setUnregisterCallback ((HTEvent_unregisterCallback *) NULL);
2649: #ifndef _WINDOWS
2650: /** need to erase all existing timers too **/
2651: HTTimer_registerSetTimerCallback (NULL);
2652: HTTimer_registerDeleteTimerCallback (NULL);
2653: #endif /* !_WINDOWS */
2654: HTHost_setActivateRequestCallback (NULL);
2655: Thread_deleteAll ();
1.21 cvs 2656:
1.116 cvs 2657: HTProxy_deleteAll ();
2658: HTNoProxy_deleteAll ();
1.207 cvs 2659: SafePut_delete ();
1.116 cvs 2660: HTGateway_deleteAll ();
2661: AHTProfile_delete ();
1.248 kahan 2662:
2663: /* close the trace file (if it exists) */
2664: if (trace_fp)
2665: fclose (trace_fp);
2666:
1.116 cvs 2667: }
2668:
2669: /*----------------------------------------------------------------------
2670: NextNameValue
2671: ---------------------------------------------------------------------*/
1.265 cvs 2672: static char * NextNameValue (char **pstr, char **name, char **value)
1.116 cvs 2673: {
2674: char * p = *pstr;
2675: char * start = NULL;
2676: if (!pstr || !*pstr) return NULL;
2677:
2678: if (!*p) {
2679: *pstr = p;
2680: *name = NULL;
2681: *value = NULL;
2682: return NULL; /* No field */
2683: }
2684:
2685: /* Now search for the next '&' and ';' delimitators */
2686: start = p;
2687: while (*p && *p != '&' && *p != ';') p++;
2688: if (*p)
2689: *p++ = '\0';
2690: *pstr = p;
2691:
2692: /* Search for the name and value */
2693: *name = start;
2694: p = start;
2695:
2696: while(*p && *p != '=')
2697: p++;
2698: if (*p)
2699: *p++ = '\0';
2700: *value = p;
2701:
2702: return start;
2703: }
2704:
2705: /*----------------------------------------------------------------------
2706: PrepareFormdata
2707: ---------------------------------------------------------------------*/
1.265 cvs 2708: static HTAssocList * PrepareFormdata (char *string)
1.116 cvs 2709: {
1.266 cvs 2710: char *tmp_string, *tmp_string_ptr;
2711: char *name;
2712: char *value;
2713: HTAssocList *formdata;
1.116 cvs 2714:
2715: if (!string)
2716: return NULL;
2717:
2718: /* store the ptr in another variable, as the original address will
2719: change
2720: */
1.236 cvs 2721:
1.265 cvs 2722: tmp_string_ptr = TtaGetMemory (strlen (string) + 1);
1.236 cvs 2723: tmp_string = tmp_string_ptr;
1.273 cvs 2724: strcpy (tmp_string_ptr, string);
1.116 cvs 2725: formdata = HTAssocList_new();
2726:
2727: while (*tmp_string)
2728: {
2729: NextNameValue (&tmp_string, &name, &value);
2730: HTAssocList_addObject(formdata,
2731: name, value);
2732: }
2733:
2734: TtaFreeMemory (tmp_string_ptr);
2735: return formdata;
1.4 cvs 2736: }
2737:
1.236 cvs 2738: /*----------------------------------------------------------------------
2739: ---------------------------------------------------------------------*/
1.216 cvs 2740: void AHTRequest_setCustomAcceptHeader (HTRequest *request, char *value)
2741: {
2742: HTRqHd rqhd = HTRequest_rqHd (request);
2743: rqhd = rqhd & (~HT_C_ACCEPT_TYPE);
2744: HTRequest_setRqHd (request, rqhd);
1.221 cvs 2745: HTRequest_addExtraHeader (request, "Accept", value);
1.216 cvs 2746: }
2747:
1.228 cvs 2748: /*----------------------------------------------------------------------
1.99 cvs 2749: InvokeGetObjectWWW_callback
2750: A simple function to invoke a callback function whenever there's an error
2751: in GetObjectWWW
2752: ---------------------------------------------------------------------*/
1.265 cvs 2753: void InvokeGetObjectWWW_callback (int docid, char *urlName,
2754: char *outputfile, TTcbf *terminate_cbf,
2755: void *context_tcbf, int status)
1.99 cvs 2756: {
2757: if (!terminate_cbf)
2758: return;
2759:
1.116 cvs 2760: (*terminate_cbf) (docid, status, urlName, outputfile,
1.99 cvs 2761: NULL, context_tcbf);
2762: }
2763:
2764:
2765:
1.5 cvs 2766: /*----------------------------------------------------------------------
1.15 cvs 2767: GetObjectWWW
1.17 cvs 2768: this function requests a resource designated by a URLname into a
2769: temporary filename. The download can come from a simple GET operation,
2770: or can come from POSTING/GETTING a form. In the latter
2771: case, the function receives a query string to send to the server.
2772:
1.5 cvs 2773: 4 file retrieval modes are proposed:
2774: AMAYA_SYNC : blocking mode
2775: AMAYA_ISYNC : incremental, blocking mode
2776: AMAYA_ASYNC : non-blocking mode
2777: AMAYA_IASYNC : incremental, non-blocking mode
2778:
2779: In the incremental mode, each time a package arrives, it will be
2780: stored in the temporary file. In addition, if an
2781: incremental_callback function is defined, this function will be
2782: called and handled a copy of the newly received data package.
2783: Finally, if a terminate_callback function is defined, it will be
2784: invoked when the request terminates. The caller of this function
1.4 cvs 2785: can define two different contexts to be passed to the callback
2786: functions.
2787:
2788: When the function is called with the SYNC mode, the function will
2789: return only when the requested file has been loaded.
2790: The ASYNC mode will immediately return after setting up the
2791: call.
2792:
2793: Notes:
2794: At the end of a succesful request, the urlName string contains the
2795: name of the actually retrieved URL. As a URL can change over the time,
2796: (e.g., be redirected elsewhere), it is advised that the function
1.17 cvs 2797: caller verify the value of the urlName variable at the end of
1.4 cvs 2798: a request.
2799:
2800: Inputs:
2801: - docid Document identifier for the set of objects being
2802: retrieved.
2803: - urlName The URL to be retrieved (MAX_URL_LENGTH chars length)
2804: - outputfile A pointer to an empty string of MAX_URL_LENGTH.
2805: - mode The retrieval mode.
2806: - incremental_cbf
2807: - context_icbf
2808: Callback and context for the incremental modes
2809: - terminate_cbf
2810: - context_icbf
2811: Callback and context for a terminate handler
1.17 cvs 2812: -error_html if TRUE, then display any server error message as an
2813: HTML document.
1.88 cvs 2814: - content_type a string
2815:
1.4 cvs 2816: Outputs:
2817: - urlName The URL that was retrieved
2818: - outputfile The name of the temporary file which holds the
2819: retrieved data. (Only in case of success)
1.88 cvs 2820: - if content_type wasn't NULL, it will contain a copy of the parameter
2821: sent in the HTTP answer
1.4 cvs 2822: Returns:
2823: HT_ERROR
2824: HT_OK
1.5 cvs 2825: ----------------------------------------------------------------------*/
1.265 cvs 2826: int GetObjectWWW (int docid, char *urlName, char *formdata,
2827: char *outputfile, int mode, TIcbf *incremental_cbf,
2828: void *context_icbf, TTcbf *terminate_cbf,
2829: void *context_tcbf, ThotBool error_html, char *content_type)
1.4 cvs 2830: {
2831: AHTReqContext *me;
1.301 vatton 2832: char *ref;
2833: char *esc_url;
1.107 cvs 2834: int status, l;
1.114 cvs 2835: int tempsubdir;
1.191 cvs 2836: ThotBool bool_tmp;
1.7 cvs 2837:
1.116 cvs 2838: if (urlName == NULL || docid == 0 || outputfile == NULL)
2839: {
2840: /* no file to be loaded */
2841: TtaSetStatus (docid, 1, TtaGetMessage (AMAYA, AM_BAD_URL), urlName);
1.69 cvs 2842:
1.116 cvs 2843: if (error_html)
1.69 cvs 2844: /* so we can show the error message */
2845: DocNetworkStatus[docid] |= AMAYA_NET_ERROR;
1.116 cvs 2846: InvokeGetObjectWWW_callback (docid, urlName, outputfile, terminate_cbf,
2847: context_tcbf, HT_ERROR);
2848: return HT_ERROR;
2849: }
1.7 cvs 2850:
1.159 cvs 2851: /* if it's a 'docImage', we have already downloaded it */
1.265 cvs 2852: if (!strncmp ("internal:", urlName, 9))
1.159 cvs 2853: {
1.265 cvs 2854: strcpy (outputfile, urlName);
1.159 cvs 2855: InvokeGetObjectWWW_callback (docid, urlName, outputfile,
2856: terminate_cbf, context_tcbf, HT_OK);
2857: return HT_OK;
2858: }
2859:
1.4 cvs 2860: /* do we support this protocol? */
1.116 cvs 2861: if (IsValidProtocol (urlName) == NO)
2862: {
2863: /* return error */
2864: outputfile[0] = EOS; /* file could not be opened */
2865: TtaSetStatus (docid, 1,
2866: TtaGetMessage (AMAYA, AM_GET_UNSUPPORTED_PROTOCOL),
2867: urlName);
2868:
2869: if (error_html)
1.69 cvs 2870: /* so we can show the error message */
2871: DocNetworkStatus[docid] |= AMAYA_NET_ERROR;
1.116 cvs 2872: InvokeGetObjectWWW_callback (docid, urlName, outputfile, terminate_cbf,
2873: context_tcbf, HT_ERROR);
2874: return HT_ERROR;
2875: }
1.4 cvs 2876:
1.114 cvs 2877: /* we store CSS in subdir named 0; all the other files go to a subidr
2878: named after their own docid */
2879: tempsubdir = (mode & AMAYA_LOAD_CSS) ? 0 : docid;
1.116 cvs 2880: /* create a tempfilename */
1.272 cvs 2881: sprintf (outputfile, "%s%c%d%c%04dAM", TempFileDirectory, DIR_SEP, tempsubdir, DIR_SEP, object_counter);
1.116 cvs 2882: /* update the object_counter (used for the tempfilename) */
1.4 cvs 2883: object_counter++;
2884: /* normalize the URL */
1.300 kahan 2885: esc_url = EscapeURL (urlName);
1.206 cvs 2886: if (esc_url)
2887: {
1.265 cvs 2888: ref = AmayaParseUrl (esc_url, "", AMAYA_PARSE_ALL);
1.206 cvs 2889: TtaFreeMemory (esc_url);
2890: }
2891: else
2892: ref = NULL;
2893:
1.4 cvs 2894: /* should we abort the request if we could not normalize the url? */
1.198 cvs 2895: if (ref == NULL || ref[0] == EOS) {
1.69 cvs 2896: /*error */
2897: outputfile[0] = EOS;
2898: TtaSetStatus (docid, 1, TtaGetMessage (AMAYA, AM_BAD_URL), urlName);
1.214 cvs 2899: if (ref)
2900: TtaFreeMemory (ref);
1.69 cvs 2901: if (error_html)
1.116 cvs 2902: /* so we can show the error message */
2903: DocNetworkStatus[docid] |= AMAYA_NET_ERROR;
1.99 cvs 2904: InvokeGetObjectWWW_callback (docid, urlName, outputfile, terminate_cbf,
1.116 cvs 2905: context_tcbf, HT_ERROR);
1.69 cvs 2906: return HT_ERROR;
2907: }
1.116 cvs 2908:
1.4 cvs 2909: /* verify if that file name existed */
1.9 cvs 2910: if (TtaFileExist (outputfile))
1.77 cvs 2911: TtaFileUnlink (outputfile);
1.116 cvs 2912:
1.4 cvs 2913: /* Initialize the request structure */
2914: me = AHTReqContext_new (docid);
1.116 cvs 2915: if (me == NULL)
2916: {
2917: outputfile[0] = EOS;
2918: /* need an error message here */
2919: TtaFreeMemory (ref);
2920: InvokeGetObjectWWW_callback (docid, urlName, outputfile, terminate_cbf,
2921: context_tcbf, HT_ERROR);
2922: return HT_ERROR;
2923: }
2924:
1.4 cvs 2925: /* Specific initializations for POST and GET */
1.222 cvs 2926: if (mode & AMAYA_FORM_POST
1.228 cvs 2927: || mode & AMAYA_FILE_POST)
1.116 cvs 2928: {
2929: me->method = METHOD_POST;
2930: HTRequest_setMethod (me->request, METHOD_POST);
2931: }
2932: else
2933: {
1.254 kahan 2934: #ifdef ANNOTATIONS
2935: /* we support the DELETE method for deleting annotations.
2936: the rest of the request is similar to the GET */
2937: if (mode & AMAYA_DELETE)
2938: {
2939: me->method = METHOD_GET;
2940: HTRequest_setMethod (me->request, METHOD_DELETE);
2941: }
2942: else
2943: #endif /* ANNOTATIONS */
2944: me->method = METHOD_GET;
1.295 kahan 2945: #ifdef ANNOTATIONS
2946: /* use the custom sent content_type */
2947: if (content_type && content_type[0] != EOS)
2948: AHTRequest_setCustomAcceptHeader (me->request, content_type);
2949: else
2950: #endif /* ANNOTATIONS */
2951: if (!HasKnownFileSuffix (ref))
1.216 cvs 2952: {
2953: /* try to adjust the Accept header in an netwise economical way */
2954: if (mode & AMAYA_LOAD_IMAGE)
2955: AHTRequest_setCustomAcceptHeader (me->request, IMAGE_ACCEPT_NEGOTIATION);
2956: else if (mode & AMAYA_LOAD_CSS)
2957: AHTRequest_setCustomAcceptHeader (me->request, "*/*;q=0.1,css/*");
1.294 kahan 2958: else
2959: AHTRequest_setCustomAcceptHeader (me->request, GENERAL_ACCEPT_NEGOTIATION);
1.216 cvs 2960: /*
2961: HTRequest_setConversion(me->request, acceptTypes, TRUE);
2962: */
2963: }
1.295 kahan 2964: else
2965: AHTRequest_setCustomAcceptHeader (me->request, GENERAL_ACCEPT_NEGOTIATION);
2966: /* language negotiation */
2967: HTRequest_setLanguage (me->request, acceptLanguages, TRUE);
1.116 cvs 2968: }
1.93 cvs 2969:
1.116 cvs 2970: /* Common initialization for all HTML methods */
1.4 cvs 2971: me->mode = mode;
2972: me->error_html = error_html;
2973: me->incremental_cbf = incremental_cbf;
2974: me->context_icbf = context_icbf;
2975: me->terminate_cbf = terminate_cbf;
2976: me->context_tcbf = context_tcbf;
1.64 cvs 2977:
1.69 cvs 2978: /* for the async. request modes, we need to have our
1.4 cvs 2979: own copy of outputfile and urlname
1.116 cvs 2980: */
1.4 cvs 2981:
1.116 cvs 2982: if ((mode & AMAYA_ASYNC) || (mode & AMAYA_IASYNC))
2983: {
1.265 cvs 2984: l = strlen (outputfile);
1.116 cvs 2985: if (l > MAX_LENGTH)
1.265 cvs 2986: me->outputfile = TtaGetMemory (l + 2);
1.116 cvs 2987: else
1.265 cvs 2988: me->outputfile = TtaGetMemory (MAX_LENGTH + 2);
2989: strcpy (me->outputfile, outputfile);
2990: l = strlen (urlName);
1.116 cvs 2991: if (l > MAX_LENGTH)
1.265 cvs 2992: me->urlName = TtaGetMemory (l + 2);
1.116 cvs 2993: else
1.265 cvs 2994: me->urlName = TtaGetMemory (MAX_LENGTH + 2);
2995: strcpy (me->urlName, urlName);
1.116 cvs 2996: #ifdef _WINDOWS
2997: /* force windows ASYNC requests to always be non preemptive */
2998: HTRequest_setPreemptive (me->request, NO);
2999: #endif /*_WINDOWS */
3000: } /* AMAYA_ASYNC mode */
3001: else
3002: #ifdef _WINDOWS
3003: {
1.233 cvs 3004: me->outputfile = outputfile;
3005: me->urlName = urlName;
1.116 cvs 3006: /* force windows SYNC requests to always be non preemptive */
3007: HTRequest_setPreemptive (me->request, YES);
3008: }
3009: #else /* !_WINDOWS */
3010: {
3011: me->outputfile = outputfile;
3012: me->urlName = urlName;
3013: }
3014: /***
1.136 cvs 3015: In order to take into account the stop button,
3016: the requests will be always asynchronous, however, if mode=AMAYA_SYNC,
1.57 cvs 3017: we will loop until the document has been received or a stop signal
3018: generated
1.77 cvs 3019: ****/
1.116 cvs 3020: HTRequest_setPreemptive (me->request, NO);
3021: #endif /* _WINDOWS */
1.61 cvs 3022:
1.151 cvs 3023: /*
3024: ** Make sure that the first request is flushed immediately and not
3025: ** buffered in the output buffer
3026: */
3027: if (mode & AMAYA_FLUSH_REQUEST)
3028: HTRequest_setFlush(me->request, YES);
3029: HTRequest_setFlush(me->request, YES);
3030:
1.61 cvs 3031: /* prepare the URLname that will be displayed in teh status bar */
3032: ChopURL (me->status_urlName, me->urlName);
1.77 cvs 3033: TtaSetStatus (me->docid, 1,
3034: TtaGetMessage (AMAYA, AM_FETCHING),
1.233 cvs 3035: me->status_urlName);
1.4 cvs 3036:
1.265 cvs 3037: me->anchor = (HTParentAnchor *) HTAnchor_findAddress (ref);
1.45 cvs 3038: TtaFreeMemory (ref);
1.177 cvs 3039:
1.223 cvs 3040: TtaGetEnvBoolean ("CACHE_DISCONNECTED_MODE", &bool_tmp);
1.177 cvs 3041: if (!bool_tmp && (mode & AMAYA_NOCACHE))
1.116 cvs 3042: HTRequest_setReloadMode (me->request, HT_CACHE_FLUSH);
3043:
3044: /* prepare the query string and format for POST */
3045: if (mode & AMAYA_FORM_POST)
1.114 cvs 3046: {
1.116 cvs 3047: HTAnchor_setFormat ((HTParentAnchor *) me->anchor,
3048: HTAtom_for ("application/x-www-form-urlencoded"));
3049: HTAnchor_setLength ((HTParentAnchor *) me->anchor, me->block_size);
3050: HTRequest_setEntityAnchor (me->request, me->anchor);
3051: }
1.114 cvs 3052:
1.127 cvs 3053: /* create the formdata element for libwww */
1.236 cvs 3054: if (formdata && ! (mode & AMAYA_FILE_POST))
3055: me->formdata = PrepareFormdata (formdata);
1.127 cvs 3056:
1.297 kirschpi 3057:
3058: #ifdef DAV
1.302 kirschpi 3059: /* try to add an "If" header (lock information) also for POST
3060: * requests and for GET forms */
1.297 kirschpi 3061: if (HTRequest_method(me->request) == METHOD_POST ||
3062: (HTRequest_method(me->request) == METHOD_GET && me->formdata))
3063: DAVAddIfHeader (me,HTAnchor_address((HTAnchor*)me->anchor));
1.302 kirschpi 3064: #endif /* DAV */
1.297 kirschpi 3065:
3066:
1.116 cvs 3067: /* do the request */
3068: if (mode & AMAYA_FORM_POST)
1.119 cvs 3069: {
1.191 cvs 3070: /* this call doesn't give back a ThotBool */
1.119 cvs 3071: HTParentAnchor * posted = NULL;
3072:
3073: posted = HTPostFormAnchor (me->formdata, (HTAnchor *) me->anchor,
3074: me->request);
3075: status = posted ? YES : NO;
3076: }
1.222 cvs 3077: #ifdef ANNOTATIONS
1.251 kahan 3078: else if (mode & AMAYA_FILE_POST)
1.222 cvs 3079: {
1.228 cvs 3080: unsigned long filesize;
3081: char *fileURL;
3082:
3083: /* @@@ a very ugly patch :)))
3084: I'm copying here some of the functionality I use in the PUT
3085: I need to put the common parts in another module */
1.252 kahan 3086: AM_GetFileSize (formdata, &filesize);
1.228 cvs 3087: me->block_size = filesize;
3088:
1.233 cvs 3089: fileURL = HTParse (formdata, "file:/", PARSE_ALL);
1.228 cvs 3090: me->source = HTAnchor_findAddress (fileURL);
3091: HT_FREE (fileURL);
1.222 cvs 3092:
1.228 cvs 3093: /* hardcoded ... */
3094: AHTRequest_setCustomAcceptHeader (me->request, "application/xml");
1.222 cvs 3095: HTAnchor_setFormat (HTAnchor_parent (me->source),
3096: HTAtom_for ("application/xml"));
1.228 cvs 3097: HTAnchor_setFormat (me->anchor,
3098: HTAtom_for ("application/xml"));
3099: HTAnchor_setLength ((HTParentAnchor *) me->source, me->block_size);
3100: /* @@ here I need to actually read the file and put it in document,
3101: then, when I kill the request, I need to kill it */
3102: {
3103: FILE *fp;
3104: int i;
3105: char c;
3106:
1.255 swick 3107: me->document = TtaGetMemory (me->block_size + 1);
1.233 cvs 3108: fp = fopen (formdata, "r");
1.244 kahan 3109: i = 0;
1.228 cvs 3110: c = getc (fp);
3111: while (!feof (fp))
3112: {
3113: me->document[i++] = c;
3114: c = getc (fp);
3115: }
3116: me->document[i] = '\0';
3117: fclose (fp);
3118: }
3119: HTAnchor_setDocument ( (HTParentAnchor *) me->source,
3120: (void * ) me->document);
3121: HTRequest_setEntityAnchor (me->request, HTAnchor_parent (me->source));
3122:
3123: status = HTPostAnchor (HTAnchor_parent (me->source),
1.222 cvs 3124: (HTAnchor *) me->anchor,
3125: me->request);
3126: }
3127: #endif /* ANNOTATIONS */
1.127 cvs 3128: else if (formdata)
3129: status = HTGetFormAnchor(me->formdata, (HTAnchor *) me->anchor,
3130: me->request);
1.116 cvs 3131: else
1.77 cvs 3132: status = HTLoadAnchor ((HTAnchor *) me->anchor, me->request);
1.69 cvs 3133:
1.123 cvs 3134: /* @@@ may need some special windows error msg here */
1.116 cvs 3135: /* control the errors */
1.4 cvs 3136:
1.130 cvs 3137: if (status == NO)
1.116 cvs 3138: /* the request invocation failed */
3139: {
3140: /* show an error message on the status bar */
3141: DocNetworkStatus[docid] |= AMAYA_NET_ERROR;
3142: TtaSetStatus (docid, 1,
3143: TtaGetMessage (AMAYA, AM_CANNOT_LOAD),
3144: urlName);
3145: if (me->reqStatus == HT_NEW)
3146: /* manually invoke the last processing that usually gets done
3147: in a succesful request */
3148: InvokeGetObjectWWW_callback (docid, urlName, outputfile,
3149: terminate_cbf, context_tcbf, HT_ERROR);
3150: /* terminate_handler wasn't called */
1.136 cvs 3151: AHTReqContext_delete (me);
1.116 cvs 3152: }
3153: else
1.136 cvs 3154: /* end treatment for SYNC requests */
1.120 cvs 3155: if ((mode & AMAYA_SYNC) || (mode & AMAYA_ISYNC))
3156: {
1.136 cvs 3157: /* wait here untilt the asynchronous request finishes */
1.130 cvs 3158: status = LoopForStop (me);
1.136 cvs 3159: /* if status returns HT_ERROR, should we invoke the callback? */
1.120 cvs 3160: if (!HTRequest_kill (me->request))
3161: AHTReqContext_delete (me);
3162: }
1.130 cvs 3163:
1.136 cvs 3164: /* an interface problem!!! */
3165: return (status == YES ? 0 : -1);
1.4 cvs 3166: }
3167:
1.5 cvs 3168: /*----------------------------------------------------------------------
1.17 cvs 3169: PutObjectWWW
3170: frontend for uploading a resource to a URL. This function downloads
3171: a file to be uploaded into memory, it then calls UploadMemWWW to
3172: finish the job.
3173:
1.5 cvs 3174: 2 upload modes are proposed:
3175: AMAYA_SYNC : blocking mode
3176: AMAYA_ASYNC : non-blocking mode
3177:
1.4 cvs 3178: When the function is called with the SYNC mode, the function will
3179: return only when the file has been uploaded.
3180: The ASYNC mode will immediately return after setting up the
3181: call. Furthermore, at the end of an upload, the ASYNC mode will
3182: call back terminate_cbf, handling it the context defined in
3183: context_tcbf.
3184:
3185: Notes:
3186: At the end of a succesful request, the urlName string contains the
3187: name of the actually uploaded URL. As a URL can change over the time,
3188: (e.g., be redirected elsewhere), it is advised that the function
3189: caller verifies the value of the urlName variable at the end of
3190: a request.
3191:
3192: Inputs:
3193: - docid Document identifier for the set of objects being
3194: retrieved.
3195: - fileName A pointer to the local file to upload
3196: - urlName The URL to be uploaded (MAX_URL_LENGTH chars length)
3197: - mode The retrieval mode.
3198: - terminate_cbf
3199: - context_icbf
3200: Callback and context for a terminate handler
3201:
3202: Outputs:
3203: - urlName The URL that was uploaded
3204:
3205: Returns:
3206: HT_ERROR
3207: HT_OK
1.5 cvs 3208: ----------------------------------------------------------------------*/
1.276 kahan 3209: int PutObjectWWW (int docid, char *fileName, char *urlName,
3210: char *contentType, int mode,
1.265 cvs 3211: TTcbf *terminate_cbf, void *context_tcbf)
1.4 cvs 3212: {
1.116 cvs 3213: AHTReqContext *me;
1.250 cvs 3214: CHARSET charset;
1.4 cvs 3215: int status;
1.250 cvs 3216: unsigned long file_size;
1.116 cvs 3217: char *fileURL;
1.168 cvs 3218: char *etag = NULL;
1.169 cvs 3219: HTParentAnchor *dest_anc_parent;
1.265 cvs 3220: char *tmp;
3221: char *esc_url;
1.168 cvs 3222: int UsePreconditions;
1.191 cvs 3223: ThotBool lost_update_check = TRUE;
1.235 cvs 3224: char url_name[MAX_LENGTH];
1.285 kahan 3225: char *resource_name;
1.265 cvs 3226: char *tmp2;
1.239 cvs 3227: #ifdef _WINDOWS
3228: char file_name[MAX_LENGTH];
3229: #endif /* _WINDOWS */
1.172 cvs 3230:
3231: /* should we protect the PUT against lost updates? */
1.203 cvs 3232: tmp = TtaGetEnvString ("ENABLE_LOST_UPDATE_CHECK");
1.265 cvs 3233: if (tmp && *tmp && strcasecmp (tmp, "yes"))
1.172 cvs 3234: lost_update_check = FALSE;
1.168 cvs 3235:
3236: UsePreconditions = mode & AMAYA_USE_PRECONDITIONS;
1.4 cvs 3237:
1.33 cvs 3238: AmayaLastHTTPErrorMsg [0] = EOS;
1.256 kahan 3239: AmayaLastHTTPErrorMsgR [0] = EOS;
3240:
1.33 cvs 3241:
1.116 cvs 3242: if (urlName == NULL || docid == 0 || fileName == NULL
3243: || !TtaFileExist (fileName))
1.4 cvs 3244: /* no file to be uploaded */
3245: return HT_ERROR;
3246:
3247: /* do we support this protocol? */
1.7 cvs 3248: if (IsValidProtocol (urlName) == NO)
3249: {
3250: /* return error */
1.198 cvs 3251: TtaSetStatus (docid, 1, TtaGetMessage (AMAYA, AM_PUT_UNSUPPORTED_PROTOCOL), urlName);
1.7 cvs 3252: return HT_ERROR;
3253: }
1.116 cvs 3254:
1.228 cvs 3255: /* get the size of the file */
1.252 kahan 3256: if (!AM_GetFileSize (fileName, &file_size) || file_size == 0L)
1.7 cvs 3257: {
3258: /* file was empty */
3259: /*errmsg here */
3260: return (HT_ERROR);
3261: }
1.116 cvs 3262:
3263: /* prepare the request context */
1.4 cvs 3264: if (THD_TRACE)
1.228 cvs 3265: fprintf (stderr, "file size == %u\n", (unsigned) file_size);
1.4 cvs 3266:
3267: me = AHTReqContext_new (docid);
1.7 cvs 3268: if (me == NULL)
3269: {
1.168 cvs 3270: /* @@ need an error message here */
1.151 cvs 3271: TtaHandlePendingEvents ();
1.7 cvs 3272: return (HT_ERROR);
1.208 cvs 3273: }
3274:
3275: /*
3276: ** Set up the original URL name
3277: */
1.285 kahan 3278:
3279: /* are we using content-location? */
3280: if (DocumentMeta[docid]->content_location)
3281: resource_name = DocumentMeta[docid]->content_location;
3282: else
3283: resource_name = NULL;
3284:
3285: /* prepare the target URL */
3286: if (resource_name)
1.208 cvs 3287: {
1.285 kahan 3288: tmp = strstr (urlName, resource_name);
3289: if (!tmp)
1.208 cvs 3290: {
1.285 kahan 3291: /* urlName does not include the resource name */
3292: me->default_put_name = TtaGetMemory (strlen (urlName)
3293: + strlen (resource_name)
3294: + sizeof (URL_SEP)
3295: + 1);
3296: strcpy (me->default_put_name, urlName);
3297: tmp = strrchr (me->default_put_name, URL_SEP);
3298: if (tmp)
1.208 cvs 3299: {
1.285 kahan 3300: /* it is a URL finishing in /. Only add the resrouce name */
3301: tmp++;
3302: strcpy (tmp, resource_name);
3303: }
3304: else
3305: {
3306: strcat (me->default_put_name, URL_STR);
3307: strcat (me->default_put_name, resource_name);
1.208 cvs 3308: }
3309: }
1.7 cvs 3310: }
1.285 kahan 3311:
3312: if (!me->default_put_name)
1.271 kahan 3313: me->default_put_name = TtaStrdup (urlName);
3314:
1.285 kahan 3315: HTRequest_setDefaultPutName (me->request, me->default_put_name);
1.116 cvs 3316:
1.4 cvs 3317: me->mode = mode;
3318: me->incremental_cbf = (TIcbf *) NULL;
3319: me->context_icbf = (void *) NULL;
3320: me->terminate_cbf = terminate_cbf;
3321: me->context_tcbf = context_tcbf;
1.286 kahan 3322:
3323: /* normalize the URL */
1.300 kahan 3324: esc_url = EscapeURL (urlName);
1.272 cvs 3325: me->urlName = TtaStrdup (esc_url);
1.206 cvs 3326: TtaFreeMemory (esc_url);
1.300 kahan 3327:
1.228 cvs 3328: me->block_size = file_size;
1.17 cvs 3329: /* select the parameters that distinguish a PUT from a GET/POST */
1.4 cvs 3330: me->method = METHOD_PUT;
3331: me->output = stdout;
1.17 cvs 3332: /* we are not expecting to receive any input from the server */
1.265 cvs 3333: me->outputfile = (char *) NULL;
1.4 cvs 3334:
1.134 cvs 3335: #ifdef _WINDOWS
3336: /* libwww's HTParse function doesn't take into account the drive name;
1.168 cvs 3337: so we sidestep it */
1.238 cvs 3338:
1.134 cvs 3339: fileURL = NULL;
3340: StrAllocCopy (fileURL, "file:");
1.273 cvs 3341: strcpy (file_name, fileName);
1.235 cvs 3342: StrAllocCat (fileURL, file_name);
1.134 cvs 3343: #else
1.116 cvs 3344: fileURL = HTParse (fileName, "file:/", PARSE_ALL);
1.134 cvs 3345: #endif /* _WINDOWS */
1.168 cvs 3346: me->source = HTAnchor_findAddress (fileURL);
1.116 cvs 3347: HT_FREE (fileURL);
1.273 cvs 3348: strcpy (url_name, me->urlName);
1.235 cvs 3349: me->dest = HTAnchor_findAddress (url_name);
1.169 cvs 3350: /* we memorize the anchor's parent @ as we use it a number of times
3351: in the following lines */
3352: dest_anc_parent = HTAnchor_parent (me->dest);
1.168 cvs 3353:
1.169 cvs 3354: /*
3355: ** Set the Content-Type of the file we are uploading
3356: */
3357: /* we try to use any content-type previosuly associated
3358: with the parent. If it doesn't exist, we try to guess it
3359: from the URL */
1.276 kahan 3360: /* @@ JK: trying to use the content type we stored */
3361: /*
1.235 cvs 3362: tmp2 = HTAtom_name (HTAnchor_format (dest_anc_parent));
1.276 kahan 3363: */
3364: tmp2 = NULL;
1.235 cvs 3365: if (!tmp2 || !strcmp (tmp2, "www/unknown"))
1.169 cvs 3366: {
1.260 kahan 3367: HTAtom *tmp_atom;
1.276 kahan 3368:
1.260 kahan 3369: tmp_atom = AHTGuessAtom_for (me->urlName, contentType);
1.276 kahan 3370: if (!tmp_atom || !strcmp (HTAtom_name (tmp_atom), "www/unknown"))
3371: {
3372: /* ask the user for a MIME type */
3373: }
1.260 kahan 3374: HTAnchor_setFormat (dest_anc_parent, tmp_atom);
1.235 cvs 3375: tmp2 = HTAtom_name (HTAnchor_format (dest_anc_parent));
1.169 cvs 3376: }
3377: /* .. and we give the same type to the source anchor */
3378: /* we go thru setOutputFormat, rather than change the parent's
3379: anchor, as that's the place that libwww expects it to be */
1.235 cvs 3380: HTAnchor_setFormat (HTAnchor_parent (me->source), HTAtom_for (tmp2));
1.219 cvs 3381:
1.235 cvs 3382: HTRequest_setOutputFormat (me->request, HTAtom_for (tmp2));
1.219 cvs 3383:
3384: /*
3385: ** Set the Charset of the file we are uploading
3386: */
1.240 cvs 3387: /* we set the charset as indicated in the document's metadata
3388: structure (and only if it exists) */
1.250 cvs 3389: charset = TtaGetDocumentCharset (docid);
3390: if (charset != UNDEFINED_CHARSET)
1.240 cvs 3391: {
1.250 cvs 3392: tmp = TtaGetCharsetName (charset);
1.272 cvs 3393: if (tmp && *tmp != EOS)
1.250 cvs 3394: {
1.273 cvs 3395: tmp2 = TtaStrdup (tmp);
1.250 cvs 3396: HTAnchor_setCharset (dest_anc_parent, HTAtom_for (tmp2));
3397: TtaFreeMemory (tmp2);
3398: tmp2 = HTAtom_name (HTAnchor_charset (dest_anc_parent));
3399: /* .. and we give the same charset to the source anchor */
3400: /* we go thru setCharSet, rather than change the parent's
3401: anchor, as that's the place that libwww expects it to be */
3402: HTAnchor_setCharset (HTAnchor_parent (me->source),
3403: HTAtom_for (tmp2));
3404: }
1.219 cvs 3405: }
3406:
3407: /*
3408: ** define other request characteristics
3409: */
1.116 cvs 3410: #ifdef _WINDOWS
1.136 cvs 3411: HTRequest_setPreemptive (me->request, NO);
1.116 cvs 3412: #else
1.134 cvs 3413: HTRequest_setPreemptive (me->request, NO);
1.116 cvs 3414: #endif /* _WINDOWS */
3415:
1.151 cvs 3416: /*
3417: ** Make sure that the first request is flushed immediately and not
3418: ** buffered in the output buffer
3419: */
3420: if (mode & AMAYA_FLUSH_REQUEST)
3421: HTRequest_setFlush(me->request, YES);
1.168 cvs 3422:
3423: /* Should we use preconditions? */
1.172 cvs 3424: if (lost_update_check)
1.168 cvs 3425: {
1.172 cvs 3426: if (UsePreconditions)
3427: etag = HTAnchor_etag (HTAnchor_parent (me->dest));
3428:
3429: if (etag)
3430: {
3431: HTRequest_setPreconditions(me->request, HT_MATCH_THIS);
3432: }
3433: else
3434: {
3435: HTRequest_setPreconditions(me->request, HT_NO_MATCH);
3436: HTRequest_addAfter(me->request, check_handler, NULL, NULL, HT_ALL,
3437: HT_FILTER_MIDDLE, YES);
1.175 cvs 3438: HTRequest_addAfter (me->request, HTAuthFilter, "http://*", NULL,
3439: HT_NO_ACCESS, HT_FILTER_MIDDLE, YES);
3440: HTRequest_addAfter (me->request, HTAuthFilter, "http://*", NULL,
3441: HT_REAUTH, HT_FILTER_MIDDLE, YES);
3442: HTRequest_addAfter (me->request, HTAuthInfoFilter, "http://*", NULL,
3443: HT_ALL, HT_FILTER_MIDDLE, YES);
3444: HTRequest_addAfter (me->request, HTUseProxyFilter, "http://*", NULL,
3445: HT_USE_PROXY, HT_FILTER_MIDDLE, YES);
1.172 cvs 3446: }
1.168 cvs 3447: }
3448: else
3449: {
1.172 cvs 3450: /* don't use preconditions */
1.168 cvs 3451: HTRequest_setPreconditions(me->request, HT_NO_MATCH);
3452: }
1.151 cvs 3453:
1.136 cvs 3454: /* don't use the cache while saving a document */
3455: HTRequest_setReloadMode (me->request, HT_CACHE_FLUSH);
1.116 cvs 3456:
1.164 cvs 3457: /* Throw away any reponse body */
3458: /*
3459: HTRequest_setOutputStream (me->request, HTBlackHole());
3460: */
3461:
1.168 cvs 3462: /* prepare the URLname that will be displayed in the status bar */
1.74 cvs 3463: ChopURL (me->status_urlName, me->urlName);
1.233 cvs 3464: TtaSetStatus (me->docid, 1, TtaGetMessage (AMAYA, AM_REMOTE_SAVING), me->status_urlName);
1.114 cvs 3465:
1.297 kirschpi 3466:
3467: #ifdef DAV
1.302 kirschpi 3468: /* MKP: for a PUT request, try to add an "If" header (lock information)
1.297 kirschpi 3469: * for a HEAD request, leave this for check_handler */
3470: if ( !(lost_update_check && (!UsePreconditions || !etag)) )
3471: DAVAddIfHeader (me,HTAnchor_address(me->dest));
1.302 kirschpi 3472: #endif /* DAV */
1.297 kirschpi 3473:
3474:
1.164 cvs 3475: /* make the request */
1.172 cvs 3476: if (lost_update_check && (!UsePreconditions || !etag))
1.168 cvs 3477: status = HTHeadAnchor (me->dest, me->request);
3478: else
3479: status = HTPutDocumentAnchor (HTAnchor_parent (me->source), me->dest, me->request);
1.4 cvs 3480:
1.130 cvs 3481: if (status == YES && me->reqStatus != HT_ERR)
1.7 cvs 3482: {
1.168 cvs 3483: /* part of the stop button handler */
3484: if ((mode & AMAYA_SYNC) || (mode & AMAYA_ISYNC))
3485: status = LoopForStop (me);
1.15 cvs 3486: }
1.136 cvs 3487: if (!HTRequest_kill (me->request))
3488: AHTReqContext_delete (me);
1.168 cvs 3489:
1.116 cvs 3490: TtaHandlePendingEvents ();
1.90 cvs 3491:
1.130 cvs 3492: return (status == YES ? 0 : -1);
1.28 cvs 3493: }
1.4 cvs 3494:
1.5 cvs 3495: /*----------------------------------------------------------------------
1.138 cvs 3496: StopRequest
1.17 cvs 3497: stops (kills) all active requests associated with a docid
1.5 cvs 3498: ----------------------------------------------------------------------*/
1.4 cvs 3499: void StopRequest (int docid)
3500: {
1.140 cvs 3501: if (Amaya && CanDoStop ())
1.138 cvs 3502: {
1.139 cvs 3503: #if 0 /* for later */
1.140 cvs 3504: AHTDocId_Status *docid_status;
3505: /* verify if there are any requests at all associated with docid */
1.138 cvs 3506: docid_status = (AHTDocId_Status *) GetDocIdStatus (docid,
3507: Amaya->docid_status);
3508: if (docid_status == (AHTDocId_Status *) NULL)
3509: return;
1.139 cvs 3510: #endif /* 0 */
1.138 cvs 3511: /* temporary call to stop all requests, as libwww changed its API */
3512: StopAllRequests (docid);
3513: }
3514: }
3515:
1.190 cvs 3516: /* @@@ the docid parameter isn't used... clean it up */
1.138 cvs 3517: /*----------------------------------------------------------------------
3518: StopAllRequests
3519: stops (kills) all active requests. We use the docid
3520: ----------------------------------------------------------------------*/
3521: void StopAllRequests (int docid)
3522: {
1.4 cvs 3523: HTList *cur;
3524: AHTReqContext *me;
1.191 cvs 3525: static ThotBool lock_stop = 0;
3526: ThotBool async_flag;
1.232 cvs 3527: AHTReqStatus old_reqStatus;
1.116 cvs 3528:
1.138 cvs 3529: /* only do the stop if we're not being called while processing a
1.146 cvs 3530: request, and if we're not already dealing with a stop */
3531: if (Amaya && CanDoStop () && !lock_stop)
1.7 cvs 3532: {
1.100 cvs 3533: #ifdef DEBUG_LIBWWW
1.138 cvs 3534: fprintf (stderr, "StopRequest: number of Amaya requests "
3535: "before kill: %d\n", Amaya->open_requests);
1.100 cvs 3536: #endif /* DEBUG_LIBWWW */
1.150 cvs 3537: /* enter the critical section */
1.146 cvs 3538: lock_stop = TRUE;
1.214 cvs 3539: /* set a module global variable so that we can do special
3540: processing easier */
3541: UserAborted_flag = TRUE;
1.232 cvs 3542: /* abort all outstanding libwww UI dialogues */
1.265 cvs 3543: CallbackDialogue (BaseDialog + FormAnswer, STRING_DATA, NULL);
3544: CallbackDialogue (BaseDialog + ConfirmForm, INTEGER_DATA, NULL);
1.164 cvs 3545: /* expire all outstanding timers */
3546: HTTimer_expireAll ();
1.160 cvs 3547: /* HTNet_killAll (); */
1.245 kahan 3548: if (Amaya->open_requests)
1.116 cvs 3549: {
1.245 kahan 3550: cur = Amaya->reqlist;
3551: while ((me = (AHTReqContext *) HTList_nextObject (cur)))
1.160 cvs 3552: {
1.245 kahan 3553: if (AmayaIsAlive ())
3554: {
1.161 cvs 3555: #ifdef DEBUG_LIBWWW
1.245 kahan 3556: fprintf (stderr,"StopRequest: killing req %p, url %s, status %d\n", me, me->urlName, me->reqStatus);
1.161 cvs 3557: #endif /* DEBUG_LIBWWW */
1.245 kahan 3558:
3559: if (me->reqStatus != HT_END && me->reqStatus != HT_ABORT)
1.163 cvs 3560: {
1.245 kahan 3561: if ((me->mode & AMAYA_ASYNC)
3562: || (me->mode & AMAYA_IASYNC))
3563: async_flag = TRUE;
3564: else
3565: async_flag = FALSE;
3566:
3567: /* change the status to say that the request aborted */
3568: /* if the request was "busy", we just change a flag to say so and
3569: let the handler finish the processing itself */
3570: old_reqStatus = me->reqStatus;
3571: me->reqStatus = HT_ABORT;
3572: if (old_reqStatus == HT_BUSY)
3573: continue;
3574:
3575: /* kill the request, using the appropriate function */
3576: if (me->request->net)
3577: HTNet_killPipe (me->request->net);
3578: else
3579: {
3580: if (me->terminate_cbf)
3581: (*me->terminate_cbf) (me->docid, -1, me->urlName,
3582: me->outputfile,
3583: NULL,
3584: me->context_tcbf);
3585:
3586: if (async_flag)
3587: /* explicitly free the request context for async
3588: requests. The sync requests context is freed
3589: by LoopForStop */
3590: AHTReqContext_delete (me);
3591: }
3592: cur = Amaya->reqlist;
1.160 cvs 3593: }
1.142 cvs 3594: #ifndef _WINDOWS
3595: #ifdef WWW_XWINDOWS
1.245 kahan 3596: /* to be on the safe side, remove all outstanding
3597: X events */
1.160 cvs 3598: else
3599: RequestKillAllXtevents (me);
1.142 cvs 3600: #endif /* WWW_XWINDOWS */
3601: #endif /* !_WINDOWS */
1.245 kahan 3602: }
1.160 cvs 3603: }
1.245 kahan 3604: /* Delete remaining channels */
3605: HTChannel_safeDeleteAll ();
1.116 cvs 3606: }
1.214 cvs 3607: /* reset the stop status */
3608: UserAborted_flag = FALSE;
1.150 cvs 3609: /* exit the critical section */
1.148 cvs 3610: lock_stop = FALSE;
1.100 cvs 3611: #ifdef DEBUG_LIBWWW
1.138 cvs 3612: fprintf (stderr, "StopRequest: number of Amaya requests "
3613: "after kill: %d\n", Amaya->open_requests);
1.100 cvs 3614: #endif /* DEBUG_LIBWWW */
1.138 cvs 3615: }
3616: } /* StopAllRequests */
1.17 cvs 3617:
3618:
1.105 cvs 3619: /*----------------------------------------------------------------------
3620: AmayaIsAlive
1.140 cvs 3621: returns the value of the AmayaAlive_flag
1.105 cvs 3622: ----------------------------------------------------------------------*/
1.191 cvs 3623: ThotBool AmayaIsAlive (void)
1.105 cvs 3624: {
1.140 cvs 3625: return AmayaAlive_flag;
3626: }
3627:
3628: /*----------------------------------------------------------------------
3629: CanDoStop
3630: returns the value of the CanDoStop flag
3631: ----------------------------------------------------------------------*/
1.191 cvs 3632: ThotBool CanDoStop (void)
1.140 cvs 3633: {
3634: return CanDoStop_flag;
3635: }
3636:
3637: /*----------------------------------------------------------------------
3638: CanDoStop_set
3639: sets the value of the CanDoStop flag
3640: ----------------------------------------------------------------------*/
1.191 cvs 3641: void CanDoStop_set (ThotBool value)
1.140 cvs 3642: {
3643: CanDoStop_flag = value;
1.176 cvs 3644: }
3645:
1.265 cvs 3646: /*----------------------------------------------------------------------
3647: ----------------------------------------------------------------------*/
1.176 cvs 3648: void libwww_updateNetworkConf (int status)
3649: {
3650: /* @@@ the docid parameter isn't used... clean it up */
3651: int docid = 1;
3652:
3653: /* first, stop all current requests, as the network
3654: may make some changes */
3655: StopAllRequests (docid);
1.207 cvs 3656:
3657: if (status & AMAYA_SAFEPUT_RESTART)
3658: {
3659: SafePut_delete ();
3660: SafePut_init ();
3661: }
1.176 cvs 3662:
3663: if (status & AMAYA_PROXY_RESTART)
3664: {
3665: HTProxy_deleteAll ();
3666: ProxyInit ();
3667: }
3668:
3669: if (status & AMAYA_CACHE_RESTART)
3670: {
3671: clear_cachelock ();
3672: HTCacheTerminate ();
3673: HTCacheMode_setEnabled (NO);
3674: CacheInit ();
3675: }
1.193 cvs 3676:
3677: if (status & AMAYA_LANNEG_RESTART)
3678: {
3679: /* clear the current values */
3680: if (acceptLanguages)
3681: HTLanguage_deleteAll (acceptLanguages);
3682: /* read in the new ones */
3683: acceptLanguages = HTList_new ();
3684: AHTAcceptLanguagesInit (acceptLanguages);
3685: }
1.105 cvs 3686: }
1.246 kahan 3687:
3688: /****************************************************************************
3689: ** The following two functions allow to set and read the value of *
3690: ** the FTPURL_flag. If this flag is true, it means we can browse FTP URLs *
3691: ***************************************************************************/
3692:
3693: /*----------------------------------------------------------------------
3694: AHT_FTPURL_flag_set
3695: ----------------------------------------------------------------------*/
3696: void AHTFTPURL_flag_set (ThotBool value)
3697: {
3698: FTPURL_flag = value;
3699: }
3700:
3701: /*----------------------------------------------------------------------
3702: AHT_FTPURL_flag
3703: ----------------------------------------------------------------------*/
3704: ThotBool AHTFTPURL_flag (void)
3705: {
3706: return (FTPURL_flag);
3707: }
1.308 kahan 3708:
3709:
3710: /*----------------------------------------------------------------------
3711: CheckSingleInstance
3712: Returns TRUE if this is the single instance of Amaya in the system,
3713: FALSE otherwise.
3714: N.B. : This implementation is naif.
3715: ----------------------------------------------------------------------*/
3716: ThotBool CheckSingleInstance (char *pid_dir)
3717: {
3718: #ifdef _WINDOWS
3719: HWND hwnd;
3720:
1.310 cvs 3721: hwnd = FindWindow ("Amaya", NULL);
1.308 kahan 3722:
3723: if (!hwnd)
3724: return TRUE;
3725: else
3726: return FALSE;
3727:
3728: #else /* _WINDOWS */
3729:
3730: int instances;
3731: char *ptr;
3732: pid_t pid;
3733:
3734: DIR *dp;
3735: struct stat st;
3736: #ifdef HAVE_DIRENT_H
3737: struct dirent *d;
3738: #else
3739: struct direct *d;
3740: #endif /* HAVE_DIRENT_H */
3741: char filename[BUFSIZ+1];
3742:
3743: if ((dp = opendir (pid_dir)) == NULL)
3744: {
3745: /* @@@ we couldn't open the directory ... we need some msg */
3746: perror (pid_dir);
3747: return FALSE;
3748: }
3749:
3750: instances = 0;
3751:
3752: while ((d = readdir (dp)) != NULL)
3753: {
3754: /* skip the UNIX . and .. links */
3755: if (!strcmp (d->d_name, "..")
3756: || !strcmp (d->d_name, "."))
3757: continue;
3758:
3759: sprintf (filename, "%s%c%s", pid_dir, DIR_SEP, d->d_name);
3760: if (lstat (filename, &st) < 0 )
3761: {
3762: /* @@2 need some error message */
3763: perror (filename);
3764: continue;
3765: }
3766:
3767: switch (st.st_mode & S_IFMT)
3768: {
3769: case S_IFDIR:
3770: case S_IFLNK:
3771: /* skip any links and directories that we find */
3772: continue;
3773: break;
3774: default:
3775: /* check if this pid exists. If not, erase it */
3776: ptr = strrchr (filename, DIR_SEP);
3777: if (!ptr)
3778: continue;
3779: sscanf (ptr, DIR_STR"%d", &pid);
3780: if (kill (pid, 0) == -1)
3781: {
3782: /* erase the stale pid file */
3783: TtaFileUnlink (filename);
3784: }
3785: else /* we found one live instance */
3786: {
3787: instances++;
3788: }
3789: break;
3790: }
3791: }
3792: closedir (dp);
3793: return (instances == 0);
3794: #endif /* !_WINDOWS */
3795: }
3796:
3797: /*----------------------------------------------------------------------
3798: FreeAmayaCache
3799: ----------------------------------------------------------------------*/
3800: void FreeAmayaCache (void)
3801: {
3802: #ifndef _WINDOWS
3803: char str[MAX_LENGTH];
3804: pid_t pid;
3805:
3806: /* unregister this instance of Amaya */
3807: pid = getpid ();
3808: sprintf (str, "%s/pid/%d", TempFileDirectory, pid);
3809: if (TtaFileExist (str))
3810: TtaFileUnlink (str);
3811: #endif /* _WINDOWS */
3812: }
3813:
3814: /*----------------------------------------------------------------------
3815: InitAmayaCache
3816: Create the temporary sub-directories for storing the HTML and
3817: other downloaded files.
3818: ----------------------------------------------------------------------*/
3819: void InitAmayaCache (void)
3820: {
3821: ThotBool can_erase;
3822: int i;
3823: char str[MAX_LENGTH];
3824: char *ptr;
1.309 cvs 3825: #ifndef _WINDOWS
1.308 kahan 3826: pid_t pid;
3827: int fd_pid;
1.309 cvs 3828: #endif /* _WINDOWS */
1.308 kahan 3829:
3830: #ifndef _WINDOWS
3831: /* create the temp dir for the Amaya pid */
3832: sprintf (str, "%s%cpid", TempFileDirectory, DIR_SEP);
3833: TtaMakeDirectory (str);
3834: #endif
3835:
3836: /* protection against dir names that have . in them to avoid
3837: erasing everything by accident */
3838: ptr = TempFileDirectory;
3839: can_erase = TRUE;
3840: while (*ptr && can_erase)
3841: {
3842: if (*ptr == '.')
3843: {
3844: if (*(ptr + 1) == '.')
3845: can_erase = FALSE;
3846: else
3847: ptr++;
3848: continue;
3849: }
3850: else if (*ptr == '~')
3851: can_erase = FALSE;
3852: else if (!isalnum (*ptr) && *ptr != DIR_SEP && *ptr != ':')
3853: can_erase = FALSE;
3854: ptr++;
3855: }
3856:
3857: if (can_erase && CheckSingleInstance (str))
3858: {
3859: /* Erase the previous directories */
3860: for (i = 0; i < DocumentTableLength; i++)
3861: {
3862: sprintf (str, "%s%c%d%c", TempFileDirectory, DIR_SEP, i, DIR_SEP);
3863: RecCleanCache (str);
3864: }
3865: }
3866:
3867: /* create the temporary cache directories if they don't exit*/
3868: for (i = 0; i < DocumentTableLength; i++)
3869: {
3870: sprintf (str, "%s%c%d", TempFileDirectory, DIR_SEP, i);
3871: TtaMakeDirectory (str);
3872: }
3873:
3874: #ifndef _WINDOWS
3875: /* register this instance of Amaya */
3876: pid = getpid ();
3877: sprintf (str, "%s/pid/%d", TempFileDirectory, pid);
3878: fd_pid = open (str, O_CREAT, S_IRUSR | S_IWUSR );
3879: if (fd_pid != -1)
3880: close (fd_pid);
3881: else
3882: printf ("Couldn't create fd_pid %s\n", str);
3883: #endif /* _WINDOWS */
3884: }
Webmaster