Diff for /Amaya/amaya/AHTBridge.c between versions 1.2 and 1.3

version 1.2, 1996/11/26 18:20:34 version 1.3, 1996/12/02 12:21:02
Line 1 Line 0
 /*                                                                  AHTBridge.c  
  *      INTERFACE BRIDGE TO XT, LIBWWW, and AMAYA  
  *  
  *      (c) COPYRIGHT   
  *      Please first read the full copyright statement in the file COPYRIGH.  
  *  
  *      This module implments the callback setup and handlers between  
  *      the Xt, libwww, and Amaya procedures  
  *  
  * History:  
  *      May 02 96 JK    First semi-stable version, Jose Kahan  
  *      June 01 96 JK   First almost-complete version, Jose Kahan   
 */  
   
 /* Unix/C/X */  
 #include "thot_gui.h"  
 #include "thot_sys.h"  
 #include "message.h"  
 #include "dialog.h"  
 #include "application.h"  
 #include "content.h"  
 #include "view.h"  
 #include "interface.h"  
 #include "amaya.h"  
   
 #if 0  
 #include "AHTCommon.h"  
 #include "query.h"  
 #endif  
   
 #include "AHTBridge.h"   /* implemented here */  
   
 #ifdef WWW_XWINDOWS  
 /* Amaya's X appcontext */  
 extern XtAppContext app_cont;  
 #endif  
   
   
 #ifndef HACK_WWW  
 extern PUBLIC HTEventCallback* HTEvent_Retrieve (SOCKET, SockOps, HTRequest** arp);  
 #endif  
   
 /*  
 ** Private functions  
 */  
 #ifdef __STDC__  
 static void RequestKillReadXtevent   (AHTReqContext*);  
 static void RequestKillWriteXtevent  (AHTReqContext*);  
 static void RequestKillExceptXtevent (AHTReqContext*);  
 #else  
 static void RequestKillReadXtevent   ();  
 static void RequestKillWriteXtevent  ();  
 static void RequestKillExceptXtevent ();  
 #endif /*__STDC__*/  
   
 /*  
  * Private variables   
  */  
   
 /*  
  * this set of SockOps map our WinSock "socket event SockOps" into   
  * our read and write sets. Note that under the canonical Unix model,  
  * a non-blocking socket passed to an accept() call will appear as readable,   
  * whilst a non-blocking call to connect() will appear as writeable. In add.  
  * if the connection has been closed, the socket will appear readable under  
  * BSD Unix semantics   
  */  
 PRIVATE const SockOps ReadBits = FD_READ | FD_ACCEPT  | FD_CLOSE;  
 PRIVATE const SockOps WriteBits = FD_WRITE | FD_CONNECT ;  
 PRIVATE const SockOps ExceptBits = FD_OOB ;  
   
 /*  
  * Private functions  
  */  
   
 /*  
  * Callback that acts as a bridge between X and wwwlib.  
  * This function is equivalent to the library's __DoCallback()  
  * function, but with a different API, to conform to Xt's event loop  
  * specifications. For more info, cf. the library's HTEvntrg.c module.  
  */  
   
 #ifdef WWW_XWINDOWS  
 #ifdef __STDC__  
 XtInputCallbackProc AHTCallback_bridge (caddr_t cd, int* s, XtInputId* id)  
 #else   
 XtInputCallbackProc AHTCallback_bridge (cd, s, id)  
 caddr_t    cd ;  
 int*       s  ;  
 XtInputId* id ;  
 #endif /* __STDC__ */  
   
 #else /* WWW_XWINDOWS */  
 /* some winproc someday? */  
 LONG AHTCallback_bridge (caddr_t cd, int* s)  
 #endif /* !WWW_XWINDOWS */  
 {  
     int            status;  
     HTRequest*     rqp = NULL;  
     AHTReqContext* me;  
     SOCKET         sock;  
     SockOps        ops; /* what value goes here ? Ask eric */  
   
    /* Libwww 4.1 does not take into account the third parameter  
       for this function call */  
   
 #ifdef HACK_WWW  
     HTEventCallback* cbf;  
 #else  
     HTEventCallback* cbf = (HTEventCallback*) __RetrieveCBF(*s, ops, &rqp);  
 #endif  
     me = HTRequest_context (rqp);  
   
 #if 0  
     switch ((XtInputId) cd) {  
            case XtInputReadMask:  
                 ops = me->read_ops;  
                 if (me->read_xtinput_id) {  
                    XtRemoveInput (me->read_xtinput_id);  
                    if (THD_TRACE)  
                       fprintf (stderr, "(BT) removing Xtinput %lu R (AHTBridge before cbf), sock %d\n", me->read_xtinput_id, *s);  
                    me->read_xtinput_id = 0;  
                 }  
                 break;  
            case XtInputWriteMask:  
                 ops = me->write_ops;  
                 if (me->write_xtinput_id) {  
                    XtRemoveInput(me->write_xtinput_id);  
                    if (THD_TRACE)  
                       fprintf (stderr, "(BT) removing Xtinput %lu W (AHTBridge before cbf), sock %d\n", me->write_xtinput_id, *s);  
                    me->write_xtinput_id = 0;  
                 }  
                 break;  
            case XtInputExceptMask:  
                 ops = me->except_ops;  
                 if (me->except_xtinput_id) {  
                    XtRemoveInput (me->except_xtinput_id);  
                    if (THD_TRACE)  
                       fprintf(stderr, "(BT) removing Xtinput %lu E (AHTBridge before cbf), sock %d\n", me->except_xtinput_id, *s);  
                     me->except_xtinput_id = 0;  
                 }  
                 break;  
     } /* switch */  
 #endif  
   
     if (THD_TRACE)   
       fprintf (stderr, "AHTBridge: Processing url %s \n", me->urlName);  
   
   
 #ifdef WWW_XWINDOWS  
     switch ((XtInputId) cd) {  
            case XtInputReadMask:  
                 ops = me->read_ops;  
                 ops = FD_READ;  
                 break;  
            case XtInputWriteMask:  
                 ops = me->write_ops;  
                 ops = FD_WRITE;  
                 break;  
            case XtInputExceptMask:  
                 ops = me->except_ops;  
                 ops = FD_OOB;  
                 break;  
     } /* switch */  
 #endif WWW_XWINDOWS  
   
     /*   
      * Liberate the input, so that when a pending socket is activated,  
      * the socket status will be ... available   
      *   
      * verify if I can CHKR_LIMIT this to the unregister function   
      * does not look so  
      *  
      * although it makes no sense, callbacks can be null   
      */  
   
     if (!cbf || !rqp || rqp->priority == HT_PRIORITY_OFF) {  
         if (THD_TRACE)  
             HTTrace("Callback.... No callback found\n");  
         /* put some more code to correctly destroy this request */  
         return (0);  
     }  
   
     me->reqStatus = HT_BUSY;  
   
     if ((status = (*cbf) (*s, rqp, ops)) != HT_OK)  
        HTTrace("Callback.... received != HT_OK");  
   
     /* Several states can happen after this callback. They  
      * are indicated by the me->reqStatus structure member and  
      * the fds external variables. The following lines examine  
      * the states and correspondly update the Xt event register  
      *  
      * Regarding the me->reqStatus member, we have the following  
      * possible states:  
      *     
      * HT_BUSY:    Request has blocked  
      * HT_WAITING: Request has been reissued  
      * HT_ABORT:   Request has been stopped  
      * HT_END:     Request has ended  
      */  
   
     /* Has the request been stopped?   
      *  
      * we verify if the request exists. If it has ended, me will have  
      *  a reqStatus with an HT_END value */  
   
     /* Was the stop button pressed? */  
   
  #ifdef WWW_XWINDOWS  
     if (me->reqStatus == HT_ABORT) {  
         me->reqStatus = HT_WAITING;  
         StopRequest (me->docid);  
         if (THD_TRACE)  
            fprintf(stderr, "(BF) removing Xtinput %lu !RWE (Stop buttonl), sock %d\n", me->read_xtinput_id, sock);  
         return(0);  
     }  
 #endif /* WWW_XWINDOWS */  
   
     /* the request is being reissued */  
   
     if (me->reqStatus == HT_WAITING) {  
        /*  
         * (1) The old request has ended and the library  
         * assigned the old socket number to a pending  
         * request.  
         *  
         * (2) The request has been reissued after an   
         * authentication or redirection directive and  
         * we are using the same old socket number.  
         */  
         
         if (THD_TRACE)  
            fprintf(stderr, "*** detected a reissue of request \n");  
       return(0);  
     }  
   
            
     /* verify if the request is still alive !! */  
   
     if ((me->request->net == (HTNet*) NULL) || (me->reqStatus == HT_END || me->reqStatus == HT_ERR)) {  
       /* the socket is now being used by a different request, so the request has ended */  
 #ifdef WWW_XWINDOWS  
        if (THD_TRACE)  
           fprintf(stderr, "(BF) removing Xtinput %lu !RWE, sock %d (Request has ended)\n", *id, *s);  
 #endif  
        if ((me->mode & AMAYA_ASYNC) || (me->mode & AMAYA_IASYNC)) {  
          AHTPrintPendingRequestStatus (me->docid, YES);  
          AHTReqContext_delete(me);  
        }  
        else  
          if (me->reqStatus != HT_END && HTError_hasSeverity(HTRequest_error(me->request), ERR_NON_FATAL))  
            me->reqStatus = HT_ERR;  
        return(0);  
     }  
     me->reqStatus = HT_WAITING;  
     return (0);  
 }  
   
   
 /*   
  * This function is called whenever a socket is available  
  * for a request. It  the necessary events to the Xt  
  * A small interface to the HTLoadAnchor libwww function.  
  * It prepares Xt to handle the asynchronous data requests.  
  */  
   
 #ifdef __STDC__  
 int Add_NewSocket_to_Loop (HTRequest* request, HTAlertOpcode op, int msgnum, const char* dfault, void* input, HTAlertPar* reply)  
 #else  
 int Add_NewSocket_to_Loop (request, op, msgnum, dfault, input, reply)  
 HTRequest*    request;  
 HTAlertOpcode op;  
 int           msgnum;  
 const char*   dfault;  
 void*         input;  
 HTAlertPar*   reply;  
 #endif /*__STDC__*/  
 {  
     SOCKET         req_socket;  
     AHTReqContext* me = HTRequest_context (request);  
   
     /* AmayaOpenRequests *reqState; */  
   
     if(me->reqStatus == HT_NEW_PENDING) {  
       /* we are opening a pending request */  
       if ((me->output = fopen (me->outputfile, "w")) == NULL) {  
         me->outputfile[0] = '\0';       /* file could not be opened */  
         TtaSetStatus (me->docid, 1, TtaGetMessage (AMAYA, AM_CANNOT_CREATE_FILE),  
                       me->outputfile);  
         me->reqStatus = HT_ERR;  
         return(HT_ERROR);  
       }  
       if (THD_TRACE)  
         fprintf(stderr, "Add_NewSocket_to_Loop: Activating pending %s . Open fd %d\n", me->urlName, (int) me->output);  
       HTRequest_setOutputStream (me->request,  
                                  AHTFWriter_new (me->request, me->output, YES));  
     }  
   
     me->reqStatus = HT_WAITING;  
   
     if (THD_TRACE)  
        fprintf(stderr, "(Activating a pending request\n");  
   
     /* reusing this function to save on file descriptors */  
   
   
     return (HT_OK);  
   
     /***  
     if(me->method == METHOD_PUT || me->method == METHOD_POST)  
         return (HT_OK);  
     ***/  
   
     /* get the socket number associated to the request */  
   
     req_socket = HTNet_socket(request->net);  
       
     if (req_socket == INVSOC) {  
         /* this should never be true */  
         return (HT_ERROR);  
     }  
   
     /* add the input */  
   
 #ifdef WWW_XWINDOWS  
     me->write_xtinput_id =   
       XtAppAddInput (app_cont,req_socket, (XtPointer) XtInputWriteMask,  
                      (XtInputCallbackProc) AHTCallback_bridge, NULL);  
     if (THD_TRACE)  
       fprintf(stderr, "(BT) adding   Xtinput %lu Socket %d W \n", me->write_xtinput_id, req_socket);  
       
     if (me->write_xtinput_id == (XtInputId) NULL) {  
       TtaSetStatus(me->docid, 1, TtaGetMessage(AMAYA, AM_XT_ERROR), me->urlName);  
         
       /* I still need to add some error treatment here, to liberate memory */  
       return (HT_ERROR);  
     }  
   
 #endif /* WWW_XWINDOWS */  
     /* To speed up the stop performances, we move the active requests to the top of the Amaya list */  
   
     /*  
     reqState  = DocRequestState(Amaya->open_requests, me->docid);  
   
     if(reqState->counter > 1) {  
       HTList_removeObject (Amaya->reqlist, (void *) me);  
       HTList_addObject (Amaya->reqlist, (void *) me);  
     }  
     */  
     return (HT_OK);  
 }  
   
   
 /*   
  * This function is called whenever a socket is available  
  * for a request. It  the necessary events to the Xt  
  * A small interface to the HTLoadAnchor libwww function.  
  * It prepares Xt to handle the asynchronous data requests.  
  */  
   
 #ifdef __STDC__  
 int AHTEvent_register(SOCKET sock, HTRequest* rqp, SockOps ops, HTEventCallback* cbf, HTPriority p)  
 #else  
 int AHTEvent_register(sock, rqp, ops,  cbf, p)  
 SOCKET           sock;  
 HTRequest*       rqp;  
 SockOps          ops;  
 HTEventCallback* cbf;  
 HTPriority       p;  
 #endif /*__STDC__*/  
 {  
     AHTReqContext* me;  
     int            status;  
       
     if (sock == INVSOC)  
       return (0);  
       
     /* get the request associated to the socket number */  
   
     if((status = HTEventrg_register (sock, rqp, ops,  
                                      cbf,p )) != HT_OK )  
       return (status);  
   
     if(rqp) {  
         
       me = HTRequest_context(rqp);  
   
       /* verify if we need to open the fd */  
   
       if(me->reqStatus == HT_NEW_PENDING) {  
         /* we are opening a pending request */  
         if ((me->output = fopen (me->outputfile, "w")) == NULL) {  
           me->outputfile[0] = '\0';     /* file could not be opened */  
           TtaSetStatus (me->docid, 1, TtaGetMessage (AMAYA, AM_CANNOT_CREATE_FILE),  
                         me->outputfile);  
           me->reqStatus = HT_ERR;  
           return(HT_ERROR);  
         }  
         HTRequest_setOutputStream (me->request,  
                                    AHTFWriter_new (me->request, me->output, YES));  
         me->reqStatus = HT_WAITING;  
   
       if (THD_TRACE)  
         fprintf(stderr,"AHTEvent_register: Activating pending request url %s, fd %d\n", me->urlName, (int) me->output);  
       }  
   
       if (THD_TRACE)  
         fprintf(stderr,"AHTEvent_register: url %s, sock %d, ops %lu \n",  
                 me->urlName, sock, ops);  
   
       /* add the input */  
       if(me->reqStatus == HT_NEW)  
         me->reqStatus = HT_WAITING;  
         
       if (ops & ReadBits)       {  
         me->read_ops = ops;  
   
 #ifdef WWW_XWINDOWS  
         if(me->read_xtinput_id)  
           XtRemoveInput(me->read_xtinput_id);  
         me->read_xtinput_id =   
           XtAppAddInput(app_cont,  
                         sock,  
                         (XtPointer) XtInputReadMask,  
                         (XtInputCallbackProc) AHTCallback_bridge,  
                         (XtPointer) XtInputReadMask);  
         if (THD_TRACE)   
           fprintf(stderr, "(BT) adding Xtinput %lu Socket %d R\n",  
                   me->read_xtinput_id, sock);  
 #endif /* WWW_XWINDOWS */  
       }  
   
       if(ops & WriteBits) {  
         me->write_ops= ops;  
 #ifdef WWW_XWINDOWS  
        if (me->write_xtinput_id)  
           XtRemoveInput(me->write_xtinput_id);  
           me->write_xtinput_id = XtAppAddInput (app_cont, sock,  
                                                (XtPointer) XtInputWriteMask,  
                                                (XtInputCallbackProc) AHTCallback_bridge,  
                                                (XtPointer) XtInputWriteMask);  
           if (THD_TRACE)   
             fprintf(stderr, "(BT) adding Xtinput %lu Socket %d W\n",  
                     me->write_xtinput_id, sock);  
 #endif /* WWW_XWINDOWS */  
       }   
   
       if (ops & ExceptBits) {  
         me->except_ops = ops;  
 #ifdef WWW_XWINDOWS  
         if (me->except_xtinput_id)  
           XtRemoveInput(me->except_xtinput_id);  
   
         me->except_xtinput_id = XtAppAddInput (app_cont, sock,  
                                                (XtPointer) XtInputExceptMask,  
                                                (XtInputCallbackProc) AHTCallback_bridge,  
                                                (XtPointer) XtInputExceptMask);  
         if (THD_TRACE)   
           fprintf(stderr, "(BT) adding Xtinput %lu Socket %d E\n", me->except_xtinput_id, sock);  
 #endif /* WWW_XWINDOWS */  
       }  
     }  
   
   
   
 #if 0  
     if (me->xtinput_id == (XtInputId) NULL) {  
        TtaSetStatus(me->docid, 1, TtaGetMessage(AMAYA, AM_XT_ERROR), me->urlName);  
           
       /* I still need to add some error treatment here, to liberate memory */  
        return (HT_ERROR);  
     }  
   
 #endif  
   
   return (status);  
 }  
   
 #ifdef __STDC__  
 int AHTEvent_unregister (SOCKET sock, SockOps ops)  
 #else  
 int AHTEvent_unregister (sock, ops)  
 SOCKET  sock;  
 SockOps ops;  
 #endif /*__STDC__*/  
 {  
     int status;  
   
     HTRequest*     rqp = NULL;  
     AHTReqContext* me;  
       
    /* Libwww 4.1 does not take into account the third parameter  
    **  for this function call */  
   
     HTEventCallback* cbf = (HTEventCallback*) __RetrieveCBF(sock, (SockOps) NULL, &rqp);  
   
    if (cbf) {  
 #ifdef WWW_XWINDOWS  
      if(rqp) {  
        me = HTRequest_context(rqp);  
   
        if(ops & ReadBits)  
          RequestKillReadXtevent (me);  
          
        if(ops & WriteBits)  
          RequestKillWriteXtevent (me);  
          
        if(ops & ExceptBits)  
          RequestKillExceptXtevent (me);  
          
 #endif /* WWW_XWINDOWS */  
          
      }  
    }  
      
      status = HTEventrg_unregister(sock, ops);  
      return(status);  
 }  
   
 #ifdef __STDC__  
 void RequestKillAllXtevents (AHTReqContext* me)  
 #else  
 void RequestKillAllXtevents (me)  
 AHTReqContext* me;  
 #endif /*__STDC__*/  
 {  
 #ifdef WWW_XWINDOWS  
     if (THD_TRACE)  
        fprintf(stderr, "Request_kill: Clearing Xtinputs\n");  
   
     RequestKillReadXtevent   (me);  
     RequestKillWriteXtevent  (me);  
     RequestKillExceptXtevent (me);  
 #endif /* WWW_XWINDOWS */  
 }  
   
 #ifdef __STDC__  
 static void RequestKillReadXtevent (AHTReqContext* me)  
 #else  
 static void RequestKillReadXtevent (me)  
 AHTReqContext* me;  
 #endif /*__STDC__*/  
 {  
 #ifdef WWW_XWINDOWS  
     if (me->read_xtinput_id) {  
        if (THD_TRACE)  
           fprintf (stderr, "Request_kill: Clearing Read Xtinputs%lu\n", me->read_xtinput_id);  
        XtRemoveInput (me->read_xtinput_id);  
        me->read_xtinput_id = (XtInputId) NULL;   
     }  
 #endif /* WWW_XWINDOWS */  
 }  
   
 #ifdef __STDC__  
 static void RequestKillWriteXtevent (AHTReqContext* me)  
 #else  
 static void RequestKillWriteXtevent (me)  
 AHTReqContext* me;  
 #endif /*__STDC__*/  
 {  
 #ifdef WWW_XWINDOWS  
     if (me->write_xtinput_id) {  
        if (THD_TRACE)  
           fprintf(stderr, "Request_kill: Clearing Write Xtinputs %lu\n", me->write_xtinput_id);  
        XtRemoveInput(me->write_xtinput_id);  
        me->write_xtinput_id = (XtInputId) NULL;   
     }  
 #endif /* WWW_XWINDOWS */  
 }  
   
 #ifdef __STDC__  
 static void RequestKillExceptXtevent (AHTReqContext* me)  
 #else  
 static void RequestKillExceptXtevent (me)  
 AHTReqContext* me;  
 #endif /*__STDC__*/  
 {  
 #ifdef WWW_XWINDOWS  
     if (me->except_xtinput_id) {  
        if (THD_TRACE)  
           fprintf (stderr, "Request_kill: Clearing Except Xtinputs %lu\n", me->except_xtinput_id);  
        XtRemoveInput (me->except_xtinput_id);  
        me->except_xtinput_id = (XtInputId) NULL;   
     }  
 #endif /* WWW_XWINDOWS */  
 }  
   
   
   
   
   
   

Removed from v.1.2  
changed lines
  Added in v.1.3


Webmaster