Annotation of Amaya/amaya/query.c, revision 1.7

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

Webmaster