Annotation of Amaya/amaya/AHTBridge.c, revision 1.8
1.6 cvs 1: /***
2: *** Copyright (c) 1996 INRIA, All rights reserved
3: ***/
4:
1.4 cvs 5: /* AHTBridge.c
6: * INTERFACE BRIDGE TO XT, LIBWWW, and AMAYA
7: *
8: * (c) COPYRIGHT
9: * Please first read the full copyright statement in the file COPYRIGH.
10: *
11: * This module implments the callback setup and handlers between
12: * the Xt, libwww, and Amaya procedures
13: *
14: * History:
15: * May 02 96 JK First semi-stable version, Jose Kahan
16: * June 01 96 JK First almost-complete version, Jose Kahan
1.7 cvs 17: */
1.4 cvs 18:
19: /* Unix/C/X */
20: #include "thot_gui.h"
21: #include "thot_sys.h"
22: #include "message.h"
23: #include "dialog.h"
24: #include "application.h"
25: #include "content.h"
26: #include "view.h"
27: #include "interface.h"
28: #include "amaya.h"
29:
30: #if 0
31: #include "AHTCommon.h"
32: #include "query.h"
33: #endif
34:
1.7 cvs 35: #include "AHTBridge.h" /* implemented here */
1.4 cvs 36:
37: #ifdef WWW_XWINDOWS
38: /* Amaya's X appcontext */
39: extern XtAppContext app_cont;
1.7 cvs 40:
1.4 cvs 41: #endif
42:
43:
44: #ifndef HACK_WWW
1.7 cvs 45: extern PUBLIC HTEventCallback *HTEvent_Retrieve (SOCKET, SockOps, HTRequest ** arp);
46:
1.4 cvs 47: #endif
48:
49: /*
1.7 cvs 50: * Private functions
51: */
1.4 cvs 52: #ifdef __STDC__
1.7 cvs 53: static void RequestKillReadXtevent (AHTReqContext *);
54: static void RequestKillWriteXtevent (AHTReqContext *);
55: static void RequestKillExceptXtevent (AHTReqContext *);
56:
1.4 cvs 57: #else
1.7 cvs 58: static void RequestKillReadXtevent ();
59: static void RequestKillWriteXtevent ();
60: static void RequestKillExceptXtevent ();
61:
62: #endif
1.4 cvs 63:
64: /*
65: * Private variables
66: */
67:
68: /*
69: * this set of SockOps map our WinSock "socket event SockOps" into
70: * our read and write sets. Note that under the canonical Unix model,
71: * a non-blocking socket passed to an accept() call will appear as readable,
72: * whilst a non-blocking call to connect() will appear as writeable. In add.
73: * if the connection has been closed, the socket will appear readable under
74: * BSD Unix semantics
75: */
1.7 cvs 76: PRIVATE const SockOps ReadBits = FD_READ | FD_ACCEPT | FD_CLOSE;
77: PRIVATE const SockOps WriteBits = FD_WRITE | FD_CONNECT;
78: PRIVATE const SockOps ExceptBits = FD_OOB;
1.4 cvs 79:
80: /*
81: * Private functions
82: */
83:
84: /*
85: * Callback that acts as a bridge between X and wwwlib.
86: * This function is equivalent to the library's __DoCallback()
87: * function, but with a different API, to conform to Xt's event loop
88: * specifications. For more info, cf. the library's HTEvntrg.c module.
89: */
90:
91: #ifdef WWW_XWINDOWS
92: #ifdef __STDC__
1.7 cvs 93: XtInputCallbackProc AHTCallback_bridge (caddr_t cd, int *s, XtInputId * id)
94: #else
1.4 cvs 95: XtInputCallbackProc AHTCallback_bridge (cd, s, id)
1.7 cvs 96: caddr_t cd;
97: int *s;
98: XtInputId *id;
99:
1.4 cvs 100: #endif /* __STDC__ */
101:
1.7 cvs 102: #else /* WWW_XWINDOWS */
1.4 cvs 103: /* some winproc someday? */
1.7 cvs 104: LONG AHTCallback_bridge (caddr_t cd, int *s)
105: #endif /* !WWW_XWINDOWS */
1.4 cvs 106: {
1.7 cvs 107: int status;
108: HTRequest *rqp = NULL;
109: AHTReqContext *me;
110: SOCKET sock;
111: SockOps ops; /* what value goes here ? Ask eric */
1.4 cvs 112:
113: /* Libwww 4.1 does not take into account the third parameter
114: for this function call */
115:
116: #ifdef HACK_WWW
1.7 cvs 117: HTEventCallback *cbf;
118:
1.4 cvs 119: #else
1.7 cvs 120: HTEventCallback *cbf = (HTEventCallback *) __RetrieveCBF (*s, ops, &rqp);
121:
1.4 cvs 122: #endif
1.7 cvs 123: me = HTRequest_context (rqp);
1.4 cvs 124:
125: #if 0
1.7 cvs 126: switch ((XtInputId) cd)
127: {
128: case XtInputReadMask:
129: ops = me->read_ops;
130: if (me->read_xtinput_id)
131: {
132: XtRemoveInput (me->read_xtinput_id);
133: if (THD_TRACE)
134: fprintf (stderr, "(BT) removing Xtinput %lu R (AHTBridge before cbf), sock %d\n", me->read_xtinput_id, *s);
135: me->read_xtinput_id = 0;
136: }
137: break;
138: case XtInputWriteMask:
139: ops = me->write_ops;
140: if (me->write_xtinput_id)
141: {
142: XtRemoveInput (me->write_xtinput_id);
143: if (THD_TRACE)
144: fprintf (stderr, "(BT) removing Xtinput %lu W (AHTBridge before cbf), sock %d\n", me->write_xtinput_id, *s);
145: me->write_xtinput_id = 0;
146: }
147: break;
148: case XtInputExceptMask:
149: ops = me->except_ops;
150: if (me->except_xtinput_id)
151: {
152: XtRemoveInput (me->except_xtinput_id);
153: if (THD_TRACE)
154: fprintf (stderr, "(BT) removing Xtinput %lu E (AHTBridge before cbf), sock %d\n", me->except_xtinput_id, *s);
155: me->except_xtinput_id = 0;
156: }
157: break;
158: } /* switch */
1.4 cvs 159: #endif
160:
1.7 cvs 161: if (THD_TRACE)
1.4 cvs 162: fprintf (stderr, "AHTBridge: Processing url %s \n", me->urlName);
163:
164:
165: #ifdef WWW_XWINDOWS
1.7 cvs 166: switch ((XtInputId) cd)
167: {
168: case XtInputReadMask:
169: ops = me->read_ops;
170: ops = FD_READ;
171: break;
172: case XtInputWriteMask:
173: ops = me->write_ops;
174: ops = FD_WRITE;
175: break;
176: case XtInputExceptMask:
177: ops = me->except_ops;
178: ops = FD_OOB;
179: break;
180: } /* switch */
181: #endif /* WWW_XWINDOWS */
182:
183: /*
184: * Liberate the input, so that when a pending socket is activated,
185: * the socket status will be ... available
186: *
187: * verify if I can CHKR_LIMIT this to the unregister function
188: * does not look so
189: *
190: * although it makes no sense, callbacks can be null
191: */
1.4 cvs 192:
1.7 cvs 193: if (!cbf || !rqp || rqp->priority == HT_PRIORITY_OFF)
194: {
1.4 cvs 195: if (THD_TRACE)
1.7 cvs 196: HTTrace ("Callback.... No callback found\n");
1.4 cvs 197: /* put some more code to correctly destroy this request */
198: return (0);
1.7 cvs 199: }
200:
201: me->reqStatus = HT_BUSY;
1.4 cvs 202:
1.7 cvs 203: if ((status = (*cbf) (*s, rqp, ops)) != HT_OK)
204: HTTrace ("Callback.... received != HT_OK");
1.4 cvs 205:
1.7 cvs 206: /* Several states can happen after this callback. They
207: * are indicated by the me->reqStatus structure member and
208: * the fds external variables. The following lines examine
209: * the states and correspondly update the Xt event register
210: *
211: * Regarding the me->reqStatus member, we have the following
212: * possible states:
213: *
214: * HT_BUSY: Request has blocked
215: * HT_WAITING: Request has been reissued
216: * HT_ABORT: Request has been stopped
217: * HT_END: Request has ended
218: */
219:
220: /* Has the request been stopped?
1.4 cvs 221:
1.7 cvs 222: * we verify if the request exists. If it has ended, me will have
223: * a reqStatus with an HT_END value */
1.4 cvs 224:
1.7 cvs 225: /* Was the stop button pressed? */
1.4 cvs 226:
1.7 cvs 227: #ifdef WWW_XWINDOWS
228: if (me->reqStatus == HT_ABORT)
229: {
1.4 cvs 230: me->reqStatus = HT_WAITING;
231: StopRequest (me->docid);
1.7 cvs 232: if (THD_TRACE)
233: fprintf (stderr, "(BF) removing Xtinput %lu !RWE (Stop buttonl), sock %d\n", me->read_xtinput_id, sock);
234: return (0);
235: }
236: #endif /* WWW_XWINDOWS */
237:
238: /* the request is being reissued */
239:
240: if (me->reqStatus == HT_WAITING)
241: {
242: /*
243: * (1) The old request has ended and the library
244: * assigned the old socket number to a pending
245: * request.
246: *
247: * (2) The request has been reissued after an
248: * authentication or redirection directive and
249: * we are using the same old socket number.
250: */
1.4 cvs 251:
1.7 cvs 252: if (THD_TRACE)
253: fprintf (stderr, "*** detected a reissue of request \n");
254: return (0);
255: }
1.4 cvs 256:
1.7 cvs 257:
258: /* verify if the request is still alive !! */
259:
260: if ((me->request->net == (HTNet *) NULL) || (me->reqStatus == HT_END || me->reqStatus == HT_ERR))
261: {
262: /* the socket is now being used by a different request, so the request has ended */
1.4 cvs 263: #ifdef WWW_XWINDOWS
1.7 cvs 264: if (THD_TRACE)
265: fprintf (stderr, "(BF) removing Xtinput %lu !RWE, sock %d (Request has ended)\n", *id, *s);
1.4 cvs 266: #endif
1.7 cvs 267: if ((me->mode & AMAYA_ASYNC) || (me->mode & AMAYA_IASYNC))
268: {
269: AHTPrintPendingRequestStatus (me->docid, YES);
270: AHTReqContext_delete (me);
271: }
272: else if (me->reqStatus != HT_END && HTError_hasSeverity (HTRequest_error (me->request), ERR_NON_FATAL))
1.4 cvs 273: me->reqStatus = HT_ERR;
1.7 cvs 274: return (0);
275: }
276: me->reqStatus = HT_WAITING;
277: return (0);
1.4 cvs 278: }
279:
280:
281: /*
282: * This function is called whenever a socket is available
283: * for a request. It the necessary events to the Xt
284: * A small interface to the HTLoadAnchor libwww function.
285: * It prepares Xt to handle the asynchronous data requests.
286: */
287:
288: #ifdef __STDC__
1.7 cvs 289: int Add_NewSocket_to_Loop (HTRequest * request, HTAlertOpcode op, int msgnum, const char *dfault, void *input, HTAlertPar * reply)
1.4 cvs 290: #else
1.7 cvs 291: int Add_NewSocket_to_Loop (request, op, msgnum, dfault, input, reply)
292: HTRequest *request;
293: HTAlertOpcode op;
294: int msgnum;
295: const char *dfault;
296: void *input;
297: HTAlertPar *reply;
298:
299: #endif /* __STDC__ */
1.4 cvs 300: {
1.7 cvs 301: SOCKET req_socket;
302: AHTReqContext *me = HTRequest_context (request);
1.4 cvs 303:
1.7 cvs 304: /* AmayaOpenRequests *reqState; */
1.4 cvs 305:
1.7 cvs 306: if (me->reqStatus == HT_NEW_PENDING)
307: {
308: /* we are opening a pending request */
309: if ((me->output = fopen (me->outputfile, "w")) == NULL)
310: {
311: me->outputfile[0] = '\0'; /* file could not be opened */
312: TtaSetStatus (me->docid, 1, TtaGetMessage (AMAYA, AM_CANNOT_CREATE_FILE),
313: me->outputfile);
314: me->reqStatus = HT_ERR;
315: return (HT_ERROR);
316: }
317: if (THD_TRACE)
318: fprintf (stderr, "Add_NewSocket_to_Loop: Activating pending %s . Open fd %d\n", me->urlName, (int) me->output);
319: HTRequest_setOutputStream (me->request,
320: AHTFWriter_new (me->request, me->output, YES));
321: }
1.4 cvs 322:
1.7 cvs 323: me->reqStatus = HT_WAITING;
1.4 cvs 324:
1.7 cvs 325: if (THD_TRACE)
326: fprintf (stderr, "(Activating a pending request\n");
1.4 cvs 327:
1.7 cvs 328: /* reusing this function to save on file descriptors */
1.4 cvs 329:
330:
1.7 cvs 331: return (HT_OK);
1.4 cvs 332:
333: /***
334: if(me->method == METHOD_PUT || me->method == METHOD_POST)
335: return (HT_OK);
336: ***/
337:
1.7 cvs 338: /* get the socket number associated to the request */
1.4 cvs 339:
1.7 cvs 340: req_socket = HTNet_socket (request->net);
341:
342: if (req_socket == INVSOC)
343: {
1.4 cvs 344: /* this should never be true */
345: return (HT_ERROR);
1.7 cvs 346: }
1.4 cvs 347:
1.7 cvs 348: /* add the input */
1.4 cvs 349:
350: #ifdef WWW_XWINDOWS
1.7 cvs 351: me->write_xtinput_id =
352: XtAppAddInput (app_cont, req_socket, (XtPointer) XtInputWriteMask,
1.4 cvs 353: (XtInputCallbackProc) AHTCallback_bridge, NULL);
1.7 cvs 354: if (THD_TRACE)
355: fprintf (stderr, "(BT) adding Xtinput %lu Socket %d W \n", me->write_xtinput_id, req_socket);
356:
357: if (me->write_xtinput_id == (XtInputId) NULL)
358: {
359: TtaSetStatus (me->docid, 1, TtaGetMessage (AMAYA, AM_XT_ERROR), me->urlName);
360:
361: /* I still need to add some error treatment here, to liberate memory */
362: return (HT_ERROR);
363: }
1.4 cvs 364:
365: #endif /* WWW_XWINDOWS */
1.7 cvs 366: /* To speed up the stop performances, we move the active requests to the top of the Amaya list */
1.4 cvs 367:
1.7 cvs 368: /*
369: reqState = DocRequestState(Amaya->open_requests, me->docid);
1.4 cvs 370:
1.7 cvs 371: if(reqState->counter > 1) {
1.4 cvs 372: HTList_removeObject (Amaya->reqlist, (void *) me);
373: HTList_addObject (Amaya->reqlist, (void *) me);
1.7 cvs 374: }
1.4 cvs 375: */
1.7 cvs 376: return (HT_OK);
1.4 cvs 377: }
378:
379:
380: /*
381: * This function is called whenever a socket is available
382: * for a request. It the necessary events to the Xt
383: * A small interface to the HTLoadAnchor libwww function.
384: * It prepares Xt to handle the asynchronous data requests.
385: */
386:
387: #ifdef __STDC__
1.7 cvs 388: int AHTEvent_register (SOCKET sock, HTRequest * rqp, SockOps ops, HTEventCallback * cbf, HTPriority p)
1.4 cvs 389: #else
1.7 cvs 390: int AHTEvent_register (sock, rqp, ops, cbf, p)
391: SOCKET sock;
392: HTRequest *rqp;
393: SockOps ops;
394: HTEventCallback *cbf;
395: HTPriority p;
396:
397: #endif /* __STDC__ */
1.4 cvs 398: {
1.7 cvs 399: AHTReqContext *me;
400: int status;
401:
402: if (sock == INVSOC)
1.4 cvs 403: return (0);
404:
1.7 cvs 405: /* get the request associated to the socket number */
406:
407: if ((status = HTEventrg_register (sock, rqp, ops,
408: cbf, p)) != HT_OK)
1.4 cvs 409: return (status);
410:
1.7 cvs 411: if (rqp)
412: {
1.4 cvs 413:
1.7 cvs 414: me = HTRequest_context (rqp);
1.4 cvs 415:
1.7 cvs 416: /* verify if we need to open the fd */
1.4 cvs 417:
1.7 cvs 418: if (me->reqStatus == HT_NEW_PENDING)
419: {
420: /* we are opening a pending request */
421: if ((me->output = fopen (me->outputfile, "w")) == NULL)
422: {
423: me->outputfile[0] = '\0'; /* file could not be opened */
424: TtaSetStatus (me->docid, 1, TtaGetMessage (AMAYA, AM_CANNOT_CREATE_FILE),
425: me->outputfile);
426: me->reqStatus = HT_ERR;
427: return (HT_ERROR);
428: }
429: HTRequest_setOutputStream (me->request,
430: AHTFWriter_new (me->request, me->output, YES));
431: me->reqStatus = HT_WAITING;
432:
433: if (THD_TRACE)
434: fprintf (stderr, "AHTEvent_register: Activating pending request url %s, fd %d\n", me->urlName, (int) me->output);
435: }
1.4 cvs 436:
1.7 cvs 437: if (THD_TRACE)
438: fprintf (stderr, "AHTEvent_register: url %s, sock %d, ops %lu \n",
439: me->urlName, sock, ops);
1.4 cvs 440:
1.7 cvs 441: /* add the input */
442: if (me->reqStatus == HT_NEW)
443: me->reqStatus = HT_WAITING;
444:
445: if (ops & ReadBits)
446: {
447: me->read_ops = ops;
448:
449: #ifdef WWW_XWINDOWS
450: if (me->read_xtinput_id)
451: XtRemoveInput (me->read_xtinput_id);
452: me->read_xtinput_id =
453: XtAppAddInput (app_cont,
454: sock,
455: (XtPointer) XtInputReadMask,
456: (XtInputCallbackProc) AHTCallback_bridge,
457: (XtPointer) XtInputReadMask);
458: if (THD_TRACE)
459: fprintf (stderr, "(BT) adding Xtinput %lu Socket %d R\n",
460: me->read_xtinput_id, sock);
461: #endif /* WWW_XWINDOWS */
462: }
463:
464: if (ops & WriteBits)
465: {
466: me->write_ops = ops;
467: #ifdef WWW_XWINDOWS
468: if (me->write_xtinput_id)
469: XtRemoveInput (me->write_xtinput_id);
470: me->write_xtinput_id = XtAppAddInput (app_cont, sock,
471: (XtPointer) XtInputWriteMask,
472: (XtInputCallbackProc) AHTCallback_bridge,
473: (XtPointer) XtInputWriteMask);
474: if (THD_TRACE)
475: fprintf (stderr, "(BT) adding Xtinput %lu Socket %d W\n",
476: me->write_xtinput_id, sock);
477: #endif /* WWW_XWINDOWS */
478: }
479:
480: if (ops & ExceptBits)
481: {
482: me->except_ops = ops;
483: #ifdef WWW_XWINDOWS
484: if (me->except_xtinput_id)
485: XtRemoveInput (me->except_xtinput_id);
486:
487: me->except_xtinput_id = XtAppAddInput (app_cont, sock,
488: (XtPointer) XtInputExceptMask,
489: (XtInputCallbackProc) AHTCallback_bridge,
490: (XtPointer) XtInputExceptMask);
491: if (THD_TRACE)
492: fprintf (stderr, "(BT) adding Xtinput %lu Socket %d E\n", me->except_xtinput_id, sock);
1.4 cvs 493: #endif /* WWW_XWINDOWS */
1.7 cvs 494: }
495: }
1.4 cvs 496:
497:
498:
499: #if 0
1.7 cvs 500: if (me->xtinput_id == (XtInputId) NULL)
501: {
502: TtaSetStatus (me->docid, 1, TtaGetMessage (AMAYA, AM_XT_ERROR), me->urlName);
503:
504: /* I still need to add some error treatment here, to liberate memory */
505: return (HT_ERROR);
506: }
1.4 cvs 507:
508: #endif
509:
1.7 cvs 510: return (status);
1.4 cvs 511: }
512:
513: #ifdef __STDC__
1.7 cvs 514: int AHTEvent_unregister (SOCKET sock, SockOps ops)
1.4 cvs 515: #else
1.7 cvs 516: int AHTEvent_unregister (sock, ops)
517: SOCKET sock;
518: SockOps ops;
519:
520: #endif /* __STDC__ */
1.4 cvs 521: {
1.7 cvs 522: int status;
523:
524: HTRequest *rqp = NULL;
525: AHTReqContext *me;
1.4 cvs 526:
527: /* Libwww 4.1 does not take into account the third parameter
1.7 cvs 528: ** for this function call */
1.4 cvs 529:
1.7 cvs 530: HTEventCallback *cbf = (HTEventCallback *) __RetrieveCBF (sock, (SockOps) NULL, &rqp);
1.4 cvs 531:
1.8 ! cvs 532: #ifdef WWW_XWINDOWS
1.7 cvs 533: if (cbf)
534: {
535: if (rqp)
536: {
537: me = HTRequest_context (rqp);
538:
539: if (ops & ReadBits)
540: RequestKillReadXtevent (me);
1.4 cvs 541:
1.7 cvs 542: if (ops & WriteBits)
543: RequestKillWriteXtevent (me);
544:
545: if (ops & ExceptBits)
546: RequestKillExceptXtevent (me);
547:
548:
549: }
550: }
551:
552: status = HTEventrg_unregister (sock, ops);
1.8 ! cvs 553: #endif /* WWW_XWINDOWS */
1.7 cvs 554: return (status);
1.4 cvs 555: }
556:
557: #ifdef __STDC__
1.7 cvs 558: void RequestKillAllXtevents (AHTReqContext * me)
1.4 cvs 559: #else
1.7 cvs 560: void RequestKillAllXtevents (me)
561: AHTReqContext *me;
562:
563: #endif /* __STDC__ */
1.4 cvs 564: {
565: #ifdef WWW_XWINDOWS
1.7 cvs 566: if (THD_TRACE)
567: fprintf (stderr, "Request_kill: Clearing Xtinputs\n");
1.4 cvs 568:
1.7 cvs 569: RequestKillReadXtevent (me);
570: RequestKillWriteXtevent (me);
571: RequestKillExceptXtevent (me);
1.4 cvs 572: #endif /* WWW_XWINDOWS */
573: }
574:
575: #ifdef __STDC__
1.7 cvs 576: static void RequestKillReadXtevent (AHTReqContext * me)
1.4 cvs 577: #else
1.7 cvs 578: static void RequestKillReadXtevent (me)
579: AHTReqContext *me;
580:
581: #endif /* __STDC__ */
1.4 cvs 582: {
583: #ifdef WWW_XWINDOWS
1.7 cvs 584: if (me->read_xtinput_id)
585: {
586: if (THD_TRACE)
587: fprintf (stderr, "Request_kill: Clearing Read Xtinputs%lu\n", me->read_xtinput_id);
588: XtRemoveInput (me->read_xtinput_id);
589: me->read_xtinput_id = (XtInputId) NULL;
590: }
1.4 cvs 591: #endif /* WWW_XWINDOWS */
592: }
593:
594: #ifdef __STDC__
1.7 cvs 595: static void RequestKillWriteXtevent (AHTReqContext * me)
1.4 cvs 596: #else
1.7 cvs 597: static void RequestKillWriteXtevent (me)
598: AHTReqContext *me;
599:
600: #endif /* __STDC__ */
1.4 cvs 601: {
602: #ifdef WWW_XWINDOWS
1.7 cvs 603: if (me->write_xtinput_id)
604: {
605: if (THD_TRACE)
606: fprintf (stderr, "Request_kill: Clearing Write Xtinputs %lu\n", me->write_xtinput_id);
607: XtRemoveInput (me->write_xtinput_id);
608: me->write_xtinput_id = (XtInputId) NULL;
609: }
1.4 cvs 610: #endif /* WWW_XWINDOWS */
611: }
612:
613: #ifdef __STDC__
1.7 cvs 614: static void RequestKillExceptXtevent (AHTReqContext * me)
1.4 cvs 615: #else
1.7 cvs 616: static void RequestKillExceptXtevent (me)
617: AHTReqContext *me;
618:
619: #endif /* __STDC__ */
1.4 cvs 620: {
621: #ifdef WWW_XWINDOWS
1.7 cvs 622: if (me->except_xtinput_id)
623: {
624: if (THD_TRACE)
625: fprintf (stderr, "Request_kill: Clearing Except Xtinputs %lu\n", me->except_xtinput_id);
626: XtRemoveInput (me->except_xtinput_id);
627: me->except_xtinput_id = (XtInputId) NULL;
628: }
1.4 cvs 629: #endif /* WWW_XWINDOWS */
630: }
Webmaster