Diff for /Amaya/amaya/query.c between versions 1.360 and 1.361

version 1.360, 2005/07/12 08:51:55 version 1.361, 2006/01/06 10:12:57
Line 18 Line 18
 *********************************/  *********************************/
   
 #ifdef _WINGUI  #ifdef _WINGUI
   #include <string.h>  #include <string.h>
 #endif /* !_WINGUI */  #endif /* !_WINGUI */
   
 #ifdef _WX  #ifdef _WX
   #include "wx/utils.h"  #include "wx/utils.h"
   #include "wx/dir.h"  #include "wx/dir.h"
   #include "wxAmayaSocketEvent.h"  #include "wxAmayaSocketEvent.h"
   #include "wxAmayaSocketEventLoop.h"  #include "wxAmayaSocketEventLoop.h"
 #endif /* _WX */  #endif /* _WX */
   
 #define AMAYA_WWW_CACHE  #define AMAYA_WWW_CACHE
Line 38 Line 38
 #include <sys/types.h>  #include <sys/types.h>
   
 #ifndef _WINDOWS  #ifndef _WINDOWS
   #include <unistd.h>  #include <unistd.h>
 #endif /* #ifndef _WINDOWS */  #endif /* #ifndef _WINDOWS */
   
 #include <fcntl.h>  #include <fcntl.h>
Line 53 Line 53
   
 /* local structures coming from libwww and which are  /* local structures coming from libwww and which are
    not found in any .h file     not found in any .h file
  */  */
   
 struct _HTStream  struct _HTStream
   {  {
      const HTStreamClass *isa;    const HTStreamClass *isa;
      FILE               *fp;    FILE               *fp;
      BOOL                leave_open;    /* Close file when TtaFreeMemory? */    BOOL                leave_open;       /* Close file when TtaFreeMemory? */
      char               *end_command;   /* Command to execute       */    char               *end_command;      /* Command to execute       */
      BOOL                remove_on_close;       /* Remove file?             */    BOOL                remove_on_close;  /* Remove file?             */
      char               *filename;      /* Name of file             */    char               *filename; /* Name of file             */
      HTRequest          *request;       /* saved for callback       */    HTRequest          *request;  /* saved for callback       */
      HTRequestCallback  *callback;    HTRequestCallback  *callback;
   };  };
   
   
 struct _HTError  struct _HTError
   {  {
      HTErrorElement      element;       /* Index number into HTError */    HTErrorElement      element;  /* Index number into HTError */
      HTSeverity          severity;      /* A la VMS */    HTSeverity          severity; /* A la VMS */
      BOOL                ignore;        /* YES if msg should not go to user */    BOOL                ignore;   /* YES if msg should not go to user */
      void               *par;   /* Explanation, e.g. filename  */    void               *par;      /* Explanation, e.g. filename  */
      int                 length;        /* For copying by generic routine */    int                 length;   /* For copying by generic routine */
      char               *where; /* Which function */    char               *where;    /* Which function */
   };  };
   
 /* Type definitions and global variables etc. local to this module */  /* Type definitions and global variables etc. local to this module */
   
Line 84  struct _HTError Line 84  struct _HTError
   
 /* libwww default parameters */  /* libwww default parameters */
 #ifdef _WINDOWS  #ifdef _WINDOWS
   #define CACHE_DIR_NAME "\\libwww-cache\\"  #define CACHE_DIR_NAME "\\libwww-cache\\"
 #endif /* _WINDOWS */  #endif /* _WINDOWS */
   
 #if defined(_UNIX)  #if defined(_UNIX)
   #define CACHE_DIR_NAME "/libwww-cache/"  #define CACHE_DIR_NAME "/libwww-cache/"
 #endif /* #if defined(_UNIX)*/  #endif /* #if defined(_UNIX)*/
   
 #define DEFAULT_CACHE_SIZE 10  #define DEFAULT_CACHE_SIZE 10
Line 114  static HTList      *safeput_list = NULL; Line 114  static HTList      *safeput_list = NULL;
   
 static int          object_counter = 0; /* loaded objects counter */  static int          object_counter = 0; /* loaded objects counter */
 static  ThotBool    AmayaAlive_flag; /* set to 1 if the application is active;  static  ThotBool    AmayaAlive_flag; /* set to 1 if the application is active;
                                         0 if we have killed */                                          0 if we have killed */
 static  ThotBool    CanDoStop_flag; /* set to 1 if we can do a stop, 0  static  ThotBool    CanDoStop_flag; /* set to 1 if we can do a stop, 0
                                        if we're inside a critical section */                                         if we're inside a critical section */
 static  ThotBool    UserAborted_flag; /* set to 1 if we're processing a user  static  ThotBool    UserAborted_flag; /* set to 1 if we're processing a user
                                          induced stop request operation */                                           induced stop request operation */
 #ifdef  AMAYA_WWW_CACHE  #ifdef  AMAYA_WWW_CACHE
 static int          fd_cachelock; /* open handle to the .lock cache file */  static int          fd_cachelock; /* open handle to the .lock cache file */
 #endif /* AMAYA_WWW_CACHE */  #endif /* AMAYA_WWW_CACHE */
Line 151  int WIN_Activate_Request (HTRequest* , H Line 151  int WIN_Activate_Request (HTRequest* , H
 /***************************************************************  /***************************************************************
  lock functions, used to avoid concurrent use of the cache   lock functions, used to avoid concurrent use of the cache
  Mostly based on W. Richard Stevens' APUE book.   Mostly based on W. Richard Stevens' APUE book.
  ***************************************************************/  ***************************************************************/
 /*----------------------------------------------------------------------  /*----------------------------------------------------------------------
   set_cachelock    set_cachelock
   sets a write lock on filename.     sets a write lock on filename. 
Line 185  static int set_cachelock (char *filename Line 185  static int set_cachelock (char *filename
   if (status == -1)    if (status == -1)
     {      {
       if (fd_cachelock > 0)        if (fd_cachelock > 0)
           close (fd_cachelock);          close (fd_cachelock);
       fd_cachelock = 0;        fd_cachelock = 0;
     }      }
   return (status);    return (status);
Line 262  static int test_cachelock (char *filenam Line 262  static int test_cachelock (char *filenam
   ----------------------------------------------------------------------*/    ----------------------------------------------------------------------*/
 AHTDocId_Status    *GetDocIdStatus (int docid, HTList * documents)  AHTDocId_Status    *GetDocIdStatus (int docid, HTList * documents)
 {  {
    AHTDocId_Status    *me;    AHTDocId_Status    *me;
    HTList             *cur;    HTList             *cur;
   
     if (documents)
       {
         cur = documents;
   
    if (documents)        while ((me = (AHTDocId_Status *) HTList_nextObject (cur)))
      {          {
         cur = documents;            if (me->docid == docid)
               return (me);
         while ((me = (AHTDocId_Status *) HTList_nextObject (cur)))          }
           {      }
              if (me->docid == docid)    return (AHTDocId_Status *) NULL;
                 return (me);  
           }  
      }  
    return (AHTDocId_Status *) NULL;  
   
 }  }
   
Line 285  AHTDocId_Status    *GetDocIdStatus (int Line 285  AHTDocId_Status    *GetDocIdStatus (int
   ----------------------------------------------------------------------*/    ----------------------------------------------------------------------*/
 static  HTAtom *AHTGuessAtom_for (char *urlName, char *contentType)  static  HTAtom *AHTGuessAtom_for (char *urlName, char *contentType)
 {  {
  HTAtom           *atom;    HTAtom           *atom;
  char *          filename;    char *          filename;
  HTEncoding        enc = NULL;    HTEncoding        enc = NULL;
  HTEncoding        cte = NULL;    HTEncoding        cte = NULL;
  HTLanguage        lang = NULL;    HTLanguage        lang = NULL;
  double            quality = 1.0;    double            quality = 1.0;
   
  /* we already have a MIME type, we jsut return the atom */    /* we already have a MIME type, we jsut return the atom */
  if (contentType && *contentType)    if (contentType && *contentType)
    atom = HTAtom_for (contentType);      atom = HTAtom_for (contentType);
  else    else
    {      {
      /* we don't have the MIME type, so        /* we don't have the MIME type, so
         we try to use the filename's suffix to infer it */           we try to use the filename's suffix to infer it */
      filename = AmayaParseUrl (urlName, "",         filename = AmayaParseUrl (urlName, "", 
                                AMAYA_PARSE_PATH | AMAYA_PARSE_PUNCTUATION);                                  AMAYA_PARSE_PATH | AMAYA_PARSE_PUNCTUATION);
      HTBind_getFormat (filename, &atom, &enc, &cte, &lang, &quality);        HTBind_getFormat (filename, &atom, &enc, &cte, &lang, &quality);
      TtaFreeMemory (filename);        TtaFreeMemory (filename);
      if (atom ==  WWW_UNKNOWN)        if (atom ==  WWW_UNKNOWN)
        {          {
          /*            /*
          ** we could not identify the suffix, so we give it a default type.            ** we could not identify the suffix, so we give it a default type.
          ** (we should ask the user, but we're not ready for that yet).            ** (we should ask the user, but we're not ready for that yet).
          */            */
          atom = HTAtom_for ("text/html");            atom = HTAtom_for ("text/html");
        }          }
    }      }
  return atom;    return atom;
 }  }
   
 /*----------------------------------------------------------------------  /*----------------------------------------------------------------------
Line 321  static  HTAtom *AHTGuessAtom_for (char * Line 321  static  HTAtom *AHTGuessAtom_for (char *
   any in-between conversions as needed.    any in-between conversions as needed.
   ----------------------------------------------------------------------*/    ----------------------------------------------------------------------*/
 void HTTP_headers_set (HTRequest *request, HTResponse *response,  void HTTP_headers_set (HTRequest *request, HTResponse *response,
                        void *context, int status)                         void *context, int status)
 {  {
   AHTReqContext  *me;    AHTReqContext  *me;
   HTAtom         *tmp_atom = NULL;    HTAtom         *tmp_atom = NULL;
Line 353  void HTTP_headers_set (HTRequest *reques Line 353  void HTTP_headers_set (HTRequest *reques
   if (me->http_headers.content_type == NULL)    if (me->http_headers.content_type == NULL)
     {      {
       /* trying to use the info in the anchor, rather than in the response.        /* trying to use the info in the anchor, rather than in the response.
          Seems it's more recent */           Seems it's more recent */
   
       /* @@ JK: trying to use the content type stored in the response object */        /* @@ JK: trying to use the content type stored in the response object */
       if (!use_anchor && response)        if (!use_anchor && response)
         tmp_atom = HTResponse_format (response);          tmp_atom = HTResponse_format (response);
       if (!tmp_atom)        if (!tmp_atom)
         tmp_atom = HTAnchor_format (anchor);          tmp_atom = HTAnchor_format (anchor);
   
       if (tmp_atom)        if (tmp_atom)
         tmp_char = HTAtom_name (tmp_atom);          tmp_char = HTAtom_name (tmp_atom);
       else        else
         tmp_char = "www/unknown";          tmp_char = "www/unknown";
               
       if (tmp_char && tmp_char[0] != EOS)        if (tmp_char && tmp_char[0] != EOS)
         {          {
           /* libwww gives www/unknown when it gets an error. As this is             /* libwww gives www/unknown when it gets an error. As this is 
              an HTML test, we force the type to text/html */               an HTML test, we force the type to text/html */
           if (!strcmp (tmp_char, "www/unknown"))            if (!strcmp (tmp_char, "www/unknown"))
             {              {
               /* if it's not a file downloaded from FTP, initialize the                /* if it's not a file downloaded from FTP, initialize the
                  content type to text/html by default */                   content type to text/html by default */
               me->http_headers.content_type = NULL;                me->http_headers.content_type = NULL;
             }              }
           else             else 
               me->http_headers.content_type = TtaStrdup (tmp_char);              me->http_headers.content_type = TtaStrdup (tmp_char);
                       
 #ifdef DEBUG_LIBWWW  #ifdef DEBUG_LIBWWW
           fprintf (stderr, "Set content type to: %s\n",             fprintf (stderr, "Set content type to: %s\n", 
                    me->http_headers.content_type);                     me->http_headers.content_type);
 #endif /* DEBUG_LIBWWW */  #endif /* DEBUG_LIBWWW */
         }          }
     }      }
   
   /* copy the charset */    /* copy the charset */
Line 403  void HTTP_headers_set (HTRequest *reques Line 403  void HTTP_headers_set (HTRequest *reques
     {      {
       tmp_char = HTAtom_name (tmp_atom);        tmp_char = HTAtom_name (tmp_atom);
       if (tmp_char)        if (tmp_char)
         me->http_headers.charset = TtaStrdup (tmp_char);          me->http_headers.charset = TtaStrdup (tmp_char);
     }      }
   
   /* copy the content length */    /* copy the content length */
Line 415  void HTTP_headers_set (HTRequest *reques Line 415  void HTTP_headers_set (HTRequest *reques
     {      {
       tmp_char = HTResponse_reason (response);        tmp_char = HTResponse_reason (response);
       if (tmp_char)        if (tmp_char)
         me->http_headers.reason = TtaStrdup (tmp_char);          me->http_headers.reason = TtaStrdup (tmp_char);
     }      }
   
   /* copy the content-location */    /* copy the content-location */
Line 424  void HTTP_headers_set (HTRequest *reques Line 424  void HTTP_headers_set (HTRequest *reques
     {      {
       /* make a copy of the full location_header, for computing the base url */        /* make a copy of the full location_header, for computing the base url */
       if (HTURL_isAbsolute (tmp_char))        if (HTURL_isAbsolute (tmp_char))
         me->http_headers.full_content_location = TtaStrdup (tmp_char);          me->http_headers.full_content_location = TtaStrdup (tmp_char);
       else        else
         me->http_headers.full_content_location = AmayaParseUrl (tmp_char, me->urlName,          me->http_headers.full_content_location = AmayaParseUrl (tmp_char, me->urlName,
                                                                 AMAYA_PARSE_ALL);                                                                  AMAYA_PARSE_ALL);
       tmp_char = me->http_headers.full_content_location;        tmp_char = me->http_headers.full_content_location;
       /* only include the filename. We suppose we have either a         /* only include the filename. We suppose we have either a 
        relative or an absolute URL and that everything after the last           relative or an absolute URL and that everything after the last
       slash is the doc name + ext */           slash is the doc name + ext */
       if (HTURL_isAbsolute (tmp_char))        if (HTURL_isAbsolute (tmp_char))
         {          {
           tmp_char2 = tmp_char + strlen (tmp_char) - 1;            tmp_char2 = tmp_char + strlen (tmp_char) - 1;
           while (*tmp_char2 != URL_SEP && tmp_char2 != tmp_char)            while (*tmp_char2 != URL_SEP && tmp_char2 != tmp_char)
             tmp_char2--;              tmp_char2--;
           if (tmp_char2 != tmp_char && *(tmp_char2 + 1))            if (tmp_char2 != tmp_char && *(tmp_char2 + 1))
             tmp_char = tmp_char2 + 1;              tmp_char = tmp_char2 + 1;
         }          }
       me->http_headers.content_location = TtaStrdup (tmp_char);        me->http_headers.content_location = TtaStrdup (tmp_char);
     }      }
   
Line 448  void HTTP_headers_set (HTRequest *reques Line 448  void HTTP_headers_set (HTRequest *reques
   
   cur = request->error_stack;    cur = request->error_stack;
   while (me->http_headers.reason == NULL    while (me->http_headers.reason == NULL
          && (pres = (HTError *) HTList_nextObject (cur)))           && (pres = (HTError *) HTList_nextObject (cur)))
     {      {
       index = HTError_index (pres);        index = HTError_index (pres);
       switch (index)        switch (index)
         {          {
         case HTERR_NO_REMOTE_HOST:          case HTERR_NO_REMOTE_HOST:
         case HTERR_SYSTEM:          case HTERR_SYSTEM:
         case HTERR_INTERNAL:          case HTERR_INTERNAL:
         case HTERR_TIME_OUT:          case HTERR_TIME_OUT:
         case HTERR_CSO_SERVER:          case HTERR_CSO_SERVER:
           me->http_headers.status = index;            me->http_headers.status = index;
           if (me->http_headers.reason)            if (me->http_headers.reason)
             TtaFreeMemory (me->http_headers.reason);              TtaFreeMemory (me->http_headers.reason);
           me->http_headers.reason = TtaStrdup ("Cannot contact server");            me->http_headers.reason = TtaStrdup ("Cannot contact server");
           break;            break;
         case HTERR_INTERRUPTED:          case HTERR_INTERRUPTED:
           me->http_headers.status = index;            me->http_headers.status = index;
           if (me->http_headers.reason)            if (me->http_headers.reason)
             TtaFreeMemory (me->http_headers.reason);              TtaFreeMemory (me->http_headers.reason);
           me->http_headers.reason = TtaStrdup ("Interrupted");            me->http_headers.reason = TtaStrdup ("Interrupted");
           break;            break;
         }          }
     }      }
 }  }
   
Line 548  char   *HTTP_headers (AHTHeaders *me, AH Line 548  char   *HTTP_headers (AHTHeaders *me, AH
   ---------------------------------------------------------------------- */    ---------------------------------------------------------------------- */
 AHTReqContext *AHTReqContext_new (int docid)  AHTReqContext *AHTReqContext_new (int docid)
 {  {
    AHTReqContext      *me;    AHTReqContext      *me;
    AHTDocId_Status    *docid_status;    AHTDocId_Status    *docid_status;
   
    if ((me = (AHTReqContext *) TtaGetMemory (sizeof (AHTReqContext))) == NULL)    if ((me = (AHTReqContext *) TtaGetMemory (sizeof (AHTReqContext))) == NULL)
      outofmem (__FILE__, "AHTReqContext_new");      outofmem (__FILE__, "AHTReqContext_new");
   
    /* clear the structure */    /* clear the structure */
    memset ((void *) me, 0, sizeof (AHTReqContext));    memset ((void *) me, 0, sizeof (AHTReqContext));
   
    /* Bind the Context object together with the Request Object */    /* Bind the Context object together with the Request Object */
    me->request = HTRequest_new ();    me->request = HTRequest_new ();
       
    /* clean the associated file structure) */    /* clean the associated file structure) */
    HTRequest_setOutputStream (me->request, NULL);    HTRequest_setOutputStream (me->request, NULL);
     
    /* Initialize the other members of the structure */    /* Initialize the other members of the structure */
    me->reqStatus = HT_NEW; /* initial status of a request */    me->reqStatus = HT_NEW; /* initial status of a request */
    me->docid = docid;    me->docid = docid;
    HTRequest_setMethod (me->request, METHOD_GET);    HTRequest_setMethod (me->request, METHOD_GET);
    HTRequest_setOutputFormat (me->request, WWW_SOURCE);    HTRequest_setOutputFormat (me->request, WWW_SOURCE);
    HTRequest_setContext (me->request, me);    HTRequest_setContext (me->request, me);
   
    /* experimental */    /* experimental */
    me->read_sock = INVSOC;    me->read_sock = INVSOC;
    me->write_sock = INVSOC;    me->write_sock = INVSOC;
    me->except_sock = INVSOC;    me->except_sock = INVSOC;
   
    /* Update the global context */    /* Update the global context */
    HTList_appendObject (Amaya->reqlist, (void *) me);    HTList_appendObject (Amaya->reqlist, (void *) me);
   
    docid_status = GetDocIdStatus (docid, Amaya->docid_status);    docid_status = GetDocIdStatus (docid, Amaya->docid_status);
   
    if (docid_status == NULL)    if (docid_status == NULL)
      {      {
         docid_status = (AHTDocId_Status *)         docid_status = (AHTDocId_Status *) 
           TtaGetMemory (sizeof (AHTDocId_Status));          TtaGetMemory (sizeof (AHTDocId_Status));
         docid_status->docid = docid;        docid_status->docid = docid;
         docid_status->counter = 1;        docid_status->counter = 1;
         HTList_addObject (Amaya->docid_status, (void *) docid_status);        HTList_addObject (Amaya->docid_status, (void *) docid_status);
      }      }
    else    else
       docid_status->counter++;      docid_status->counter++;
   
 #ifdef DAV                /* clean the DAV request context */  #ifdef DAV                /* clean the DAV request context */
    me->dav_context = NULL; /* it should be create only when doing a DAV request */    me->dav_context = NULL; /* it should be create only when doing a DAV request */
 #endif /* DAV */    #endif /* DAV */  
   
    Amaya->open_requests++;    Amaya->open_requests++;
   
 #ifdef DEBUG_LIBWWW  #ifdef DEBUG_LIBWWW
    fprintf (stderr, "AHTReqContext_new: Created object %p\n", me);    fprintf (stderr, "AHTReqContext_new: Created object %p\n", me);
 #endif     #endif   
   
    return me;    return me;
 }  }
   
 /*----------------------------------------------------------------------  /*----------------------------------------------------------------------
Line 611  AHTReqContext *AHTReqContext_new (int do Line 611  AHTReqContext *AHTReqContext_new (int do
   ----------------------------------------------------------------------*/    ----------------------------------------------------------------------*/
 ThotBool  AHTReqContext_delete (AHTReqContext * me)  ThotBool  AHTReqContext_delete (AHTReqContext * me)
 {  {
    AHTDocId_Status    *docid_status;    AHTDocId_Status    *docid_status;
   
    if (me)    if (me)
      {      {
 #ifdef DEBUG_LIBWWW  #ifdef DEBUG_LIBWWW
        fprintf (stderr, "AHTReqContext_delete: Deleting object %p\n", me);        fprintf (stderr, "AHTReqContext_delete: Deleting object %p\n", me);
 #endif     #endif   
   
 #ifdef DAV /* if there is a DAV context object, delete it */  #ifdef DAV /* if there is a DAV context object, delete it */
        if (me->dav_context) AHTDAVContext_delete ((AHTDAVContext*)me->dav_context);        if (me->dav_context) AHTDAVContext_delete ((AHTDAVContext*)me->dav_context);
 #endif /* DAV */  #endif /* DAV */
   
        if (Amaya->reqlist)        if (Amaya->reqlist)
          HTList_removeObject (Amaya->reqlist, (void *) me);          HTList_removeObject (Amaya->reqlist, (void *) me);
                 
        docid_status = GetDocIdStatus (me->docid, Amaya->docid_status);        docid_status = GetDocIdStatus (me->docid, Amaya->docid_status);
        if (docid_status)        if (docid_status)
          {          {
            docid_status->counter--;            docid_status->counter--;
                         
            if (docid_status->counter == 0)            if (docid_status->counter == 0)
              {              {
                HTList_removeObject (Amaya->docid_status, (void *) docid_status);                HTList_removeObject (Amaya->docid_status, (void *) docid_status);
                TtaFreeMemory ((void *) docid_status);                TtaFreeMemory ((void *) docid_status);
              }              }
          }          }
   
        HTNoFreeStream_delete (HTRequest_outputStream (me->request));        HTNoFreeStream_delete (HTRequest_outputStream (me->request));
        HTRequest_setOutputStream (me->request, NULL);         HTRequest_setOutputStream (me->request, NULL); 
        /* JK: no longer needed in libwww 5.2.3        /* JK: no longer needed in libwww 5.2.3
           if (me->method != METHOD_PUT && HTRequest_outputStream (me->request))           if (me->method != METHOD_PUT && HTRequest_outputStream (me->request))
           AHTFWriter_FREE (HTRequest_outputStream (me->request));           AHTFWriter_FREE (HTRequest_outputStream (me->request));
        */        */
        HTRequest_delete (me->request);        HTRequest_delete (me->request);
                 
        if (me->output && me->output != stdout)        if (me->output && me->output != stdout)
          {                {       
 #ifdef DEBUG_LIBWWW         #ifdef DEBUG_LIBWWW       
            fprintf (stderr, "AHTReqContext_delete: URL is  %s, closing "            fprintf (stderr, "AHTReqContext_delete: URL is  %s, closing "
                     "FILE %p\n", me->urlName, me->output);                      "FILE %p\n", me->urlName, me->output); 
 #endif  #endif
            TtaReadClose (me->output);            TtaReadClose (me->output);
            me->output = NULL;            me->output = NULL;
          }          }
                       
        if (me->error_stream != (char *) NULL)        if (me->error_stream != (char *) NULL)
          HT_FREE (me->error_stream);          HT_FREE (me->error_stream);
 #if defined(_GTK) || defined(_WX) || defined(_NOGUI)  #if defined(_GTK) || defined(_WX) || defined(_NOGUI)
 #ifdef WWW_XWINDOWS       #ifdef WWW_XWINDOWS     
        if (me->read_xtinput_id || me->write_xtinput_id ||        if (me->read_xtinput_id || me->write_xtinput_id ||
            me->except_xtinput_id)            me->except_xtinput_id)
          RequestKillAllXtevents(me);          RequestKillAllXtevents(me);
 #endif /* WWW_XWINDOWS */  #endif /* WWW_XWINDOWS */
 #endif /* #if defined(_GTK) || defined(_WX) || defined(_NOGUI) */  #endif /* #if defined(_GTK) || defined(_WX) || defined(_NOGUI) */
                 
        if (me->reqStatus == HT_ABORT)        if (me->reqStatus == HT_ABORT)
          {          {
            if (me->outputfile && me->outputfile[0] != EOS)            if (me->outputfile && me->outputfile[0] != EOS)
              {              {
                TtaFileUnlink (me->outputfile);                TtaFileUnlink (me->outputfile);
                me->outputfile[0] = EOS;                me->outputfile[0] = EOS;
              }              }
          }          }
                 
        if ((me->mode & AMAYA_ASYNC) || (me->mode & AMAYA_IASYNC))        if ((me->mode & AMAYA_ASYNC) || (me->mode & AMAYA_IASYNC))
          /* for the ASYNC mode, free the memory we allocated in GetObjectWWW          /* for the ASYNC mode, free the memory we allocated in GetObjectWWW
             or in PutObjectWWW */             or in PutObjectWWW */
          {          {
            if (me->urlName)            if (me->urlName)
              TtaFreeMemory (me->urlName);              TtaFreeMemory (me->urlName);
            if (me->outputfile)            if (me->outputfile)
              TtaFreeMemory (me->outputfile);              TtaFreeMemory (me->outputfile);
          }          }
   
        /* the real name to which we are publishing */        /* the real name to which we are publishing */
        if (me->default_put_name)        if (me->default_put_name)
          TtaFreeMemory (me->default_put_name);          TtaFreeMemory (me->default_put_name);
   
        /* @@ temp change for the %esc conversion */        /* @@ temp change for the %esc conversion */
        if (me->method == METHOD_PUT && me->urlName)        if (me->method == METHOD_PUT && me->urlName)
          TtaFreeMemory (me->urlName);          TtaFreeMemory (me->urlName);
   
        if (me->formdata)        if (me->formdata)
          HTAssocList_delete (me->formdata);          HTAssocList_delete (me->formdata);
   
        /* erase the response headers */        /* erase the response headers */
        HTTP_headers_delete (me->http_headers);        HTTP_headers_delete (me->http_headers);
                 
 #ifdef ANNOTATIONS  #ifdef ANNOTATIONS
        if (me->document)        if (me->document)
          TtaFreeMemory (me->document);          TtaFreeMemory (me->document);
 #endif /* ANNOTATIONS */  #endif /* ANNOTATIONS */
   
        if (me->refdocUrl)        if (me->refdocUrl)
          TtaFreeMemory (me->refdocUrl);          TtaFreeMemory (me->refdocUrl);
   
        /* to trace bugs */        /* to trace bugs */
        memset ((void *) me, 0, sizeof (AHTReqContext));        memset ((void *) me, 0, sizeof (AHTReqContext));
                 
        TtaFreeMemory ((void *) me);        TtaFreeMemory ((void *) me);
                 
        Amaya->open_requests--;        Amaya->open_requests--;
                 
        return TRUE;        return TRUE;
      }      }
    return FALSE;    return FALSE;
 }  }
   
   
Line 734  static void         Thread_deleteAll (vo Line 734  static void         Thread_deleteAll (vo
     {      {
       if (Amaya->open_requests > 0)        if (Amaya->open_requests > 0)
 #ifdef DEBUG_LIBWWW  #ifdef DEBUG_LIBWWW
         fprintf (stderr, "Thread_deleteAll: Killing %d outstanding "          fprintf (stderr, "Thread_deleteAll: Killing %d outstanding "
                  "requests\n", Amaya->open_requests);                   "requests\n", Amaya->open_requests);
 #endif     #endif   
       {        {
         cur = Amaya->reqlist;            cur = Amaya->reqlist;  
         /* erase the requests */          /* erase the requests */
         while ((me = (AHTReqContext *) HTList_removeLastObject (cur)))          while ((me = (AHTReqContext *) HTList_removeLastObject (cur)))
           {            {
             if (me->request)              if (me->request)
               {                {
 #if defined(_GTK) || defined(_WX) || defined(_NOGUI)  #if defined(_GTK) || defined(_WX) || defined(_NOGUI)
 #ifdef WWW_XWINDOWS   #ifdef WWW_XWINDOWS 
                 RequestKillAllXtevents (me);                  RequestKillAllXtevents (me);
 #endif /* WWW_XWINDOWS */  #endif /* WWW_XWINDOWS */
 #endif /* #if defined(_GTK) || defined(_WX) || defined(_NOGUI) */  #endif /* #if defined(_GTK) || defined(_WX) || defined(_NOGUI) */
                 if (!HTRequest_kill (me->request))                  if (!HTRequest_kill (me->request))
                   AHTReqContext_delete (me);                    AHTReqContext_delete (me);
               }                }
           }            }
                       
         /* erase the docid_status entities */          /* erase the docid_status entities */
         while ((docid_status = (AHTDocId_Status *) HTList_removeLastObject ((HTList *) Amaya->docid_status)))          while ((docid_status = (AHTDocId_Status *) HTList_removeLastObject ((HTList *) Amaya->docid_status)))
           TtaFreeMemory ((void *) docid_status);            TtaFreeMemory ((void *) docid_status);
       }        }
     }      }
 }  }
Line 770  int                 AHTOpen_file (HTRequ Line 770  int                 AHTOpen_file (HTRequ
   
   me = (AHTReqContext *)HTRequest_context (request);    me = (AHTReqContext *)HTRequest_context (request);
   if (!me)    if (!me)
       return HT_ERROR;      return HT_ERROR;
 #ifdef DEBUG_LIBWWW  #ifdef DEBUG_LIBWWW
   fprintf(stderr, "AHTOpen_file: start for object : %p\n", me);    fprintf(stderr, "AHTOpen_file: start for object : %p\n", me);
 #endif /* DEBUG_LIBWWW */  #endif /* DEBUG_LIBWWW */
Line 811  int                 AHTOpen_file (HTRequ Line 811  int                 AHTOpen_file (HTRequ
       fprintf(stderr, "AHTOpen_file: couldn't open output stream for url %s\n", me->urlName);        fprintf(stderr, "AHTOpen_file: couldn't open output stream for url %s\n", me->urlName);
 #endif  #endif
       TtaSetStatus (me->docid, 1,        TtaSetStatus (me->docid, 1,
                     TtaGetMessage (AMAYA, AM_CANNOT_CREATE_FILE),                      TtaGetMessage (AMAYA, AM_CANNOT_CREATE_FILE),
                     me->outputfile);                      me->outputfile);
       me->reqStatus = HT_ERR;        me->reqStatus = HT_ERR;
       return (HT_ERROR);        return (HT_ERROR);
     }      }
                       
   HTRequest_setOutputStream (me->request,    HTRequest_setOutputStream (me->request,
                              AHTFWriter_new (me->request, me->output, YES));                               AHTFWriter_new (me->request, me->output, YES));
   me->reqStatus = HT_WAITING;    me->reqStatus = HT_WAITING;
   
   return HT_OK;    return HT_OK;
Line 844  static void SafePut_init (void) Line 844  static void SafePut_init (void)
       /* convert to lowercase */        /* convert to lowercase */
       ptr = ptr2;        ptr = ptr2;
       while (*ptr)         while (*ptr) 
         {          {
           *ptr = tolower (*ptr);            *ptr = tolower (*ptr);
           ptr++;            ptr++;
         }          }
               
       /* create the list container */        /* create the list container */
       safeput_list = HTList_new ();        safeput_list = HTList_new ();
Line 855  static void SafePut_init (void) Line 855  static void SafePut_init (void)
       /* store the domain list */        /* store the domain list */
       ptr = ptr2;        ptr = ptr2;
       while ((domain = HTNextField (&ptr)) != NULL)        while ((domain = HTNextField (&ptr)) != NULL)
           HTList_addObject (safeput_list, TtaStrdup (domain));           HTList_addObject (safeput_list, TtaStrdup (domain)); 
   
       TtaFreeMemory (ptr2);        TtaFreeMemory (ptr2);
     }      }
Line 874  static void SafePut_delete (void) Line 874  static void SafePut_delete (void)
     return;      return;
   
   while ((domain = (char *) HTList_nextObject (cur)))     while ((domain = (char *) HTList_nextObject (cur))) 
       TtaFreeMemory (domain);      TtaFreeMemory (domain);
    HTList_delete (safeput_list);    HTList_delete (safeput_list);
    safeput_list = NULL;    safeput_list = NULL;
 }  }
   
 /*----------------------------------------------------------------------  /*----------------------------------------------------------------------
Line 900  static ThotBool SafePut_query (char *url Line 900  static ThotBool SafePut_query (char *url
     {      {
       strcpy (tmp, me);        strcpy (tmp, me);
       if (strstr (url, tmp))        if (strstr (url, tmp))
         {          {
           found = TRUE;            found = TRUE;
           break;            break;
         }           } 
     }      }
   
   return (found);    return (found);
Line 915  static ThotBool SafePut_query (char *url Line 915  static ThotBool SafePut_query (char *url
   redirections.    redirections.
   ----------------------------------------------------------------------*/    ----------------------------------------------------------------------*/
 static int redirection_handler (HTRequest *request, HTResponse *response,  static int redirection_handler (HTRequest *request, HTResponse *response,
                                 void *param, int status)                                  void *param, int status)
 {  {
   HTAnchor           *new_anchor = HTResponse_redirection (response);    HTAnchor           *new_anchor = HTResponse_redirection (response);
   AHTReqContext      *me = (AHTReqContext *)HTRequest_context (request);    AHTReqContext      *me = (AHTReqContext *)HTRequest_context (request);
Line 924  static int redirection_handler (HTReques Line 924  static int redirection_handler (HTReques
   char               *escape_src, *dst;    char               *escape_src, *dst;
   char                urlAdr[MAX_LENGTH];    char                urlAdr[MAX_LENGTH];
   
    if (!me)    if (!me)
      /* if the redirect doesn't come from Amaya, we call libwww's standard redirect filter */      /* if the redirect doesn't come from Amaya, we call libwww's standard redirect filter */
      return (HTRedirectFilter (request, response, param, status));      return (HTRedirectFilter (request, response, param, status));
         
    if (!new_anchor)    if (!new_anchor)
      {      {
        if (PROT_TRACE)        if (PROT_TRACE)
          HTTrace ("Redirection. No destination\n");          HTTrace ("Redirection. No destination\n");
        return HT_OK;        return HT_OK;
      }      }
   
    /*    /*
    ** Only do redirect on GET, HEAD, and authorized domains for PUT    ** Only do redirect on GET, HEAD, and authorized domains for PUT
    */    */
    if ((me->method == METHOD_PUT && !SafePut_query (me->urlName)) ||    if ((me->method == METHOD_PUT && !SafePut_query (me->urlName)) ||
        (me->method != METHOD_PUT && !HTMethod_isSafe (method)))        (me->method != METHOD_PUT && !HTMethod_isSafe (method)))
      {      {
      /*        /*
      ** If we got a 303 See Other then change the method to GET.        ** If we got a 303 See Other then change the method to GET.
      ** Otherwise ask the user whether we should continue.        ** Otherwise ask the user whether we should continue.
      */        */
      if (status == HT_SEE_OTHER)        if (status == HT_SEE_OTHER)
        {          {
          if (PROT_TRACE)            if (PROT_TRACE)
            HTTrace("Redirection. Changing method from %s to GET\n", HTMethod_name(method));              HTTrace("Redirection. Changing method from %s to GET\n", HTMethod_name(method));
          HTRequest_setMethod(request, METHOD_GET);            HTRequest_setMethod(request, METHOD_GET);
        }          }
      else        else
        {          {
          HTAlertCallback    *prompt = HTAlert_find (HT_A_CONFIRM);            HTAlertCallback    *prompt = HTAlert_find (HT_A_CONFIRM);
          if (prompt)            if (prompt)
            {              {
              if ((*prompt) (request, HT_A_CONFIRM, HT_MSG_REDIRECTION, NULL, NULL, NULL) != YES)                if ((*prompt) (request, HT_A_CONFIRM, HT_MSG_REDIRECTION, NULL, NULL, NULL) != YES)
                {                  {
                  /* the user didn't agree on the redirection, so                    /* the user didn't agree on the redirection, so
                     we consider it's an abort */                       we consider it's an abort */
                  me->reqStatus = HT_ABORT;                    me->reqStatus = HT_ABORT;
                  /* and we return HT_OK so that the terminate_handler                    /* and we return HT_OK so that the terminate_handler
                     will be called */                       will be called */
                  return HT_OK;                    return HT_OK;
                }                  }
            }              }
        }          }
    }      }
   
    /*    /*
    **  Start new request with the redirect anchor found in the headers.    **  Start new request with the redirect anchor found in the headers.
    **  Note that we reuse the same request object which means that we must    **  Note that we reuse the same request object which means that we must
    **  keep this around until the redirected request has terminated. It also    **  keep this around until the redirected request has terminated. It also
    **  allows us in an easy way to keep track of the number of redirections    **  allows us in an easy way to keep track of the number of redirections
    **  so that we can detect endless loops.    **  so that we can detect endless loops.
    */    */
    if (HTRequest_doRetry (request))    if (HTRequest_doRetry (request))
      {      {
        /*        /*
        ** Start request with new credentials         ** Start request with new credentials 
        */        */
        /* only do a redirect using a network protocol understood by Amaya */        /* only do a redirect using a network protocol understood by Amaya */
        strncpy (urlAdr, new_anchor->parent->address, MAX_LENGTH - 1);        strncpy (urlAdr, new_anchor->parent->address, MAX_LENGTH - 1);
        urlAdr[MAX_LENGTH - 1] = EOS;        urlAdr[MAX_LENGTH - 1] = EOS;
        if (me->urlName && !strcmp (me->urlName, urlAdr))        if (me->urlName && !strcmp (me->urlName, urlAdr))
          {          {
            /* redirect to itself */            /* redirect to itself */
            me->reqStatus = HT_ABORT;            me->reqStatus = HT_ABORT;
            /* and we return HT_OK so that the terminate_handler            /* and we return HT_OK so that the terminate_handler
               will be called */               will be called */
            return HT_OK;            return HT_OK;
          }          }
        if (IsValidProtocol (urlAdr))        if (IsValidProtocol (urlAdr))
          {          {
            /* if it's a valid URL, we try to normalize it */            /* if it's a valid URL, we try to normalize it */
            /* We use the pre-redirection anchor as a base name */            /* We use the pre-redirection anchor as a base name */
            /* @@ how to obtain this address here? */            /* @@ how to obtain this address here? */
            dst = urlAdr;            dst = urlAdr;
            escape_src = EscapeURL (me->urlName);            escape_src = EscapeURL (me->urlName);
            if (escape_src)            if (escape_src)
              {              {
                ref = AmayaParseUrl (dst, escape_src, AMAYA_PARSE_ALL);                ref = AmayaParseUrl (dst, escape_src, AMAYA_PARSE_ALL);
                if (me->method != METHOD_PUT)                if (me->method != METHOD_PUT)
                  AHTRequest_setRefererHeader (me);                  AHTRequest_setRefererHeader (me);
                TtaFreeMemory (escape_src);                TtaFreeMemory (escape_src);
              }              }
            else            else
              ref = NULL;              ref = NULL;
                         
            if (ref)            if (ref)
              {              {
                HTAnchor_setPhysical (HTAnchor_parent (new_anchor), ref);                HTAnchor_setPhysical (HTAnchor_parent (new_anchor), ref);
                TtaFreeMemory (ref);                TtaFreeMemory (ref);
              }              }
            else            else
              return HT_OK; /* We can't redirect anymore */              return HT_OK; /* We can't redirect anymore */
          }          }
        else        else
          return HT_OK; /* We can't redirect anymore */          return HT_OK; /* We can't redirect anymore */
                 
        /* update the current file name */        /* update the current file name */
        if ((me->mode & AMAYA_ASYNC) || (me->mode & AMAYA_IASYNC) ||        if ((me->mode & AMAYA_ASYNC) || (me->mode & AMAYA_IASYNC) ||
            (me->method == METHOD_PUT))            (me->method == METHOD_PUT))
          {          {
            TtaFreeMemory (me->urlName);            TtaFreeMemory (me->urlName);
            me->urlName = TtaStrdup (urlAdr);            me->urlName = TtaStrdup (urlAdr);
          }          }
        else        else
          {          {
            /* it's a SYNC mode, so we should keep the urlName */            /* it's a SYNC mode, so we should keep the urlName */
            strncpy (me->urlName, urlAdr, MAX_LENGTH - 1);            strncpy (me->urlName, urlAdr, MAX_LENGTH - 1);
            me->urlName[MAX_LENGTH - 1] = EOS;            me->urlName[MAX_LENGTH - 1] = EOS;
          }          }
        ChopURL (me->status_urlName, me->urlName);        ChopURL (me->status_urlName, me->urlName);
   
        /* @@ verify if this is important */        /* @@ verify if this is important */
        /* @@@ new libwww doesn't need this free stream while making        /* @@@ new libwww doesn't need this free stream while making
           a PUT. Is it the case everywhere or just for PUT? */           a PUT. Is it the case everywhere or just for PUT? */
       if (me->method != METHOD_PUT &&        if (me->method != METHOD_PUT &&
           me->request->orig_output_stream != NULL)            me->request->orig_output_stream != NULL)
       {  
         AHTFWriter_FREE (me->request->orig_output_stream);  
         me->request->orig_output_stream = NULL;  
         if (me->output != stdout)  
         {          {
           /* Are we writing to a file? */            AHTFWriter_FREE (me->request->orig_output_stream);
             me->request->orig_output_stream = NULL;
             if (me->output != stdout)
               {
                 /* Are we writing to a file? */
 #ifdef DEBUG_LIBWWW  #ifdef DEBUG_LIBWWW
           fprintf (stderr, "redirection_handler: New URL is  %s, closing FILE %p\n", me->urlName, me->output);                 fprintf (stderr, "redirection_handler: New URL is  %s, closing FILE %p\n", me->urlName, me->output); 
 #endif   #endif 
           TtaReadClose (me->output);                TtaReadClose (me->output);
           me->output = NULL;                me->output = NULL;
               }
         }          }
       }  
                 
        /* tell the user what we're doing */        /* tell the user what we're doing */
        TtaSetStatus (me->docid, 1,        TtaSetStatus (me->docid, 1,
        TtaGetMessage (AMAYA, AM_RED_FETCHING), me->status_urlName);                       TtaGetMessage (AMAYA, AM_RED_FETCHING), me->status_urlName); 
        /*        /*
        ** launch the request        ** launch the request
        */        */
        /* add a link relationship? */        /* add a link relationship? */
        /* reset the request status */        /* reset the request status */
        me->reqStatus = HT_NEW;         me->reqStatus = HT_NEW; 
        /* clear the errors */        /* clear the errors */
        HTError_deleteAll (HTRequest_error (request));        HTError_deleteAll (HTRequest_error (request));
        HTRequest_setError (request, NULL);        HTRequest_setError (request, NULL);
        /* clear the authentication credentials, as they get regenerated  */        /* clear the authentication credentials, as they get regenerated  */
        HTRequest_deleteCredentialsAll (request);        HTRequest_deleteCredentialsAll (request);
   
 #ifdef DAV  #ifdef DAV
        /* remove the old header "If" (WebDAV lock information) */        /* remove the old header "If" (WebDAV lock information) */
        DAVRemoveIfHeader (me);        DAVRemoveIfHeader (me);
                 
        /* search lock information for the new url */        /* search lock information for the new url */
        if (me->method == METHOD_POST || me->method == METHOD_PUT)         if (me->method == METHOD_POST || me->method == METHOD_PUT) 
            DAVAddIfHeader (me,me->urlName);          DAVAddIfHeader (me,me->urlName);
 #endif /* DAV */        #endif /* DAV */      
                 
        if (me->method == METHOD_POST || me->method == METHOD_PUT)        if (me->method == METHOD_POST || me->method == METHOD_PUT)
          {          {
            /* PUT, POST etc. */            /* PUT, POST etc. */
            /* for PUT, we memorize there was a redirection, so that we             /* for PUT, we memorize there was a redirection, so that we 
               can clear the original cache entry in the terminate_handler */               can clear the original cache entry in the terminate_handler */
            if (me->method == METHOD_PUT)            if (me->method == METHOD_PUT)
              me->put_redirection = TRUE;              me->put_redirection = TRUE;
            status = HTLoadAbsolute (me->urlName, request);            status = HTLoadAbsolute (me->urlName, request);
          }          }
        else        else
          HTLoadAnchor (new_anchor, request);          HTLoadAnchor (new_anchor, request);
      }      }
    else    else
      {      {
        HTRequest_addError (request, ERR_FATAL, NO, HTERR_MAX_REDIRECT, NULL, 0, "HTRedirectFilter");        HTRequest_addError (request, ERR_FATAL, NO, HTERR_MAX_REDIRECT, NULL, 0, "HTRedirectFilter");
        /* so that we can show the error message */        /* so that we can show the error message */
        if (me->error_html)        if (me->error_html)
          DocNetworkStatus[me->docid] |= AMAYA_NET_ERROR;          DocNetworkStatus[me->docid] |= AMAYA_NET_ERROR;
        me->reqStatus = HT_ERR;        me->reqStatus = HT_ERR;
        TtaSetStatus (me->docid, 1, TtaGetMessage (AMAYA, AM_REDIRECTIONS_LIMIT), NULL);        TtaSetStatus (me->docid, 1, TtaGetMessage (AMAYA, AM_REDIRECTIONS_LIMIT), NULL);
      }      }
         
    /*    /*
    **  By returning HT_ERROR we make sure that this is the last handler to be    **  By returning HT_ERROR we make sure that this is the last handler to be
    **  called. We do this as we don't want any other filter to delete the     **  called. We do this as we don't want any other filter to delete the 
    **  request object now when we have just started a new one ourselves    **  request object now when we have just started a new one ourselves
    */    */
    return HT_ERROR;    return HT_ERROR;
 }  }
   
 #ifdef AMAYA_LOST_UPDATE  #ifdef AMAYA_LOST_UPDATE
Line 1114  static int redirection_handler (HTReques Line 1114  static int redirection_handler (HTReques
   412 "Precondition failed" handler    412 "Precondition failed" handler
   ----------------------------------------------------------------------*/    ----------------------------------------------------------------------*/
 static int precondition_handler (HTRequest *request, HTResponse *response,  static int precondition_handler (HTRequest *request, HTResponse *response,
                                  void *context, int status)                                   void *context, int status)
 {  {
   AHTReqContext      *me = (AHTReqContext *) HTRequest_context (request);    AHTReqContext      *me = (AHTReqContext *) HTRequest_context (request);
   HTAlertCallback    *prompt = HTAlert_find (HT_A_CONFIRM);    HTAlertCallback    *prompt = HTAlert_find (HT_A_CONFIRM);
Line 1126  static int precondition_handler (HTReque Line 1126  static int precondition_handler (HTReque
   if (prompt)    if (prompt)
     {      {
       if (me->method == METHOD_GET)        if (me->method == METHOD_GET)
             {          {
               /* @@@@ IV */            /* @@@@ IV */
               (*prompt) (request, HT_A_CONFIRM, status, NULL, NULL, NULL);            (*prompt) (request, HT_A_CONFIRM, status, NULL, NULL, NULL);
               force_put = NO;            force_put = NO;
             }          }
       else        else
               force_put = ((*prompt)(request, HT_A_CONFIRM, HT_MSG_RULES, NULL, NULL, NULL) != 0);                force_put = ((*prompt)(request, HT_A_CONFIRM, HT_MSG_RULES, NULL, NULL, NULL) != 0);
     }      }
Line 1148  static int precondition_handler (HTReque Line 1148  static int precondition_handler (HTReque
        * code, otherwise we supose that the cause   *         * code, otherwise we supose that the cause   *
        * was an eventual If header.                 */         * was an eventual If header.                 */
       if (HTRequest_preconditions(me->request) != HT_NO_MATCH)        if (HTRequest_preconditions(me->request) != HT_NO_MATCH)
           noIf = NO;          noIf = NO;
       else        else
           noIf = YES;                noIf = YES;      
 #endif /* DAV */  #endif /* DAV */
               
               
       /* start a new PUT request without preconditions */        /* start a new PUT request without preconditions */
       /* @@ do we need to kill the request? */        /* @@ do we need to kill the request? */
       if (me->output && me->output != stdout)        if (me->output && me->output != stdout)
         {          {
           TtaReadClose (me->output);            TtaReadClose (me->output);
           me->output = NULL;            me->output = NULL;
         }          }
       /*        /*
       ** reset the Amaya and libwww request status         ** reset the Amaya and libwww request status 
       */        */
Line 1180  static int precondition_handler (HTReque Line 1180  static int precondition_handler (HTReque
       ** buffered in the output buffer        ** buffered in the output buffer
       */        */
       if (me->mode & AMAYA_FLUSH_REQUEST)        if (me->mode & AMAYA_FLUSH_REQUEST)
         HTRequest_setFlush(me->request, YES);          HTRequest_setFlush(me->request, YES);
   
       /* turn off preconditions */        /* turn off preconditions */
       HTRequest_setPreconditions(me->request, HT_NO_MATCH);        HTRequest_setPreconditions(me->request, HT_NO_MATCH);
Line 1191  static int precondition_handler (HTReque Line 1191  static int precondition_handler (HTReque
       /* MKP: add an If header (lock information) only         /* MKP: add an If header (lock information) only 
        * if there wasn't preconditions */         * if there wasn't preconditions */
       if (noIf != YES)        if (noIf != YES)
         DAVAddIfHeader (me,HTAnchor_address(me->dest));          DAVAddIfHeader (me,HTAnchor_address(me->dest));
 #endif /* DAV */  #endif /* DAV */
               
               
       /* make the request */              /* make the request */      
       status = HTPutDocumentAnchor (HTAnchor_parent (me->source),         status = HTPutDocumentAnchor (HTAnchor_parent (me->source), 
                                     me->dest, me->request);                                      me->dest, me->request);
       /* stop here */        /* stop here */
       return HT_ERROR;        return HT_ERROR;
     }      }
Line 1216  static int precondition_handler (HTReque Line 1216  static int precondition_handler (HTReque
   Request HEAD checker filter    Request HEAD checker filter
   ----------------------------------------------------------------------*/    ----------------------------------------------------------------------*/
 static int check_handler (HTRequest * request, HTResponse * response,  static int check_handler (HTRequest * request, HTResponse * response,
                            void * param, int status)                            void * param, int status)
 {  {
   AHTReqContext  *me = (AHTReqContext *) HTRequest_context (request);    AHTReqContext  *me = (AHTReqContext *) HTRequest_context (request);
   HTAlertCallback    *prompt = HTAlert_find (HT_A_CONFIRM);    HTAlertCallback    *prompt = HTAlert_find (HT_A_CONFIRM);
Line 1267  static int check_handler (HTRequest * re Line 1267  static int check_handler (HTRequest * re
       ** buffered in the output buffer        ** buffered in the output buffer
       */        */
       if (me->mode & AMAYA_FLUSH_REQUEST)        if (me->mode & AMAYA_FLUSH_REQUEST)
         HTRequest_setFlush(me->request, YES);          HTRequest_setFlush(me->request, YES);
         
 #ifdef DAV  #ifdef DAV
       /* MKP: try to add an "If" header (lock information)         /* MKP: try to add an "If" header (lock information) 
Line 1278  static int check_handler (HTRequest * re Line 1278  static int check_handler (HTRequest * re
   
   
       /* turn on the special preconditions, to avoid having this        /* turn on the special preconditions, to avoid having this
          ressource appear before we do the PUT */           ressource appear before we do the PUT */
       HTRequest_setPreconditions(me->request, HT_DONT_MATCH_ANY);        HTRequest_setPreconditions(me->request, HT_DONT_MATCH_ANY);
       me->reqStatus = HT_NEW;        me->reqStatus = HT_NEW;
       status = HTPutDocumentAnchor (HTAnchor_parent (me->source), me->dest, me->request);        status = HTPutDocumentAnchor (HTAnchor_parent (me->source), me->dest, me->request);
Line 1292  static int check_handler (HTRequest * re Line 1292  static int check_handler (HTRequest * re
               force_put = FALSE;                force_put = FALSE;
   
       if (force_put)        if (force_put)
         {          {
           /* Start a new PUT request without preconditions */            /* Start a new PUT request without preconditions */
   
           /* get a new, clean request structure */            /* get a new, clean request structure */
           HTRequest_delete (me->request);            HTRequest_delete (me->request);
           me->request = HTRequest_new ();            me->request = HTRequest_new ();
           /* add the default PUT name */            /* add the default PUT name */
           HTRequest_setDefaultPutName (me->request, me->default_put_name);            HTRequest_setDefaultPutName (me->request, me->default_put_name);
           /* clean the associated file structure) */            /* clean the associated file structure) */
           HTRequest_setOutputStream (me->request, NULL);            HTRequest_setOutputStream (me->request, NULL);
           /* Initialize the other members of the structure */            /* Initialize the other members of the structure */
           HTRequest_setMethod (me->request, METHOD_GET);            HTRequest_setMethod (me->request, METHOD_GET);
           HTRequest_setOutputFormat (me->request, WWW_SOURCE);            HTRequest_setOutputFormat (me->request, WWW_SOURCE);
           HTRequest_setContext (me->request, me);            HTRequest_setContext (me->request, me);
           HTRequest_setPreemptive (me->request, NO);            HTRequest_setPreemptive (me->request, NO);
         
 #ifdef DAV  #ifdef DAV
          /* MKP: try to add an "If" header (lock information)             /* MKP: try to add an "If" header (lock information) 
           *      Such header will be added only if there is a             *      Such header will be added only if there is a
           *      lock information in the local base. */              *      lock information in the local base. */ 
           DAVAddIfHeader (me,HTAnchor_address(me->dest));               DAVAddIfHeader (me,HTAnchor_address(me->dest));   
 #endif /* DAV */  #endif /* DAV */
   
                       
           /*            /*
           ** Make sure that the first request is flushed immediately and not            ** Make sure that the first request is flushed immediately and not
           ** buffered in the output buffer            ** buffered in the output buffer
           */            */
           if (me->mode & AMAYA_FLUSH_REQUEST)            if (me->mode & AMAYA_FLUSH_REQUEST)
             HTRequest_setFlush(me->request, YES);              HTRequest_setFlush(me->request, YES);
           /* remove the preconditions */            /* remove the preconditions */
           HTRequest_setPreconditions(me->request, HT_NO_MATCH);            HTRequest_setPreconditions(me->request, HT_NO_MATCH);
           me->reqStatus = HT_NEW;             me->reqStatus = HT_NEW; 
           status = HTPutDocumentAnchor (HTAnchor_parent (me->source),             status = HTPutDocumentAnchor (HTAnchor_parent (me->source), 
                                         me->dest, me->request);                                          me->dest, me->request);
           return HT_ERROR; /* stop here */            return HT_ERROR; /* stop here */
         }           } 
       else        else
         {          {
           /* we'd need to call terminate_handler, to free the resources */            /* we'd need to call terminate_handler, to free the resources */
           /* abort the request */            /* abort the request */
           /* @@ should we call StopRequest here? */            /* @@ should we call StopRequest here? */
           me->reqStatus = HT_ABORT;            me->reqStatus = HT_ABORT;
           /* stop here */            /* stop here */
           return HT_ERROR;             return HT_ERROR; 
         }          }
     }      }
   return HT_ERROR;    return HT_ERROR;
 }  }
Line 1347  static int check_handler (HTRequest * re Line 1347  static int check_handler (HTRequest * re
   this function is registered to handle the result of the request    this function is registered to handle the result of the request
   ----------------------------------------------------------------------*/    ----------------------------------------------------------------------*/
 static int terminate_handler (HTRequest *request, HTResponse *response,  static int terminate_handler (HTRequest *request, HTResponse *response,
                               void *context, int status)                                void *context, int status)
 {  {
   AHTReqContext      *me = (AHTReqContext *) HTRequest_context (request);    AHTReqContext      *me = (AHTReqContext *) HTRequest_context (request);
   ThotBool            error_flag;    ThotBool            error_flag;
   
   if (!me)    if (!me)
      return HT_ERROR;           /* not an Amaya request */      return HT_ERROR;            /* not an Amaya request */
   
   if (me->reqStatus == HT_END)    if (me->reqStatus == HT_END)
     /* we have already processed this request! */      /* we have already processed this request! */
Line 1362  static int terminate_handler (HTRequest Line 1362  static int terminate_handler (HTRequest
   /* if Amaya was killed, treat with this request as if it were    /* if Amaya was killed, treat with this request as if it were
      issued by a Stop button event */       issued by a Stop button event */
   
    if (!AmayaIsAlive ())               if (!AmayaIsAlive ())           
       me->reqStatus = HT_ABORT;       me->reqStatus = HT_ABORT; 
   
     /* trying to protect against this problem... hard to place
        the detection elsewhere :-/ */
     /* @@ JK: Is this still needed? */
     if (IsHTTP09Error (request))
       status = -1;
   
    /* trying to protect against this problem... hard to place    if (status == HT_LOADED
       the detection elsewhere :-/ */        || status == HT_CREATED
    /* @@ JK: Is this still needed? */        || status == HT_NO_DATA
    if (IsHTTP09Error (request))        /* JK: removed it as the kludge doesn't seem useful anymore */
      status = -1;        /* kludge for work around libwww problem */
         /* || (status == HT_INTERRUPTED && me->method == METHOD_PUT) */
    if (status == HT_LOADED  
        || status == HT_CREATED  
        || status == HT_NO_DATA  
        /* JK: removed it as the kludge doesn't seem useful anymore */  
        /* kludge for work around libwww problem */  
        /* || (status == HT_INTERRUPTED && me->method == METHOD_PUT) */  
 #ifdef AMAYA_WWW_CACHE  #ifdef AMAYA_WWW_CACHE
        /* what status to use to know we're downloading from a cache? */        /* what status to use to know we're downloading from a cache? */
        || status ==  HT_NOT_MODIFIED        || status ==  HT_NOT_MODIFIED
        || status == HT_PARTIAL_CONTENT        || status == HT_PARTIAL_CONTENT
 #endif /* AMAYA_WWW_CACHE */  #endif /* AMAYA_WWW_CACHE */
        || me->reqStatus == HT_ABORT)        || me->reqStatus == HT_ABORT)
      error_flag = FALSE;      error_flag = FALSE;
 #ifdef DAV  #ifdef DAV
    else if (status == HT_LOCKED     else if (status == HT_LOCKED 
             || status ==  HT_FAILED_DEPENDENCY              || status ==  HT_FAILED_DEPENDENCY 
             || status == HT_MULTI_STATUS)              || status == HT_MULTI_STATUS) 
     {      {
      /* WebDAV return codes - they are handled in        /* WebDAV return codes - they are handled in
       * specific filters. We don't need to deal         * specific filters. We don't need to deal
       * with them anymore         * with them anymore
       */         */
      error_flag = FALSE;                   error_flag = FALSE;          
     }      }
 #endif   /* DAV */  #endif   /* DAV */
    else    else
      error_flag = TRUE;      error_flag = TRUE;
   
    /* If we did a PUT that was redirected, clean the original    /* If we did a PUT that was redirected, clean the original
       cache entry */       cache entry */
    if (status == 204 && me->method == METHOD_PUT && me->put_redirection)    if (status == 204 && me->method == METHOD_PUT && me->put_redirection)
    {      {
      HTCache * cache;        HTCache * cache;
      HTParentAnchor * anchor = HTAnchor_parent (me->dest);        HTParentAnchor * anchor = HTAnchor_parent (me->dest);
      cache = HTCache_find (anchor, NULL);        cache = HTCache_find (anchor, NULL);
      if (cache)        if (cache)
        {          {
          /* what a problem... we update the cache with the wrong data            /* what a problem... we update the cache with the wrong data
             from the response... after the redirection */               from the response... after the redirection */
          HTCache_resetMeta (cache, request, response);            HTCache_resetMeta (cache, request, response);
        }          }
      else        else
        /* If entry doesn't already exist then create a new entry */          /* If entry doesn't already exist then create a new entry */
        HTCache_touch(request, response, HTAnchor_parent (me->dest));          HTCache_touch(request, response, HTAnchor_parent (me->dest));
    }      }
   
    /* output any errors from the server */    /* output any errors from the server */
   
    /*    /*
    ** me->output = output file which will receive an html file    ** me->output = output file which will receive an html file
    ** me->error_html = yes, output HTML errors in the screen    ** me->error_html = yes, output HTML errors in the screen
    ** request->error_stack == if there are any errors, they will be here    ** request->error_stack == if there are any errors, they will be here
    ** me->error_stream_size If it's != 0 means an error message has already    ** me->error_stream_size If it's != 0 means an error message has already
    **                       been written to the stack    **                       been written to the stack
    */    */
         
    /* First, we verify if there are any errors and if they are not    /* First, we verify if there are any errors and if they are not
    ** yet written to the error stack. If no, then let's try to write them    ** yet written to the error stack. If no, then let's try to write them
    ** ourselves    ** ourselves
    */    */
         
 #ifdef DEBUG_LIBWWW  #ifdef DEBUG_LIBWWW
    fprintf (stderr, "terminate_handler: URL is "    fprintf (stderr, "terminate_handler: URL is "
             "%s, closing FILE %p status is %d\n", me->urlName, me->output,              "%s, closing FILE %p status is %d\n", me->urlName, me->output, 
             status);              status); 
 #endif  #endif
         
    if (me->output && me->output != stdout)    if (me->output && me->output != stdout)
      {      {
        /* we are writing to a local file */        /* we are writing to a local file */
        if (me->reqStatus != HT_ABORT)        if (me->reqStatus != HT_ABORT)
          {                                {                       
            /* if the request was not aborted and            /* if the request was not aborted and
               there were some errors and we want to print them */               there were some errors and we want to print them */
   
            /* JK: 30/04/2004. The 201 reponse from the annotation server            /* JK: 30/04/2004. The 201 reponse from the annotation server
               is being stored inside the error flag! */               is being stored inside the error flag! */
            if ((status == 201 && me->mode & AMAYA_FILE_POST && me->error_stream)            if ((status == 201 && me->mode & AMAYA_FILE_POST && me->error_stream)
                || (error_flag && me->error_html == TRUE))                || (error_flag && me->error_html == TRUE))
              {                        {           
                /* if the transfer was interrupted, the file may not be                /* if the transfer was interrupted, the file may not be
                   empty. So, we erase it */                   empty. So, we erase it */
                fflush (me->output);                fflush (me->output);
                rewind (me->output);                rewind (me->output);
   
                if (me->error_stream)                if (me->error_stream)
                  {      /* if the stream is non-empty */                  {       /* if the stream is non-empty */
                    fprintf (me->output, "%s", me->error_stream);/* output the errors */                    fprintf (me->output, "%s", me->error_stream);/* output the errors */
                    /* Clear the error context, so that we can deal with                    /* Clear the error context, so that we can deal with
                       this answer as if it were a normal reply */                       this answer as if it were a normal reply */
                     HTError_deleteAll( HTRequest_error (request));                    HTError_deleteAll( HTRequest_error (request));
                     HTRequest_setError (request, NULL);                    HTRequest_setError (request, NULL);
                     error_flag = 0;                    error_flag = 0;
                  }                  }
              }                  /* if error_stack */              }                   /* if error_stack */
          }          }
                 
        /* if != HT_ABORT */        /* if != HT_ABORT */
                 
 #ifdef DEBUG_LIBWWW         #ifdef DEBUG_LIBWWW       
        fprintf (stderr, "terminate_handler: URL is  %s, closing "        fprintf (stderr, "terminate_handler: URL is  %s, closing "
                 "FILE %p\n", me->urlName, me->output);                  "FILE %p\n", me->urlName, me->output); 
 #endif  #endif
        TtaWriteClose (me->output);        TtaWriteClose (me->output);
        me->output = NULL;        me->output = NULL;
      }      }
   
    /* a very special handling so that we can put a message box    /* a very special handling so that we can put a message box
       to tell the user WHAT he has just done... */       to tell the user WHAT he has just done... */
    if (UserAborted_flag && me->method == METHOD_PUT)    if (UserAborted_flag && me->method == METHOD_PUT)
      {      {
        HTRequest_addError (request, ERR_FATAL, NO, HTERR_INTERRUPTED,        HTRequest_addError (request, ERR_FATAL, NO, HTERR_INTERRUPTED,
                            (void *)"Operation aborted by user", 0, NULL);                            (void *)"Operation aborted by user", 0, NULL);
      }      }
   
    if (error_flag)    if (error_flag)
      me->reqStatus = HT_ERR;      me->reqStatus = HT_ERR;
    else     else 
      if (me->reqStatus != HT_ABORT)      if (me->reqStatus != HT_ABORT)
        me->reqStatus = HT_END;        me->reqStatus = HT_END;
   
    /* copy the headers in which the application is interested */    /* copy the headers in which the application is interested */
    HTTP_headers_set (request, response, context, status);    HTTP_headers_set (request, response, context, status);
   
    /* to avoid a hangup while downloading css files */    /* to avoid a hangup while downloading css files */
    if (AmayaAlive_flag && (me->mode & AMAYA_LOAD_CSS))    if (AmayaAlive_flag && (me->mode & AMAYA_LOAD_CSS))
      TtaSetStatus (me->docid, 1,      TtaSetStatus (me->docid, 1,
                    TtaGetMessage (AMAYA, AM_ELEMENT_LOADED),                    TtaGetMessage (AMAYA, AM_ELEMENT_LOADED),
                    me->status_urlName);                    me->status_urlName);
         
   /* don't remove or Xt will hang up during the PUT */    /* don't remove or Xt will hang up during the PUT */
    if (AmayaIsAlive ()  && ((me->method == METHOD_POST) ||    if (AmayaIsAlive ()  && ((me->method == METHOD_POST) ||
                             (me->method == METHOD_PUT)))                             (me->method == METHOD_PUT)))
      {      {
        PrintTerminateStatus (me, status);        PrintTerminateStatus (me, status);
      }       } 
   
    ProcessTerminateRequest (request, response, context, status);    ProcessTerminateRequest (request, response, context, status);
         
    /* stop here */    /* stop here */
    return HT_ERROR;    return HT_ERROR;
 }  }
   
 /*----------------------------------------------------------------------  /*----------------------------------------------------------------------
Line 1520  static int terminate_handler (HTRequest Line 1520  static int terminate_handler (HTRequest
   when a request has ended, so that we can setup the correct status.    when a request has ended, so that we can setup the correct status.
   ----------------------------------------------------------------------*/    ----------------------------------------------------------------------*/
 int AHTLoadTerminate_handler (HTRequest *request, HTResponse *response,  int AHTLoadTerminate_handler (HTRequest *request, HTResponse *response,
                               void *param, int status)                                void *param, int status)
 {  {
   /** @@@@ use this with printstatus ?? */    /** @@@@ use this with printstatus ?? */
    AHTReqContext      *me = (AHTReqContext *)HTRequest_context (request);    AHTReqContext      *me = (AHTReqContext *)HTRequest_context (request);
    HTAlertCallback    *cbf;    HTAlertCallback    *cbf;
    AHTDocId_Status    *docid_status;    AHTDocId_Status    *docid_status;
   
    switch (status)    switch (status)
      {      {
          case HT_LOADED:      case HT_LOADED:
            if (PROT_TRACE)        if (PROT_TRACE)
              HTTrace ("Load End.... OK: `%s\' has been accessed\n",          HTTrace ("Load End.... OK: `%s\' has been accessed\n",
                       me->status_urlName);                   me->status_urlName);
   
            docid_status = GetDocIdStatus (me->docid,        docid_status = GetDocIdStatus (me->docid,
                                           Amaya->docid_status);                                       Amaya->docid_status);
   
            if (docid_status != NULL && docid_status->counter > 1)        if (docid_status != NULL && docid_status->counter > 1)
              TtaSetStatus (me->docid, 1,           TtaSetStatus (me->docid, 1, 
                            TtaGetMessage (AMAYA, AM_ELEMENT_LOADED),                        TtaGetMessage (AMAYA, AM_ELEMENT_LOADED),
                            me->status_urlName);                        me->status_urlName);
                break;        break;
                                 
      case HT_NO_DATA:      case HT_NO_DATA:
        if (PROT_TRACE)        if (PROT_TRACE)
          HTTrace ("Load End.... OK BUT NO DATA: `%s\'\n",           HTTrace ("Load End.... OK BUT NO DATA: `%s\'\n", 
                   me->status_urlName);                   me->status_urlName);
 #ifdef DAV        #ifdef DAV      
        if (me->method==METHOD_UNLOCK)         if (me->method==METHOD_UNLOCK) 
         {          {
            /* MKP: set an appropriate status message */            /* MKP: set an appropriate status message */
            TtaSetStatus (me->docid, 1,             TtaSetStatus (me->docid, 1, 
                      TtaGetMessage (AMAYA, AM_UNLOCK_SUCCEED),                          TtaGetMessage (AMAYA, AM_UNLOCK_SUCCEED),
                      NULL);                          NULL);
         }          }
        else        else
 #endif /* DAV */  #endif /* DAV */
            TtaSetStatus (me->docid, 1,           TtaSetStatus (me->docid, 1, 
                      TtaGetMessage (AMAYA, AM_LOADED_NO_DATA),                        TtaGetMessage (AMAYA, AM_LOADED_NO_DATA),
                      me->status_urlName);                        me->status_urlName);
        break;        break;
                 
      case HT_INTERRUPTED:      case HT_INTERRUPTED:
        if (PROT_TRACE)        if (PROT_TRACE)
          HTTrace ("Load End.... INTERRUPTED: `%s\'\n",           HTTrace ("Load End.... INTERRUPTED: `%s\'\n", 
                   me->status_urlName);                   me->status_urlName);
        TtaSetStatus (me->docid, 1,         TtaSetStatus (me->docid, 1, 
                      TtaGetMessage (AMAYA, AM_LOAD_ABORT),                       TtaGetMessage (AMAYA, AM_LOAD_ABORT), 
                      NULL);                      NULL);
        break;        break;
   
      case HT_RETRY:      case HT_RETRY:
        if (PROT_TRACE)        if (PROT_TRACE)
          HTTrace ("Load End.... NOT AVAILABLE, RETRY AT %ld\n",          HTTrace ("Load End.... NOT AVAILABLE, RETRY AT %ld\n",
                   HTResponse_retryTime (response));                   HTResponse_retryTime (response));
        TtaSetStatus (me->docid, 1,         TtaSetStatus (me->docid, 1, 
                      TtaGetMessage (AMAYA, AM_NOT_AVAILABLE_RETRY),                      TtaGetMessage (AMAYA, AM_NOT_AVAILABLE_RETRY),
                      me->status_urlName);                      me->status_urlName);
        break;        break;
   
      case HT_NOT_MODIFIED:      case HT_NOT_MODIFIED:
        if (PROT_TRACE)        if (PROT_TRACE)
          HTTrace ("Load End.... NOT MODIFIED (%s)",          HTTrace ("Load End.... NOT MODIFIED (%s)",
                   me->status_urlName ? me->status_urlName :" <UNKNOWN>");                   me->status_urlName ? me->status_urlName :" <UNKNOWN>");
        break;        break;
                 
      case HT_ERROR:      case HT_ERROR:
        cbf = HTAlert_find (HT_A_MESSAGE);        cbf = HTAlert_find (HT_A_MESSAGE);
        if (cbf)        if (cbf)
          (*cbf) (request, HT_A_MESSAGE, HT_MSG_NULL, NULL,          (*cbf) (request, HT_A_MESSAGE, HT_MSG_NULL, NULL,
                  HTRequest_error (request), NULL);                  HTRequest_error (request), NULL);
        if (PROT_TRACE)        if (PROT_TRACE)
            HTTrace ("Load End.... ERROR: Can't access `%s\'\n",          HTTrace ("Load End.... ERROR: Can't access `%s\'\n",
                     me->status_urlName ? me->status_urlName :"<UNKNOWN>");                    me->status_urlName ? me->status_urlName :"<UNKNOWN>"); 
        TtaSetStatus (me->docid, 1,        TtaSetStatus (me->docid, 1,
                      TtaGetMessage (AMAYA, AM_CANNOT_LOAD),                      TtaGetMessage (AMAYA, AM_CANNOT_LOAD),
                      me->status_urlName ? me->status_urlName : (char *)"<UNKNOWN>");                      me->status_urlName ? me->status_urlName : (char *)"<UNKNOWN>");
        break;        break;
   
      case HTERR_TIMEOUT:      case HTERR_TIMEOUT:
        cbf = HTAlert_find (HT_A_MESSAGE);        cbf = HTAlert_find (HT_A_MESSAGE);
        if (cbf)        if (cbf)
          (*cbf) (request, HT_A_MESSAGE, HT_MSG_NULL, NULL,          (*cbf) (request, HT_A_MESSAGE, HT_MSG_NULL, NULL,
                  HTRequest_error (request), NULL);                  HTRequest_error (request), NULL);
        if (PROT_TRACE)        if (PROT_TRACE)
            HTTrace ("Load End.... REQUEST TIMEOUT: Can't access `%s\'\n",          HTTrace ("Load End.... REQUEST TIMEOUT: Can't access `%s\'\n",
                     me->status_urlName ? me->status_urlName :"<UNKNOWN>");                    me->status_urlName ? me->status_urlName :"<UNKNOWN>"); 
        TtaSetStatus (me->docid, 1, TtaGetMessage (AMAYA, AM_CANNOT_LOAD),        TtaSetStatus (me->docid, 1, TtaGetMessage (AMAYA, AM_CANNOT_LOAD),
                      me->status_urlName ? me->status_urlName : (char *)"<UNKNOWN>");                      me->status_urlName ? me->status_urlName : (char *)"<UNKNOWN>");
        break;        break;
   
      default:      default:
        if (PROT_TRACE)        if (PROT_TRACE)
          HTTrace ("Load End.... UNKNOWN RETURN CODE %d\n", status);          HTTrace ("Load End.... UNKNOWN RETURN CODE %d\n", status);
        break;        break;
      }      }
         
    return HT_OK;    return HT_OK;
 }  }
   
 /*----------------------------------------------------------------------  /*----------------------------------------------------------------------
Line 1637  static  int LineTrace (const char * fmt, Line 1637  static  int LineTrace (const char * fmt,
   ----------------------------------------------------------------------*/    ----------------------------------------------------------------------*/
 static void           AHTAcceptTypesInit (HTList *c)  static void           AHTAcceptTypesInit (HTList *c)
 {  {
    if (c == (HTList *) NULL)     if (c == (HTList *) NULL) 
       return;      return;
   
    /* define here all the mime types that Amaya can accept */    /* define here all the mime types that Amaya can accept */
   
    HTConversion_add (c, "image/png",  "www/present", HTThroughLine, 1.0, 0.0, 0.0);    HTConversion_add (c, "image/png",  "www/present", HTThroughLine, 1.0, 0.0, 0.0);
    HTConversion_add (c, "image/jpeg", "www/present", HTThroughLine, 1.0, 0.0, 0.0);    HTConversion_add (c, "image/jpeg", "www/present", HTThroughLine, 1.0, 0.0, 0.0);
    HTConversion_add (c, "image/gif",  "www/present", HTThroughLine, 1.0, 0.0, 0.0);    HTConversion_add (c, "image/gif",  "www/present", HTThroughLine, 1.0, 0.0, 0.0);
    HTConversion_add (c, "image/xbm",  "www/present", HTThroughLine, 1.0, 0.0, 0.0);    HTConversion_add (c, "image/xbm",  "www/present", HTThroughLine, 1.0, 0.0, 0.0);
    HTConversion_add (c, "image/xpm",  "www/present", HTThroughLine, 1.0, 0.0, 0.0);    HTConversion_add (c, "image/xpm",  "www/present", HTThroughLine, 1.0, 0.0, 0.0);
   
    /* Define here the equivalences between MIME types and file extensions for    /* Define here the equivalences between MIME types and file extensions for
       the types that Amaya can display */       the types that Amaya can display */
   
    /* Initialize suffix bindings for local files */    /* Initialize suffix bindings for local files */
    HTBind_init();    HTBind_init();
   
    /* Register the default set of file suffix bindings */    /* Register the default set of file suffix bindings */
    HTFileInit ();    HTFileInit ();
   
    /* Register additional bindings */    /* Register additional bindings */
    HTBind_add("htm", "text/html",  NULL, "8bit", NULL, 1.0);    HTBind_add("htm", "text/html",  NULL, "8bit", NULL, 1.0);
    HTBind_add("tgz", "application/gnutar",  NULL, "binary", NULL, 1.0);    HTBind_add("tgz", "application/gnutar",  NULL, "binary", NULL, 1.0);
    HTBind_add("mml", AM_MATHML_MIME_TYPE,  NULL, "8bit", NULL, 1.0);    HTBind_add("mml", AM_MATHML_MIME_TYPE,  NULL, "8bit", NULL, 1.0);
    HTBind_add("svg", AM_SVG_MIME_TYPE,  NULL, "8bit", NULL, 1.0);    HTBind_add("svg", AM_SVG_MIME_TYPE,  NULL, "8bit", NULL, 1.0);
    HTBind_add("xsl", "text/xml",  NULL, "8bit", NULL, 1.0);    HTBind_add("xsl", "text/xml",  NULL, "8bit", NULL, 1.0);
    /* Don't do any case distinction */    /* Don't do any case distinction */
    HTBind_caseSensitive (FALSE);    HTBind_caseSensitive (FALSE);
 }  }
   
 /*----------------------------------------------------------------------  /*----------------------------------------------------------------------
Line 1694  static void         AHTAcceptLanguagesIn Line 1694  static void         AHTAcceptLanguagesIn
       ptr = lang_list;        ptr = lang_list;
       count = 0;        count = 0;
       while (*ptr != EOS)        while (*ptr != EOS)
         {          {
           while (*ptr != EOS &&            while (*ptr != EOS &&
                  (*ptr < 'A' || (*ptr > 'Z' && *ptr < 'a') || *ptr > 'z'))                   (*ptr < 'A' || (*ptr > 'Z' && *ptr < 'a') || *ptr > 'z'))
             /* skip the whole separator */              /* skip the whole separator */
             ptr++;              ptr++;
           lg = 0;            lg = 0;
           while ((*ptr >= 'A' &&            while ((*ptr >= 'A' &&
                   *ptr <= 'Z') || (*ptr >= 'a' && *ptr <= 'z') || *ptr == '-')                    *ptr <= 'Z') || (*ptr >= 'a' && *ptr <= 'z') || *ptr == '-')
             {              {
               /* it's a new language */                /* it's a new language */
               ptr++;                ptr++;
               lg++;                lg++;
             }              }
           if (lg >= 2)            if (lg >= 2)
             count++;              count++;
           if (*ptr != EOS)            if (*ptr != EOS)
             ptr++;              ptr++;
         }          }
   
       if (count > 0)        if (count > 0)
         quality = 1.1 - (double) count/10.0;          quality = 1.1 - (double) count/10.0;
       else        else
         quality = 1.0;          quality = 1.0;
   
       /* Read the languages from the registry, then inject them one, by one.        /* Read the languages from the registry, then inject them one, by one.
          The first one is the one with the highest priority.           The first one is the one with the highest priority.
          The libwww ask for the lowest priority first.           The libwww ask for the lowest priority first.
       */        */
       ptr--;        ptr--;
       still = TRUE;        still = TRUE;
       while (count)        while (count)
         {          {
           while (still && (*ptr < 'A' || (*ptr > 'Z' && *ptr < 'a') || *ptr > 'z'))            while (still && (*ptr < 'A' || (*ptr > 'Z' && *ptr < 'a') || *ptr > 'z'))
             /* skip the whole separator */              /* skip the whole separator */
             if (ptr > lang_list)              if (ptr > lang_list)
               ptr--;                ptr--;
             else              else
               still = FALSE;                still = FALSE;
           lg = 0;            lg = 0;
           while (still &&            while (still &&
                  ((*ptr >= 'A' &&                   ((*ptr >= 'A' &&
                    *ptr <= 'Z') || (*ptr >= 'a' && *ptr <= 'z') || *ptr == '-'))                     *ptr <= 'Z') || (*ptr >= 'a' && *ptr <= 'z') || *ptr == '-'))
             {              {
               /* it's a new language */                /* it's a new language */
               if (ptr > lang_list)                if (ptr > lang_list)
                 ptr--;                  ptr--;
               else                else
                 still = FALSE;                  still = FALSE;
               lg++;                lg++;
             }              }
           if (lg >= 2)            if (lg >= 2)
             {              {
               if (still)                if (still)
                 strncpy  (s, &ptr[1], 2);                  strncpy  (s, &ptr[1], 2);
               else                else
                 strncpy (s, lang_list, 2);                  strncpy (s, lang_list, 2);
               count--;                count--;
               HTLanguage_add (c, s, quality);                HTLanguage_add (c, s, quality);
               quality += 0.1;                quality += 0.1;
             }              }
           ptr--;            ptr--;
         }          }
     }      }
 }  }
   
Line 1766  static void         AHTAcceptLanguagesIn Line 1766  static void         AHTAcceptLanguagesIn
   ----------------------------------------------------------------------*/    ----------------------------------------------------------------------*/
 static void         AHTConverterInit (HTList *c)  static void         AHTConverterInit (HTList *c)
 {  {
    /* Handler for custom http error messages */    /* Handler for custom http error messages */
    HTConversion_add (c, "*/*", "www/debug", AHTMemConverter, 1.0, 0.0, 0.0);    HTConversion_add (c, "*/*", "www/debug", AHTMemConverter, 1.0, 0.0, 0.0);
   
    /*    /*
     ** These are converters that converts to something other than www/present,    ** These are converters that converts to something other than www/present,
     ** that is not directly outputting someting to the user on the screen    ** that is not directly outputting someting to the user on the screen
     */    */
   
    HTConversion_add (c, "message/rfc822", "*/*", HTMIMEConvert, 1.0, 0.0, 0.0);    HTConversion_add (c, "message/rfc822", "*/*", HTMIMEConvert, 1.0, 0.0, 0.0);
    HTConversion_add (c, "message/x-rfc822-foot", "*/*", HTMIMEFooter, 1.0, 0.0, 0.0);    HTConversion_add (c, "message/x-rfc822-foot", "*/*", HTMIMEFooter, 1.0, 0.0, 0.0);
    HTConversion_add (c, "message/x-rfc822-head", "*/*", HTMIMEHeader, 1.0, 0.0, 0.0);    HTConversion_add (c, "message/x-rfc822-head", "*/*", HTMIMEHeader, 1.0, 0.0, 0.0);
    HTConversion_add(c,"message/x-rfc822-cont",  "*/*", HTMIMEContinue, 1.0, 0.0, 0.0);    HTConversion_add(c,"message/x-rfc822-cont",   "*/*", HTMIMEContinue, 1.0, 0.0, 0.0);
    HTConversion_add(c,"message/x-rfc822-partial","*/*", HTMIMEPartial, 1.0, 0.0, 0.0);    HTConversion_add(c,"message/x-rfc822-partial","*/*",  HTMIMEPartial, 1.0, 0.0, 0.0);
    HTConversion_add (c, "multipart/*", "*/*", HTBoundary, 1.0, 0.0, 0.0);    HTConversion_add (c, "multipart/*", "*/*", HTBoundary, 1.0, 0.0, 0.0);
    HTConversion_add (c, "text/plain", "text/html", HTPlainToHTML, 1.0, 0.0, 0.0);    HTConversion_add (c, "text/plain", "text/html", HTPlainToHTML, 1.0, 0.0, 0.0);
   
    /*    /*
    ** The following conversions are converting ASCII output from various    ** The following conversions are converting ASCII output from various
    ** protocols to HTML objects.    ** protocols to HTML objects.
    */    */
    HTConversion_add (c, "text/x-http", "*/*", HTTPStatus_new, 1.0, 0.0, 0.0);    HTConversion_add (c, "text/x-http", "*/*", HTTPStatus_new, 1.0, 0.0, 0.0);
   
    /*    /*
    ** We also register a special content type guess stream that can figure out    ** We also register a special content type guess stream that can figure out
    ** the content type by reading the first bytes of the stream    ** the content type by reading the first bytes of the stream
    */    */
    HTConversion_add (c, "www/unknown", "*/*", HTGuess_new, 1.0, 0.0, 0.0);    HTConversion_add (c, "www/unknown", "*/*", HTGuess_new, 1.0, 0.0, 0.0);
   
 #ifdef AMAYA_WWW_CACHE  #ifdef AMAYA_WWW_CACHE
    /*    /*
    ** Register a persistent cache stream which can save an object to local    ** Register a persistent cache stream which can save an object to local
    ** file    ** file
    */    */
    HTConversion_add (c, "www/cache", "*/*", HTCacheWriter, 1.0, 0.0, 0.0);    HTConversion_add (c, "www/cache", "*/*", HTCacheWriter, 1.0, 0.0, 0.0);
    HTConversion_add(c,"www/cache-append", "*/*", HTCacheAppend, 1.0, 0.0, 0.0);    HTConversion_add(c,"www/cache-append", "*/*", HTCacheAppend, 1.0, 0.0, 0.0);
 #endif /*AMAYA_WWW_CACHE*/  #endif /*AMAYA_WWW_CACHE*/
   
    /*    /*
    ** This dumps all other formats to local disk without any further    ** This dumps all other formats to local disk without any further
    ** action taken    ** action taken
    */    */
    HTConversion_add (c, "*/*", "www/present", HTSaveLocally, 0.3, 0.0, 0.0);      HTConversion_add (c, "*/*", "www/present", HTSaveLocally, 0.3, 0.0, 0.0);  
 }  }
   
   
Line 1822  static void         AHTProtocolInit (voi Line 1822  static void         AHTProtocolInit (voi
   /*     /* 
      NB. Preemptive == YES means Blocking requests       NB. Preemptive == YES means Blocking requests
      Non-preemptive == NO means Non-blocking requests       Non-preemptive == NO means Non-blocking requests
      */    */
   HTTransport_add("tcp", HT_TP_SINGLE, HTReader_new, HTWriter_new);    HTTransport_add("tcp", HT_TP_SINGLE, HTReader_new, HTWriter_new);
   HTTransport_add("buffered_tcp", HT_TP_SINGLE, HTReader_new,     HTTransport_add("buffered_tcp", HT_TP_SINGLE, HTReader_new, 
                   HTBufferWriter_new);                    HTBufferWriter_new);
   HTProtocol_add ("http", "buffered_tcp", HTTP_PORT, NO, HTLoadHTTP, NULL);    HTProtocol_add ("http", "buffered_tcp", HTTP_PORT, NO, HTLoadHTTP, NULL);
 #ifdef _WINDOWS  #ifdef _WINDOWS
   /* TODO: verifier que le param YES est adapte pour WX */    /* TODO: verifier que le param YES est adapte pour WX */
Line 1836  static void         AHTProtocolInit (voi Line 1836  static void         AHTProtocolInit (voi
 #endif /* #if defined(_UNIX) */  #endif /* #if defined(_UNIX) */
   
 #ifdef AMAYA_WWW_CACHE  #ifdef AMAYA_WWW_CACHE
    HTProtocol_add("cache",  "local", 0, YES, HTLoadCache, NULL);    HTProtocol_add("cache",  "local", 0, YES, HTLoadCache, NULL);
 #endif /* AMAYA_WWW_CACHE */  #endif /* AMAYA_WWW_CACHE */
 #if 0 /* experimental code */  #if 0 /* experimental code */
 #endif  #endif
    HTProtocol_add ("ftp", "tcp", FTP_PORT, NO, HTLoadFTP, NULL);    HTProtocol_add ("ftp", "tcp", FTP_PORT, NO, HTLoadFTP, NULL);
   
    /* initialize pipelining */    /* initialize pipelining */
   strptr = TtaGetEnvString ("ENABLE_PIPELINING");    strptr = TtaGetEnvString ("ENABLE_PIPELINING");
   if (strptr && *strptr && strcasecmp (strptr, "yes"))    if (strptr && *strptr && strcasecmp (strptr, "yes"))
     HTTP_setConnectionMode (HTTP_11_NO_PIPELINING);      HTTP_setConnectionMode (HTTP_11_NO_PIPELINING);
Line 1855  static void         AHTProtocolInit (voi Line 1855  static void         AHTProtocolInit (voi
 static void         AHTNetInit (void)  static void         AHTNetInit (void)
 {  {
   
 /*      Register BEFORE filters    /*      Register BEFORE filters
 **      The BEFORE filters handle proxies, caches, rule files etc.    **      The BEFORE filters handle proxies, caches, rule files etc.
 **      The filters are called in the order by which the are registered    **      The filters are called in the order by which the are registered
 **      Not done automaticly - may be done by application!    **      Not done automaticly - may be done by application!
 */    */
   
   HTNet_addBefore (HTCredentialsFilter, "http://*", NULL, HT_FILTER_LATE);    HTNet_addBefore (HTCredentialsFilter, "http://*", NULL, HT_FILTER_LATE);
   HTNet_addBefore (HTProxyFilter, NULL, NULL, HT_FILTER_LATE);    HTNet_addBefore (HTProxyFilter, NULL, NULL, HT_FILTER_LATE);
   HTHost_setActivateRequestCallback (AHTOpen_file);    HTHost_setActivateRequestCallback (AHTOpen_file);
   
 /*      register AFTER filters    /*      register AFTER filters
 **      The AFTER filters handle error messages, logging, redirection,    **      The AFTER filters handle error messages, logging, redirection,
 **      authentication etc.    **      authentication etc.
 **      The filters are called in the order by which the are registered    **      The filters are called in the order by which the are registered
 **      Not done automaticly - may be done by application!    **      Not done automaticly - may be done by application!
 */    */
   
   HTNet_addAfter (HTAuthFilter, "http://*", NULL, HT_NO_ACCESS, HT_FILTER_MIDDLE);    HTNet_addAfter (HTAuthFilter, "http://*", NULL, HT_NO_ACCESS, HT_FILTER_MIDDLE);
   HTNet_addAfter (HTAuthFilter, "http://*", NULL, HT_REAUTH, HT_FILTER_MIDDLE);    HTNet_addAfter (HTAuthFilter, "http://*", NULL, HT_REAUTH, HT_FILTER_MIDDLE);
Line 1893  static void         AHTNetInit (void) Line 1893  static void         AHTNetInit (void)
   /* @@ JK: Filters for doing ftp authentication */    /* @@ JK: Filters for doing ftp authentication */
   HTNet_addAfter (HTAuthFilter, "ftp://*", NULL, HT_NO_ACCESS, HT_FILTER_MIDDLE);    HTNet_addAfter (HTAuthFilter, "ftp://*", NULL, HT_NO_ACCESS, HT_FILTER_MIDDLE);
   HTNet_addAfter (HTAuthFilter, "ftp://*", NULL, HT_REAUTH, HT_FILTER_MIDDLE);    HTNet_addAfter (HTAuthFilter, "ftp://*", NULL, HT_REAUTH, HT_FILTER_MIDDLE);
    /* handles all errors */    /* handles all errors */
   HTNet_addAfter (terminate_handler, NULL, NULL, HT_ALL, HT_FILTER_LAST);    HTNet_addAfter (terminate_handler, NULL, NULL, HT_ALL, HT_FILTER_LAST);
 }  }
   
Line 1903  static void         AHTNetInit (void) Line 1903  static void         AHTNetInit (void)
   ----------------------------------------------------------------------*/    ----------------------------------------------------------------------*/
 static void         AHTAlertInit (void)  static void         AHTAlertInit (void)
 {  {
    HTAlert_add (AHTProgress, HT_A_PROGRESS);    HTAlert_add (AHTProgress, HT_A_PROGRESS);
   
 #ifdef _WINDOWS  #ifdef _WINDOWS
    HTAlert_add ((HTAlertCallback *) WIN_Activate_Request, HT_PROG_CONNECT);    HTAlert_add ((HTAlertCallback *) WIN_Activate_Request, HT_PROG_CONNECT);
 #endif /* _WINDOWS */  #endif /* _WINDOWS */
         
    HTAlert_add (AHTError_print, HT_A_MESSAGE);    HTAlert_add (AHTError_print, HT_A_MESSAGE);
    HTError_setShow ( (HTErrorShow)(~((unsigned int) 0 ) & ~((unsigned int) HT_ERR_SHOW_DEBUG)) );       /* process all messages except debug ones*/    HTError_setShow ( (HTErrorShow)(~((unsigned int) 0 ) & ~((unsigned int) HT_ERR_SHOW_DEBUG)) );        /* process all messages except debug ones*/
    HTAlert_add (AHTConfirm, HT_A_CONFIRM);    HTAlert_add (AHTConfirm, HT_A_CONFIRM);
    HTAlert_add (AHTPrompt, HT_A_PROMPT);    HTAlert_add (AHTPrompt, HT_A_PROMPT);
    HTAlert_add (AHTPromptUsernameAndPassword, HT_A_USER_PW);    HTAlert_add (AHTPromptUsernameAndPassword, HT_A_USER_PW);
 }  }
   
 #ifdef AMAYA_WWW_CACHE  #ifdef AMAYA_WWW_CACHE
Line 1951  static void RecCleanCache (char *dirname Line 1951  static void RecCleanCache (char *dirname
   while (status)     while (status) 
     {      {
       if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)        if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
         {          {
           /* it's a directory, erase it recursively */            /* it's a directory, erase it recursively */
           if (strcmp (ffd.cFileName, "..") && strcmp (ffd.cFileName, "."))            if (strcmp (ffd.cFileName, "..") && strcmp (ffd.cFileName, "."))
             {              {
               strcpy (ptr, ffd.cFileName);                strcpy (ptr, ffd.cFileName);
               strcat (ptr, DIR_STR);                strcat (ptr, DIR_STR);
               RecCleanCache (t_dir);                RecCleanCache (t_dir);
               rmdir (t_dir);                rmdir (t_dir);
             }              }
         }          }
         else        else
           {          {
             /* it's a file, erase it */            /* it's a file, erase it */
             strcpy (ptr, ffd.cFileName);            strcpy (ptr, ffd.cFileName);
             TtaFileUnlink (t_dir);            TtaFileUnlink (t_dir);
           }          }
       status = FindNextFile (hFindFile, &ffd);        status = FindNextFile (hFindFile, &ffd);
     }      }
   FindClose (hFindFile);    FindClose (hFindFile);
Line 1996  static void RecCleanCache (char *dirname Line 1996  static void RecCleanCache (char *dirname
     ThotBool cont = wx_dir.GetFirst(&name);      ThotBool cont = wx_dir.GetFirst(&name);
     while (cont)      while (cont)
       {        {
         name = wx_dir.GetName()+separator+name;          name = wx_dir.GetName()+separator+name;
         if (wxDirExists(name))          if (wxDirExists(name))
           {            {
             name = name+separator;              name = name+separator;
             /* it's a sub-directory */              /* it's a sub-directory */
             sprintf(buftmp, "%s", (const char *)name.mb_str(*wxConvCurrent) );              sprintf(buftmp, "%s", (const char *)name.mb_str(*wxConvCurrent) );
             /* delete it recursively */              /* delete it recursively */
             RecCleanCache(buftmp);              RecCleanCache(buftmp);
           }            }
         else          else
           {            {
             /* it's a file */              /* it's a file */
             wxRemoveFile(name);              wxRemoveFile(name);
           }            }
                   
         cont = wx_dir.GetNext(&name);          cont = wx_dir.GetNext(&name);
       }        }
   }    }
   /* try to delete the current directory */    /* try to delete the current directory */
Line 2039  static void RecCleanCache (char *dirname Line 2039  static void RecCleanCache (char *dirname
     {      {
       /* skip the UNIX . and .. links */        /* skip the UNIX . and .. links */
       if (!strcmp (d->d_name, "..")        if (!strcmp (d->d_name, "..")
           || !strcmp (d->d_name, "."))            || !strcmp (d->d_name, "."))
         continue;          continue;
   
       sprintf (filename, "%s%c%s", dirname, DIR_SEP, d->d_name);        sprintf (filename, "%s%c%s", dirname, DIR_SEP, d->d_name);
       if  (lstat (filename, &st) < 0 )         if  (lstat (filename, &st) < 0 ) 
         {          {
           /* @@2 need some error message */            /* @@2 need some error message */
           perror (filename);            perror (filename);
           continue;            continue;
         }          }
               
       switch (st.st_mode & S_IFMT)        switch (st.st_mode & S_IFMT)
         {          {
         case S_IFDIR:          case S_IFDIR:
           /* if we find a directory, we erase it, recursively */            /* if we find a directory, we erase it, recursively */
           strcat (filename, DIR_STR);            strcat (filename, DIR_STR);
           RecCleanCache (filename);            RecCleanCache (filename);
           rmdir (filename);            rmdir (filename);
           break;            break;
         case S_IFLNK:          case S_IFLNK:
           /* skip any links we find */            /* skip any links we find */
           continue;            continue;
           break;            break;
         default:          default:
           /* erase the filename */            /* erase the filename */
           TtaFileUnlink (filename);            TtaFileUnlink (filename);
           break;            break;
         }          }
     }      }
   closedir (dp);    closedir (dp);
 #endif /* #if defined(_GTK) || defined(_NOGUI) */  #endif /* #if defined(_GTK) || defined(_NOGUI) */
Line 2113  void libwww_CleanCache (void) Line 2113  void libwww_CleanCache (void)
      CACHE_DIR_NAME */       CACHE_DIR_NAME */
   error = TRUE;    error = TRUE;
   ptr = strstr (real_dir, CACHE_DIR_NAME);      ptr = strstr (real_dir, CACHE_DIR_NAME);  
     if (ptr && *ptr && !strcasecmp (ptr, CACHE_DIR_NAME))    if (ptr && *ptr && !strcasecmp (ptr, CACHE_DIR_NAME))
       error = FALSE;      error = FALSE;
   if (error)    if (error)
     return;        return;  
       
Line 2158  void libwww_CleanCache (void) Line 2158  void libwww_CleanCache (void)
 static void CacheInit (void)  static void CacheInit (void)
 {  {
 #ifndef AMAYA_WWW_CACHE  #ifndef AMAYA_WWW_CACHE
    HTCacheMode_setEnabled (NO);    HTCacheMode_setEnabled (NO);
   
 #else /* AMAYA_WWW_CACHE */  #else /* AMAYA_WWW_CACHE */
   char     *strptr;    char     *strptr;
Line 2171  static void CacheInit (void) Line 2171  static void CacheInit (void)
   ThotBool  cache_locked;    ThotBool  cache_locked;
   ThotBool  tmp_bool;    ThotBool  tmp_bool;
   
 int i;    int i;
   
   /* activate cache? */    /* activate cache? */
   strptr = TtaGetEnvString ("ENABLE_CACHE");    strptr = TtaGetEnvString ("ENABLE_CACHE");
Line 2198  int i; Line 2198  int i;
       real_dir = (char *)TtaGetMemory (strlen (strptr) + strlen (CACHE_DIR_NAME) + 20);        real_dir = (char *)TtaGetMemory (strlen (strptr) + strlen (CACHE_DIR_NAME) + 20);
       strcpy (real_dir, strptr);        strcpy (real_dir, strptr);
       if (*(real_dir + strlen (real_dir) - 1) != DIR_SEP)        if (*(real_dir + strlen (real_dir) - 1) != DIR_SEP)
         strcat (real_dir, DIR_STR);          strcat (real_dir, DIR_STR);
     }      }
   else    else
     {      {
Line 2217  int i; Line 2217  int i;
   else    else
     {      {
       i = strlen (CACHE_DIR_NAME);        i = strlen (CACHE_DIR_NAME);
           if (strptr[i] != EOS)        if (strptr[i] != EOS)
           strcat (real_dir, CACHE_DIR_NAME);          strcat (real_dir, CACHE_DIR_NAME);
     }      }
   
   /* convert the local cache dir into a file URL, as expected by    /* convert the local cache dir into a file URL, as expected by
Line 2242  int i; Line 2242  int i;
       cache_locked = FALSE;        cache_locked = FALSE;
       if ( TtaFileExist(cache_lockfile) &&        if ( TtaFileExist(cache_lockfile) &&
            !(cache_locked = (test_cachelock(cache_lockfile) != 0))             !(cache_locked = (test_cachelock(cache_lockfile) != 0))
          )             )
             {          {
 #ifdef DEBUG_LIBWWW  #ifdef DEBUG_LIBWWW
               fprintf (stderr, "found a stale cache, removing it\n");            fprintf (stderr, "found a stale cache, removing it\n");
 #endif /* DEBUG_LIBWWW */  #endif /* DEBUG_LIBWWW */
               /* remove the lock and clean the cache (the clean cache             /* remove the lock and clean the cache (the clean cache 
                  will remove all, making the following call unnecessary */               will remove all, making the following call unnecessary */
               /* little trick to win some memory */            /* little trick to win some memory */
               strptr = strrchr (cache_lockfile, '.');            strptr = strrchr (cache_lockfile, '.');
               *strptr = EOS;            *strptr = EOS;
               RecCleanCache (cache_lockfile);            RecCleanCache (cache_lockfile);
               *strptr = '.';            *strptr = '.';
             }          }
   
       if (!cache_locked)         if (!cache_locked) 
         {          {
           /* initialize the cache if there's no other amaya            /* initialize the cache if there's no other amaya
              instance running */               instance running */
           HTCacheMode_setMaxCacheEntrySize (cache_entry_size);            HTCacheMode_setMaxCacheEntrySize (cache_entry_size);
           if (TtaGetEnvBoolean ("CACHE_EXPIRE_IGNORE", &tmp_bool) && tmp_bool)            if (TtaGetEnvBoolean ("CACHE_EXPIRE_IGNORE", &tmp_bool) && tmp_bool)
             HTCacheMode_setExpires (HT_EXPIRES_IGNORE);              HTCacheMode_setExpires (HT_EXPIRES_IGNORE);
           else            else
             HTCacheMode_setExpires (HT_EXPIRES_AUTO);              HTCacheMode_setExpires (HT_EXPIRES_AUTO);
           TtaGetEnvBoolean ("CACHE_DISCONNECTED_MODE", &tmp_bool);            TtaGetEnvBoolean ("CACHE_DISCONNECTED_MODE", &tmp_bool);
           if (tmp_bool)            if (tmp_bool)
             HTCacheMode_setDisconnected (HT_DISCONNECT_NORMAL);              HTCacheMode_setDisconnected (HT_DISCONNECT_NORMAL);
           else            else
             HTCacheMode_setDisconnected (HT_DISCONNECT_NONE);              HTCacheMode_setDisconnected (HT_DISCONNECT_NONE);
           if (HTCacheInit (cache_dir, cache_size))            if (HTCacheInit (cache_dir, cache_size))
             {              {
               if (set_cachelock (cache_lockfile) == -1)                if (set_cachelock (cache_lockfile) == -1)
                 /* couldn't open the .lock file, so, we close the cache to                  /* couldn't open the .lock file, so, we close the cache to
                    be in the safe side */                     be in the safe side */
                 {                  {
                   HTCacheTerminate ();                    HTCacheTerminate ();
                   HTCacheMode_setEnabled (FALSE);                    HTCacheMode_setEnabled (FALSE);
 #ifdef DEBUG_LIBWWW  #ifdef DEBUG_LIBWWW
                   fprintf (stderr, "couldnt set the cache lock\n");                    fprintf (stderr, "couldnt set the cache lock\n");
 #endif /* DEBUG_LIBWWW */  #endif /* DEBUG_LIBWWW */
                 }                  }
 #ifdef DEBUG_LIBWWW  #ifdef DEBUG_LIBWWW
               else                else
                 fprintf (stderr, "created the cache lock\n");                  fprintf (stderr, "created the cache lock\n");
 #endif /* DEBUG_LIBWWW */  #endif /* DEBUG_LIBWWW */
             }              }
           else            else
             {              {
 #ifdef DEBUG_LIBWWW  #ifdef DEBUG_LIBWWW
               fprintf (stderr, "couldn't create the cache\n");                fprintf (stderr, "couldn't create the cache\n");
 #endif /* DEBUG_LIBWWW */               #endif /* DEBUG_LIBWWW */             
               HTCacheTerminate ();                HTCacheTerminate ();
             }              }
         }          }
       else         else 
         {          {
           HTCacheMode_setEnabled (FALSE);            HTCacheMode_setEnabled (FALSE);
 #ifdef DEBUG_LIBWWW  #ifdef DEBUG_LIBWWW
           fprintf (stderr, "lock detected, starting libwww without a cache/n");            fprintf (stderr, "lock detected, starting libwww without a cache/n");
 #endif /* DEBUG_LIBWWW */  #endif /* DEBUG_LIBWWW */
         }          }
       TtaFreeMemory (cache_lockfile);        TtaFreeMemory (cache_lockfile);
     }      }
   else    else
Line 2319  int i; Line 2319  int i;
   
       TtaGetEnvBoolean ("WARN_NO_CACHE", &warn_user);        TtaGetEnvBoolean ("WARN_NO_CACHE", &warn_user);
       if (warn_user)        if (warn_user)
         InitInfo ("Cache", TtaGetMessage (AMAYA, AM_CANT_CREATE_CACHE));          InitInfo ("Cache", TtaGetMessage (AMAYA, AM_CANT_CREATE_CACHE));
     }      }
 #endif /* AMAYA_WWW_CACHE */  #endif /* AMAYA_WWW_CACHE */
 }  }
Line 2348  static void ProxyInit (void) Line 2348  static void ProxyInit (void)
       if (!strncasecmp (strptr, "http://", 7))         if (!strncasecmp (strptr, "http://", 7)) 
         HTProxy_add ("http", tmp);          HTProxy_add ("http", tmp);
       else         else 
         {          {
           strptrA = (char *) TtaGetMemory (strlen (strptr) + 9);            strptrA = (char *) TtaGetMemory (strlen (strptr) + 9);
           strcpy (strptrA, "http://");            strcpy (strptrA, "http://");
           strcat (strptrA, tmp);            strcat (strptrA, tmp);
           HTProxy_add ("http", strptrA);            HTProxy_add ("http", strptrA);
           TtaFreeMemory (strptrA);            TtaFreeMemory (strptrA);
         }          }
       TtaFreeMemory (tmp);        TtaFreeMemory (tmp);
     }      }
   
Line 2366  static void ProxyInit (void) Line 2366  static void ProxyInit (void)
       tmp = strptrA;        tmp = strptrA;
       strcpy (tmp, strptr);        strcpy (tmp, strptr);
       /* as HTNextField changes the ptr we pass as an argument, we'll        /* as HTNextField changes the ptr we pass as an argument, we'll
          work with another variable, so that we can free the tmp           work with another variable, so that we can free the tmp
          block later on */           block later on */
       while ((name = HTNextField (&tmp)) != NULL)         while ((name = HTNextField (&tmp)) != NULL) 
         {          {
           char* portstr = strchr (name, ':');            char* portstr = strchr (name, ':');
           unsigned port=0;            unsigned port=0;
           if (portstr)            if (portstr)
             {               { 
               *portstr++ = EOS;                *portstr++ = EOS;
               if (*portstr)                 if (*portstr) 
                 port = (unsigned) atoi (portstr);                  port = (unsigned) atoi (portstr);
             }              }
           /* Register it for all access methods */            /* Register it for all access methods */
           HTNoProxy_add (name, NULL, port);            HTNoProxy_add (name, NULL, port);
         }          }
       TtaFreeMemory (strptrA);        TtaFreeMemory (strptrA);
     }      }
       
Line 2390  static void ProxyInit (void) Line 2390  static void ProxyInit (void)
   HTProxy_setNoProxyIsOnlyProxy (proxy_is_onlyproxy);    HTProxy_setNoProxyIsOnlyProxy (proxy_is_onlyproxy);
   
   /* use libwww's routine to get all proxy settings from the environment */    /* use libwww's routine to get all proxy settings from the environment */
    HTProxy_getEnvVar ();    HTProxy_getEnvVar ();
 }  }
   
 /*----------------------------------------------------------------------  /*----------------------------------------------------------------------
Line 2399  static void ProxyInit (void) Line 2399  static void ProxyInit (void)
   ----------------------------------------------------------------------*/    ----------------------------------------------------------------------*/
 static void AHTProfile_newAmaya (const char *AppName, const char *AppVersion)  static void AHTProfile_newAmaya (const char *AppName, const char *AppVersion)
 {  {
    char *strptr;    char *strptr;
   
    /* If the Library is not already initialized then do it */    /* If the Library is not already initialized then do it */
    if (!HTLib_isInitialized ())     if (!HTLib_isInitialized ()) 
        HTLibInit (AppName, AppVersion);      HTLibInit (AppName, AppVersion);
   
    if (!converters)    if (!converters)
       converters = HTList_new ();      converters = HTList_new ();
    if (!acceptTypes)    if (!acceptTypes)
       acceptTypes = HTList_new ();      acceptTypes = HTList_new ();
    if (!acceptLanguages)    if (!acceptLanguages)
       acceptLanguages = HTList_new ();      acceptLanguages = HTList_new ();
    if (!transfer_encodings)    if (!transfer_encodings)
       transfer_encodings = HTList_new ();      transfer_encodings = HTList_new ();
    if (!content_encodings)    if (!content_encodings)
       content_encodings = HTList_new ();      content_encodings = HTList_new ();
   
    /* inhibits libwww's automatic file_suffix_binding */    /* inhibits libwww's automatic file_suffix_binding */
    HTFile_doFileSuffixBinding (FALSE);    HTFile_doFileSuffixBinding (FALSE);
   
    /* Register the default set of transport protocols */    /* Register the default set of transport protocols */
    HTTransportInit ();    HTTransportInit ();
   
    /* Register the default set of application protocol modules */    /* Register the default set of application protocol modules */
    AHTProtocolInit ();    AHTProtocolInit ();
   
    /* Register the default set of messages and dialog functions */    /* Register the default set of messages and dialog functions */
    AHTAlertInit ();    AHTAlertInit ();
    HTAlert_setInteractive (YES);    HTAlert_setInteractive (YES);
   
 #ifdef AMAYA_WWW_CACHE  #ifdef AMAYA_WWW_CACHE
    /* Enable the persistent cache  */    /* Enable the persistent cache  */
    CacheInit ();    CacheInit ();
 #else  #else
    HTCacheMode_setEnabled (NO);    HTCacheMode_setEnabled (NO);
 #endif /* AMAYA_WWW_CACHE */  #endif /* AMAYA_WWW_CACHE */
   
    /* Register the default set of BEFORE and AFTER filters */    /* Register the default set of BEFORE and AFTER filters */
    AHTNetInit ();    AHTNetInit ();
   
    /* Set up the default set of Authentication schemes */    /* Set up the default set of Authentication schemes */
    HTAA_newModule ("basic", HTBasic_generate, HTBasic_parse, NULL, HTBasic_delete);    HTAA_newModule ("basic", HTBasic_generate, HTBasic_parse, NULL, HTBasic_delete);
    /* activate MDA by defaul */    /* activate MDA by defaul */
    strptr = TtaGetEnvString ("ENABLE_MDA");    strptr = TtaGetEnvString ("ENABLE_MDA");
    if (!strptr || (strptr && *strptr && strcasecmp (strptr, "no")))    if (!strptr || (strptr && *strptr && strcasecmp (strptr, "no")))
      HTAA_newModule ("digest", HTDigest_generate, HTDigest_parse, HTDigest_updateInfo, HTDigest_delete);      HTAA_newModule ("digest", HTDigest_generate, HTDigest_parse, HTDigest_updateInfo, HTDigest_delete);
         
    /* Get any proxy settings */    /* Get any proxy settings */
    ProxyInit ();    ProxyInit ();
   
    /* Set up the domains where we accept a redirect on PUT */    /* Set up the domains where we accept a redirect on PUT */
    SafePut_init ();    SafePut_init ();
   
    /* Register the default set of converters */    /* Register the default set of converters */
    AHTConverterInit (converters);    AHTConverterInit (converters);
    HTFormat_setConversion (converters);    HTFormat_setConversion (converters);
    AHTAcceptTypesInit (acceptTypes);    AHTAcceptTypesInit (acceptTypes);
    AHTAcceptLanguagesInit (acceptLanguages);    AHTAcceptLanguagesInit (acceptLanguages);
   
    /* Register the default set of transfer encoders and decoders */    /* Register the default set of transfer encoders and decoders */
    HTTransferEncoderInit (transfer_encodings);    HTTransferEncoderInit (transfer_encodings);
    HTFormat_setTransferCoding (transfer_encodings);    HTFormat_setTransferCoding (transfer_encodings);
    /* Register the default set of content encoders and decoders */    /* Register the default set of content encoders and decoders */
    /* commented because we don't know yet how to handle deflate in the content enconding */    /* commented because we don't know yet how to handle deflate in the content enconding */
    /* HTContentEncoderInit (content_encodings); */    /* HTContentEncoderInit (content_encodings); */
    HTCoding_add (content_encodings, "gzip", NULL, HTIdentityCoding, 1.0);    HTCoding_add (content_encodings, "gzip", NULL, HTIdentityCoding, 1.0);
    /* ignore all other encoding formats (or libwww will send them     /* ignore all other encoding formats (or libwww will send them 
       thru a blackhole otherwise */       thru a blackhole otherwise */
    HTCoding_add (content_encodings, "*", NULL, HTIdentityCoding, 1.0);    HTCoding_add (content_encodings, "*", NULL, HTIdentityCoding, 1.0);
    if (HTList_count(content_encodings) > 0)    if (HTList_count(content_encodings) > 0)
      HTFormat_setContentCoding(content_encodings);      HTFormat_setContentCoding(content_encodings);
    else     else 
      {      {
        HTList_delete(content_encodings);        HTList_delete(content_encodings);
        content_encodings = NULL;        content_encodings = NULL;
      }      }
   
    /* Register the default set of MIME header parsers */    /* Register the default set of MIME header parsers */
    HTMIMEInit ();   /* must be called again for language selector */    HTMIMEInit ();   /* must be called again for language selector */
   
    /* Register the default set of Icons for directory listings */    /* Register the default set of Icons for directory listings */
    /*HTIconInit(NULL); *//* experimental */    /*HTIconInit(NULL); *//* experimental */
 }  }
   
 /*----------------------------------------------------------------------  /*----------------------------------------------------------------------
Line 2522  static void         AHTProfile_delete (v Line 2522  static void         AHTProfile_delete (v
   HTTimer_deleteAll ();    HTTimer_deleteAll ();
   HTEventList_unregisterAll ();    HTEventList_unregisterAll ();
   /* these two functions are broken, so we can't call them right now     /* these two functions are broken, so we can't call them right now 
   HTHeader_deleteAll ();       HTHeader_deleteAll ();
   HTTimer_deleteAll ();       HTTimer_deleteAll ();
   */    */
   HTTransport_deleteAll ();    HTTransport_deleteAll ();
   /* remove bindings between suffixes, media types*/    /* remove bindings between suffixes, media types*/
Line 2556  void         QueryInit () Line 2556  void         QueryInit ()
   int     tmp_i;    int     tmp_i;
   long    tmp_l;    long    tmp_l;
   
    AmayaContextInit ();    AmayaContextInit ();
    AHTProfile_newAmaya (TtaGetAppName(), TtaGetAppVersion());    AHTProfile_newAmaya (TtaGetAppName(), TtaGetAppVersion());
    CanDoStop_set (TRUE);    CanDoStop_set (TRUE);
    UserAborted_flag = FALSE;    UserAborted_flag = FALSE;
   
 #ifdef _WINGUI  #ifdef _WINGUI
    HTEventInit ();    HTEventInit ();
 #endif /* _WINGUI */  #endif /* _WINGUI */
   
 #ifdef _WX  #ifdef _WX
    wxAmayaSocketEventLoop::InitSocketLib();    wxAmayaSocketEventLoop::InitSocketLib();
 #endif /* _WX */  #endif /* _WX */
   
 #if defined(_GTK) || defined(_WX) || defined(_NOGUI)  #if defined(_GTK) || defined(_WX) || defined(_NOGUI)
    HTEvent_setRegisterCallback ( AHTEvent_register);    HTEvent_setRegisterCallback ( AHTEvent_register);
    HTEvent_setUnregisterCallback (AHTEvent_unregister);    HTEvent_setUnregisterCallback (AHTEvent_unregister);
    HTTimer_registerSetTimerCallback ((BOOL (*)(HTTimer*)) AMAYA_SetTimer);    HTTimer_registerSetTimerCallback ((BOOL (*)(HTTimer*)) AMAYA_SetTimer);
    HTTimer_registerDeleteTimerCallback ((BOOL (*)(HTTimer*))AMAYA_DeleteTimer);    HTTimer_registerDeleteTimerCallback ((BOOL (*)(HTTimer*))AMAYA_DeleteTimer);
 #endif /* #if defined(_GTK) || defined(_WX) || defined(_NOGUI) */  #endif /* #if defined(_GTK) || defined(_WX) || defined(_NOGUI) */
   
 #ifdef HTDEBUG  #ifdef HTDEBUG
    /* an undocumented option for being able to generate an HTTP protocol    /* an undocumented option for being able to generate an HTTP protocol
       trace.  The flag can take values from 1-10, which are interpreted as       trace.  The flag can take values from 1-10, which are interpreted as
       different kinds of debug traces. Value 99 means a complete trace.       different kinds of debug traces. Value 99 means a complete trace.
       0 or other values means No Debug.1 No Debug (default), up to Full debug, respectively. */       0 or other values means No Debug.1 No Debug (default), up to Full debug, respectively. */
    if (TtaGetEnvInt ("ENABLE_LIBWWW_DEBUG", &tmp_i))    if (TtaGetEnvInt ("ENABLE_LIBWWW_DEBUG", &tmp_i))
      {      {
        switch (tmp_i)        switch (tmp_i)
          {          {
          case 1:          case 1:
            WWW_TraceFlag = SHOW_URI_TRACE;            WWW_TraceFlag = SHOW_URI_TRACE;
            break;            break;
          case 2:          case 2:
            WWW_TraceFlag = SHOW_BIND_TRACE;            WWW_TraceFlag = SHOW_BIND_TRACE;
            break;            break;
          case 3:          case 3:
            WWW_TraceFlag = SHOW_THREAD_TRACE;            WWW_TraceFlag = SHOW_THREAD_TRACE;
            break;            break;
          case 4:          case 4:
            WWW_TraceFlag = SHOW_STREAM_TRACE;            WWW_TraceFlag = SHOW_STREAM_TRACE;
            break;            break;
          case 5:          case 5:
            WWW_TraceFlag = SHOW_PROTOCOL_TRACE;            WWW_TraceFlag = SHOW_PROTOCOL_TRACE;
            break;            break;
          case 6:          case 6:
            WWW_TraceFlag = SHOW_MEM_TRACE;            WWW_TraceFlag = SHOW_MEM_TRACE;
            break;            break;
          case 7:          case 7:
            WWW_TraceFlag = SHOW_URI_TRACE;            WWW_TraceFlag = SHOW_URI_TRACE;
            break;            break;
          case 8:          case 8:
            WWW_TraceFlag = SHOW_AUTH_TRACE;            WWW_TraceFlag = SHOW_AUTH_TRACE;
            break;            break;
          case 9:          case 9:
            WWW_TraceFlag = SHOW_ANCHOR_TRACE;            WWW_TraceFlag = SHOW_ANCHOR_TRACE;
            break;            break;
          case 10 :          case 10 :
            WWW_TraceFlag = SHOW_CORE_TRACE;             WWW_TraceFlag = SHOW_CORE_TRACE; 
            break;            break;
          case 11 :          case 11 :
            WWW_TraceFlag = SHOW_CORE_TRACE | SHOW_ANCHOR_TRACE | SHOW_AUTH_TRACE | SHOW_URI_TRACE | SHOW_THREAD_TRACE | SHOW_STREAM_TRACE;            WWW_TraceFlag = SHOW_CORE_TRACE | SHOW_ANCHOR_TRACE | SHOW_AUTH_TRACE | SHOW_URI_TRACE | SHOW_THREAD_TRACE | SHOW_STREAM_TRACE;
            break;            break;
          case 99 :          case 99 :
            WWW_TraceFlag = SHOW_ALL_TRACE;            WWW_TraceFlag = SHOW_ALL_TRACE;
            break;            break;
          default:          default:
            WWW_TraceFlag = 0;            WWW_TraceFlag = 0;
            break;            break;
          }          }
        if (WWW_TraceFlag)        if (WWW_TraceFlag)
          {          {
            /* Trace activation (for debugging) */            /* Trace activation (for debugging) */
            char   *s, *tmp;            char   *s, *tmp;
            s = TtaGetEnvString ("APP_TMPDIR");            s = TtaGetEnvString ("APP_TMPDIR");
            tmp = (char *)TtaGetMemory (strlen (s) + sizeof ("/libwww.log") + 1);            tmp = (char *)TtaGetMemory (strlen (s) + sizeof ("/libwww.log") + 1);
            strcpy (tmp, s);            strcpy (tmp, s);
            strcat (tmp, "/libwww.log");            strcat (tmp, "/libwww.log");
            trace_fp = fopen (tmp, "ab");            trace_fp = fopen (tmp, "ab");
            TtaFreeMemory (tmp);            TtaFreeMemory (tmp);
            if (trace_fp)            if (trace_fp)
              HTTrace_setCallback(LineTrace);              HTTrace_setCallback(LineTrace);
          }          }
      }      }
    else    else
      WWW_TraceFlag = 0;      WWW_TraceFlag = 0;
 #endif /* HTDEBUG */  #endif /* HTDEBUG */
   
 #ifdef DEBUG_LIBWWW  #ifdef DEBUG_LIBWWW
   /* forwards error messages to our own function */    /* forwards error messages to our own function */
    WWW_TraceFlag = THD_TRACE;    WWW_TraceFlag = THD_TRACE;
    HTTrace_setCallback(LineTrace);    HTTrace_setCallback(LineTrace);
   
    /***    /***
     WWW_TraceFlag = SHOW_CORE_TRACE | SHOW_THREAD_TRACE | SHOW_PROTOCOL_TRACE;        WWW_TraceFlag = SHOW_CORE_TRACE | SHOW_THREAD_TRACE | SHOW_PROTOCOL_TRACE;
     ***/    ***/
 #endif  #endif
   
    TtaGetEnvBoolean ("ENABLE_FTP", &FTPURL_flag);    TtaGetEnvBoolean ("ENABLE_FTP", &FTPURL_flag);
   
    /* Setting up different network parameters */    /* Setting up different network parameters */
   
    /* Maximum number of simultaneous open sockets */    /* Maximum number of simultaneous open sockets */
    strptr = TtaGetEnvString ("MAX_SOCKET");    strptr = TtaGetEnvString ("MAX_SOCKET");
    if (strptr && *strptr)     if (strptr && *strptr) 
      tmp_i = atoi (strptr);      tmp_i = atoi (strptr);
    else    else
      tmp_i = DEFAULT_MAX_SOCKET;      tmp_i = DEFAULT_MAX_SOCKET;
    HTNet_setMaxSocket (tmp_i);    HTNet_setMaxSocket (tmp_i);
   
    /* different network services timeouts */  
    /* dns timeout */  
    strptr = TtaGetEnvString ("DNS_TIMEOUT");  
    if (strptr && *strptr)   
      tmp_i = atoi (strptr);  
    else  
      tmp_i = DEFAULT_DNS_TIMEOUT;  
    HTDNS_setTimeout (tmp_i);  
   
    /* persistent connections timeout */  
    strptr = TtaGetEnvString ("PERSIST_CX_TIMEOUT");  
    if (strptr && *strptr)   
      tmp_l = atol (strptr);   
    else  
      tmp_l = DEFAULT_PERSIST_TIMEOUT;  
    HTHost_setPersistTimeout (tmp_l);  
   
    /* default timeout in ms */  
    strptr = TtaGetEnvString ("NET_EVENT_TIMEOUT");  
    if (strptr && *strptr)   
      tmp_i = atoi (strptr);  
    else  
      tmp_i = DEFAULT_NET_EVENT_TIMEOUT;  
    HTHost_setEventTimeout (tmp_i);  
   
    HTRequest_setMaxRetry (8);    /* different network services timeouts */
     /* dns timeout */
     strptr = TtaGetEnvString ("DNS_TIMEOUT");
     if (strptr && *strptr) 
       tmp_i = atoi (strptr);
     else
       tmp_i = DEFAULT_DNS_TIMEOUT;
     HTDNS_setTimeout (tmp_i);
   
     /* persistent connections timeout */
     strptr = TtaGetEnvString ("PERSIST_CX_TIMEOUT");
     if (strptr && *strptr) 
       tmp_l = atol (strptr); 
     else
       tmp_l = DEFAULT_PERSIST_TIMEOUT;
     HTHost_setPersistTimeout (tmp_l);
   
     /* default timeout in ms */
     strptr = TtaGetEnvString ("NET_EVENT_TIMEOUT");
     if (strptr && *strptr) 
       tmp_i = atoi (strptr);
     else
       tmp_i = DEFAULT_NET_EVENT_TIMEOUT;
     HTHost_setEventTimeout (tmp_i);
   
     HTRequest_setMaxRetry (8);
 #ifdef CATCH_SIG  #ifdef CATCH_SIG
    signal (SIGPIPE, SIG_IGN);    signal (SIGPIPE, SIG_IGN);
 #endif  #endif
 }  }
   
Line 2715  static int          LoopForStop (AHTReqC Line 2715  static int          LoopForStop (AHTReqC
   libwww_window = HTEventList_getWinHandle (&libwww_msg);    libwww_window = HTEventList_getWinHandle (&libwww_msg);
     
   while (me->reqStatus != HT_END && me->reqStatus != HT_ERR    while (me->reqStatus != HT_END && me->reqStatus != HT_ERR
          && me->reqStatus != HT_ABORT && AmayaIsAlive () &&           && me->reqStatus != HT_ABORT && AmayaIsAlive () &&
          GetMessage (&msg, NULL, 0, 0))           GetMessage (&msg, NULL, 0, 0))
     {      {
       if (msg.message != WM_QUIT)        if (msg.message != WM_QUIT)
         TtaHandleOneEvent (&msg);          TtaHandleOneEvent (&msg);
       else        else
         break;                break;      
     }      }
   if (!AmayaIsAlive ())    if (!AmayaIsAlive ())
     /* Amaya was killed by one of the callback handlers */      /* Amaya was killed by one of the callback handlers */
Line 2729  static int          LoopForStop (AHTReqC Line 2729  static int          LoopForStop (AHTReqC
 #endif /* _WINGUI */  #endif /* _WINGUI */
       
 #if defined(_GTK) || defined(_WX)    #if defined(_GTK) || defined(_WX)  
    ThotEvent                ev;    ThotEvent                ev;
   
    /* to test the async calls  */    /* to test the async calls  */
    /* Loop while waiting for new events, exists when the request is over */    /* Loop while waiting for new events, exists when the request is over */
    while (me->reqStatus != HT_ABORT &&    while (me->reqStatus != HT_ABORT &&
           me->reqStatus != HT_END &&           me->reqStatus != HT_END &&
           me->reqStatus != HT_ERR) {           me->reqStatus != HT_ERR) {
          if (!AmayaIsAlive ())      if (!AmayaIsAlive ())
             /* Amaya was killed by one of the callback handlers */              /* Amaya was killed by one of the callback handlers */
             exit (0);              exit (0);
                     
          if (TtaFetchOneAvailableEvent (&ev))      if (TtaFetchOneAvailableEvent (&ev))
            TtaHandleOneEvent (&ev);        TtaHandleOneEvent (&ev);
 #ifdef _WX  #ifdef _WX
          /* this is necessary for synchronous request*/      /* this is necessary for synchronous request*/
          /* check the socket stats */      /* check the socket stats */
          wxAmayaSocketEvent::CheckSocketStatus( 500 );      wxAmayaSocketEvent::CheckSocketStatus( 500 );
 #endif /* _WX */  #endif /* _WX */
    }    }
 #endif /* #if defined(_GTK) || defined(_WX) */  #endif /* #if defined(_GTK) || defined(_WX) */
   
    switch (me->reqStatus) {    switch (me->reqStatus) {
    case HT_ERR:    case HT_ERR:
    case HT_ABORT:    case HT_ABORT:
      status_req = NO;      status_req = NO;
      break;      break;
    case HT_END:    case HT_END:
      status_req = YES;      status_req = YES;
      break;      break;
    default:    default:
      break;      break;
    }    }
    return (status_req);    return (status_req);
 }  }
   
 /*----------------------------------------------------------------------  /*----------------------------------------------------------------------
Line 2780  void QueryClose () Line 2780  void QueryClose ()
   HTEvent_setUnregisterCallback ((HTEvent_unregisterCallback *) NULL);    HTEvent_setUnregisterCallback ((HTEvent_unregisterCallback *) NULL);
 #if defined(_GTK) || defined(_WX) || defined(_NOGUI)  #if defined(_GTK) || defined(_WX) || defined(_NOGUI)
   /** need to erase all existing timers too **/    /** need to erase all existing timers too **/
    HTTimer_registerSetTimerCallback (NULL);    HTTimer_registerSetTimerCallback (NULL);
    HTTimer_registerDeleteTimerCallback (NULL);    HTTimer_registerDeleteTimerCallback (NULL);
 #endif /* #if defined(_GTK) || defined(_WX) || defined(_NOGUI) */  #endif /* #if defined(_GTK) || defined(_WX) || defined(_NOGUI) */
   HTHost_setActivateRequestCallback (NULL);    HTHost_setActivateRequestCallback (NULL);
   Thread_deleteAll ();    Thread_deleteAll ();
Line 2807  static char * NextNameValue (char **pstr Line 2807  static char * NextNameValue (char **pstr
   char * start = NULL;    char * start = NULL;
   if (!pstr || !*pstr) return NULL;    if (!pstr || !*pstr) return NULL;
       
     if (!*p) {    if (!*p) {
       *pstr = p;  
       *name = NULL;  
       *value = NULL;  
       return NULL;                                       /* No field */  
     }  
       
     /* Now search for the next '&' and ';' delimitators */  
     start = p;  
     while (*p && *p != '&' && *p != ';') p++;  
     if (*p)   
       *p++ = '\0';  
     *pstr = p;      *pstr = p;
       *name = NULL;
     /* Search for the name and value */      *value = NULL;
     *name = start;      return NULL;                                         /* No field */
     p = start;    }
           
     while(*p && *p != '=')     /* Now search for the next '&' and ';' delimitators */
       p++;    start = p;
     if (*p)     while (*p && *p != '&' && *p != ';') p++;
       *p++ = '\0';    if (*p) 
     *value = p;      *p++ = '\0';
     *pstr = p;
   
     /* Search for the name and value */
     *name = start;
     p = start;
       
     while(*p && *p != '=') 
       p++;
     if (*p) 
       *p++ = '\0';
     *value = p;
   
     return start;    return start;
 }  }
   
 /*----------------------------------------------------------------------  /*----------------------------------------------------------------------
Line 2849  static   HTAssocList * PrepareFormdata ( Line 2849  static   HTAssocList * PrepareFormdata (
   
   /* store the ptr in another variable, as the original address will    /* store the ptr in another variable, as the original address will
      change       change
      */    */
       
   tmp_string_ptr = (char *)TtaGetMemory (strlen (string) + 1);    tmp_string_ptr = (char *)TtaGetMemory (strlen (string) + 1);
   tmp_string = tmp_string_ptr;    tmp_string = tmp_string_ptr;
Line 2860  static   HTAssocList * PrepareFormdata ( Line 2860  static   HTAssocList * PrepareFormdata (
     {      {
       NextNameValue (&tmp_string, &name, &value);        NextNameValue (&tmp_string, &name, &value);
       HTAssocList_addObject(formdata,        HTAssocList_addObject(formdata,
                             name, value);                              name, value);
     }      }
   
   TtaFreeMemory (tmp_string_ptr);    TtaFreeMemory (tmp_string_ptr);
Line 2906  void AHTRequest_setCustomAcceptHeader (H Line 2906  void AHTRequest_setCustomAcceptHeader (H
 static void GetOutputFileName (char *outputfile, int tempsubdir)  static void GetOutputFileName (char *outputfile, int tempsubdir)
 {  {
   sprintf (outputfile, "%s%c%d%c%04dAM", TempFileDirectory, DIR_SEP, tempsubdir, DIR_SEP,    sprintf (outputfile, "%s%c%d%c%04dAM", TempFileDirectory, DIR_SEP, tempsubdir, DIR_SEP,
            object_counter);             object_counter);
   /* update the object_counter (used for the tempfilename) */    /* update the object_counter (used for the tempfilename) */
   object_counter++;    object_counter++;
 }  }
Line 2917  static void GetOutputFileName (char *out Line 2917  static void GetOutputFileName (char *out
   in GetObjectWWW    in GetObjectWWW
   ---------------------------------------------------------------------*/    ---------------------------------------------------------------------*/
 void InvokeGetObjectWWW_callback (int docid, char *urlName,  void InvokeGetObjectWWW_callback (int docid, char *urlName,
                                   char *outputfile, TTcbf *terminate_cbf,                                    char *outputfile, TTcbf *terminate_cbf,
                                   void *context_tcbf, int status)                                    void *context_tcbf, int status)
 {  {
   if (!terminate_cbf)    if (!terminate_cbf)
     return;      return;
       
   (*terminate_cbf) (docid, status, urlName, outputfile,    (*terminate_cbf) (docid, status, urlName, outputfile,
                     NULL, context_tcbf);                        NULL, context_tcbf);  
 }  }
   
   
 /*----------------------------------------------------------------------  /*----------------------------------------------------------------------
    GetObjectWWW    GetObjectWWW
    this function requests a resource designated by a URLname into a    this function requests a resource designated by a URLname into a
    temporary filename. The download can come from a simple GET operation,    temporary filename. The download can come from a simple GET operation,
    or can come from POSTING/GETTING a form. In the latter    or can come from POSTING/GETTING a form. In the latter
    case, the function receives a query string to send to the server.    case, the function receives a query string to send to the server.
   
    4  file retrieval modes are proposed:                                  4  file retrieval modes are proposed:                              
    AMAYA_SYNC : blocking mode                                AMAYA_SYNC : blocking mode                            
    AMAYA_ISYNC : incremental, blocking mode                  AMAYA_ISYNC : incremental, blocking mode              
    AMAYA_ASYNC : non-blocking mode                           AMAYA_ASYNC : non-blocking mode                       
    AMAYA_IASYNC : incremental, non-blocking mode             AMAYA_IASYNC : incremental, non-blocking mode         
         
    In the incremental mode, each time a package arrives, it will be       In the incremental mode, each time a package arrives, it will be   
    stored in the temporary file. In addition, if an                       stored in the temporary file. In addition, if an                   
    incremental_callback function is defined, this function will be        incremental_callback function is defined, this function will be    
    called and handled a copy of the newly received data package.          called and handled a copy of the newly received data package.      
    Finally, if a terminate_callback function is defined, it will be       Finally, if a terminate_callback function is defined, it will be   
    invoked when the request terminates. The caller of this function    invoked when the request terminates. The caller of this function
    can define two different contexts to be passed to the callback    can define two different contexts to be passed to the callback
    functions.    functions.
   
    When the function is called with the SYNC mode, the function will    When the function is called with the SYNC mode, the function will
    return only when the requested file has been loaded.    return only when the requested file has been loaded.
    The ASYNC mode will immediately return after setting up the    The ASYNC mode will immediately return after setting up the
    call.    call.
   
    Notes:    Notes:
    At the end of a succesful request, the urlName string contains the    At the end of a succesful request, the urlName string contains the
    name of the actually retrieved URL. As a URL can change over the time,    name of the actually retrieved URL. As a URL can change over the time,
    (e.g., be redirected elsewhere), it is advised that the function    (e.g., be redirected elsewhere), it is advised that the function
    caller verify the value of the urlName variable at the end of    caller verify the value of the urlName variable at the end of
    a request.    a request.
   
    Inputs:    Inputs:
    - docid  Document identifier for the set of objects being    - docid  Document identifier for the set of objects being
    retrieved.    retrieved.
    - refdoc Document identifier to refer.    - refdoc Document identifier to refer.
    - urlName The utf8-coded URL to be retrieved (MAX_URL_LENGTH chars length)    - urlName The utf8-coded URL to be retrieved (MAX_URL_LENGTH chars length)
    - outputfile A pointer to an empty string of MAX_URL_LENGTH.    - outputfile A pointer to an empty string of MAX_URL_LENGTH.
    - mode The retrieval mode.    - mode The retrieval mode.
    - incremental_cbf     - incremental_cbf 
    - context_icbf    - context_icbf
    Callback and context for the incremental modes    Callback and context for the incremental modes
    - terminate_cbf     - terminate_cbf 
    - context_icbf    - context_icbf
    Callback and context for a terminate handler    Callback and context for a terminate handler
    -error_html if TRUE, then display any server error message as an    -error_html if TRUE, then display any server error message as an
    HTML document.    HTML document.
    - content_type a string    - content_type a string
     
    Outputs:    Outputs:
    - urlName The URL that was retrieved    - urlName The URL that was retrieved
    - outputfile The name of the temporary file which holds the    - outputfile The name of the temporary file which holds the
    retrieved data. (Only in case of success)    retrieved data. (Only in case of success)
    - if content_type wasn't NULL, it will contain a copy of the parameter    - if content_type wasn't NULL, it will contain a copy of the parameter
      sent in the HTTP answer    sent in the HTTP answer
    Returns:    Returns:
    HT_ERROR    HT_ERROR
    HT_OK    HT_OK
   ----------------------------------------------------------------------*/    ----------------------------------------------------------------------*/
 int GetObjectWWW (int docid, int refdoc, char *urlName, char *formdata,  int GetObjectWWW (int docid, int refdoc, char *urlName, char *formdata,
                   char *outputfile, int mode, TIcbf *incremental_cbf,                     char *outputfile, int mode, TIcbf *incremental_cbf, 
                   void *context_icbf, TTcbf *terminate_cbf,                     void *context_icbf, TTcbf *terminate_cbf, 
                   void *context_tcbf, ThotBool error_html, char *content_type)                    void *context_tcbf, ThotBool error_html, char *content_type)
 {  {
    AHTReqContext      *me;    AHTReqContext      *me;
    char               *ref;    char               *ref;
    char               *esc_url;    char               *esc_url;
    int                 status, l;    int                 status, l;
    int                 tempsubdir;    int                 tempsubdir;
    ThotBool            bool_tmp, referer;    ThotBool            bool_tmp, referer;
   
    if (urlName == NULL || outputfile == NULL)     if (urlName == NULL || outputfile == NULL) 
      {      {
        /* no file to be loaded */        /* no file to be loaded */
        TtaSetStatus (docid, 1, TtaGetMessage (AMAYA, AM_BAD_URL), urlName);  
          
        if (error_html)  
          /* so we can show the error message */  
          DocNetworkStatus[docid] |= AMAYA_NET_ERROR;  
        InvokeGetObjectWWW_callback (docid, urlName, outputfile, terminate_cbf,  
                                     context_tcbf, HT_ERROR);  
        return HT_ERROR;  
      }  
   
    /* if it's a 'docImage', we have already downloaded it */  
    if (!strncmp ("internal:", urlName, 9))   
      {  
        strcpy (outputfile, urlName);  
        InvokeGetObjectWWW_callback (docid, urlName, outputfile,  
                                     terminate_cbf, context_tcbf, HT_OK);  
        return HT_OK;  
      }  
   
    /* do we support this protocol? */  
    if (IsValidProtocol (urlName) == NO)   
      {  
        /* return error */  
        outputfile[0] = EOS;     /* file could not be opened */  
        TtaSetStatus (docid, 1,   
                      TtaGetMessage (AMAYA, AM_GET_UNSUPPORTED_PROTOCOL),  
                      urlName);  
   
        if (error_html)  
          /* so we can show the error message */  
          DocNetworkStatus[docid] |= AMAYA_NET_ERROR;  
        InvokeGetObjectWWW_callback (docid, urlName, outputfile, terminate_cbf,  
                                     context_tcbf, HT_ERROR);  
        return HT_ERROR;  
      }  
   
    /* we store CSS in subdir named 0; all the other files go to a subdir  
       named after their own docid */  
    tempsubdir = (mode & AMAYA_LOAD_CSS) ? 0 : docid;  
    /* create a tempfilename */  
    GetOutputFileName (outputfile, tempsubdir);  
   
    /* normalize the URL */  
    esc_url = EscapeURL (urlName);  
    if (esc_url)   
      {  
        ref = AmayaParseUrl (esc_url, "", AMAYA_PARSE_ALL);  
        TtaFreeMemory (esc_url);  
      }  
    else  
      ref = NULL;  
   
    /* should we abort the request if we could not normalize the url? */  
    if (ref == NULL || ref[0] == EOS) {  
       /*error */  
       outputfile[0] = EOS;  
       TtaSetStatus (docid, 1, TtaGetMessage (AMAYA, AM_BAD_URL), urlName);        TtaSetStatus (docid, 1, TtaGetMessage (AMAYA, AM_BAD_URL), urlName);
       if (ref)         
         TtaFreeMemory (ref);   
       if (error_html)        if (error_html)
         /* so we can show the error message */          /* so we can show the error message */
         DocNetworkStatus[docid] |= AMAYA_NET_ERROR;          DocNetworkStatus[docid] |= AMAYA_NET_ERROR;
         InvokeGetObjectWWW_callback (docid, urlName, outputfile, terminate_cbf,
                                      context_tcbf, HT_ERROR);
         return HT_ERROR;
       }
   
     /* if it's a 'docImage', we have already downloaded it */
     if (!strncmp ("internal:", urlName, 9)) 
       {
         strcpy (outputfile, urlName);
         InvokeGetObjectWWW_callback (docid, urlName, outputfile,
                                      terminate_cbf, context_tcbf, HT_OK);
         return HT_OK;
       }
   
     /* do we support this protocol? */
     if (IsValidProtocol (urlName) == NO) 
       {
         /* return error */
         outputfile[0] = EOS;      /* file could not be opened */
         TtaSetStatus (docid, 1, 
                       TtaGetMessage (AMAYA, AM_GET_UNSUPPORTED_PROTOCOL),
                       urlName);
   
         if (error_html)
           /* so we can show the error message */
           DocNetworkStatus[docid] |= AMAYA_NET_ERROR;
         InvokeGetObjectWWW_callback (docid, urlName, outputfile, terminate_cbf,
                                      context_tcbf, HT_ERROR);
         return HT_ERROR;
       }
   
     /* we store CSS in subdir named 0; all the other files go to a subdir
        named after their own docid */
     tempsubdir = (mode & AMAYA_LOAD_CSS) ? 0 : docid;
     /* create a tempfilename */
     GetOutputFileName (outputfile, tempsubdir);
   
     /* normalize the URL */
     esc_url = EscapeURL (urlName);
     if (esc_url) 
       {
         ref = AmayaParseUrl (esc_url, "", AMAYA_PARSE_ALL);
         TtaFreeMemory (esc_url);
       }
     else
       ref = NULL;
   
     /* should we abort the request if we could not normalize the url? */
     if (ref == NULL || ref[0] == EOS) {
       /*error */
       outputfile[0] = EOS;
       TtaSetStatus (docid, 1, TtaGetMessage (AMAYA, AM_BAD_URL), urlName);
       if (ref)
         TtaFreeMemory (ref); 
       if (error_html)
         /* so we can show the error message */
         DocNetworkStatus[docid] |= AMAYA_NET_ERROR;
       InvokeGetObjectWWW_callback (docid, urlName, outputfile, terminate_cbf,
                                    context_tcbf, HT_ERROR);
       return HT_ERROR;
     }
   
     /* verify if that file name existed */
     if (TtaFileExist (outputfile))
       TtaFileUnlink (outputfile);
      
     /* Initialize the request structure */
     me = AHTReqContext_new (docid);
     if (me == NULL) 
       {
         outputfile[0] = EOS;
         /* need an error message here */
         TtaFreeMemory (ref);
       InvokeGetObjectWWW_callback (docid, urlName, outputfile, terminate_cbf,        InvokeGetObjectWWW_callback (docid, urlName, outputfile, terminate_cbf,
                                    context_tcbf, HT_ERROR);                                     context_tcbf, HT_ERROR);
       return HT_ERROR;        return HT_ERROR;
    }      }
   
    /* verify if that file name existed */    /* Specific initializations for POST and GET */
    if (TtaFileExist (outputfile))    if (mode & AMAYA_FORM_POST
      TtaFileUnlink (outputfile);        || mode & AMAYA_FILE_POST)
          {
    /* Initialize the request structure */        me->method = METHOD_POST;
    me = AHTReqContext_new (docid);        HTRequest_setMethod (me->request, METHOD_POST);
    if (me == NULL)       }
      {    else 
        outputfile[0] = EOS;      {
        /* need an error message here */  
        TtaFreeMemory (ref);  
        InvokeGetObjectWWW_callback (docid, urlName, outputfile, terminate_cbf,  
                                    context_tcbf, HT_ERROR);  
        return HT_ERROR;  
      }  
   
    /* Specific initializations for POST and GET */  
    if (mode & AMAYA_FORM_POST  
        || mode & AMAYA_FILE_POST)  
      {  
        me->method = METHOD_POST;  
        HTRequest_setMethod (me->request, METHOD_POST);  
      }  
    else   
      {  
 #ifdef ANNOTATIONS  #ifdef ANNOTATIONS
        /* we support the DELETE method for deleting annotations.        /* we support the DELETE method for deleting annotations.
           the rest of the request is similar to the GET */           the rest of the request is similar to the GET */
        if (mode & AMAYA_DELETE)        if (mode & AMAYA_DELETE)
          {          {
            me->method = METHOD_GET;            me->method = METHOD_GET;
            HTRequest_setMethod (me->request, METHOD_DELETE);            HTRequest_setMethod (me->request, METHOD_DELETE);
          }          }
          else        else
 #endif /* ANNOTATIONS */  #endif /* ANNOTATIONS */
            me->method = METHOD_GET;          me->method = METHOD_GET;
 #ifdef ANNOTATIONS  #ifdef ANNOTATIONS
        /* use the custom sent content_type */        /* use the custom sent content_type */
        if (content_type && content_type[0] != EOS)        if (content_type && content_type[0] != EOS)
          AHTRequest_setCustomAcceptHeader (me->request, content_type);          AHTRequest_setCustomAcceptHeader (me->request, content_type);
        else        else
 #endif /* ANNOTATIONS */  #endif /* ANNOTATIONS */
          if (!HasKnownFileSuffix (ref))          if (!HasKnownFileSuffix (ref))
          {            {
            /* try to adjust the Accept header in an netwise economical way */              /* try to adjust the Accept header in an netwise economical way */
            if (mode & AMAYA_LOAD_IMAGE)              if (mode & AMAYA_LOAD_IMAGE)
              AHTRequest_setCustomAcceptHeader (me->request, IMAGE_ACCEPT_NEGOTIATION);                AHTRequest_setCustomAcceptHeader (me->request, IMAGE_ACCEPT_NEGOTIATION);
            else if (mode & AMAYA_LOAD_CSS)              else if (mode & AMAYA_LOAD_CSS)
              AHTRequest_setCustomAcceptHeader (me->request, "*/*;q=0.1,css/*");                AHTRequest_setCustomAcceptHeader (me->request, "*/*;q=0.1,css/*");
            else              else
              AHTRequest_setCustomAcceptHeader (me->request, GENERAL_ACCEPT_NEGOTIATION);                AHTRequest_setCustomAcceptHeader (me->request, GENERAL_ACCEPT_NEGOTIATION);
            /*              /*
            HTRequest_setConversion(me->request, acceptTypes, TRUE);                HTRequest_setConversion(me->request, acceptTypes, TRUE);
            */              */
          }            }
          else          else
            AHTRequest_setCustomAcceptHeader (me->request, GENERAL_ACCEPT_NEGOTIATION);            AHTRequest_setCustomAcceptHeader (me->request, GENERAL_ACCEPT_NEGOTIATION);
        /* IV 13/08/2003 */        /* IV 13/08/2003 */
        TtaGetEnvBoolean ("SEND_REFERER", &referer);        TtaGetEnvBoolean ("SEND_REFERER", &referer);
        if (referer && refdoc && DocumentURLs[refdoc] &&        if (referer && refdoc && DocumentURLs[refdoc] &&
            IsHTTPPath (DocumentURLs[refdoc]))            IsHTTPPath (DocumentURLs[refdoc]))
          {          {
            me->refdocUrl = TtaStrdup (DocumentURLs[refdoc]);            me->refdocUrl = TtaStrdup (DocumentURLs[refdoc]);
            AHTRequest_setRefererHeader (me);            AHTRequest_setRefererHeader (me);
          }          }
        /* language negotiation */        /* language negotiation */
        HTRequest_setLanguage (me->request, acceptLanguages, TRUE);        HTRequest_setLanguage (me->request, acceptLanguages, TRUE);
      }      }
   
    /* Common initialization for all HTML methods */  
    me->mode = mode;  
    me->error_html = error_html;  
    me->incremental_cbf = incremental_cbf;  
    me->context_icbf = context_icbf;  
    me->terminate_cbf = terminate_cbf;  
    me->context_tcbf = context_tcbf;  
   
    /* for the async. request modes, we need to have our    /* Common initialization for all HTML methods */
       own copy of outputfile and urlname    me->mode = mode;
       */    me->error_html = error_html;
     me->incremental_cbf = incremental_cbf;
     me->context_icbf = context_icbf;
     me->terminate_cbf = terminate_cbf;
     me->context_tcbf = context_tcbf;
   
     /* for the async. request modes, we need to have our
        own copy of outputfile and urlname
     */
   
    if ((mode & AMAYA_ASYNC) || (mode & AMAYA_IASYNC))     if ((mode & AMAYA_ASYNC) || (mode & AMAYA_IASYNC)) 
      {      {
        l = strlen (outputfile);        l = strlen (outputfile);
        if (l > MAX_LENGTH)        if (l > MAX_LENGTH)
          me->outputfile = (char *)TtaGetMemory (l + 2);          me->outputfile = (char *)TtaGetMemory (l + 2);
        else        else
          me->outputfile = (char *)TtaGetMemory (MAX_LENGTH + 2);          me->outputfile = (char *)TtaGetMemory (MAX_LENGTH + 2);
        strcpy (me->outputfile, outputfile);        strcpy (me->outputfile, outputfile);
        l = strlen (urlName);        l = strlen (urlName);
        if (l > MAX_LENGTH)        if (l > MAX_LENGTH)
          me->urlName = (char *)TtaGetMemory (l + 2);          me->urlName = (char *)TtaGetMemory (l + 2);
        else        else
          me->urlName = (char *)TtaGetMemory (MAX_LENGTH + 2);          me->urlName = (char *)TtaGetMemory (MAX_LENGTH + 2);
        strcpy (me->urlName, urlName);        strcpy (me->urlName, urlName);
          /* TODO: a tester que ca marche bien avec WX */        /* TODO: a tester que ca marche bien avec WX */
 #ifdef _WINDOWS  #ifdef _WINDOWS
      /* force windows ASYNC requests to always be non preemptive */        /* force windows ASYNC requests to always be non preemptive */
      HTRequest_setPreemptive (me->request, NO);        HTRequest_setPreemptive (me->request, NO);
 #endif /*_WINDOWS */  #endif /*_WINDOWS */
      } /* AMAYA_ASYNC mode */       } /* AMAYA_ASYNC mode */ 
    else     else 
 #ifdef _WINDOWS  #ifdef _WINDOWS
      {      {
        me->outputfile = outputfile;        me->outputfile = outputfile;
        me->urlName = urlName;        me->urlName = urlName;
        /* force windows SYNC requests to always be non preemptive */        /* force windows SYNC requests to always be non preemptive */
        HTRequest_setPreemptive (me->request, YES);        HTRequest_setPreemptive (me->request, YES);
      }      }
 #endif /* !_WINDOWS */  #endif /* !_WINDOWS */
         
 #if defined(_UNIX)  #if defined(_UNIX)
      {    {
        me->outputfile = outputfile;      me->outputfile = outputfile;
        me->urlName = urlName;      me->urlName = urlName;
      }    }
    /***    /***
      In order to take into account the stop button,         In order to take into account the stop button, 
      the requests will be always asynchronous, however, if mode=AMAYA_SYNC,        the requests will be always asynchronous, however, if mode=AMAYA_SYNC,
      we will loop until the document has been received or a stop signal        we will loop until the document has been received or a stop signal
      generated        generated
      ****/    ****/
    HTRequest_setPreemptive (me->request, NO);    HTRequest_setPreemptive (me->request, NO);
 #endif /* #if defined(_UNIX) */  #endif /* #if defined(_UNIX) */
   
    /*    /*
    ** Make sure that the first request is flushed immediately and not    ** Make sure that the first request is flushed immediately and not
    ** buffered in the output buffer    ** buffered in the output buffer
    */    */
    if (mode & AMAYA_FLUSH_REQUEST)    if (mode & AMAYA_FLUSH_REQUEST)
      HTRequest_setFlush(me->request, YES);      HTRequest_setFlush(me->request, YES);
    HTRequest_setFlush(me->request, YES);    HTRequest_setFlush(me->request, YES);
   
    /* prepare the URLname that will be displayed in teh status bar */    /* prepare the URLname that will be displayed in teh status bar */
    ChopURL (me->status_urlName, me->urlName);    ChopURL (me->status_urlName, me->urlName);
    TtaSetStatus (me->docid, 1,     TtaSetStatus (me->docid, 1, 
                  TtaGetMessage (AMAYA, AM_FETCHING),                  TtaGetMessage (AMAYA, AM_FETCHING),
                  me->status_urlName);                  me->status_urlName);
   
    me->anchor = (HTParentAnchor *) HTAnchor_findAddress (ref);    me->anchor = (HTParentAnchor *) HTAnchor_findAddress (ref);
    TtaFreeMemory (ref);    TtaFreeMemory (ref);
         
    TtaGetEnvBoolean ("CACHE_DISCONNECTED_MODE", &bool_tmp);    TtaGetEnvBoolean ("CACHE_DISCONNECTED_MODE", &bool_tmp);
    if (!bool_tmp && (mode & AMAYA_NOCACHE))    if (!bool_tmp && (mode & AMAYA_NOCACHE))
       HTRequest_setReloadMode (me->request, HT_CACHE_FLUSH);      HTRequest_setReloadMode (me->request, HT_CACHE_FLUSH);
   
    /* prepare the query string and format for POST */    /* prepare the query string and format for POST */
    if (mode & AMAYA_FORM_POST)    if (mode & AMAYA_FORM_POST)
      {      {
        HTAnchor_setFormat ((HTParentAnchor *) me->anchor,         HTAnchor_setFormat ((HTParentAnchor *) me->anchor, 
                            HTAtom_for ("application/x-www-form-urlencoded"));                            HTAtom_for ("application/x-www-form-urlencoded"));
        HTAnchor_setLength ((HTParentAnchor *) me->anchor, me->block_size);        HTAnchor_setLength ((HTParentAnchor *) me->anchor, me->block_size);
        HTRequest_setEntityAnchor (me->request, me->anchor);        HTRequest_setEntityAnchor (me->request, me->anchor);
      }       } 
   
    /* create the formdata element for libwww */    /* create the formdata element for libwww */
    if (formdata && ! (mode & AMAYA_FILE_POST))    if (formdata && ! (mode & AMAYA_FILE_POST))
       me->formdata = PrepareFormdata (formdata);      me->formdata = PrepareFormdata (formdata);
   
                 
 #ifdef DAV   #ifdef DAV 
    /* try to add an "If" header (lock information) also for POST     /* try to add an "If" header (lock information) also for POST 
     * requests and for GET forms */     * requests and for GET forms */
    if (HTRequest_method(me->request) == METHOD_POST ||    if (HTRequest_method(me->request) == METHOD_POST ||
           (HTRequest_method(me->request) == METHOD_GET && me->formdata))                   (HTRequest_method(me->request) == METHOD_GET && me->formdata))       
        DAVAddIfHeader (me,HTAnchor_address((HTAnchor*)me->anchor));      DAVAddIfHeader (me,HTAnchor_address((HTAnchor*)me->anchor));
 #endif /* DAV */  #endif /* DAV */
                 
         
    /* do the request */    /* do the request */
    if (mode & AMAYA_FORM_POST)    if (mode & AMAYA_FORM_POST)
      {      {
        /* this call doesn't give back a ThotBool */        /* this call doesn't give back a ThotBool */
        HTParentAnchor * posted = NULL;        HTParentAnchor * posted = NULL;
   
        posted = HTPostFormAnchor (me->formdata, (HTAnchor *) me->anchor,         posted = HTPostFormAnchor (me->formdata, (HTAnchor *) me->anchor, 
                                     me->request);                                   me->request);
        status = posted ? YES : NO;         status = posted ? YES : NO; 
      }      }
 #ifdef ANNOTATIONS  #ifdef ANNOTATIONS
    else if (mode & AMAYA_FILE_POST)    else if (mode & AMAYA_FILE_POST)
      {      {
        unsigned long filesize;        unsigned long filesize;
        char *fileURL;        char *fileURL;
   
        /* @@@ a very ugly patch :)))        /* @@@ a very ugly patch :)))
         I'm copying here some of the functionality I use in the PUT           I'm copying here some of the functionality I use in the PUT
        I need to put the common parts in another module */           I need to put the common parts in another module */
        AM_GetFileSize (formdata, &filesize);        AM_GetFileSize (formdata, &filesize);
        me->block_size = filesize;        me->block_size = filesize;
   
        fileURL = HTParse (formdata, "file:/", PARSE_ALL);        fileURL = HTParse (formdata, "file:/", PARSE_ALL);
        me->source = HTAnchor_findAddress (fileURL);        me->source = HTAnchor_findAddress (fileURL);
        HT_FREE (fileURL);        HT_FREE (fileURL);
   
        /* hardcoded ... */        /* hardcoded ... */
        AHTRequest_setCustomAcceptHeader (me->request, "application/xml");        AHTRequest_setCustomAcceptHeader (me->request, "application/xml");
        HTAnchor_setFormat (HTAnchor_parent (me->source),        HTAnchor_setFormat (HTAnchor_parent (me->source),
                            HTAtom_for ("application/xml"));                            HTAtom_for ("application/xml"));
        HTAnchor_setFormat (me->anchor,        HTAnchor_setFormat (me->anchor,
                            HTAtom_for ("application/xml"));                            HTAtom_for ("application/xml"));
        HTAnchor_setLength ((HTParentAnchor *) me->source, me->block_size);        HTAnchor_setLength ((HTParentAnchor *) me->source, me->block_size);
        /* @@ here I need to actually read the file and put it in document,        /* @@ here I need to actually read the file and put it in document,
           then, when I kill the request, I need to kill it */           then, when I kill the request, I need to kill it */
        {        {
          FILE *fp;          FILE *fp;
          int i;          int i;
          char c;          char c;
   
          me->document = (char *)TtaGetMemory (me->block_size + 1);          me->document = (char *)TtaGetMemory (me->block_size + 1);
          fp = TtaReadOpen (formdata);          fp = TtaReadOpen (formdata);
          i = 0;           i = 0; 
          c = getc (fp);          c = getc (fp);
          while (!feof (fp))          while (!feof (fp))
            {            {
              me->document[i++] = c;              me->document[i++] = c;
              c = getc (fp);              c = getc (fp);
            }            }
          me->document[i] = EOS;          me->document[i] = EOS;
          TtaReadClose (fp);          TtaReadClose (fp);
        }        }
        HTAnchor_setDocument ( (HTParentAnchor *) me->source,        HTAnchor_setDocument ( (HTParentAnchor *) me->source,
                               (void * ) me->document);                               (void * ) me->document);
        HTRequest_setEntityAnchor (me->request, HTAnchor_parent (me->source));        HTRequest_setEntityAnchor (me->request, HTAnchor_parent (me->source));
     
        status = HTPostAnchor (HTAnchor_parent (me->source),         status = HTPostAnchor (HTAnchor_parent (me->source), 
                               (HTAnchor *) me->anchor,                                (HTAnchor *) me->anchor, 
                               me->request);                               me->request);
      }      }
 #endif /* ANNOTATIONS */  #endif /* ANNOTATIONS */
    else if (formdata)    else if (formdata)
      status = HTGetFormAnchor(me->formdata, (HTAnchor *) me->anchor,      status = HTGetFormAnchor(me->formdata, (HTAnchor *) me->anchor,
                               me->request);                               me->request);
    else    else
      status = HTLoadAnchor ((HTAnchor *) me->anchor, me->request);      status = HTLoadAnchor ((HTAnchor *) me->anchor, me->request);
   
    /* @@@ may need some special windows error msg here */    /* @@@ may need some special windows error msg here */
    /* control the errors */    /* control the errors */
   
     if (status == NO)    if (status == NO)
      /* the request invocation failed */      /* the request invocation failed */
      {      {
        /* show an error message on the status bar */        /* show an error message on the status bar */
        DocNetworkStatus[docid] |= AMAYA_NET_ERROR;        DocNetworkStatus[docid] |= AMAYA_NET_ERROR;
        TtaSetStatus (docid, 1,         TtaSetStatus (docid, 1, 
                      TtaGetMessage (AMAYA, AM_CANNOT_LOAD),                      TtaGetMessage (AMAYA, AM_CANNOT_LOAD),
                      urlName);                      urlName);
        if (me->reqStatus == HT_NEW)        if (me->reqStatus == HT_NEW)
          /* manually invoke the last processing that usually gets done          /* manually invoke the last processing that usually gets done
             in a succesful request */             in a succesful request */
          InvokeGetObjectWWW_callback (docid, urlName, outputfile,           InvokeGetObjectWWW_callback (docid, urlName, outputfile, 
                                       terminate_cbf, context_tcbf, HT_ERROR);                                       terminate_cbf, context_tcbf, HT_ERROR);
        /* terminate_handler wasn't called */        /* terminate_handler wasn't called */
        AHTReqContext_delete (me);        AHTReqContext_delete (me);
      }      }
    else    else
      /* end treatment for SYNC requests */      /* end treatment for SYNC requests */
      if ((mode & AMAYA_SYNC) || (mode & AMAYA_ISYNC))      if ((mode & AMAYA_SYNC) || (mode & AMAYA_ISYNC))
        {        {
          /* wait here untilt the asynchronous request finishes */          /* wait here untilt the asynchronous request finishes */
          status = LoopForStop (me);          status = LoopForStop (me);
          /* if status returns HT_ERROR, should we invoke the callback? */          /* if status returns HT_ERROR, should we invoke the callback? */
          if (!HTRequest_kill (me->request))          if (!HTRequest_kill (me->request))
            AHTReqContext_delete (me);            AHTReqContext_delete (me);
        }        }
   
     /* an interface problem!!! */    /* an interface problem!!! */
     return (status == YES ? 0 : -1);    return (status == YES ? 0 : -1);
 }  }
   
 /*----------------------------------------------------------------------  /*----------------------------------------------------------------------
    PutObjectWWW    PutObjectWWW
    frontend for uploading a resource to a URL. This function downloads    frontend for uploading a resource to a URL. This function downloads
    a file to be uploaded into memory, it then calls UploadMemWWW to    a file to be uploaded into memory, it then calls UploadMemWWW to
    finish the job.    finish the job.
   
    2 upload modes are proposed:                                           2 upload modes are proposed:                                       
    AMAYA_SYNC : blocking mode                                AMAYA_SYNC : blocking mode                            
    AMAYA_ASYNC : non-blocking mode                           AMAYA_ASYNC : non-blocking mode                       
         
    When the function is called with the SYNC mode, the function will    When the function is called with the SYNC mode, the function will
    return only when the file has been uploaded.    return only when the file has been uploaded.
    The ASYNC mode will immediately return after setting up the    The ASYNC mode will immediately return after setting up the
    call. Furthermore, at the end of an upload, the ASYNC mode will     call. Furthermore, at the end of an upload, the ASYNC mode will 
    call back terminate_cbf, handling it the context defined in    call back terminate_cbf, handling it the context defined in
    context_tcbf.    context_tcbf.
   
    Notes:    Notes:
    At the end of a succesful request, the urlName string contains the    At the end of a succesful request, the urlName string contains the
    name of the actually uploaded URL. As a URL can change over the time,    name of the actually uploaded URL. As a URL can change over the time,
    (e.g., be redirected elsewhere), it is advised that the function    (e.g., be redirected elsewhere), it is advised that the function
    caller verifies the value of the urlName variable at the end of    caller verifies the value of the urlName variable at the end of
    a request.    a request.
   
    Inputs:    Inputs:
    - docid  Document identifier for the set of objects being    - docid  Document identifier for the set of objects being
    retrieved.    retrieved.
    - fileName A pointer to the local file to upload    - fileName A pointer to the local file to upload
    - urlName The URL to be uploaded (MAX_URL_LENGTH chars length)    - urlName The URL to be uploaded (MAX_URL_LENGTH chars length)
    - mode The retrieval mode.    - mode The retrieval mode.
    - terminate_cbf     - terminate_cbf 
    - context_icbf    - context_icbf
    Callback and context for a terminate handler    Callback and context for a terminate handler
   
    Outputs:    Outputs:
    - urlName The URL that was uploaded    - urlName The URL that was uploaded
   
    Returns:    Returns:
    HT_ERROR    HT_ERROR
    HT_OK    HT_OK
   ----------------------------------------------------------------------*/    ----------------------------------------------------------------------*/
 int PutObjectWWW (int docid, char *fileName, char *urlName,   int PutObjectWWW (int docid, char *fileName, char *urlName, 
                   char *contentType, char *outputfile, int mode,                    char *contentType, char *outputfile, int mode,
                   TTcbf *terminate_cbf, void *context_tcbf)                    TTcbf *terminate_cbf, void *context_tcbf)
 {  {
    AHTReqContext      *me;    AHTReqContext      *me;
    CHARSET             charset;    CHARSET             charset;
    int                 status;    int                 status;
    unsigned long       file_size = 0;    unsigned long       file_size = 0;
    char               *fileURL;    char               *fileURL;
    char               *etag = NULL;    char               *etag = NULL;
    HTParentAnchor     *dest_anc_parent;    HTParentAnchor     *dest_anc_parent;
    char               *tmp;    char               *tmp;
    char               *esc_url;    char               *esc_url;
    int                 UsePreconditions;    int                 UsePreconditions;
    char                url_name[MAX_LENGTH];    char                url_name[MAX_LENGTH];
    char               *resource_name;    char               *resource_name;
    char               *tmp2;    char               *tmp2;
    char                file_name[MAX_LENGTH];    char                file_name[MAX_LENGTH];
    ThotBool            lost_update_check = TRUE;    ThotBool            lost_update_check = TRUE;
   
    if (mode & AMAYA_SIMPLE_PUT)    if (mode & AMAYA_SIMPLE_PUT)
      {      {
        lost_update_check = FALSE;        lost_update_check = FALSE;
        UsePreconditions = FALSE;        UsePreconditions = FALSE;
        if (!outputfile)        if (!outputfile)
          return HT_ERROR;          return HT_ERROR;
      }      }
    else    else
      {      {
        /* should we protect the PUT against lost updates? */        /* should we protect the PUT against lost updates? */
        tmp = TtaGetEnvString ("ENABLE_LOST_UPDATE_CHECK");        tmp = TtaGetEnvString ("ENABLE_LOST_UPDATE_CHECK");
        if (tmp && *tmp && strcasecmp (tmp, "yes"))        if (tmp && *tmp && strcasecmp (tmp, "yes"))
          lost_update_check = FALSE;          lost_update_check = FALSE;
   
        UsePreconditions = mode & AMAYA_USE_PRECONDITIONS;        UsePreconditions = mode & AMAYA_USE_PRECONDITIONS;
      }      }
   
    AmayaLastHTTPErrorMsg [0] = EOS;    AmayaLastHTTPErrorMsg [0] = EOS;
    AmayaLastHTTPErrorMsgR [0] = EOS;    AmayaLastHTTPErrorMsgR [0] = EOS;
   
         
    if (urlName == NULL || docid == 0 || fileName == NULL     if (urlName == NULL || docid == 0 || fileName == NULL 
        || !TtaFileExist (fileName))        || !TtaFileExist (fileName))
       /* no file to be uploaded */      /* no file to be uploaded */
       return HT_ERROR;
   
     /* do we support this protocol? */
     if (IsValidProtocol (urlName) == NO)
       {
         /* return error */
         TtaSetStatus (docid, 1, TtaGetMessage (AMAYA, AM_PUT_UNSUPPORTED_PROTOCOL), urlName);
       return HT_ERROR;        return HT_ERROR;
       }
   
     /* get the size of the file */
     if (!AM_GetFileSize (fileName, &file_size) || file_size == 0L)
       {
         /* file was empty */
         /*errmsg here */
         return (HT_ERROR);
       }
   
    /* do we support this protocol? */    /* prepare the request context */
    if (IsValidProtocol (urlName) == NO)    if (THD_TRACE)
      {      fprintf (stderr, "file size == %u\n", (unsigned) file_size);
         /* return error */  
         TtaSetStatus (docid, 1, TtaGetMessage (AMAYA, AM_PUT_UNSUPPORTED_PROTOCOL), urlName);    me = AHTReqContext_new (docid);
         return HT_ERROR;    if (me == NULL)
      }      {
         /* @@ need an error message here */
    /* get the size of the file */        TtaHandlePendingEvents (); 
    if (!AM_GetFileSize (fileName, &file_size) || file_size == 0L)        return (HT_ERROR);
      {      }
         /* file was empty */  
         /*errmsg here */    /*
         return (HT_ERROR);    ** Set up the original URL name
      }    */
   
    /* prepare the request context */    /* are we using content-location? */
    if (THD_TRACE)    if (DocumentMeta[docid]->content_location)
       fprintf (stderr, "file size == %u\n", (unsigned) file_size);      resource_name = DocumentMeta[docid]->content_location;
     else
    me = AHTReqContext_new (docid);      resource_name = NULL;
    if (me == NULL)  
      {    /* prepare the target URL */
        /* @@ need an error message here */    if (resource_name)
         TtaHandlePendingEvents ();       {
         return (HT_ERROR);        tmp = strstr (urlName, resource_name);     
      }        if (!tmp)
           {
    /*            /* urlName does not include the resource name */
    ** Set up the original URL name            me->default_put_name = (char *)TtaGetMemory (strlen (urlName)
    */                                                         + strlen (resource_name)
                                                          + sizeof (URL_SEP)
    /* are we using content-location? */                                                         + 1);
    if (DocumentMeta[docid]->content_location)            strcpy (me->default_put_name, urlName);
      resource_name = DocumentMeta[docid]->content_location;            tmp = strrchr (me->default_put_name, URL_SEP);
    else            if (tmp)
      resource_name = NULL;              {
                 /* it is a URL finishing in /. Only add the resrouce name */
    /* prepare the target URL */                tmp++;
    if (resource_name)                strcpy (tmp, resource_name);
      {              }
        tmp = strstr (urlName, resource_name);                 else
        if (!tmp)              {
          {                strcat (me->default_put_name, URL_STR);
            /* urlName does not include the resource name */                strcat (me->default_put_name, resource_name);
            me->default_put_name = (char *)TtaGetMemory (strlen (urlName)              }
                                                 + strlen (resource_name)          }
                                                 + sizeof (URL_SEP)      }
                                                 + 1);     
            strcpy (me->default_put_name, urlName);    if (!me->default_put_name)
            tmp = strrchr (me->default_put_name, URL_SEP);      me->default_put_name = TtaStrdup (urlName);
            if (tmp)     
              {    HTRequest_setDefaultPutName (me->request, me->default_put_name);
                /* it is a URL finishing in /. Only add the resrouce name */  
                tmp++;    me->mode = mode;
                strcpy (tmp, resource_name);    me->incremental_cbf = (TIcbf *) NULL;
              }    me->context_icbf = (void *) NULL;
            else    me->terminate_cbf = terminate_cbf;
              {    me->context_tcbf = context_tcbf;
                strcat (me->default_put_name, URL_STR);  
                strcat (me->default_put_name, resource_name);    /* normalize the URL */
              }    esc_url = EscapeURL (urlName);
          }    me->urlName = TtaStrdup (esc_url);
      }    TtaFreeMemory (esc_url);
      
    if (!me->default_put_name)    me->block_size =  file_size;
      me->default_put_name = TtaStrdup (urlName);    /* select the parameters that distinguish a PUT from a GET/POST */
        me->method = METHOD_PUT;
    HTRequest_setDefaultPutName (me->request, me->default_put_name);    if (mode & AMAYA_SIMPLE_PUT)
       {
    me->mode = mode;        me->output = NULL;
    me->incremental_cbf = (TIcbf *) NULL;        GetOutputFileName (outputfile, docid);
    me->context_icbf = (void *) NULL;        me->outputfile = outputfile;
    me->terminate_cbf = terminate_cbf;      }
    me->context_tcbf = context_tcbf;    else
       {
    /* normalize the URL */        me->output = stdout;
    esc_url = EscapeURL (urlName);        /* we are not expecting to receive any input from the server */
    me->urlName = TtaStrdup (esc_url);        me->outputfile = (char  *) NULL; 
    TtaFreeMemory (esc_url);      }
   
    me->block_size =  file_size;  
    /* select the parameters that distinguish a PUT from a GET/POST */  
    me->method = METHOD_PUT;  
    if (mode & AMAYA_SIMPLE_PUT)  
      {  
        me->output = NULL;  
        GetOutputFileName (outputfile, docid);  
        me->outputfile = outputfile;  
      }  
    else  
      {  
        me->output = stdout;  
        /* we are not expecting to receive any input from the server */  
        me->outputfile = (char  *) NULL;   
      }  
   
 #ifdef _WX  #ifdef _WX
   char * localfilename = TtaGetRealFileName (fileName);    char * localfilename = TtaGetRealFileName (fileName);
Line 3531  int PutObjectWWW (int docid, char *fileN Line 3531  int PutObjectWWW (int docid, char *fileN
   fileURL = EscapeURL (localfilename);    fileURL = EscapeURL (localfilename);
   TtaFreeMemory(localfilename);    TtaFreeMemory(localfilename);
 #else /* _WX */  #else /* _WX */
    /* @@IV 18/08/2004 eencode spaces in the local filename */    /* @@IV 18/08/2004 eencode spaces in the local filename */
    fileURL = EscapeURL (fileName);    fileURL = EscapeURL (fileName);
 #endif /* _WX */  #endif /* _WX */
    if (fileURL)    if (fileURL)
    {      {
      strcpy (file_name, fileURL);        strcpy (file_name, fileURL);
      TtaFreeMemory (fileURL);        TtaFreeMemory (fileURL);
    }      }
    else    else
      strcpy (file_name, fileName);      strcpy (file_name, fileName);
    fileURL = NULL;    fileURL = NULL;
   
 #ifdef _WINDOWS  #ifdef _WINDOWS
    /* libwww's HTParse function doesn't take into account the drive name;    /* libwww's HTParse function doesn't take into account the drive name;
       so we sidestep it */       so we sidestep it */
    StrAllocCopy (fileURL, "file:");    StrAllocCopy (fileURL, "file:");
    StrAllocCat (fileURL, file_name);    StrAllocCat (fileURL, file_name);
 #endif /* _WINDOWS */  #endif /* _WINDOWS */
 #if defined(_UNIX)  #if defined(_UNIX)
    fileURL = HTParse (file_name, "file:/", PARSE_ALL);    fileURL = HTParse (file_name, "file:/", PARSE_ALL);
 #endif /* #if defined(_UNIX) */  #endif /* #if defined(_UNIX) */
   
    me->source = HTAnchor_findAddress (fileURL);    me->source = HTAnchor_findAddress (fileURL);
    HT_FREE (fileURL);    HT_FREE (fileURL);
    strcpy (url_name, me->urlName);    strcpy (url_name, me->urlName);
    me->dest = HTAnchor_findAddress (url_name);    me->dest = HTAnchor_findAddress (url_name);
    /* we memorize the anchor's parent @ as we use it a number of times    /* we memorize the anchor's parent @ as we use it a number of times
       in the following lines */       in the following lines */
    dest_anc_parent = HTAnchor_parent (me->dest);    dest_anc_parent = HTAnchor_parent (me->dest);
   
    /*    /*
    **  Set the Content-Type of the file we are uploading     **  Set the Content-Type of the file we are uploading 
    */    */
    /* we try to use any content-type previosuly associated    /* we try to use any content-type previosuly associated
       with the parent. If it doesn't exist, we try to guess it       with the parent. If it doesn't exist, we try to guess it
       from the URL */       from the URL */
    /* @@ JK: trying to use the content type we stored */    /* @@ JK: trying to use the content type we stored */
    /*    /*
    tmp2 = HTAtom_name (HTAnchor_format (dest_anc_parent));      tmp2 = HTAtom_name (HTAnchor_format (dest_anc_parent));
    */    */
    tmp2 = NULL;    tmp2 = NULL;
    if (!tmp2 || !strcmp (tmp2, "www/unknown"))    if (!tmp2 || !strcmp (tmp2, "www/unknown"))
      {      {
        HTAtom *tmp_atom;        HTAtom *tmp_atom;
        char   *s = NULL;        char   *s = NULL;
                 
        tmp_atom = AHTGuessAtom_for (me->urlName, contentType);        tmp_atom = AHTGuessAtom_for (me->urlName, contentType);
        if (tmp_atom)        if (tmp_atom)
          s = HTAtom_name (tmp_atom);          s = HTAtom_name (tmp_atom);
        if (!tmp_atom || (s && !strcmp (s, "www/unknown")))        if (!tmp_atom || (s && !strcmp (s, "www/unknown")))
          {          {
            /* ask the user for a MIME type */            /* ask the user for a MIME type */
          }          }
        HTAnchor_setFormat (dest_anc_parent, tmp_atom);        HTAnchor_setFormat (dest_anc_parent, tmp_atom);
        tmp2 = HTAtom_name (HTAnchor_format (dest_anc_parent));        tmp2 = HTAtom_name (HTAnchor_format (dest_anc_parent));
      }      }
    /* .. and we give the same type to the source anchor */    /* .. and we give the same type to the source anchor */
    /* we go thru setOutputFormat, rather than change the parent's    /* we go thru setOutputFormat, rather than change the parent's
       anchor, as that's the place that libwww expects it to be */       anchor, as that's the place that libwww expects it to be */
    HTAnchor_setFormat (HTAnchor_parent (me->source), HTAtom_for (tmp2));    HTAnchor_setFormat (HTAnchor_parent (me->source), HTAtom_for (tmp2));
   
    HTRequest_setOutputFormat (me->request, HTAtom_for (tmp2));    HTRequest_setOutputFormat (me->request, HTAtom_for (tmp2));
   
    /*    /*
    **  Set the Charset of the file we are uploading     **  Set the Charset of the file we are uploading 
    */    */
    /* we set the charset as indicated in the document's metadata    /* we set the charset as indicated in the document's metadata
       structure (and only if it exists) */       structure (and only if it exists) */
    charset = TtaGetDocumentCharset (docid);    charset = TtaGetDocumentCharset (docid);
    if (charset != UNDEFINED_CHARSET)    if (charset != UNDEFINED_CHARSET)
      {      {
        tmp =  TtaGetCharsetName (charset);        tmp =  TtaGetCharsetName (charset);
        if (tmp && *tmp != EOS)        if (tmp && *tmp != EOS)
          {          {
            tmp2 = TtaStrdup (tmp);            tmp2 = TtaStrdup (tmp);
            HTAnchor_setCharset (dest_anc_parent, HTAtom_for (tmp2));            HTAnchor_setCharset (dest_anc_parent, HTAtom_for (tmp2));
            TtaFreeMemory (tmp2);            TtaFreeMemory (tmp2);
            tmp2 = HTAtom_name (HTAnchor_charset (dest_anc_parent));            tmp2 = HTAtom_name (HTAnchor_charset (dest_anc_parent));
            /* .. and we give the same charset to the source anchor */            /* .. and we give the same charset to the source anchor */
            /* we go thru setCharSet, rather than change the parent's            /* we go thru setCharSet, rather than change the parent's
               anchor, as that's the place that libwww expects it to be */               anchor, as that's the place that libwww expects it to be */
            HTAnchor_setCharset (HTAnchor_parent (me->source),            HTAnchor_setCharset (HTAnchor_parent (me->source),
                                 HTAtom_for (tmp2));                                 HTAtom_for (tmp2));
          }          }
      }      }
   
    /*    /*
    ** define other request characteristics    ** define other request characteristics
    */    */
    HTRequest_setPreemptive (me->request, NO);    HTRequest_setPreemptive (me->request, NO);
   
    /*    /*
    ** Make sure that the first request is flushed immediately and not    ** Make sure that the first request is flushed immediately and not
    ** buffered in the output buffer    ** buffered in the output buffer
    */    */
    if (mode & AMAYA_FLUSH_REQUEST)    if (mode & AMAYA_FLUSH_REQUEST)
      HTRequest_setFlush(me->request, YES);      HTRequest_setFlush(me->request, YES);
      
    /* Should we use preconditions? */  
    if (lost_update_check)  
      {  
        if (UsePreconditions)   
          etag = HTAnchor_etag (HTAnchor_parent (me->dest));  
          
        if (etag)   
          {  
            HTRequest_setPreconditions(me->request, HT_MATCH_THIS);  
          }  
        else  
          {  
            HTRequest_setPreconditions(me->request, HT_NO_MATCH);  
            HTRequest_addAfter(me->request, check_handler, NULL, NULL, HT_ALL,  
                               HT_FILTER_MIDDLE, YES);  
            HTRequest_addAfter (me->request, HTAuthFilter, "http://*", NULL,   
                                HT_NO_ACCESS, HT_FILTER_MIDDLE, YES);  
            HTRequest_addAfter (me->request, HTAuthFilter, "http://*", NULL,  
                                HT_REAUTH, HT_FILTER_MIDDLE, YES);  
            HTRequest_addAfter (me->request, HTAuthInfoFilter, "http://*", NULL,  
                                HT_ALL, HT_FILTER_MIDDLE, YES);  
            HTRequest_addAfter (me->request, HTUseProxyFilter, "http://*", NULL,  
                                HT_USE_PROXY, HT_FILTER_MIDDLE, YES);  
          }  
      }  
    else  
      {  
        /* don't use preconditions */  
        HTRequest_setPreconditions(me->request, HT_NO_MATCH);  
      }  
         
    /* don't use the cache while saving a document */    /* Should we use preconditions? */
    HTRequest_setReloadMode (me->request, HT_CACHE_FLUSH);    if (lost_update_check)
       {
         if (UsePreconditions) 
           etag = HTAnchor_etag (HTAnchor_parent (me->dest));
          
         if (etag) 
           {
             HTRequest_setPreconditions(me->request, HT_MATCH_THIS);
           }
         else
           {
             HTRequest_setPreconditions(me->request, HT_NO_MATCH);
             HTRequest_addAfter(me->request, check_handler, NULL, NULL, HT_ALL,
                                HT_FILTER_MIDDLE, YES);
             HTRequest_addAfter (me->request, HTAuthFilter, "http://*", NULL, 
                                 HT_NO_ACCESS, HT_FILTER_MIDDLE, YES);
             HTRequest_addAfter (me->request, HTAuthFilter, "http://*", NULL,
                                 HT_REAUTH, HT_FILTER_MIDDLE, YES);
             HTRequest_addAfter (me->request, HTAuthInfoFilter, "http://*", NULL,
                                 HT_ALL, HT_FILTER_MIDDLE, YES);
             HTRequest_addAfter (me->request, HTUseProxyFilter, "http://*", NULL,
                                 HT_USE_PROXY, HT_FILTER_MIDDLE, YES);
           }
       }
     else
       {
         /* don't use preconditions */
         HTRequest_setPreconditions(me->request, HT_NO_MATCH);
       }
      
     /* don't use the cache while saving a document */
     HTRequest_setReloadMode (me->request, HT_CACHE_FLUSH);
   
 #if 0  #if 0
    /* Throw away any reponse body */    /* Throw away any reponse body */
    /*    /*
    HTRequest_setOutputStream (me->request, HTBlackHole());              HTRequest_setOutputStream (me->request, HTBlackHole());        
    */    */
    HTRequest_setOutputStream (me->request, NULL);    HTRequest_setOutputStream (me->request, NULL);
 #endif  #endif
   
    /* prepare the URLname that will be displayed in the status bar */    /* prepare the URLname that will be displayed in the status bar */
    ChopURL (me->status_urlName, me->urlName);    ChopURL (me->status_urlName, me->urlName);
    TtaSetStatus (me->docid, 1, TtaGetMessage (AMAYA, AM_REMOTE_SAVING), me->status_urlName);    TtaSetStatus (me->docid, 1, TtaGetMessage (AMAYA, AM_REMOTE_SAVING), me->status_urlName);
   
         
 #ifdef DAV  #ifdef DAV
    /* MKP: for a PUT request, try to add an "If" header (lock information)    /* MKP: for a PUT request, try to add an "If" header (lock information)
     * for a HEAD request, leave this for check_handler */     * for a HEAD request, leave this for check_handler */
    if ( !(lost_update_check && (!UsePreconditions || !etag)) )    if ( !(lost_update_check && (!UsePreconditions || !etag)) )
        DAVAddIfHeader (me,HTAnchor_address(me->dest));         DAVAddIfHeader (me,HTAnchor_address(me->dest));   
 #endif /* DAV */  #endif /* DAV */
   
         
    /* make the request */    /* make the request */
    if (lost_update_check && (!UsePreconditions || !etag))    if (lost_update_check && (!UsePreconditions || !etag))
      status = HTHeadAnchor (me->dest, me->request);      status = HTHeadAnchor (me->dest, me->request);
    else    else
      status = HTPutDocumentAnchor (HTAnchor_parent (me->source), me->dest, me->request);      status = HTPutDocumentAnchor (HTAnchor_parent (me->source), me->dest, me->request);
   
    if (status == YES && me->reqStatus != HT_ERR)    if (status == YES && me->reqStatus != HT_ERR)
      {      {
        /* part of the stop button handler */        /* part of the stop button handler */
        if ((mode & AMAYA_SYNC) || (mode & AMAYA_ISYNC))        if ((mode & AMAYA_SYNC) || (mode & AMAYA_ISYNC))
          status = LoopForStop (me);          status = LoopForStop (me);
      }      }
    if (!HTRequest_kill (me->request))    if (!HTRequest_kill (me->request))
      AHTReqContext_delete (me);      AHTReqContext_delete (me);
         
    TtaHandlePendingEvents ();    TtaHandlePendingEvents ();
   
    return (status == YES ? 0 : -1);    return (status == YES ? 0 : -1);
 }  }
   
 /*----------------------------------------------------------------------  /*----------------------------------------------------------------------
Line 3710  int PutObjectWWW (int docid, char *fileN Line 3710  int PutObjectWWW (int docid, char *fileN
   ----------------------------------------------------------------------*/    ----------------------------------------------------------------------*/
 void                StopRequest (int docid)  void                StopRequest (int docid)
 {  {
    if (Amaya && CanDoStop ())    if (Amaya && CanDoStop ())
      {       { 
 #if 0 /* for later */  #if 0 /* for later */
        AHTDocId_Status    *docid_status;        AHTDocId_Status    *docid_status;
         /* verify if there are any requests at all associated with docid */        /* verify if there are any requests at all associated with docid */
        docid_status = (AHTDocId_Status *) GetDocIdStatus (docid,        docid_status = (AHTDocId_Status *) GetDocIdStatus (docid,
                                                           Amaya->docid_status);                                                           Amaya->docid_status);
        if (docid_status == (AHTDocId_Status *) NULL)        if (docid_status == (AHTDocId_Status *) NULL)
          return;          return;
 #endif /* 0 */  #endif /* 0 */
        /* temporary call to stop all requests, as libwww changed its API */         /* temporary call to stop all requests, as libwww changed its API */
        StopAllRequests (docid);        StopAllRequests (docid);
      }      }
 }  }
   
 /* @@@ the docid parameter isn't used... clean it up */  /* @@@ the docid parameter isn't used... clean it up */
Line 3732  void                StopRequest (int doc Line 3732  void                StopRequest (int doc
   ----------------------------------------------------------------------*/    ----------------------------------------------------------------------*/
 void                StopAllRequests (int docid)  void                StopAllRequests (int docid)
 {  {
    HTList             *cur;    HTList             *cur;
    AHTReqContext      *me;    AHTReqContext      *me;
    static ThotBool     lock_stop = 0;    static ThotBool     lock_stop = 0;
    ThotBool            async_flag;    ThotBool            async_flag;
    AHTReqStatus        old_reqStatus;    AHTReqStatus        old_reqStatus;
   
    /* only do the stop if we're not being called while processing a     /* only do the stop if we're not being called while processing a 
       request, and if we're not already dealing with a stop */       request, and if we're not already dealing with a stop */
    if (Amaya && CanDoStop () && !lock_stop)    if (Amaya && CanDoStop () && !lock_stop)
      {      {
 #ifdef DEBUG_LIBWWW  #ifdef DEBUG_LIBWWW
        fprintf (stderr, "StopRequest: number of Amaya requests "        fprintf (stderr, "StopRequest: number of Amaya requests "
                 "before kill: %d\n", Amaya->open_requests);                 "before kill: %d\n", Amaya->open_requests);
 #endif /* DEBUG_LIBWWW */  #endif /* DEBUG_LIBWWW */
        /* enter the critical section */         /* enter the critical section */
        lock_stop = TRUE;         lock_stop = TRUE; 
        /* set a module global variable so that we can do special        /* set a module global variable so that we can do special
           processing easier */           processing easier */
        UserAborted_flag = TRUE;        UserAborted_flag = TRUE;
        /* abort all outstanding libwww UI dialogues */        /* abort all outstanding libwww UI dialogues */
        CallbackDialogue (BaseDialog + FormAnswer,  STRING_DATA, NULL);        CallbackDialogue (BaseDialog + FormAnswer,  STRING_DATA, NULL);
        CallbackDialogue (BaseDialog + ConfirmForm, INTEGER_DATA, NULL);        CallbackDialogue (BaseDialog + ConfirmForm, INTEGER_DATA, NULL);
        /* expire all outstanding timers */        /* expire all outstanding timers */
        HTTimer_expireAll ();        HTTimer_expireAll ();
        /* HTNet_killAll (); */        /* HTNet_killAll (); */
        if (Amaya->open_requests)        if (Amaya->open_requests)
          {          {
            cur = Amaya->reqlist;            cur = Amaya->reqlist;
            while ((me = (AHTReqContext *) HTList_nextObject (cur)))             while ((me = (AHTReqContext *) HTList_nextObject (cur))) 
              {              {
                if (AmayaIsAlive ())                if (AmayaIsAlive ())
                  {                  {
 #ifdef DEBUG_LIBWWW  #ifdef DEBUG_LIBWWW
                    fprintf (stderr,"StopRequest: killing req %p, url %s, status %d\n", me, me->urlName, me->reqStatus);                    fprintf (stderr,"StopRequest: killing req %p, url %s, status %d\n", me, me->urlName, me->reqStatus);
 #endif /* DEBUG_LIBWWW */  #endif /* DEBUG_LIBWWW */
                                         
                    if (me->reqStatus != HT_END && me->reqStatus != HT_ABORT)                    if (me->reqStatus != HT_END && me->reqStatus != HT_ABORT)
                      {                      {
                        if ((me->mode & AMAYA_ASYNC)                        if ((me->mode & AMAYA_ASYNC)
                            || (me->mode & AMAYA_IASYNC))                            || (me->mode & AMAYA_IASYNC))
                          async_flag = TRUE;                          async_flag = TRUE;
                        else                        else
                          async_flag = FALSE;                          async_flag = FALSE;
                                                 
                        /* change the status to say that the request aborted */                        /* change the status to say that the request aborted */
                        /* if the request was "busy", we just change a flag to say so and                        /* if the request was "busy", we just change a flag to say so and
                           let the handler finish the processing itself */                           let the handler finish the processing itself */
                        old_reqStatus = me->reqStatus;                        old_reqStatus = me->reqStatus;
                        me->reqStatus = HT_ABORT;                        me->reqStatus = HT_ABORT;
                        if (old_reqStatus == HT_BUSY)                        if (old_reqStatus == HT_BUSY)
                          continue;                          continue;
                                                 
                        /* kill the request, using the appropriate function */                        /* kill the request, using the appropriate function */
                        if (me->request->net)                        if (me->request->net)
                          HTNet_killPipe (me->request->net);                          HTNet_killPipe (me->request->net);
                        else                        else
                          {                          {
                            if (me->terminate_cbf)                            if (me->terminate_cbf)
                              (*me->terminate_cbf) (me->docid, -1, me->urlName,                              (*me->terminate_cbf) (me->docid, -1, me->urlName,
                                                    me->outputfile,                                                    me->outputfile,
                                                    NULL,                                                    NULL,
                                                    me->context_tcbf);                                                    me->context_tcbf);
                                                         
                            if (async_flag)                             if (async_flag) 
                              /* explicitly free the request context for async                              /* explicitly free the request context for async
                                 requests. The sync requests context is freed                                 requests. The sync requests context is freed
                                 by LoopForStop */                                 by LoopForStop */
                              AHTReqContext_delete (me);                              AHTReqContext_delete (me);
                          }                          }
                        cur = Amaya->reqlist;                        cur = Amaya->reqlist;
                      }                      }
 #if defined(_GTK) || defined(_WX) || defined(_NOGUI)  #if defined(_GTK) || defined(_WX) || defined(_NOGUI)
 #ifdef WWW_XWINDOWS  #ifdef WWW_XWINDOWS
                    /* to be on the safe side, remove all outstanding                     /* to be on the safe side, remove all outstanding 
                       X events */                       X events */
                    else                     else 
                      RequestKillAllXtevents (me);                      RequestKillAllXtevents (me);
 #endif /* WWW_XWINDOWS */  #endif /* WWW_XWINDOWS */
 #endif /* #if defined(_GTK) || defined(_WX) || defined(_NOGUI) */  #endif /* #if defined(_GTK) || defined(_WX) || defined(_NOGUI) */
                  }                  }
              }              }
            /* Delete remaining channels */            /* Delete remaining channels */
            HTChannel_safeDeleteAll ();            HTChannel_safeDeleteAll ();
          }          }
        /* reset the stop status */        /* reset the stop status */
        UserAborted_flag = FALSE;        UserAborted_flag = FALSE;
        /* exit the critical section */        /* exit the critical section */
        lock_stop = FALSE;         lock_stop = FALSE; 
 #ifdef DEBUG_LIBWWW  #ifdef DEBUG_LIBWWW
        fprintf (stderr, "StopRequest: number of Amaya requests "        fprintf (stderr, "StopRequest: number of Amaya requests "
                 "after kill: %d\n", Amaya->open_requests);                 "after kill: %d\n", Amaya->open_requests);
 #endif /* DEBUG_LIBWWW */  #endif /* DEBUG_LIBWWW */
      }      }
 } /* StopAllRequests */  } /* StopAllRequests */
   
   
Line 3863  void libwww_updateNetworkConf (int statu Line 3863  void libwww_updateNetworkConf (int statu
   int docid = 1;    int docid = 1;
   
   /* first, stop all current requests, as the network    /* first, stop all current requests, as the network
    may make some changes */       may make some changes */
   StopAllRequests (docid);    StopAllRequests (docid);
   
   if (status & AMAYA_SAFEPUT_RESTART)    if (status & AMAYA_SAFEPUT_RESTART)
Line 3890  void libwww_updateNetworkConf (int statu Line 3890  void libwww_updateNetworkConf (int statu
     {      {
       /* clear the current values */        /* clear the current values */
       if (acceptLanguages)        if (acceptLanguages)
         HTLanguage_deleteAll (acceptLanguages);          HTLanguage_deleteAll (acceptLanguages);
       /* read in the new ones */        /* read in the new ones */
       acceptLanguages = HTList_new ();        acceptLanguages = HTList_new ();
       AHTAcceptLanguagesInit (acceptLanguages);        AHTAcceptLanguagesInit (acceptLanguages);
Line 3971  ThotBool CheckSingleInstance (char *pid_ Line 3971  ThotBool CheckSingleInstance (char *pid_
     {      {
       /* skip the UNIX . and .. links */        /* skip the UNIX . and .. links */
       if (!strcmp (d->d_name, "..")        if (!strcmp (d->d_name, "..")
           || !strcmp (d->d_name, "."))            || !strcmp (d->d_name, "."))
         continue;          continue;
   
       sprintf (filename, "%s%c%s", pid_dir, DIR_SEP, d->d_name);        sprintf (filename, "%s%c%s", pid_dir, DIR_SEP, d->d_name);
       if  (lstat (filename, &st) < 0 )         if  (lstat (filename, &st) < 0 ) 
         {          {
           /* @@2 need some error message */            /* @@2 need some error message */
           perror (filename);            perror (filename);
           continue;            continue;
         }          }
               
       switch (st.st_mode & S_IFMT)        switch (st.st_mode & S_IFMT)
         {          {
         case S_IFDIR:          case S_IFDIR:
         case S_IFLNK:          case S_IFLNK:
           /* skip any links and directories that we find */            /* skip any links and directories that we find */
           continue;            continue;
           break;            break;
         default:          default:
           /* check if this pid exists. If not, erase it */            /* check if this pid exists. If not, erase it */
           ptr = strrchr (filename, DIR_SEP);            ptr = strrchr (filename, DIR_SEP);
           if (!ptr)             if (!ptr) 
             continue;              continue;
           sscanf (ptr, DIR_STR"%d", &pid);            sscanf (ptr, DIR_STR"%d", &pid);
           if (kill (pid, 0) == -1)            if (kill (pid, 0) == -1)
             {              {
               /* erase the stale pid file */                /* erase the stale pid file */
               TtaFileUnlink (filename);                TtaFileUnlink (filename);
             }              }
           else /* we found one live instance */            else /* we found one live instance */
             {              {
               instances++;                instances++;
             }              }
           break;            break;
         }          }
     }      }
   closedir (dp);    closedir (dp);
   return (instances == 0);    return (instances == 0);
Line 4060  void InitAmayaCache (void) Line 4060  void InitAmayaCache (void)
   while (*ptr && can_erase)    while (*ptr && can_erase)
     {      {
       if (*ptr == '.')        if (*ptr == '.')
         {          {
           if (*(ptr + 1) == '.')            if (*(ptr + 1) == '.')
             can_erase = FALSE;              can_erase = FALSE;
           else            else
             ptr++;              ptr++;
           continue;            continue;
         }          }
       else if (*ptr == '~')        else if (*ptr == '~')
         can_erase = FALSE;          can_erase = FALSE;
       else if (!isalnum (*ptr) && *ptr != SPACE && *ptr != DIR_SEP && *ptr != ':')        else if (!isalnum (*ptr) && *ptr != SPACE && *ptr != DIR_SEP && *ptr != ':')
         can_erase = FALSE;          can_erase = FALSE;
       ptr++;        ptr++;
     }      }
 #endif /* _UNIX */  #endif /* _UNIX */
Line 4081  void InitAmayaCache (void) Line 4081  void InitAmayaCache (void)
     {      {
       /* Erase the previous directories */        /* Erase the previous directories */
       for (i = 0; i < DocumentTableLength; i++)        for (i = 0; i < DocumentTableLength; i++)
         {                {      
           sprintf (str, "%s%c%d%c", TempFileDirectory, DIR_SEP, i, DIR_SEP);            sprintf (str, "%s%c%d%c", TempFileDirectory, DIR_SEP, i, DIR_SEP);
           RecCleanCache (str);            RecCleanCache (str);
         }          }
     }      }
   
   /* create the temporary cache directories if they don't exit*/    /* create the temporary cache directories if they don't exit*/

Removed from v.1.360  
changed lines
  Added in v.1.361


Webmaster