Return to query.c CVS log | Up to [Public] / Amaya / amaya |
1.5 cvs 1: /*** 2: *** Copyright (c) 1996 INRIA, All rights reserved 3: ***/ 1.4 cvs 4: 1.12 cvs 5: /* Amaya includes */ 1.4 cvs 6: 7: #include "amaya.h" 8: #include "dialog.h" 9: #include "content.h" 10: #include "view.h" 11: #include "interface.h" 12: #include "amaya.h" 13: #include "message.h" 14: #include "application.h" 15: #include "AHTURLTools.h" 16: #include "AHTBridge.h" 17: #include "AHTMemConv.h" 1.7 cvs 18: 1.4 cvs 19: #if defined(__svr4__) 20: #define CATCH_SIG 21: #endif 22: 23: /* local structures coming from libwww and which are 1.7 cvs 24: ** not found in any .h file 25: */ 1.4 cvs 26: 1.7 cvs 27: struct _HTStream 28: { 29: HTStreamClass *isa; 30: }; 31: 32: struct _HTError 33: { 34: HTErrorElement element; /* Index number into HTError */ 35: HTSeverity severity; /* A la VMS */ 36: BOOL ignore; /* YES if msg should not go to user */ 37: void *par; /* Explanation, e.g. filename */ 38: int length; /* For copying by generic routine */ 39: char *where; /* Which function */ 40: }; 41: 42: 43: struct _HTHost 44: { 45: char *hostname; /* name of host + optional port */ 46: time_t ntime; /* Creation time */ 47: char *type; /* Peer type */ 48: int version; /* Peer version */ 49: HTMethod methods; /* Public methods (bit-flag) */ 50: char *server; /* Server name */ 51: char *user_agent; /* User Agent */ 52: char *range_units; /* Acceptable range units */ 53: HTTransportMode mode; /* Supported mode */ 54: HTChannel *channel; /* Persistent channel */ 55: HTList *pipeline; /* Pipe line of net objects */ 56: HTList *pending; /* List of pending Net objects */ 57: time_t expires; /* Persistent channel expires time */ 58: }; 1.4 cvs 59: 60: /* Type definitions and global variables etc. local to this module */ 61: 62: 63: /**** Global variables ****/ 64: 65: AmayaContext *Amaya; /* Amaya's global context */ 66: 67: /*** private variables ***/ 68: 69: static HTList *converters = NULL; /* List of global converters */ 70: static HTList *encodings = NULL; 71: 72: /*** private functions ***/ 73: 74: /*** 75: #ifdef __STDC__ 76: char *ExtractFileName(char); 77: #else 78: char *ExtractFileName(); 79: #endif *__STDC__* 80: ***/ 81: 82: 83: #ifdef __STDC__ 84: static int AHTUpload_callback (HTRequest *, HTStream *); 85: static AHTReqContext *AHTReqContext_new (int); 86: static void Thread_deleteAll (void); 87: static int authentication_handler (HTRequest *, void *, int); 1.7 cvs 88: static int redirection_handler (HTRequest *, HTResponse *, void *, int); 1.4 cvs 89: static int terminate_handler (HTRequest * request, HTResponse *, void *, int); 90: static int AHTLoadTerminate_handler (HTRequest *, HTResponse *, void *, int); 91: static int LoopForStop (AHTReqContext *); 92: static void AHTProfile_delete (void); 93: static void AHTAlertInit (void); 94: 95: #else 96: static int AHTUpload_callback (); 97: static AHTReqContext *AHTReqContext_new (); 98: static void Thread_deleteAll (); 99: static int authentication_handler (); 100: static int redirection_handler (); 101: static int terminate_handler (); 102: static int AHTLoadTerminate_handler (); 103: static int LoopForStop (); 104: static void AHTProfile_delete (); 105: static void AHTAlertInit (); 106: 107: #endif 108: 109: #ifdef CATCH_SIG 110: 1.5 cvs 111: /*---------------------------------------------------------------------- 112: SetSignal: This function sets up signal handlers. This might not 113: be necessary to call if the application has its own handlers. 114: ----------------------------------------------------------------------*/ 1.4 cvs 115: #ifdef __STDC__ 116: static void SetSignal (void) 117: #else 118: static void SetSignal () 119: #endif 120: { 121: /* On some systems (SYSV) it is necessary to catch the SIGPIPE signal 122: ** when attemting to connect to a remote host where you normally should 123: ** get `connection refused' back 124: */ 1.7 cvs 125: if (signal (SIGPIPE, SIG_IGN) == SIG_ERR) 126: { 127: if (PROT_TRACE) 128: HTTrace ("HTSignal.... Can't catch SIGPIPE\n"); 129: } 130: else 131: { 132: if (PROT_TRACE) 133: HTTrace ("HTSignal.... Ignoring SIGPIPE\n"); 134: } 1.4 cvs 135: } 136: #endif /* CATCH_SIG */ 137: 1.5 cvs 138: /*---------------------------------------------------------------------- 139: Create a new Amaya Context Object 140: 141: ----------------------------------------------------------------------*/ 1.4 cvs 142: #ifdef __STDC__ 143: static AHTReqContext *AHTReqContext_new (int docid) 144: #else 145: static AHTReqContext *AHTReqContext_new (docid) 146: int docid; 147: 148: #endif 149: { 150: AHTReqContext *me; 151: AHTDocId_Status *docid_status; 152: 153: if ((me = (AHTReqContext *) TtaGetMemory (sizeof (AHTReqContext))) == NULL) 154: outofmem (__FILE__, "Context_new"); 155: 156: /* Bind the Context object together with the Request Object */ 157: 158: me->request = HTRequest_new (); 159: 160: /*** This is for correcting the keep-alive bug. Is this interfering with */ 161: /**** libwww v5? */ 162: 163: /* test 164: me->request->GenMask &= ~((int) HT_G_CONNECTION); 1.7 cvs 165: */ 1.4 cvs 166: 167: /* Initialize the other members of the structure */ 168: me->reqStatus = HT_NEW; 169: me->output = NULL; 170: #ifdef WWW_XWINDOWS 171: me->read_xtinput_id = (XtInputId) NULL; 172: me->write_xtinput_id = (XtInputId) NULL; 173: me->except_xtinput_id = (XtInputId) NULL; 174: #endif 175: me->docid = docid; 176: HTRequest_setConversion (me->request, converters, YES); 177: HTRequest_setMethod (me->request, METHOD_GET); 178: HTRequest_setOutputFormat (me->request, WWW_SOURCE); 179: HTRequest_setContext (me->request, me); 180: 181: /* to interface with Eric's new routines */ 182: me->read_ops = 0; 183: me->write_ops = 0; 184: me->except_ops = 0; 185: 186: /* Update the global context */ 187: HTList_appendObject (Amaya->reqlist, (void *) me); 188: 189: docid_status = GetDocIdStatus (docid, Amaya->docid_status); 190: 1.7 cvs 191: if (docid_status == NULL) 192: { 193: docid_status = (AHTDocId_Status *) TtaGetMemory (sizeof (AHTDocId_Status)); 194: docid_status->docid = docid; 195: docid_status->counter = 1; 196: HTList_addObject (Amaya->docid_status, (void *) docid_status); 197: } 198: else 1.4 cvs 199: docid_status->counter++; 200: 201: 202: Amaya->open_requests++; 203: 204: /* error stream handling */ 205: me->error_stream = (char *) NULL; 206: me->error_stream_size = 0; 207: 208: return me; 209: } 210: 1.5 cvs 211: /*---------------------------------------------------------------------- 212: Delete an Amaya Context Object 213: ----------------------------------------------------------------------*/ 1.4 cvs 214: 215: #ifdef __STDC__ 216: BOOL AHTReqContext_delete (AHTReqContext * me) 217: #else 218: BOOL AHTReqContext_delete (me) 219: AHTReqContext *me; 220: 221: #endif 222: { 223: AHTDocId_Status *docid_status; 224: 1.7 cvs 225: if (me) 226: { 1.4 cvs 227: 1.7 cvs 228: if (Amaya->reqlist) 229: HTList_removeObject (Amaya->reqlist, (void *) me); 1.4 cvs 230: 1.7 cvs 231: docid_status = GetDocIdStatus (me->docid, Amaya->docid_status); 1.4 cvs 232: 1.7 cvs 233: if (docid_status) 234: { 235: docid_status->counter--; 236: 237: if (docid_status->counter == 0) 238: { 239: HTList_removeObject (Amaya->docid_status, (void *) docid_status); 240: TtaFreeMemory ((void *) docid_status); 241: } 242: } 243: HTRequest_delete (me->request); 1.4 cvs 244: 1.7 cvs 245: if (me->error_stream != (char *) NULL) 246: HT_FREE (me->error_stream); 1.4 cvs 247: 1.7 cvs 248: TtaFreeMemory ((void *) me); 1.4 cvs 249: 1.7 cvs 250: Amaya->open_requests--; 1.4 cvs 251: 1.7 cvs 252: return YES; 1.4 cvs 253: 1.7 cvs 254: } 1.4 cvs 255: return NO; 256: } 257: 258: 259: #ifdef __STDC__ 260: static int AHTUpload_callback (HTRequest * request, HTStream * target) 261: #else 262: static int AHTUpload_callback (request, target) 263: HTRequest *request; 264: HTStream *target; 265: 266: #endif 267: { 268: AHTReqContext *me = HTRequest_context (request); 1.7 cvs 269: HTParentAnchor *entity = HTRequest_entityAnchor (request); 270: int len = HTAnchor_length (entity); 1.4 cvs 271: int status; 272: 273: /* Send the data down the pipe */ 1.7 cvs 274: 1.4 cvs 275: status = (*target->isa->put_block) (target, me->mem_ptr, len); 276: 1.7 cvs 277: if (status == HT_LOADED || status == HT_OK) 278: { 1.13 ! cvs 279: if (PROT_TRACE) ! 280: HTTrace ("Posting Data Target is SAVED\n"); ! 281: (*target->isa->flush) (target); ! 282: return (HT_LOADED); 1.7 cvs 283: } 284: if (status == HT_WOULD_BLOCK) 285: { 286: if (PROT_TRACE) 287: HTTrace ("Posting Data Target WOULD BLOCK\n"); 288: return HT_WOULD_BLOCK; 289: } 290: else if (status == HT_PAUSE) 291: { 292: if (PROT_TRACE) 293: HTTrace ("Posting Data Target PAUSED\n"); 294: return HT_PAUSE; 295: } 296: else if (status > 0) 297: { /* Stream specific return code */ 298: if (PROT_TRACE) 299: HTTrace ("Posting Data. Target returns %d\n", status); 300: return status; 301: } 302: else 303: { /* we have a real error */ 304: if (PROT_TRACE) 305: HTTrace ("Posting Data Target ERROR %d\n", status); 306: return status; 307: } 1.4 cvs 308: } 309: 310: 1.5 cvs 311: /*---------------------------------------------------------------------- 312: Gets the status associated to a docid 313: ----------------------------------------------------------------------*/ 1.4 cvs 314: #ifdef __STDC__ 315: AHTDocId_Status *GetDocIdStatus (int docid, HTList * documents) 316: #else 317: AHTDocID_Status *GetDocIdStatus (docid, documents) 318: int docid; 319: HTList *documents; 320: 321: #endif 322: { 323: AHTDocId_Status *me; 324: HTList *cur; 325: 1.7 cvs 326: if (documents) 327: { 328: cur = documents; 329: 330: while ((me = (AHTDocId_Status *) HTList_nextObject (cur))) 331: { 332: if (me->docid == docid) 333: return (me); 334: } /* while */ 335: } /* if */ 1.4 cvs 336: return (AHTDocId_Status *) NULL; 337: 338: } 339: 1.5 cvs 340: /*---------------------------------------------------------------------- 341: This function deletes the whole list of active threads. 342: ----------------------------------------------------------------------*/ 1.4 cvs 343: #ifdef __STDC__ 344: static void Thread_deleteAll (void) 345: #else 346: static void Thread_deleteAll () 347: #endif 348: { 1.7 cvs 349: if (Amaya && Amaya->reqlist) 350: { 351: if (Amaya->open_requests > 0) 352: { 353: HTList *cur = Amaya->reqlist; 354: AHTReqContext *me; 355: AHTDocId_Status *docid_status; 356: 357: HTNet_killAll (); 358: /* erase the requests */ 359: while ((me = (AHTReqContext *) HTList_nextObject (cur))) 360: { 361: if (me->request) 362: { 1.4 cvs 363: #ifdef WWW_XWINDOWS 1.7 cvs 364: RequestKillAllXtevents (me); 1.4 cvs 365: #endif /* WWW_XWINDOWS */ 1.7 cvs 366: /* HTRequest_kill(me->request); 367: if(me->output) 368: fclose(me->output); 369: */ 370: AHTReqContext_delete (me); 371: } 372: } /* while */ 373: HTList_delete (Amaya->reqlist); 374: /* erase the docid_status entities */ 375: while ((docid_status = (AHTDocId_Status *) HTList_removeLastObject ((void *) Amaya->docid_status))) 376: TtaFreeMemory ((void *) docid_status); 377: 378: HTList_delete (Amaya->reqlist); 379: } /* if */ 380: TtaFreeMemory ((void *) Amaya); 381: } 1.4 cvs 382: } 383: 1.5 cvs 384: /*---------------------------------------------------------------------- 385: authentication_handler 386: This function is registered to handle access authentication, 387: for example for HTTP 388: ----------------------------------------------------------------------*/ 1.4 cvs 389: #ifdef __STDC__ 390: static int authentication_handler (HTRequest * request, void *context, int status) 391: #else 392: static int authentication_handler (request, context, status) 393: HTRequest *request; 394: void *context; 395: int status; 396: 397: #endif 398: { 399: AHTReqContext *me = HTRequest_context (request); 400: 401: 402: /* check how many times we have passed this way, to protect against 1.7 cvs 403: ** traviserrors (tm) 1.4 cvs 404: */ 405: 406: /* Ask the authentication module for getting credentials */ 407: 1.7 cvs 408: if (HTRequest_retrys (request) /*&& HTBasic_parse (request, context, status) */ ) 409: { 1.4 cvs 410: 1.7 cvs 411: /* Make sure we do a reload from cache */ 412: /* 413: #ifndef HACK_WWW 414: HTRequest_setReloadMode(request, HT_FORCE_RELOAD); 415: #endif 416: */ 417: /* Log current request */ 418: if (HTLog_isOpen ()) 419: HTLog_add (request, status); 1.4 cvs 420: 1.7 cvs 421: /* Start request with new credentials */ 1.4 cvs 422: 423: /*** 424: if(me->xtinput_id != (XtInputId) NULL ) { 425: if (THD_TRACE) 426: fprintf(stderr, "AH: Removing Xtinput: %lu\n", 427: me->xtinput_id); 428: XtRemoveInput(me->xtinput_id); 429: me->xtinput_id = (XtInputId) NULL; 430: } 431: ***/ 432: 1.7 cvs 433: /* Start request with new credentials */ 434: me->reqStatus = HT_NEW; 1.4 cvs 435: 1.7 cvs 436: if (me->method == METHOD_PUT || me->method == METHOD_POST) 437: /* PUT, POST etc. */ 438: /* HTCopyAnchor((HTAnchor *) HTRequest_anchor(request), request); */ 439: status = HTLoadAbsolute (me->urlName, request); 440: else 441: HTLoadAnchor ((HTAnchor *) HTRequest_anchor (request), request); 442: 443: } 444: else 445: { 446: TtaSetStatus (me->docid, 1, TtaGetMessage (AMAYA, AM_ACCESS_DENIED), 447: me->urlName); 448: me->reqStatus = HT_ERR; 449: if (me->error_html) 450: FilesLoading[me->docid] = 2; /* so we can show the error message */ 451: } 1.4 cvs 452: 453: return HT_ERROR; /* Make sure this is the last callback in the list */ 454: } 455: 456: 1.5 cvs 457: /*---------------------------------------------------------------------- 458: redirection_handler 1.4 cvs 459: ** This function is registered to handle permanent and temporary 460: ** redirections 1.5 cvs 461: 462: 1.4 cvs 463: [x] Verfiy Put, Post 464: [ ] Verify if NormalizeURL is not redundant 465: [ ] Errors, should be done here or in terminate handler?? 1.5 cvs 466: 467: ----------------------------------------------------------------------*/ 1.4 cvs 468: #ifdef __STDC__ 1.7 cvs 469: static int redirection_handler (HTRequest * request, HTResponse * response, void *param, int status) 1.4 cvs 470: #else 471: static int redirection_handler (request, context, status) 472: HTRequest *request; 473: HTResponse *response; 474: void *param; 475: int status; 476: 477: #endif 478: { 479: 480: char *ref; 481: HTAnchor *new_anchor = HTResponse_redirection (response); 1.7 cvs 482: AHTReqContext *me = HTRequest_context (request); 1.4 cvs 483: HTMethod method = HTRequest_method (request); 484: 485: 1.7 cvs 486: if (!new_anchor) 487: { 488: if (PROT_TRACE) 489: HTTrace ("Redirection. No destination\n"); 490: return HT_OK; 491: } 1.4 cvs 492: 493: /* 494: ** Only do redirect on GET and HEAD 495: */ 1.7 cvs 496: if (!HTMethod_isSafe (method)) 497: { 498: HTAlertCallback *prompt = HTAlert_find (HT_A_CONFIRM); 499: 500: if (prompt) 501: { 502: if ((*prompt) (request, HT_A_CONFIRM, HT_MSG_REDIRECTION, 503: NULL, NULL, NULL) != YES) 504: return HT_ERROR; 505: } 506: } 1.4 cvs 507: 508: /* 509: ** Start new request with the redirect anchor found in the headers. 510: ** Note that we reuse the same request object which means that we must 511: ** keep this around until the redirected request has terminated. It also 512: ** allows us in an easy way to keep track of the number of redirections 513: ** so that we can detect endless loops. 514: */ 1.7 cvs 515: if (HTRequest_doRetry (request)) 516: { 517: 518: /* Verify if this is not redundant */ 519: 520: /* do we need to normalize the URL? */ 521: if (strncmp (new_anchor->parent->address, "http:", 5)) 522: { 523: /* Yes, so we use the pre-redirection anchor as a base name */ 524: ref = HTParse (new_anchor->parent->address, me->urlName, PARSE_ALL); 525: if (ref) 526: { 527: HT_FREE (new_anchor->parent->address); 528: new_anchor->parent->address = ref; 529: } 530: } 531: 532: /* update the current file name */ 533: if (strlen (new_anchor->parent->address) > (MAX_LENGTH - 1)) 534: { 535: /* 536: ** copy MAX_LENGTH cars. The error will be detected later on and shown on the 537: ** screen. This code will be fixed up later on 538: */ 539: strncpy (me->urlName, new_anchor->parent->address, MAX_LENGTH); 540: me->urlName[MAX_LENGTH] = '\0'; 541: } 542: else 543: strcpy (me->urlName, new_anchor->parent->address); 544: 545: TtaSetStatus (me->docid, 1, TtaGetMessage (AMAYA, AM_RED_FETCHING), 546: me->urlName); 547: 548: /* Start request with new credentials */ 1.4 cvs 549: 1.7 cvs 550: me->reqStatus = HT_NEW; 551: if (me->method == METHOD_PUT || me->method == METHOD_POST) /* PUT, POST etc. */ 552: /* HTCopyAnchor((HTAnchor *) HTRequest_anchor(request), request); */ 553: status = HTLoadAbsolute (me->urlName, request); 554: else 555: HTLoadAnchor (new_anchor, request); 556: } 557: else 558: { 559: HTRequest_addError (request, ERR_FATAL, NO, HTERR_MAX_REDIRECT, 560: NULL, 0, "HTRedirectFilter"); 561: TtaSetStatus (me->docid, 1, TtaGetMessage (AMAYA, AM_REDIRECTIONS_LIMIT), 562: NULL); 563: if (me->error_html) 564: FilesLoading[me->docid] = 2; /* so we can show the error message */ 565: } 1.4 cvs 566: 567: /* 1.7 cvs 568: ** By returning HT_ERROR we make sure that this is the last handler to be 569: ** called. We do this as we don't want any other filter to delete the 570: ** request object now when we have just started a new one ourselves 571: */ 1.4 cvs 572: return HT_ERROR; 573: } 574: 1.5 cvs 575: /*---------------------------------------------------------------------- 576: terminate_handler 1.4 cvs 577: ** This function is registered to handle the result of the request 1.5 cvs 578: 579: ----------------------------------------------------------------------*/ 1.4 cvs 580: #if __STDC__ 1.7 cvs 581: static int terminate_handler (HTRequest * request, HTResponse * response, void *context, int status) 1.4 cvs 582: #else 583: static int terminate_handler (request, response, context, status) 584: HTRequest *request; 585: HTResponse *response; 586: void *context; 587: int status; 588: 589: #endif 590: { 591: AHTReqContext *me = (AHTReqContext *) HTRequest_context (request); 1.13 ! cvs 592: boolean error_flag; 1.4 cvs 593: 594: if (!me) 595: return HT_OK; /* not an Amaya request */ 596: 1.13 ! cvs 597: if (status == HT_LOADED || status == HT_CREATED || status == HT_NO_DATA) ! 598: error_flag = FALSE; ! 599: else ! 600: error_flag = TRUE; ! 601: 1.4 cvs 602: /* output any errors from the server */ 603: 1.5 cvs 604: /*** 1.4 cvs 605: ** me->output = output file which will receive an html file 606: ** me->error_html = yes, output HTML errors in the screen 607: ** request->error_stack == if there are any errors, they will be here 608: ** me->error_stream_size If it's != 0 means an error message has already 609: ** been written to the stack 610: */ 611: 612: /* First, we verify if there are any errors and if they are not 613: ** yet written to the error stack. If no, then let's try to write them 614: ** ourselves 615: */ 616: 1.7 cvs 617: if (me->output && me->output != stdout) 618: { 619: /* we are writing to a file */ 620: if (me->reqStatus != HT_ABORT) 621: { /* if the request was not aborted and */ 1.13 ! cvs 622: if (error_flag) ! 623: { /* there were some errors */ ! 624: if (me->error_html == YES) ! 625: { /* and we want to print errors */ ! 626: if (me->error_stream_size == 0) /* and the stream is empty */ 1.7 cvs 627: AHTError_MemPrint (request); /* copy errors from the error stack 628: ** into a data structure */ 629: if (me->error_stream) 630: { /* if the stream is non-empty */ 631: fprintf (me->output, me->error_stream); /* output the errors */ 1.13 ! cvs 632: error_flag = FALSE; /* show it in the HTML window */ 1.7 cvs 633: } 634: else 635: me->reqStatus = HT_ERR; /* we did not get an error msg, 636: ** so just 637: ** mark error 638: */ 639: } 640: else 641: me->reqStatus = HT_ERR; /* we don't want to print the error */ 642: } /* if error_stack */ 1.13 ! cvs 643: } /* if != HT_ABORT */ 1.7 cvs 644: fclose (me->output); 645: } 646: else 647: { 648: /* We must be doing a PUT. Verify if there was an error */ 1.13 ! cvs 649: if (error_flag) ! 650: me->reqStatus = HT_ERR; 1.7 cvs 651: } /* if me-output */ 652: 1.4 cvs 653: /* setup the request status and invoke the cbf */ 1.7 cvs 654: 1.4 cvs 655: /* work to be done: verify if we can put join all the terminate cbf in 656: only one call after the following lines */ 1.7 cvs 657: 1.13 ! cvs 658: if (!error_flag && me->reqStatus != HT_ERR 1.7 cvs 659: && me->reqStatus != HT_ABORT) 660: { 661: me->reqStatus = HT_END; /* no errors */ 662: if (me->terminate_cbf) 663: (*me->terminate_cbf) ((AHTReqContext *) me, 664: HT_LOADED); 665: } 666: else if (me->reqStatus == HT_ABORT) 667: { 668: if (me->terminate_cbf) 669: (*me->terminate_cbf) ((AHTReqContext *) me, 670: HT_ERROR); 671: if (me->outputfile && me->outputfile[0] != EOS) 672: { 1.9 cvs 673: TtaFileUnlink (me->outputfile); 1.7 cvs 674: me->outputfile[0] = EOS; 675: } 676: } 677: else if (me->reqStatus == HT_ERR) 678: { 679: /* there was an error */ 680: if (me->terminate_cbf) 681: (*me->terminate_cbf) ((AHTReqContext *) me, 682: HT_ERROR); 683: 684: if (me->outputfile && me->outputfile[0] != EOS) 685: { 1.9 cvs 686: TtaFileUnlink (me->outputfile); 1.7 cvs 687: me->outputfile[0] = EOS; 688: } 1.4 cvs 689: } 1.13 ! cvs 690: else if (error_flag && 1.7 cvs 691: (me->reqStatus == HT_BUSY || me->reqStatus == HT_WAITING)) 692: { 693: /* there was an error */ 694: if (me->terminate_cbf) 695: (*me->terminate_cbf) ((AHTReqContext *) me, 696: HT_ERROR); 697: 698: if (me->outputfile && me->outputfile[0] != EOS) 699: { 1.9 cvs 700: TtaFileUnlink (me->outputfile); 1.7 cvs 701: me->outputfile[0] = EOS; 702: me->reqStatus = HT_ERR; 703: } 704: } /* if-else HT_END, HT_ABORT, HT_ERROR */ 1.4 cvs 705: if (HTLog_isOpen ()) 1.7 cvs 706: HTLog_add (request, status); 1.4 cvs 707: 1.7 cvs 708: if ((me->mode & AMAYA_ASYNC) || (me->mode & AMAYA_IASYNC)) 709: { 710: TtaFreeMemory (me->urlName); 711: TtaFreeMemory (me->outputfile); 712: /* AHTReqContext_delete(me); */ 713: } 1.4 cvs 714: /* don't remove or Xt will hang up during the put */ 715: 1.7 cvs 716: if (me->method == METHOD_PUT || me->method == METHOD_POST) 717: { 718: TtaSetStatus (me->docid, 1, TtaGetMessage (AMAYA, AM_PROG_WRITE), 719: me->urlName); 1.4 cvs 720: 1.7 cvs 721: } 1.4 cvs 722: return HT_OK; 723: } 724: 1.5 cvs 725: /*---------------------------------------------------------------------- 726: Application "AFTER" Callback 727: This function uses all the functionaly that the app part of 728: the Library gives for handling AFTER a request. 729: ----------------------------------------------------------------------*/ 1.4 cvs 730: 731: #ifdef __STDC__ 1.7 cvs 732: static int AHTLoadTerminate_handler (HTRequest * request, HTResponse * response, void *param, int status) 1.4 cvs 733: #else 734: static int AHTLoadTerminate_handler (request, response, param, status) 735: HTRequest *request; 736: HTResponse *response; 737: void *param; 738: int status; 739: 740: #endif 741: { 742: char *uri = HTAnchor_address ((HTAnchor *) request->anchor); 743: AHTReqContext *me = HTRequest_context (request); 744: HTAlertCallback *cbf; 745: AHTDocId_Status *docid_status; 746: 1.7 cvs 747: switch (status) 748: { 749: case HT_LOADED: 750: if (PROT_TRACE) 751: HTTrace ("Load End.... OK: `%s\' has been accessed\n", 1.4 cvs 752: uri); 753: 1.7 cvs 754: docid_status = GetDocIdStatus (me->docid, 755: Amaya->docid_status); 756: 757: if (docid_status != NULL && docid_status->counter > 1) 758: TtaSetStatus (me->docid, 1, TtaGetMessage (AMAYA, 759: AM_ELEMENT_LOADED), uri); 760: 761: break; 762: 763: case HT_NO_DATA: 764: if (PROT_TRACE) 765: HTTrace ("Load End.... OK BUT NO DATA: `%s\'\n", uri); 766: TtaSetStatus (me->docid, 1, TtaGetMessage (AMAYA, AM_LOADED_NO_DATA), 767: uri); 768: break; 769: 770: case HT_INTERRUPTED: 771: if (PROT_TRACE) 772: HTTrace ("Load End.... INTERRUPTED: `%s\'\n", uri); 773: TtaSetStatus (me->docid, 1, TtaGetMessage (AMAYA, AM_LOAD_ABORT), NULL); 774: 775: break; 776: 777: case HT_RETRY: 778: if (PROT_TRACE) 779: HTTrace ("Load End.... NOT AVAILABLE, RETRY AT %ld\n", 780: HTResponse_retryTime (response)); 781: TtaSetStatus (me->docid, 1, TtaGetMessage (AMAYA, AM_NOT_AVAILABLE_RETRY), 782: uri); 783: break; 784: 785: case HT_ERROR: 786: 787: cbf = HTAlert_find (HT_A_MESSAGE); 788: if (cbf) 789: (*cbf) (request, HT_A_MESSAGE, HT_MSG_NULL, NULL, 790: HTRequest_error (request), NULL); 791: break; 792: 793: if (PROT_TRACE) 794: HTTrace ("Load End.... ERROR: Can't access `%s\'\n", 795: uri ? uri : "<UNKNOWN>"); 796: TtaSetStatus (me->docid, 1, TtaGetMessage (AMAYA, AM_CANNOT_LOAD), 797: uri ? uri : "<UNKNOWN>"); 798: break; 799: default: 800: if (PROT_TRACE) 801: HTTrace ("Load End.... UNKNOWN RETURN CODE %d\n", status); 802: break; 803: } 804: 1.4 cvs 805: /* Should we do logging? */ 806: if (HTLog_isOpen ()) 1.7 cvs 807: HTLog_add (request, status); 1.4 cvs 808: HT_FREE (uri); 1.7 cvs 809: 1.4 cvs 810: return HT_OK; 811: } 812: 813: /* 814: ** After filter for handling PUT of document. We should now have the 815: */ 1.7 cvs 816: static int AHTSaveFilter (HTRequest * request, HTResponse * response, void *param, int status) 1.4 cvs 817: { 818: AHTReqContext *me = HTRequest_context (request); 819: 820: if (APP_TRACE) 1.7 cvs 821: HTTrace ("Save Filter\n"); 1.4 cvs 822: 823: /* 1.7 cvs 824: ** Just ignore authentication in the hope that some other filter will 825: ** handle this. 1.4 cvs 826: */ 1.7 cvs 827: 828: if (status == HT_NO_ACCESS || status == HT_NO_PROXY_ACCESS) 829: { 830: if (APP_TRACE) 831: HTTrace ("Save Filter. Waiting for authentication\n"); 832: status = HT_OK; 833: } 834: else if (status == HT_TEMP_REDIRECT || status == HT_PERM_REDIRECT) 835: { 1.4 cvs 836: /* 1.7 cvs 837: ** The destination entity has been redirected. Ask the user 838: ** what to do. If there is no user confirmation to go ahead then stop 839: */ 840: /* put here the equiv. code of redirection handler, and a prompt 841: for user */ 842: HTAlertCallback *prompt = HTAlert_find (HT_A_CONFIRM); 843: HTAnchor *redirection = HTResponse_redirection (response); 844: 845: if (prompt && redirection) 846: { 847: if ((*prompt) (request, HT_A_CONFIRM, HT_MSG_SOURCE_MOVED, 848: NULL, NULL, NULL) == YES) 849: { 850: return HT_OK; 851: } 852: else 853: { 854: /* 855: ** Make sure that the operation stops 856: */ 857: me->reqStatus = HT_ABORT; 1.4 cvs 858: 1.7 cvs 859: /* add a message? */ 1.4 cvs 860: 1.7 cvs 861: status = HT_ERROR; 862: } 863: } 864: status = HT_OK; 865: } 866: else if (status == HT_ERROR) 867: { 868: if (me->reqStatus != HT_ABORT && me->reqStatus != HT_END) 869: me->reqStatus = HT_ERR; 870: } 871: else 872: { 873: /* 874: ** No authentication or redirection was detected ... let's erase this filter 875: ** 876: */ 877: HTRequest_deleteAfter (request, AHTSaveFilter); 1.4 cvs 878: status = HT_OK; 1.7 cvs 879: } 1.4 cvs 880: 1.7 cvs 881: return status; 1.4 cvs 882: 883: } 884: 885: 1.5 cvs 886: /*---------------------------------------------------------------------- 887: BINDINGS BETWEEN A SOURCE MEDIA TYPE AND A DEST MEDIA TYPE (CONVERSION) 888: ----------------------------------------------------------------------*/ 1.4 cvs 889: 890: static void AHTConverterInit (HTList * c) 891: { 892: 893: /* Handler for custom http error messages */ 1.7 cvs 894: HTConversion_add (c, "*/*", "www/debug", AHTMemConverter, 1.0, 0.0, 0.0); 1.4 cvs 895: 896: /* 897: ** These are converters that converts to something other than www/present, 898: ** that is not directly outputting someting to the user on the screen 899: */ 900: 901: HTConversion_add (c, "message/rfc822", "*/*", HTMIMEConvert, 1.0, 0.0, 0.0); 902: HTConversion_add (c, "message/x-rfc822-foot", "*/*", HTMIMEFooter, 903: 1.0, 0.0, 0.0); 904: HTConversion_add (c, "message/x-rfc822-head", "*/*", HTMIMEHeader, 905: 1.0, 0.0, 0.0); 906: HTConversion_add (c, "multipart/*", "*/*", HTBoundary, 907: 1.0, 0.0, 0.0); 908: HTConversion_add (c, "text/plain", "text/html", HTPlainToHTML, 909: 1.0, 0.0, 0.0); 910: 911: 912: /* 913: ** The following conversions are converting ASCII output from various 914: ** protocols to HTML objects. 915: */ 916: HTConversion_add (c, "text/x-http", "*/*", HTTPStatus_new, 917: 1.0, 0.0, 0.0); 918: HTConversion_add (c, "text/x-nntp-list", "*/*", HTNewsList, 919: 1.0, 0.0, 0.0); 920: HTConversion_add (c, "text/x-nntp-over", "*/*", HTNewsGroup, 921: 1.0, 0.0, 0.0); 922: 923: 924: /* 925: ** We also register a special content type guess stream that can figure out 926: ** the content type by reading the first bytes of the stream 927: */ 928: HTConversion_add (c, "www/unknown", "*/*", HTGuess_new, 929: 1.0, 0.0, 0.0); 930: 931: /* 932: ** Register a persistent cache stream which can save an object to local 933: ** file 934: */ 935: HTConversion_add (c, "www/cache", "*/*", HTCacheWriter, 936: 1.0, 0.0, 0.0); 937: 938: /* 939: ** This dumps all other formats to local disk without any further 940: ** action taken 941: */ 942: HTConversion_add (c, "*/*", "www/present", HTSaveLocally, 943: 0.3, 0.0, 0.0); 944: 945: #if 0 /* no use to send this in our request */ 946: HTConversion_add (c, "application/octet-stream", "www/present", 947: HTSaveLocally, 0.1, 0.0, 0.0); 948: HTConversion_add (c, "application/x-compressed", "www/present", 949: HTSaveLocally, 0.1, 0.0, 0.0); 950: #endif 951: 952: /* Normal converters */ 953: /* this one was 0.5 before */ 954: #if 0 955: HTConversion_add (c, "*/*", "www/present", HTSaveLocally, 1.0, 0.0, 0.0); 956: #endif 957: 958: } 959: 960: /* REGISTER BEFORE AND AFTER FILTERS 961: ** We register a commonly used set of BEFORE and AFTER filters. 962: ** Not done automaticly - may be done by application! 963: */ 964: 965: /* REGISTER ALL AMAYA SUPPORTED PROTOCOLS 966: */ 967: static void AHTProtocolInit (void) 968: { 969: 970: /* NB. Preemptive == YES = Blocking request 971: ** Non-preemptive == NO = Non-blocking request 972: */ 973: 974: HTProtocol_add ("http", "buffered_tcp", NO, HTLoadHTTP, NULL); 975: /* HTProtocol_add ("http", "tcp", NO, HTLoadHTTP, NULL); */ 976: HTProtocol_add ("file", "local", NO, HTLoadFile, NULL); 977: HTProtocol_add ("cache", "local", NO, HTLoadCache, NULL); 978: HTProtocol_add ("telnet", "", YES, HTLoadTelnet, NULL); 979: HTProtocol_add ("tn3270", "", YES, HTLoadTelnet, NULL); 980: HTProtocol_add ("rlogin", "", YES, HTLoadTelnet, NULL); 981: 982: HTProtocol_add ("ftp", "tcp", NO, HTLoadFTP, NULL); 983: HTProtocol_add ("nntp", "tcp", NO, HTLoadNews, NULL); 984: HTProtocol_add ("news", "tcp", NO, HTLoadNews, NULL); 985: } 986: 987: static void AHTNetInit (void) 988: { 989: 990: /* Register BEFORE filters 991: ** The BEFORE filters handle proxies, caches, rule files etc. 992: ** The filters are called in the order by which the are registered 993: ** Not done automaticly - may be done by application! 994: */ 995: 996: 1.7 cvs 997: /*#ifndef HACK_WWW */ 998: HTNet_addBefore (HTCredentialsFilter, "http://*", NULL, 6); 999: HTNet_addBefore (HTProxyFilter, NULL, NULL, 10); 1.4 cvs 1000: 1.7 cvs 1001: /*#endif */ 1.4 cvs 1002: 1003: /* register AFTER filters 1004: ** The AFTER filters handle error messages, logging, redirection, 1005: ** authentication etc. 1006: ** The filters are called in the order by which the are registered 1007: ** Not done automaticly - may be done by application! 1008: */ 1009: 1010: #ifndef HACK_WWW 1011: 1.7 cvs 1012: HTNet_addAfter (HTAuthFilter, "http://*", NULL, HT_NO_ACCESS, 1013: 5); 1.4 cvs 1014: 1.7 cvs 1015: HTNet_addAfter (redirection_handler, "http://*", NULL, HT_TEMP_REDIRECT, 1016: 5); 1017: HTNet_addAfter (redirection_handler, "http://*", NULL, HT_PERM_REDIRECT, 1018: 5); 1019: HTNet_addAfter (HTUseProxyFilter, "http://*", NULL, HT_USE_PROXY, 1020: 5); 1.4 cvs 1021: 1.7 cvs 1022: HTNet_addAfter (AHTLoadTerminate_handler, NULL, NULL, HT_ALL, HT_FILTER_LAST); /* handles all errors */ 1023: HTNet_addAfter (terminate_handler, NULL, NULL, HT_ALL, HT_FILTER_LAST); 1.4 cvs 1024: #endif 1025: } 1026: 1027: static void AHTProfile_newAmaya (const char *AppName, const char *AppVersion) 1028: { 1029: /* If the Library is not already initialized then do it */ 1030: if (!HTLib_isInitialized ()) 1031: HTLibInit (AppName, AppVersion); 1032: 1033: if (!converters) 1034: converters = HTList_new (); 1035: if (!encodings) 1036: encodings = HTList_new (); 1037: 1038: /* Register the default set of transport protocols */ 1039: HTTransportInit (); 1040: 1041: /* Register the default set of application protocol modules */ 1042: #ifndef HACK_WWW 1043: AHTProtocolInit (); 1044: #endif 1045: 1046: /* Enable the persistent cache */ 1047: /* HTCacheInit (NULL, 20); */ 1048: 1049: /* Register the default set of BEFORE and AFTER filters */ 1050: AHTNetInit (); 1051: 1052: /* Set up the default set of Authentication schemes */ 1053: HTAAInit (); 1054: 1055: /* Get any proxy or gateway environment variables */ 1056: HTProxy_getEnvVar (); 1057: 1058: /* Register the default set of converters */ 1059: AHTConverterInit (converters); 1060: HTFormat_setConversion (converters); 1061: 1062: /* Register the default set of transfer encoders and decoders */ 1063: HTEncoderInit (encodings); /* chunks ??? */ 1064: HTFormat_setTransferCoding (encodings); 1065: 1066: /* Register the default set of MIME header parsers */ 1067: HTMIMEInit (); /* must be called again for language selector */ 1068: 1069: /* Register the default set of file suffix bindings */ 1070: HTFileInit (); 1071: 1072: /* Register the default set of Icons for directory listings */ 1073: /*HTIconInit(NULL); *//*is this useful ? */ 1074: 1075: /* Register the default set of messages and dialog functions */ 1076: AHTAlertInit (); 1077: HTAlert_setInteractive (YES); 1078: } 1079: 1.5 cvs 1080: /*---------------------------------------------------------------------- 1081: ----------------------------------------------------------------------*/ 1.4 cvs 1082: 1083: #ifdef __STDC__ 1084: static void AHTProfile_delete (void) 1085: #else 1086: static void AHTProfile_delete () 1.7 cvs 1087: #endif /* __STDC__ */ 1.4 cvs 1088: { 1.7 cvs 1089: if (HTLib_isInitialized ()) 1090: { 1.4 cvs 1091: 1.7 cvs 1092: /* Clean up the persistent cache (if any) */ 1093: HTCacheTerminate (); 1.4 cvs 1094: 1.7 cvs 1095: /* Clean up all the global preferences */ 1096: HTFormat_deleteAll (); 1.4 cvs 1097: 1.7 cvs 1098: HTLibTerminate (); 1099: /* Terminate libwww */ 1100: } 1.4 cvs 1101: } 1102: 1103: /* REGISTER CALLBACKS FOR THE ALERT MANAGER 1104: ** We register a set of alert messages 1105: */ 1106: 1.5 cvs 1107: /*---------------------------------------------------------------------- 1108: ----------------------------------------------------------------------*/ 1109: 1.4 cvs 1110: #ifdef __STDC__ 1111: static void AHTAlertInit (void) 1112: #else 1113: static void AHTAlertInit () 1114: #endif 1115: { 1116: 1117: HTAlert_add (AHTProgress, HT_A_PROGRESS); 1118: HTAlert_add ((HTAlertCallback *) Add_NewSocket_to_Loop, HT_PROG_CONNECT); 1.7 cvs 1119: HTAlert_add (AHTError_print, HT_A_MESSAGE); 1120: HTError_setShow (0xFF); /* process all messages */ 1.4 cvs 1121: /* HTAlert_add (HTError_print, HT_A_MESSAGE); */ 1122: HTAlert_add (AHTConfirm, HT_A_CONFIRM); 1123: HTAlert_add (AHTPrompt, HT_A_PROMPT); 1124: HTAlert_add (AHTPromptPassword, HT_A_SECRET); 1125: HTAlert_add (AHTPromptUsernameAndPassword, HT_A_USER_PW); 1126: /* Setup a global call to input XtEvents for new sockets */ 1127: /* should not be necessary anymore */ 1128: 1129: } 1130: 1.5 cvs 1131: /*---------------------------------------------------------------------- 1132: ----------------------------------------------------------------------*/ 1.4 cvs 1133: #ifdef __STDC__ 1134: void QueryInit () 1135: #else 1136: void QueryInit () 1137: #endif 1138: { 1139: 1140: AHTProfile_newAmaya (HTAppName, HTAppVersion); 1141: 1142: /* New AHTBridge stuff */ 1143: 1144: HTEvent_setRegisterCallback (AHTEvent_register); 1145: HTEvent_setUnregisterCallback (AHTEvent_unregister); 1146: 1147: /* Setup authentication manager */ 1148: /*** 1149: HTAuthCall_add("basic", HTBasic_parse, HTBasic_generate, HTBasic_delete); 1150: ****/ 1151: 1152: /* Trace activation (for debugging) */ 1.7 cvs 1153: /* 1.4 cvs 1154: WWW_TraceFlag = SHOW_APP_TRACE | SHOW_UTIL_TRACE | 1155: SHOW_BIND_TRACE | SHOW_THREAD_TRACE | 1156: SHOW_STREAM_TRACE | SHOW_PROTOCOL_TRACE | 1157: SHOW_URI_TRACE | SHOW_AUTH_TRACE | SHOW_ANCHOR_TRACE | 1158: SHOW_CORE_TRACE; 1159: 1.7 cvs 1160: */ 1.4 cvs 1161: 1162: /*** 1163: WWW_TraceFlag = SHOW_CORE_TRACE | SHOW_AUTH_TRACE | SHOW_ANCHOR_TRACE | 1164: SHOW_PROTOCOL_TRACE| SHOW_APP_TRACE | SHOW_UTIL_TRACE; 1165: ***/ 1166: 1167: HTBind_caseSensitive (FALSE); 1168: HTBind_addType ("html", "text/html", 0.9); 1169: HTBind_addType ("htm", "text/html", 0.9); 1170: HTBind_addType ("gif", "image/gif", 0.9); 1171: HTBind_addType ("png", "image/png", 0.9); 1172: HTBind_addType ("jpg", "image/jpeg", 0.9); 1173: HTBind_addType ("txt", "text/plain", 0.9); 1174: 1175: /* Setting up other user interfaces */ 1176: /* needs a little bit more work */ 1177: 1178: /* Setting up handlers */ 1179: #ifndef HACK_WWW 1180: /* HTNetCall_addBefore(HTLoadStart, NULL, 0); */ 1181: #endif 1182: 1183: /* Setting up different network parameters */ 1184: HTNet_setMaxSocket (8); 1185: HTDNS_setTimeout (3600); 1186: HTCacheMode_setEnabled (0); 1187: 1188: /* Initialization of the global context */ 1189: Amaya = (AmayaContext *) TtaGetMemory (sizeof (AmayaContext)); 1190: Amaya->reqlist = HTList_new (); 1191: Amaya->docid_status = HTList_new (); 1192: Amaya->open_requests = 0; 1193: 1194: #ifdef CATCH_SIG 1195: SetSignal (); 1196: #endif 1197: 1.12 cvs 1198: 1.4 cvs 1199: } 1200: 1201: 1.5 cvs 1202: /*---------------------------------------------------------------------- 1203: ----------------------------------------------------------------------*/ 1.4 cvs 1204: void QueryClose () 1205: { 1206: /** HTConversion_deleteAll(converters); **/ 1207: /* Later, the following call should use all the active docids. For the mome 1208: nt, it stops everything */ 1209: /* StopRequest (); */ 1210: Thread_deleteAll (); 1211: 1212: #ifndef HACK_WWW 1213: /** HTAuthInfo_deleteAll (); **/ 1214: #endif 1215: HTProxy_deleteAll (); 1216: HTNoProxy_deleteAll (); 1217: HTGateway_deleteAll (); 1218: AHTProfile_delete (); 1219: } 1220: 1221: 1.5 cvs 1222: /*---------------------------------------------------------------------- 1223: GetObjectWWW loads the file designated by urlName in a temporary 1224: file. 1225: 1226: 4 file retrieval modes are proposed: 1227: AMAYA_SYNC : blocking mode 1228: AMAYA_ISYNC : incremental, blocking mode 1229: AMAYA_ASYNC : non-blocking mode 1230: AMAYA_IASYNC : incremental, non-blocking mode 1231: 1232: In the incremental mode, each time a package arrives, it will be 1233: stored in the temporary file. In addition, if an 1234: incremental_callback function is defined, this function will be 1235: called and handled a copy of the newly received data package. 1236: Finally, if a terminate_callback function is defined, it will be 1237: invoked when the request terminates. The caller of this function 1.4 cvs 1238: can define two different contexts to be passed to the callback 1239: functions. 1240: 1241: When the function is called with the SYNC mode, the function will 1242: return only when the requested file has been loaded. 1243: The ASYNC mode will immediately return after setting up the 1244: call. 1245: 1246: Notes: 1247: At the end of a succesful request, the urlName string contains the 1248: name of the actually retrieved URL. As a URL can change over the time, 1249: (e.g., be redirected elsewhere), it is advised that the function 1250: caller verifies the value of the urlName variable at the end of 1251: a request. 1252: 1253: Inputs: 1254: - docid Document identifier for the set of objects being 1255: retrieved. 1256: - urlName The URL to be retrieved (MAX_URL_LENGTH chars length) 1257: - outputfile A pointer to an empty string of MAX_URL_LENGTH. 1258: - mode The retrieval mode. 1259: - incremental_cbf 1260: - context_icbf 1261: Callback and context for the incremental modes 1262: - terminate_cbf 1263: - context_icbf 1264: Callback and context for a terminate handler 1265: 1266: Outputs: 1267: - urlName The URL that was retrieved 1268: - outputfile The name of the temporary file which holds the 1269: retrieved data. (Only in case of success) 1270: Returns: 1271: HT_ERROR 1272: HT_OK 1.5 cvs 1273: 1274: ----------------------------------------------------------------------*/ 1.4 cvs 1275: #ifdef __STDC__ 1276: int GetObjectWWW (int docid, char *urlName, char *postString, 1277: char *outputfile, int mode, 1278: TIcbf * incremental_cbf, void *context_icbf, 1279: TTcbf * terminate_cbf, void *context_tcbf, BOOL error_html) 1280: #else 1281: int GetObjectWWW (docid, urlName, postString, outputfile, mode, 1282: incremental_cbf, context_icbf, terminate_cbf, context_tcbf, 1283: error_html) 1284: int docid; 1285: char *urlName; 1286: char *postString; 1287: char *outputfile; 1288: int mode; 1289: TIcbf *incremental_cbf; 1290: void *context_icbf; 1291: TTcbf *terminate_cbf; 1292: void *context_tcbf; 1293: BOOL error_html; 1294: 1295: #endif 1296: { 1297: AHTReqContext *me; 1298: 1299: FILE *tmp_fp; 1300: char *tmp_dir; 1301: char *ref; 1302: int status; 1303: 1304: static int object_counter = 0; /* loaded objects counter */ 1305: 1306: HTList *cur, *pending; 1307: 1308: #if 0 1309: char *test; 1310: 1.7 cvs 1311: /*** test URL*/ 1312: test = AHTMakeRelativeName ("http://www.w3.org/", "http://www.w3.org/pub/Amaya"); 1313: HT_FREE (test); 1314: test = AHTMakeRelativeName ("http://www.w3.org", "http://www.w3.org/pub/Amaya"); 1315: HT_FREE (test); 1316: test = AHTMakeRelativeName ("http://www.w3.org/pub/Amaya", "http://www.w3.org"); 1317: HT_FREE (test); 1318: #endif 1319: 1320: if (urlName == NULL || docid == 0 || outputfile == NULL) 1321: { 1322: 1323: /* no file to be loaded */ 1324: TtaSetStatus (docid, 1, TtaGetMessage (AMAYA, AM_BAD_URL), 1325: urlName); 1326: 1327: if (error_html) 1328: FilesLoading[docid] = 2; /* so we can show the error message */ 1329: return HT_ERROR; 1.4 cvs 1330: 1.7 cvs 1331: } 1.4 cvs 1332: /* do we support this protocol? */ 1.7 cvs 1333: if (IsValidProtocol (urlName) == NO) 1334: { 1335: /* return error */ 1336: outputfile[0] = EOS; /* file could not be opened */ 1337: TtaSetStatus (docid, 1, TtaGetMessage (AMAYA, AM_GET_UNSUPPORTED_PROTOCOL), 1338: urlName); 1339: 1340: if (error_html) 1341: FilesLoading[docid] = 2; /* so we can show the error message */ 1342: return HT_ERROR; 1343: } 1.4 cvs 1344: 1345: /* verify if a docid directory exists */ 1346: 1347: tmp_dir = TtaGetMemory (strlen (TempFileDirectory) + 5 + 1); 1348: sprintf (tmp_dir, "%s/%d", TempFileDirectory, docid); 1349: 1350: tmp_fp = fopen (tmp_dir, "r"); 1.7 cvs 1351: if (tmp_fp == 0) 1352: { 1353: /*directory did not exist */ 1354: if (mkdir (tmp_dir, S_IRWXU) == -1) 1355: { 1356: /*error */ 1357: outputfile[0] = EOS; 1358: TtaSetStatus (docid, 1, TtaGetMessage (AMAYA, AM_CACHE_ERROR), 1359: urlName); 1360: 1361: if (error_html) 1362: FilesLoading[docid] = 2; /* so we can show the error message */ 1363: 1364: return HT_ERROR; 1365: } 1366: } 1367: else 1.4 cvs 1368: fclose (tmp_fp); 1369: 1370: /*create a tempfilename */ 1371: 1372: sprintf (outputfile, "%s/%04dAM", tmp_dir, object_counter); 1373: 1374: TtaFreeMemory (tmp_dir); 1375: 1376: /* update the object_counter */ 1377: object_counter++; 1378: 1379: /* normalize the URL */ 1380: ref = HTParse (urlName, "", PARSE_ALL); 1381: 1382: /* should we abort the request if we could not normalize the url? */ 1383: 1.7 cvs 1384: if (ref == (char *) NULL || ref[0] == EOS) 1385: { 1386: /*error */ 1387: outputfile[0] = EOS; 1388: TtaSetStatus (docid, 1, TtaGetMessage (AMAYA, AM_BAD_URL), 1389: urlName); 1.4 cvs 1390: 1.7 cvs 1391: if (error_html) 1392: FilesLoading[docid] = 2; /* so we can show the error message */ 1.4 cvs 1393: 1.7 cvs 1394: return HT_ERROR; 1395: } 1.4 cvs 1396: /* verify if that file name existed */ 1.9 cvs 1397: if (TtaFileExist (outputfile)) 1.7 cvs 1398: { 1.9 cvs 1399: TtaFileUnlink (outputfile); 1.7 cvs 1400: } 1.4 cvs 1401: 1402: /* try to open the outputfile */ 1403: 1.7 cvs 1404: if ((tmp_fp = fopen (outputfile, "w")) == NULL) 1405: { 1406: outputfile[0] = EOS; /* file could not be opened */ 1407: TtaSetStatus (docid, 1, TtaGetMessage (AMAYA, AM_CANNOT_CREATE_FILE), 1408: outputfile); 1409: HT_FREE (ref); 1410: 1411: if (error_html) 1412: FilesLoading[docid] = 2; /* so we can show the error message */ 1413: return (HT_ERROR); 1414: } 1.4 cvs 1415: 1416: /* the terminate_handler closes the above open fp */ 1417: /* Not anymore, we do that in the AHTCallback_bridge, as all 1418: requests are now asynchronous */ 1419: 1420: /* Initialize the request structure */ 1421: 1422: me = AHTReqContext_new (docid); 1423: 1.7 cvs 1424: if (me == NULL) 1425: { 1426: fclose (tmp_fp); 1427: outputfile[0] = EOS; 1428: /* need an error message here */ 1429: HT_FREE (ref); 1430: return (HT_ERROR); 1431: } 1.4 cvs 1432: 1433: 1434: /* Specific initializations for POST and GET */ 1.7 cvs 1435: if (mode & AMAYA_FORM_POST) 1436: { 1437: me->method = METHOD_POST; 1438: me->mem_ptr = postString; 1439: me->block_size = strlen (postString); 1440: HTRequest_setMethod (me->request, METHOD_POST); 1441: HTRequest_setPostCallback (me->request, AHTUpload_callback); 1442: } 1443: else 1444: { 1445: me->method = METHOD_GET; 1446: me->dest = (HTParentAnchor *) NULL; /*useful only for PUT and POST methods */ 1447: } 1.4 cvs 1448: 1449: /* Common initialization */ 1450: 1451: me->mode = mode; 1452: me->error_html = error_html; 1453: me->incremental_cbf = incremental_cbf; 1454: me->context_icbf = context_icbf; 1455: me->terminate_cbf = terminate_cbf; 1456: me->context_tcbf = context_tcbf; 1457: me->output = tmp_fp; 1458: 1459: HTRequest_setOutputStream (me->request, 1460: AHTFWriter_new (me->request, me->output, YES)); 1.7 cvs 1461: 1.4 cvs 1462: 1463: /*for the async. request modes, we need to have our 1464: own copy of outputfile and urlname 1465: */ 1466: 1.7 cvs 1467: if ((mode & AMAYA_ASYNC) || (mode & AMAYA_IASYNC)) 1468: { 1469: char *tmp; 1470: 1471: tmp = TtaGetMemory (strlen (outputfile) + 1); 1472: strcpy (tmp, outputfile); 1473: me->outputfile = tmp; 1474: 1475: tmp = TtaGetMemory (MAX_LENGTH); 1476: strcpy (tmp, urlName); 1477: me->urlName = tmp; 1.4 cvs 1478: 1.7 cvs 1479: } 1480: else 1481: { 1482: me->outputfile = outputfile; 1483: me->urlName = urlName; 1484: } 1.4 cvs 1485: 1486: /*** 1487: Change for taking into account the stop button: 1488: The requests will be always asynchronous, however, if mode=AMAYA_SYNC, 1489: we will loop until the document has been received or a stop signal 1490: generated 1491: ****/ 1492: 1493: HTRequest_setPreemptive (me->request, NO); 1494: TtaSetStatus (me->docid, 1, TtaGetMessage (AMAYA, AM_FETCHING), 1495: me->urlName); 1496: 1497: me->anchor = (HTParentAnchor *) HTAnchor_findAddress (ref); 1498: 1499: HT_FREE (ref); 1500: 1.7 cvs 1501: if (mode & AMAYA_FORM_POST) 1502: { 1503: HTAnchor_setFormat ((HTParentAnchor *) me->anchor, HTAtom_for ("application/x-www-form-urlencoded")); 1504: HTAnchor_setLength ((HTParentAnchor *) me->anchor, me->block_size); 1505: HTRequest_setEntityAnchor (me->request, me->anchor); 1.4 cvs 1506: 1.7 cvs 1507: status = HTLoadAbsolute (urlName, me->request); 1508: } 1509: else 1.4 cvs 1510: status = HTLoadAnchor ((HTAnchor *) me->anchor, 1511: me->request); 1512: 1513: if (status == HT_ERROR || me->reqStatus == HT_END 1.7 cvs 1514: || me->reqStatus == HT_ERR) 1515: { 1.4 cvs 1516: 1.7 cvs 1517: /* in case of error, free all allocated memory and exit */ 1518: 1519: if ((mode & AMAYA_ASYNC) || (mode & AMAYA_IASYNC)) 1520: { 1521: TtaFreeMemory (me->outputfile); 1522: TtaFreeMemory (me->urlName); 1523: } 1524: TtaSetStatus (me->docid, 1, TtaGetMessage (AMAYA, AM_CANNOT_LOAD), 1525: me->urlName); 1.4 cvs 1526: 1.7 cvs 1527: status = (me->reqStatus == HT_END) ? HT_OK : HT_ERROR; 1528: 1529: AHTReqContext_delete (me); 1530: 1531: } 1532: else 1533: { 1534: 1535: /* part of the stop button handler */ 1536: 1537: if ((mode & AMAYA_SYNC) || (mode & AMAYA_ISYNC)) 1538: { 1539: status = LoopForStop (me); 1540: AHTReqContext_delete (me); 1541: } 1542: else 1543: { 1544: 1545: /* ASYNC MODE */ 1546: /* if the request went to the pending events queue, then we close 1547: ** the file. It'll be open by AddEventLoop upon liberation of the 1548: ** queue 1.4 cvs 1549: */ 1.7 cvs 1550: 1551: /* verify if this request went to the pending request queue */ 1552: 1553: if ((cur = (HTList *) me->request->net->host->pending)) 1554: while ((pending = HTList_nextObject (cur))) 1555: { 1556: if (me->request->net == (HTNet *) pending) 1557: { 1558: /* To correct: see if we can fine tune this request */ 1559: if (me->reqStatus == HT_WAITING) 1560: break; 1561: me->reqStatus = HT_NEW_PENDING; 1562: /* the request went to the pending queue, so we close the fd to 1563: **avoid having many of them open without being used 1564: */ 1565: if (THD_TRACE) 1566: fprintf (stderr, "GetObjectWWW: %s is pending. Closing fd %d\n", me->urlName, (int) me->output); 1567: fclose (me->output); 1568: me->output = NULL; 1569: break; 1570: } 1571: } 1572: 1.4 cvs 1573: } 1.7 cvs 1574: } 1.4 cvs 1575: TtaHandlePendingEvents (); 1576: 1577: return (status); 1578: } 1579: 1.5 cvs 1580: /*---------------------------------------------------------------------- 1581: PutObjectWWW uploads a file into a URL 1582: 1583: 2 upload modes are proposed: 1584: AMAYA_SYNC : blocking mode 1585: AMAYA_ASYNC : non-blocking mode 1586: 1587: 1.4 cvs 1588: When the function is called with the SYNC mode, the function will 1589: return only when the file has been uploaded. 1590: The ASYNC mode will immediately return after setting up the 1591: call. Furthermore, at the end of an upload, the ASYNC mode will 1592: call back terminate_cbf, handling it the context defined in 1593: context_tcbf. 1594: 1595: Notes: 1596: At the end of a succesful request, the urlName string contains the 1597: name of the actually uploaded URL. As a URL can change over the time, 1598: (e.g., be redirected elsewhere), it is advised that the function 1599: caller verifies the value of the urlName variable at the end of 1600: a request. 1601: 1602: Inputs: 1603: - docid Document identifier for the set of objects being 1604: retrieved. 1605: - fileName A pointer to the local file to upload 1606: - urlName The URL to be uploaded (MAX_URL_LENGTH chars length) 1607: - mode The retrieval mode. 1608: 1609: - terminate_cbf 1610: - context_icbf 1611: Callback and context for a terminate handler 1612: 1613: Outputs: 1614: - urlName The URL that was uploaded 1615: 1616: Returns: 1617: HT_ERROR 1618: HT_OK 1.5 cvs 1619: 1620: ----------------------------------------------------------------------*/ 1.4 cvs 1621: #ifdef __STDC__ 1622: int PutObjectWWW (int docid, char *fileName, char *urlName, int mode, 1623: TTcbf * terminate_cbf, void *context_tcbf) 1624: #else 1625: int PutObjectWWW (docid, urlName, fileName, mode, 1626: ,terminate_cbf, context_tcbf) 1627: int docid; 1628: char *urlName; 1629: char *fileName; 1630: int mode; 1631: TTcbf *terminate_cbf; 1632: void *context_tcbf; 1633: 1634: #endif 1635: { 1.7 cvs 1636: /*AHTReqContext *me; */ 1.4 cvs 1637: int status; 1638: 1639: #ifdef WWW_XWINDOWS 1640: /*** Temporary patch (I hope) ****/ 1641: int fd; 1642: struct stat file_stat; 1643: char *mem_ptr; 1644: unsigned long block_size; 1645: 1646: if (urlName == NULL || docid == 0 || fileName == NULL || 1.9 cvs 1647: !TtaFileExist (fileName)) 1.4 cvs 1648: /* no file to be uploaded */ 1649: return HT_ERROR; 1650: 1651: /* do we support this protocol? */ 1.7 cvs 1652: if (IsValidProtocol (urlName) == NO) 1653: { 1654: /* return error */ 1655: TtaSetStatus (docid, 1, TtaGetMessage (AMAYA, AM_PUT_UNSUPPORTED_PROTOCOL), 1656: urlName); 1657: return HT_ERROR; 1658: } 1.4 cvs 1659: /* read the file into memory */ 1660: 1.7 cvs 1661: if ((fd = open (fileName, O_RDONLY)) == -1) 1662: { 1.4 cvs 1663: 1.7 cvs 1664: /* if we could not open the file, exit */ 1.4 cvs 1665: 1.7 cvs 1666: /*error msg here */ 1.4 cvs 1667: 1.7 cvs 1668: return (HT_ERROR); 1669: } 1.4 cvs 1670: 1671: fstat (fd, &file_stat); 1672: 1.7 cvs 1673: if (file_stat.st_size == 0) 1674: { 1.4 cvs 1675: 1.7 cvs 1676: /* file was empty */ 1.4 cvs 1677: 1.7 cvs 1678: /*errmsg here */ 1.4 cvs 1679: 1.7 cvs 1680: close (fd); 1681: return (HT_ERROR); 1682: } 1.4 cvs 1683: block_size = file_stat.st_size; 1684: 1685: if (THD_TRACE) 1686: fprintf (stderr, "file size == %u\n", (unsigned) block_size); 1687: 1688: mem_ptr = (char *) TtaGetMemory (block_size); 1689: 1.7 cvs 1690: if (mem_ptr == (char *) NULL) 1691: { 1.4 cvs 1692: 1.7 cvs 1693: /* could not allocate enough memory */ 1.4 cvs 1694: 1.7 cvs 1695: /*errmsg here */ 1.4 cvs 1696: 1.7 cvs 1697: close (fd); 1698: return (HT_ERROR); 1699: } 1.4 cvs 1700: read (fd, mem_ptr, block_size); 1701: 1702: close (fd); 1703: 1704: status = UploadMemWWW (docid, METHOD_PUT, urlName, mem_ptr, 1705: block_size, mode, terminate_cbf, 1706: context_tcbf, (char *) NULL); 1707: 1708: TtaFreeMemory (mem_ptr); 1709: 1710: #endif /*WWW_XWINDOWS */ 1711: 1712: return (status); 1713: /*** End of temporary patch */ 1714: 1715: } 1716: 1717: 1.5 cvs 1718: /*---------------------------------------------------------------------- 1719: ----------------------------------------------------------------------*/ 1720: 1.4 cvs 1721: #ifdef __STDC__ 1722: int UploadMemWWW (int docid, HTMethod method, 1723: char *urlName, char *mem_ptr, unsigned long block_size, 1724: int mode, TTcbf * terminate_cbf, void *context_tcbf, 1725: char *outputfile) 1726: #else 1727: int UploadMemWWW (docid, method, urlName, mem_ptr, block_size, mode, 1728: terminate_cbf, context_tcbf, outputfile) 1729: int docid; 1730: HTMethod method; 1731: char *urlName; 1732: char *mem_ptr; 1733: usigned long block_size; 1734: int mode; 1735: TTcbf *terminate_cbf; 1736: void *context_tcbf; 1737: char *outputfile; 1.7 cvs 1738: 1.4 cvs 1739: #endif 1740: { 1741: AHTReqContext *me; 1742: int status; 1743: 1744: /**** 1745: int basename_flag; 1746: ****/ 1747: 1748: if (mem_ptr == (char *) NULL || 1749: block_size == 0 || 1750: docid == 0 || 1.7 cvs 1751: urlName == (char *) NULL) 1752: { 1753: /* nothing to be uploaded */ 1754: return HT_ERROR; 1755: } 1.4 cvs 1756: /* if we are doing a post, try to open the destination file */ 1757: 1758: /* Initialize the request structure */ 1759: me = AHTReqContext_new (docid); 1760: 1.7 cvs 1761: if (me == NULL) 1762: { 1763: /* need an error message here */ 1764: TtaHandlePendingEvents (); 1765: return (HT_ERROR); 1766: } 1.4 cvs 1767: me->mode = mode; 1768: 1769: me->incremental_cbf = (TIcbf *) NULL; 1770: me->context_icbf = (void *) NULL; 1771: me->terminate_cbf = terminate_cbf; 1772: me->context_tcbf = context_tcbf; 1773: 1774: me->output = stdout; 1775: me->outputfile = (char *) NULL; 1776: me->urlName = urlName; 1777: 1778: HTRequest_setPreemptive (me->request, NO); 1779: 1780: me->method = METHOD_PUT; 1781: HTRequest_setMethod (me->request, METHOD_PUT); 1782: me->output = stdout; 1783: me->outputfile = (char *) NULL; 1784: 1785: me->mem_ptr = mem_ptr; 1786: me->block_size = block_size; 1787: HTRequest_setPostCallback (me->request, AHTUpload_callback); 1788: 1789: HTRequest_setOutputStream (me->request, 1790: HTFWriter_new (me->request, me->output, YES)); 1791: 1792: me->anchor = (HTParentAnchor *) HTAnchor_findAddress (urlName); 1.7 cvs 1793: 1794: HTAnchor_setFormat ((HTParentAnchor *) me->anchor, HTAtom_for ("text/html")); /* test */ 1795: HTAnchor_setLength ((HTParentAnchor *) me->anchor, me->block_size); 1.4 cvs 1796: HTRequest_setEntityAnchor (me->request, me->anchor); 1.5 cvs 1797: /* 1.7 cvs 1798: HTRequest_addAfter (me->request, AHTSaveFilter, NULL, NULL, HT_ALL, 1799: HT_FILTER_FIRST, NO); 1800: */ 1.4 cvs 1801: status = HTLoadAbsolute (urlName, me->request); 1802: 1803: if (status == HT_ERROR || me->reqStatus == HT_END 1.7 cvs 1804: || me->reqStatus == HT_ERR || HTError_hasSeverity (HTRequest_error (me->request), ERR_NON_FATAL)) 1805: { 1806: /* just in case ... :-) <-- because it's the case sometimes */ 1.4 cvs 1807: 1808: #ifdef WWW_XWINDOWS 1809: /*** 1810: if(me->xtinput_id != (XtInputId) NULL) { 1811: if (THD_TRACE) 1812: fprintf(stderr, "Query: Removing Xtinput: %lu\n", 1813: me->xtinput_id); 1814: XtRemoveInput(me->xtinput_id); 1815: } 1816: ***/ 1817: #endif /* WWW_XWINDOWS */ 1818: 1.7 cvs 1819: TtaSetStatus (me->docid, 1, TtaGetMessage (AMAYA, AM_CANNOT_SAVE), 1820: me->urlName); 1.4 cvs 1821: 1.7 cvs 1822: status = HT_ERROR; 1823: AHTReqContext_delete (me); 1.4 cvs 1824: 1.7 cvs 1825: } 1826: else 1827: { 1.4 cvs 1828: 1.7 cvs 1829: TtaSetStatus (me->docid, 1, TtaGetMessage (AMAYA, AM_REMOTE_SAVING), 1830: me->urlName); 1.4 cvs 1831: 1.7 cvs 1832: /* part of the stop button handler */ 1.4 cvs 1833: 1.7 cvs 1834: if ((mode & AMAYA_SYNC) || (mode & AMAYA_ISYNC)) 1835: { 1836: status = LoopForStop (me); 1837: AHTReqContext_delete (me); 1838: } 1839: } /* if-else */ 1.4 cvs 1840: 1841: return (status); 1842: 1843: } 1844: 1845: 1.5 cvs 1846: /*---------------------------------------------------------------------- 1847: Stop Request stops (kills) all active requests associated with a docid 1848: ----------------------------------------------------------------------*/ 1.4 cvs 1849: #ifdef __STDC__ 1850: void StopRequest (int docid) 1851: #else 1852: void StopRequest (docid) 1853: int docid; 1854: 1855: #endif 1856: { 1857: HTList *cur; 1858: AHTDocId_Status *docid_status; 1859: AHTReqContext *me; 1860: int open_requests; 1861: 1.7 cvs 1862: if (Amaya) 1863: { 1.4 cvs 1864: 1.7 cvs 1865: cur = Amaya->reqlist; 1866: docid_status = (AHTDocId_Status *) GetDocIdStatus (docid, 1.4 cvs 1867: Amaya->docid_status); 1868: 1.7 cvs 1869: /* verify if there are any requests at all associated with docid */ 1.4 cvs 1870: 1.7 cvs 1871: if (docid_status == (AHTDocId_Status *) NULL) 1872: return; 1.4 cvs 1873: 1.7 cvs 1874: open_requests = docid_status->counter; 1.4 cvs 1875: 1.7 cvs 1876: while ((me = (AHTReqContext *) HTList_nextObject (cur))) 1877: { 1.4 cvs 1878: 1.7 cvs 1879: if (me->docid == docid) 1880: { 1.4 cvs 1881: 1.7 cvs 1882: /* kill this request */ 1.4 cvs 1883: 1.7 cvs 1884: switch (me->reqStatus) 1885: { 1.4 cvs 1886: 1.7 cvs 1887: case HT_ABORT: 1888: break; 1.4 cvs 1889: 1.7 cvs 1890: case HT_BUSY: 1891: me->reqStatus = HT_ABORT; 1892: break; 1893: case HT_NEW_PENDING: 1894: case HT_WAITING: 1895: default: 1.4 cvs 1896: #ifdef WWW_XWINDOWS 1.7 cvs 1897: RequestKillAllXtevents (me); 1.4 cvs 1898: #endif 1.7 cvs 1899: me->reqStatus = HT_ABORT; 1.4 cvs 1900: /*** 1901: HTNet_kill(me->request); 1902: ***/ 1903: 1.7 cvs 1904: HTRequest_kill (me->request); 1.4 cvs 1905: 1.7 cvs 1906: if (me->mode == AMAYA_ASYNC || 1907: me->mode == AMAYA_IASYNC) 1908: { 1.4 cvs 1909: 1.7 cvs 1910: AHTReqContext_delete (me); 1911: } 1912: cur = Amaya->reqlist; 1.4 cvs 1913: 1.7 cvs 1914: open_requests--; 1.4 cvs 1915: 1.7 cvs 1916: break; 1.4 cvs 1917: 1.7 cvs 1918: } /* switch */ 1919: } /* if me docid */ 1920: } /* while */ 1921: } /* if amaya open requests */ 1.4 cvs 1922: } /* StopRequest */ 1923: 1924: 1.5 cvs 1925: /*---------------------------------------------------------------------- 1926: ----------------------------------------------------------------------*/ 1.4 cvs 1927: 1928: #ifdef __STDC__ 1929: static int LoopForStop (AHTReqContext * me) 1930: #else 1931: static int LoopForStop (AHTReqContext * me) 1932: #endif 1933: { 1934: 1935: #ifdef WWW_XWINDOWS 1936: extern XtAppContext app_cont; 1937: XEvent ev; 1938: XtInputMask status; 1939: 1940: #endif /* WWW_XWINDOWS */ 1941: int status_req; 1942: 1943: /* to test the async calls */ 1944: /* Boucle d'attente des evenements */ 1945: 1946: while (me->reqStatus != HT_ABORT && 1947: me->reqStatus != HT_END && 1.7 cvs 1948: me->reqStatus != HT_ERR) 1949: { 1.4 cvs 1950: 1951: #ifdef WWW_XWINDOWS 1.7 cvs 1952: status = XtAppPending (app_cont); 1953: if (status & XtIMXEvent) 1954: { 1955: XtAppNextEvent (app_cont, &ev); 1956: TtaHandleOneEvent (&ev); 1957: } 1958: else if (status & (XtIMAll & (~XtIMXEvent))) 1959: { 1960: XtAppProcessEvent (app_cont, 1961: (XtIMAll & (~XtIMXEvent))); 1962: } 1963: else 1964: { 1965: XtAppNextEvent (app_cont, &ev); 1966: TtaHandleOneEvent (&ev); 1967: } 1.4 cvs 1968: 1969: #endif /* WWW_XWINDOWS */ 1.7 cvs 1970: } /* while */ 1971: 1972: switch (me->reqStatus) 1973: { 1.4 cvs 1974: 1.7 cvs 1975: case HT_ERR: 1976: case HT_ABORT: 1977: status_req = HT_ERROR; 1978: break; 1979: 1980: case HT_END: 1981: status_req = HT_OK; 1982: break; 1.4 cvs 1983: 1.7 cvs 1984: default: 1985: break; 1986: } 1.4 cvs 1987: 1988: return (status_req); 1989: }