Index: Library/Examples/Makefile.am
===================================================================
RCS file: /sources/public/libwww/Library/Examples/Makefile.am,v
retrieving revision 1.15
diff -r1.15 Makefile.am
5c5
< 	range tzcheck mget isredirected
---
> 	range tzcheck mget isredirected listen
Index: Library/src/HTAccess.c
===================================================================
RCS file: /sources/public/libwww/Library/src/HTAccess.c,v
retrieving revision 1.151
diff -r1.151 HTAccess.c
1757a1758,1786
> 
> /* ------------------------------------------------------------------------- */
> /*				SERVER METHODS 				     */
> /* ------------------------------------------------------------------------- */
> 
> PRIVATE BOOL launch_server (HTRequest * request, BOOL recursive)
> {
>     if (PROT_TRACE) {
> 	HTParentAnchor *anchor = HTRequest_anchor(request);
> 	char * full_address = HTAnchor_address((HTAnchor *) anchor);
> 	HTTrace("HTAccess.... Serving %s\n", full_address);
> 	HT_FREE(full_address);
>     }
>     return HTServe(request, recursive);
> }
> 
> /*	Serving a request
> **	-----------------
> **	Returns YES if request accepted, else NO
> */
> PUBLIC BOOL HTServeAbsolute (const char * url, HTRequest * request)
> {
>     if (url && request) {
> 	HTAnchor * anchor = HTAnchor_findAddress(url);
> 	HTRequest_setAnchor(request, anchor);
> 	return launch_server(request, NO);
>     }
>     return NO;
> }
Index: Library/src/HTAccess.html
===================================================================
RCS file: /sources/public/libwww/Library/src/HTAccess.html,v
retrieving revision 2.87
diff -r2.87 HTAccess.html
75a76,80
> Furthermore, it contains a <A HREF="#serve">few access methods for handling
> incoming requests</A> - in orther words acting as a server. Although libwww
> is primarily for clients, it is in fact symmetric in that it can handle both
> client requests and server requests.
> <P>
734a740,764
> </PRE>
> <H2>
>   Serve a Reqeust
> </H2>
> <P>
> Although libwww is primarily for clients, it is in fact symmetric in that
> it can handle both client requests and server requests. The way this is handled
> is that each <A HREF="HTProt.html">protocol</A> is registered with both a
> client handler and a server handler - depending on which type of request
> you use, one of them is called. Note that in order to be able to serve any
> document, there actually have to be a server handler. However, libwww only
> comes with a <A HREF="HTSocket.html">raw socket loader</A> which isn't much
> of a server. There is an <A HREF="HTTPServ.html">attempt of an HTTP server</A>
> but it is not complete
> <P>
> The protocol handler used to serve the request is determined by the URI -
> just as for client side requests. That is, libwww can in fact simultaneously
> be the server for multiple protocols if you really want to. Examples of URIs
> that you can use are <TT>noop://localhost:8888</TT> which means that libwww
> starts listening on port 8888 (see the <A HREF="../Examples/listen.c">listen
> example</A> for details). Other examples are <TT>http://localhost:7777</TT>
> which means that it listens for HTTP on port 7777. Again, there is no HTTP
> server in libwww - this is just an example.
> <PRE>
> extern BOOL HTServeAbsolute (const char * address, HTRequest * request);
Index: Library/src/HTHost.c
===================================================================
RCS file: /sources/public/libwww/Library/src/HTHost.c,v
retrieving revision 2.53
diff -r2.53 HTHost.c
1281a1282,1338
> PUBLIC int HTHost_accept (HTHost * host, HTNet * net, HTNet ** accepted,
> 			  char * url, HTProtocolId port)
> {
>     HTRequest * request = HTNet_request(net);
>     int status = HT_OK;
>     if (!host) {
> 	HTProtocol * protocol = HTNet_protocol(net);
> 	if ((host = HTHost_newWParse(request, url, HTProtocol_id(protocol))) == NULL)
> 	    return HT_ERROR;
> 	else {
> 	    SockA *sin = &host->sock_addr;
> 	    sin->sin_addr.s_addr = INADDR_ANY;
> 	}
> 
> 	/*
> 	** If not already locked and without a channel
> 	** then lock the darn thing
> 	*/
> 	if (!host->lock && !host->channel) {
> 	    host->forceWriteFlush = YES;
> 	    host->lock = net;
> 	}
> 	HTNet_setHost(net, host);
> 
> 	/*
> 	** Start listening on the socket
> 	*/
> 	{
> 	    status = HTDoListen(net, port, INVSOC, HT_BACKLOG);
> 	    if (status != HT_OK) {
> 		if (CORE_TRACE) HTTrace("Listen...... On Host %p resulted in %d\n", host, status);
> 		return HT_ERROR;
> 	    }
> 	}
>     }
> 
>     if (!host->lock || (host->lock && host->lock == net)) {
> 	status = HTDoAccept(net, accepted);
> 	if (status == HT_OK) {
> 
> 	    /* Add the new accepted Net object to the pipeline */
> 	    HTList_appendObject(host->pipeline, *accepted);
> 
> 	    /* Unlock the accept object */
> 	    host->lock = NULL;
> 
> 	    return HT_OK;
> 	}
> 	if (status == HT_WOULD_BLOCK) {
> 	    host->lock = net;
> 	    return status;
> 	}
> 	if (status == HT_PENDING) return HT_WOULD_BLOCK;
>     }
>     return HT_ERROR; /* @@@ - some more deletion and stuff here? */
> }
> 
Index: Library/src/HTHost.html
===================================================================
RCS file: /sources/public/libwww/Library/src/HTHost.html,v
retrieving revision 2.24
diff -r2.24 HTHost.html
213a214,216
> 
> extern int HTHost_accept  (HTHost * host, HTNet * net, HTNet ** accepted,
> 	                   char * url, HTProtocolId port);
Index: Library/src/HTNet.c
===================================================================
RCS file: /sources/public/libwww/Library/src/HTNet.c,v
retrieving revision 2.97
diff -r2.97 HTNet.c
600,601c600
< 
< PUBLIC BOOL HTNet_newServer (HTRequest * request, HTNet * net, char * access)
---
> PUBLIC BOOL HTNet_newServer (HTRequest * request)
602a602,603
>     HTParentAnchor * anchor = HTRequest_anchor(request);
>     HTNet * me = NULL;
604a606,607
>     char * physical = NULL;
>     int status;
605a609
> 
608,609c612,620
<     /* Find a protocol object for this access scheme */
<     protocol = HTProtocol_find(request, access);
---
>     /*
>     ** First we do all the "BEFORE" callbacks in order to see if we are to
>     ** continue with this request or not. If we receive a callback status
>     ** that is NOT HT_OK then jump directly to the after callbacks and return
>     */
>     if ((status = HTNet_executeBeforeAll(request)) != HT_OK) {
> 	HTNet_executeAfterAll(request, status);
> 	return YES;
>     }
611,616c622,631
<     /* added - JTD:5/28/96 */
<     /* Find a transport object for this protocol */
<     tp = HTTransport_find(request, HTProtocol_transport(protocol));
<     if (tp == NULL) {
<         if (CORE_TRACE) HTTrace("Net Object.. NO TRANSPORT OBJECT\n");
<         return NO;
---
>     /*
>     ** If no translation was provided by the filters then use the anchor
>     ** address directly
>     */
>     if (!(physical = HTAnchor_physical(anchor))) {
> 	char * addr = HTAnchor_address((HTAnchor *) anchor);
> 	if (CORE_TRACE) HTTrace("Net Object.. Using default address\n");
> 	HTAnchor_setPhysical(anchor, addr);
> 	physical = HTAnchor_physical(anchor);
> 	HT_FREE(addr);
618d632
<     /* end of additions - JTD:5/28/96 */
620,630c634,653
<     /* Fill out the net object and bind it to the request object */
<     net->preemptive = (HTProtocol_preemptive(protocol) || HTRequest_preemptive(request));
< #if 0
<     net->protocol = protocol;
<     net->transport = tp; 		/* added - JTD:5/28/96 */
< #endif
<     net->event.priority = HTRequest_priority(request);
<     net->request = request;
<     HTRequest_setNet(request, net);
<     if (!(cbf = HTProtocol_server(protocol))) {
<         if (CORE_TRACE) HTTrace("Net Object.. NO CALL BACK FUNCTION!\n");
---
>     /* Find a protocol object for this access scheme */
>     {
> 	char * access = HTParse(physical, "", PARSE_ACCESS);      
> 	if ((protocol = HTProtocol_find(request, access)) == NULL) {
> 	    if (CORE_TRACE) HTTrace("Net Object.. NO PROTOCOL Object found for URI scheme `%s\'\n", access);
> 	    HT_FREE(access);
> 	    return NO;
> 	}
> 	if (!(cbf = HTProtocol_server(protocol))) {
> 	    if (CORE_TRACE) HTTrace("Net Object.. NO SERVER HANDLER for URI scheme `%s\'\n", access);
> 	    HT_FREE(access);
> 	    HT_FREE(me);
> 	    return NO;
> 	}
> 	HT_FREE(access);
>     }
> 
>     /* Find a transport object for this protocol */
>     if ((tp = HTTransport_find(request, HTProtocol_transport(protocol))) == NULL) {
>         if (CORE_TRACE) HTTrace("Net Object.. NO TRANSPORT found for protocol `%s\'\n", HTProtocol_name(protocol));
634,635c657,664
<     /* Increase the number of retrys for this download */
<     HTRequest_addRetry(request);
---
>     /* Create new net object and bind to request object */
>     if ((me = create_object()) == NULL) return NO;
>     me->preemptive = (HTProtocol_preemptive(protocol) || HTRequest_preemptive(request));
>     HTNet_setEventPriority(me, HTRequest_priority(request));
>     me->protocol = protocol;
>     me->transport = tp; 		/* added - JTD:5/28/96 */
>     me->request = request;
>     HTRequest_setNet(request, me);
639,640c668,669
<         HTTrace("Net Object.. starting SERVER request %p with net object %p\n", request, net);
<     (*(cbf))(HTNet_socket(net), request);
---
>         HTTrace("Net Object.. starting SERVER request %p and net object %p\n", request, me);
>     (*(cbf))(INVSOC, request);
662a692
> 
690c720
< 	    if (CORE_TRACE) HTTrace("Net Object.. NO PROTOCOL OBJECT\n");
---
> 	    if (CORE_TRACE) HTTrace("Net Object.. NO PROTOCOL Object found for URI scheme `%s\'\n", access);
693a724,729
> 	if (!(cbf = HTProtocol_client(protocol))) {
> 	    if (CORE_TRACE) HTTrace("Net Object.. NO CLIENT HANDLER for URI scheme `%s\'\n", access);
> 	    HT_FREE(access);
> 	    HT_FREE(me);
> 	    return NO;
> 	}
700c736
< 	if (CORE_TRACE) HTTrace("Net Object.. NO TRANSPORT OBJECT\n");
---
> 	if (CORE_TRACE) HTTrace("Net Object.. NO TRANSPORT found for protocol `%s\'\n", HTProtocol_name(protocol));
715,719d750
<     if (!(cbf = HTProtocol_client(protocol))) {
< 	if (CORE_TRACE) HTTrace("Net Object.. NO CALL BACK FUNCTION!\n");
< 	HT_FREE(me);
< 	return NO;
<     }
842a874,878
> }
> 
> PUBLIC BOOL HTNet_deleteDup (HTNet * dup)
> {
>     return dup ? remove_net(dup) : NO;
Index: Library/src/HTNet.html
===================================================================
RCS file: /sources/public/libwww/Library/src/HTNet.html,v
retrieving revision 2.54
diff -r2.54 HTNet.html
409c409
< extern BOOL HTNet_newServer (HTRequest * request, HTNet * net, char *access);
---
> extern BOOL HTNet_newServer (HTRequest * request);
423a424
> extern BOOL HTNet_deleteDup (HTNet * dup);
Index: Library/src/HTProt.c
===================================================================
RCS file: /sources/public/libwww/Library/src/HTProt.c,v
retrieving revision 2.18
diff -r2.18 HTProt.c
151c151
<     if (request && access) {
---
>     if (access) {
159,160c159,161
< 	HTRequest_addError(request, ERR_FATAL, NO, HTERR_CLASS, (char*) access,
< 			   (int) strlen(access), "HTProtocol_find");
---
> 	if (request)
> 	    HTRequest_addError(request, ERR_FATAL, NO, HTERR_CLASS, (char*) access,
> 			       (int) strlen(access), "HTProtocol_find");
186a188,191
> PUBLIC const char * HTProtocol_name (HTProtocol * protocol)
> {
>     return (protocol ? protocol->name : NULL);
> }
Index: Library/src/HTProt.html
===================================================================
RCS file: /sources/public/libwww/Library/src/HTProt.html,v
retrieving revision 2.23
diff -r2.23 HTProt.html
127a128,135
>   Get the Protocol Name
> </H3>
> <P>
> Get the protocol name that was registered when the protocol object was created
> <PRE>
> extern const char * HTProtocol_name (HTProtocol * protocol);
> </PRE>
> <H3>
Index: Library/src/HTReq.html
===================================================================
RCS file: /sources/public/libwww/Library/src/HTReq.html,v
retrieving revision 2.64
diff -r2.64 HTReq.html
80,84c80,87
< This is the "<I>basic request issue method</I>" provided by the Request class.
< This is a very low level API as the caller must have set up the request object
< before passing it to the Library. You can find many higher level issuing
< functions in the <A HREF="HTAccess.html">HTAccess module</A>. If you like,
< you can of course use this directly!
---
> These are the "<I>basic request methods</I>" provided directly by the Request
> class. This is a very low level API as the caller must have set up the request
> object before passing it to libwww. There are two versions: one for issuing
> client requests and one for issuing server requests. You will probably most
> often use the client version but libwww can in fact also deal with incoming
> connections. You can find many higher level issuing functions in the
> <A HREF="HTAccess.html">HTAccess module</A>. If you like, you can of course
> use this directly!
86a90
> extern BOOL HTServe(HTRequest * request, BOOL recursive);
Index: Library/src/HTReqMan.c
===================================================================
RCS file: /sources/public/libwww/Library/src/HTReqMan.c,v
retrieving revision 2.73
diff -r2.73 HTReqMan.c
1630a1631,1655
> PUBLIC BOOL HTServe (HTRequest * me, BOOL recursive)
> {
>     if (!me || !me->anchor) {
>         if (CORE_TRACE) HTTrace("Serve Start. Bad argument\n");
>         return NO;
>     }
> 
>     /* Make sure that we don't carry over any old physical address */
>     if (!recursive) HTAnchor_clearPhysical(me->anchor);
> 
>     /* Should we keep the error stack or not? */
>     if (!recursive && me->error_stack) {
> 	HTError_deleteAll(me->error_stack);
> 	me->error_stack = NULL;
>     }
> 
>     /* Delete any old Response Object */
>     if (me->response) {
> 	HTResponse_delete(me->response);
> 	me->response = NULL;
>     }
> 
>     /* Now start the Net Manager */
>     return HTNet_newServer(me);
> }
Index: Library/src/HTSocket.c
===================================================================
RCS file: /sources/public/libwww/Library/src/HTSocket.c,v
retrieving revision 2.32
diff -r2.32 HTSocket.c
20a21,41
> #ifndef RAW_PORT
> #define RAW_PORT 1024
> #endif
> 
> /* Final states have negative value */
> typedef enum _RAWState {
>     RAW_ERROR		= -2,
>     RAW_OK		= -1,
>     RAW_BEGIN		= 0,
>     RAW_NEED_STREAM,
>     RAW_READ
> } RawState;
> 
> /* This is the context structure for the this module */
> typedef struct _raw_info {
>     RawState		state;		  /* Current State of the connection */
>     HTNet *		listen;
>     HTNet *		accepted;
>     HTRequest *		request;
> } raw_info;
> 
30a52,81
> PRIVATE int RawCleanup (HTRequest * request, int status)
> {
>     HTNet * listen = HTRequest_net(request);
>     raw_info * raw = (raw_info *) HTNet_context(listen);
> 
>     if (PROT_TRACE)
> 	HTTrace("Raw clean... Called with status %d, net %p\n", status, raw->accepted);
> 
>     if (status == HT_INTERRUPTED) {
>     	HTAlertCallback * cbf = HTAlert_find(HT_PROG_INTERRUPT);
>     	if (cbf) (*cbf)(request, HT_PROG_INTERRUPT,
> 	    HT_MSG_NULL, NULL, NULL, NULL);
>     } else if (status == HT_TIMEOUT) {
>     	HTAlertCallback * cbf = HTAlert_find(HT_PROG_TIMEOUT);
>     	if (cbf) (*cbf)(request, HT_PROG_TIMEOUT,
> 	    HT_MSG_NULL, NULL, NULL, NULL);
>     }	
> 
>     /* Delete both of the Net objects */
>     if (raw->accepted) {
> 	HTNet_deleteDup(listen);
> 	HTNet_delete(raw->accepted, status);
>     } else {
> 	HTNet_delete(listen, HT_ERROR);
>     }
> 
>     HT_FREE(raw);
>     return YES;
> }
> 
44a96
>     raw_info * raw;			    /* Specific protocol information */
46,61c98,104
<     if (soc==INVSOC) {
< 	if (PROT_TRACE) HTTrace("Load Socket. invalid socket\n");
< 	return HT_ERROR;
<     }
<     if (PROT_TRACE) HTTrace("Load Socket. Loading socket %d\n",soc);
< 
<     /* 
<     ** Create the stream pipe FROM the channel to the application.
<     ** The target for the input stream pipe is set up using the
<     ** stream stack.
<     */
<     {
< 	net->readStream = HTRequest_outputStream(request);
< 	if (!net->readStream) net->readStream = HTErrorStream();
< 	HTRequest_setOutputConnected(request, YES);
<     }
---
>     if (PROT_TRACE) HTTrace("Load socket. Setting up socket for accept\n");
>     if ((raw = (raw_info *) HT_CALLOC(1, sizeof(raw_info))) == NULL)
>       HT_OUTOFMEM("HTLoadSocket");
>     raw->state = RAW_BEGIN;
>     raw->listen = net;
>     raw->request = request;
>     HTNet_setContext(net, raw);
63c106
<     HTNet_setEventParam(net, net);  /* callbacks get http* */
---
>     HTNet_setEventParam(net, raw);
65c108,109
<     return SocketEvent(soc, net, HTEvent_BEGIN);		/* get it started - ops is ignored */
---
>     /* Get it started - ops is ignored */
>     return SocketEvent(soc, raw, HTEvent_BEGIN);
70,72c114,135
<     HTNet * net = (HTNet *)pVoid;
<     if (type == HTEvent_CLOSE) {			      /* Interrupted */
< 	HTNet_delete(net, HT_INTERRUPTED);
---
>     raw_info * raw = (raw_info *)pVoid;
>     int status = HT_ERROR;
>     HTNet * listen = raw->listen;
>     HTRequest * request = HTNet_request(listen);
>     HTParentAnchor * anchor = HTRequest_anchor(request);
>     HTHost * host = HTNet_host(listen);
> 
>     /*
>     **  Check whether we have been interrupted or timed out
>     */
>     if (type == HTEvent_BEGIN) {
> 	raw->state = RAW_BEGIN;
>     } else if (type == HTEvent_CLOSE) {			      /* Interrupted */
> 	RawCleanup(request, HT_INTERRUPTED);
> 	return HT_OK;
>     } else if (type == HTEvent_TIMEOUT) {
> 	HTRequest_addError(request, ERR_FATAL, NO, HTERR_TIME_OUT,
> 			   NULL, 0, "HTLoadSocket");
> 	RawCleanup(request, HT_TIMEOUT);
> 	return HT_OK;
>     } else if (type == HTEvent_END) {
> 	RawCleanup(request, HT_OK);
75,79c138,194
< 
<     /* In this load function we only have one state: READ */
<     {
< 	int status = HTHost_read(net->host, net);
< 	if (PROT_TRACE) HTTrace("Load Socket. Read returns %d\n", status);
---
> 	
>     /* Now jump into the state machine */
>     while (1) {
> 	switch(raw->state) {
> 	case RAW_BEGIN:
> 	    status = HTHost_accept(host, listen, &raw->accepted, HTAnchor_physical(anchor), RAW_PORT);
> 	    host = HTNet_host(listen);
>             if (status == HT_OK) {
> 		raw->state = RAW_NEED_STREAM;
> 	    } else if (status == HT_WOULD_BLOCK || status == HT_PENDING) {
> 		return HT_OK;
> 	    } else	
> 		raw->state = RAW_ERROR;	       /* Error or interrupt */
> 	    break;
> 
> 	case RAW_NEED_STREAM:
> 	{
> 	    /* 
> 	    ** Create the stream pipe FROM the channel to the application.
> 	    ** The target for the input stream pipe is set up using the
> 	    ** stream stack.
> 	    */
>             HTStream * in_stream =
> 		HTStreamStack(WWW_RAW,
> 			      HTRequest_outputFormat(request),
> 			      HTRequest_outputStream(request),
> 			      request, YES);
> 	    HTNet_setReadStream(raw->accepted, in_stream);
>             HTRequest_setOutputConnected(request, YES);
> 
> 	    raw->state = RAW_READ;
> 	    break;
> 	}
> 
> 	case RAW_READ:
> 	    status = HTHost_read(host, raw->accepted);
> 	    if (status == HT_WOULD_BLOCK)
> 		return HT_OK;
> 	    else if (status==HT_CLOSED)
> 		raw->state = RAW_OK;
> 	    else 
> 		raw->state = RAW_ERROR;
> 	    break;
> 
> 	case RAW_OK:
> 	    RawCleanup(request, HT_OK);
> 	    return HT_OK;
> 	    break;
> 
> 	case RAW_ERROR:
> 	    RawCleanup(request, HT_ERROR);
> 	    return HT_OK;
> 	    break;
> 
> 	default:
> 	    HTDebugBreak(__FILE__, __LINE__, "Bad raw state %d\n", raw->state);
> 	}
Index: Library/src/HTTCP.c
===================================================================
RCS file: /sources/public/libwww/Library/src/HTTCP.c,v
retrieving revision 2.110
diff -r2.110 HTTCP.c
412d411
< 
414a414
>     HTHost * me = HTNet_host(net);
435c435
< 	    HTEvent_register(HTNet_socket(net), HTEvent_ACCEPT, &net->event);
---
> 	    HTHost_register(me, net, HTEvent_ACCEPT);
455,460d454
<     /* Create a channel for the new socket */
<     {
< 	HTHost * host = (*accepted)->host;
< 	HTChannel * ch = HTChannel_new(HTNet_socket(*accepted), NULL, NO);
< 	HTHost_setChannel(host, ch);
<     }
475c469,473
<     int status;
---
>     HTHost * me = HTNet_host(net);
>     HTRequest * request = HTNet_request(net);
>     int preemptive = net->preemptive;
>     int status = HT_OK;
>     char * hostname = HTHost_name(me);
479,500c477,516
< 	switch (net->host->tcpstate) {
< 	  case TCP_BEGIN:
< 	    {
< 		SockA *sin = &net->host->sock_addr;
< 		memset((void *) sin, '\0', sizeof(SockA));
< #ifdef DECNET
< 		sin->sdn_family = AF_DECnet;
< 		sin->sdn_objnum = port;
< #else
< 		sin->sin_family = AF_INET;
< 		if (master != INVSOC) {
< 		    int len = sizeof(SockA);
< 		    if (getsockname(master, (struct sockaddr *) sin, &len)<0) {
< 			HTRequest_addSystemError(net->request, ERR_FATAL,
< 						 socerrno, NO, "getsockname");
< 			net->host->tcpstate = TCP_ERROR;
< 			break;
< 		    }
< 		} else
< 		    sin->sin_addr.s_addr = INADDR_ANY;
< 		sin->sin_port = htons(port);
< #endif
---
> 	switch (me->tcpstate) {
> 	case TCP_BEGIN:
> 	{
> 	    /*
> 	    ** Add the net object to the host object found above. If the
> 	    ** host is idle then we can start the request right away,
> 	    ** otherwise we must wait until it is free. 
> 	    */
> 	    if ((status = HTHost_addNet(net->host, net)) == HT_PENDING)
> 		if (PROT_TRACE) HTTrace("HTDoListen.. Pending...\n");
> 
> 	    /*
> 	    ** If we are pending then return here, otherwise go to next state
> 	    ** which is setting up a channel
> 	    */
> 	    me->tcpstate = TCP_CHANNEL;
> 	    if (PROT_TRACE) HTTrace("HTHost %p going to state TCP_CHANNEL.\n", me);
> 	    if (status == HT_PENDING) return HT_PENDING;
> 	}
> 	break;
> 
> 	case TCP_CHANNEL:
> 	    /*
> 	    **  The next state depends on whether we have a connection or not.
> 	    */
> 	    if (HTHost_channel(me) == NULL) {
> 		me->tcpstate = TCP_NEED_SOCKET;
> 		if (PROT_TRACE) HTTrace("HTHost %p going to state TCP_SOCKET.\n", me);
> 	    } else {
> 
> 		/*
> 		**  There is now one more using the channel
> 		*/
> 		HTChannel_upSemaphore(me->channel);
> 
> 		/*
> 		**  We are now all set and can jump to connected mode
> 		*/
> 		me->tcpstate = TCP_CONNECTED;
> 		if (PROT_TRACE) HTTrace("HTHost %p going to state TCP_CONNECTED.\n", me);
502,504c518
< 	    if (PROT_TRACE)
< 		HTTrace("Socket...... Listen on port %d\n", port);
< 	    net->host->tcpstate = TCP_NEED_SOCKET;
---
> 	    hostname = HTHost_name(me);
507,511c521,523
< 	  case TCP_NEED_SOCKET:
< 	    if (_makeSocket(net->host, net->request, net->preemptive, net->transport) == -1)
< 	        break;
< 	    net->host->tcpstate = TCP_NEED_BIND;
< 	    break;
---
> 	case TCP_NEED_SOCKET:
> 	    if (_makeSocket(me, request, preemptive, net->transport) == -1)
> 		break;
513,516c525
< 	  case TCP_NEED_BIND:
< 	    status = bind(HTNet_socket(net), (struct sockaddr *) &net->host->sock_addr,
< 			  sizeof(net->host->sock_addr));
< 	    if (NETCALL_ERROR(status))
---
> 	    /* Progress */
518,522c527,545
< 		if (PROT_TRACE)
< 		    HTTrace("Socket...... Bind failed %d\n", socerrno);
< 		net->host->tcpstate = TCP_ERROR;		
< 	    } else
< 		net->host->tcpstate = TCP_NEED_LISTEN;
---
> 		HTAlertCallback *cbf = HTAlert_find(HT_PROG_ACCEPT);
> 		if (cbf) (*cbf)(request, HT_PROG_ACCEPT, HT_MSG_NULL,
> 				NULL, hostname, NULL);
> 	    }
> 	    me->tcpstate = TCP_NEED_BIND;
> 	    if (PROT_TRACE) HTTrace("HTHost %p going to state TCP_NEED_BIND\n", me);
> 	    break;
> 
> 	case TCP_NEED_BIND:
> 	    if (PROT_TRACE) HTTrace("Socket...... Binding socket %d\n", HTNet_socket(net));
> 	    status = bind(HTNet_socket(net), (struct sockaddr *) &me->sock_addr,
> 			  sizeof(me->sock_addr));
> 	    if (NETCALL_ERROR(status)) {
> 		if (PROT_TRACE) HTTrace("Socket...... Bind failed %d\n", socerrno);
> 		me->tcpstate = TCP_ERROR;		
> 	    } else {
> 		if (PROT_TRACE) HTTrace("Socket...... Starting listening on socket %d\n", HTNet_socket(net));
> 		me->tcpstate = TCP_NEED_LISTEN;
> 	    }
525c548
< 	  case TCP_NEED_LISTEN:
---
> 	case TCP_NEED_LISTEN:
528c551
< 		net->host->tcpstate = TCP_ERROR;		
---
> 		me->tcpstate = TCP_ERROR;		
530c553
< 		net->host->tcpstate = TCP_CONNECTED;
---
> 		me->tcpstate = TCP_CONNECTED;
533,538c556,560
< 	  case TCP_CONNECTED:
< 	    net->host->tcpstate = TCP_BEGIN;
< 	    if (PROT_TRACE)
< 		HTTrace("Socket...... Bind and listen on port %d %s\n",
< 			(int) ntohs(net->host->sock_addr.sin_port),
< 			HTInetString(&net->host->sock_addr));
---
> 	case TCP_CONNECTED:
> 	    HTHost_unregister(me, net, HTEvent_ACCEPT);
> 	    HTHost_setRetry(me, 0);
> 	    me->tcpstate = TCP_IN_USE;
> 	    if (PROT_TRACE) HTTrace("HTHost %p listening.\n", me);
542,550c564,593
< 	  case TCP_CHANNEL:
< 	  case TCP_NEED_CONNECT:
< 	  case TCP_IN_USE:
< 	  case TCP_DNS:
< 	  case TCP_DNS_ERROR:
< 	  case TCP_ERROR:
< 	    if (PROT_TRACE) HTTrace("Socket...... Listen failed\n");
< 	    HTRequest_addSystemError(net->request, ERR_FATAL, socerrno, NO, "HTDoListen");
< 	    net->host->tcpstate = TCP_BEGIN;
---
> 	    /* once a host is connected, subsequent connections are immediately OK */
> 	case TCP_IN_USE:
> 	    if ((status = HTHost_addNet(net->host, net)) == HT_PENDING) {
> 		if (PROT_TRACE) HTTrace("HTDoListen.. Pending...\n");
> 		return HT_PENDING;
> 	    }
> 
> 	    HTChannel_upSemaphore(me->channel);
> 	    return HT_OK;
> 
> 	case TCP_NEED_CONNECT:
> 	case TCP_DNS:
> 	case TCP_DNS_ERROR:
> 	case TCP_ERROR:
> 	    if (HTChannel_socket(me->channel) != INVSOC) {
> 		NETCLOSE(HTChannel_socket(me->channel));
> #if 1 /* @@@ */
> 		if (HTHost_isPersistent(me)) {	 /* Inherited socket */
> 		    HTHost_setPersistent(me, NO, HT_TP_SINGLE);
> 		    me->tcpstate = TCP_NEED_SOCKET;
> 		    if (PROT_TRACE) HTTrace("HTHost %p going to state TCP_NEED_SOCKET.\n", me);
> 		    break;
> 		}
> #endif
> 	    }
> 
> 	    HTRequest_addSystemError(request, ERR_FATAL, socerrno, NO, "accept");
> 	    HTHost_setRetry(me, 0);
> 	    me->tcpstate = TCP_BEGIN;
> 	    if (PROT_TRACE) HTTrace("HTHost %p going to state TCP_BEGIN.\n", me);
Index: Library/src/HTTrans.c
===================================================================
RCS file: /sources/public/libwww/Library/src/HTTrans.c,v
retrieving revision 2.5
diff -r2.5 HTTrans.c
95c95
<     if (request && name) {
---
>     if (name) {
103,104c103,105
< 	HTRequest_addError(request, ERR_FATAL, NO, HTERR_CLASS, (char *) name,
< 			   (int) strlen(name), "HTTransport_find");
---
> 	if (request)
> 	    HTRequest_addError(request, ERR_FATAL, NO, HTERR_CLASS, (char *) name,
> 			       (int) strlen(name), "HTTransport_find");

