Blame src/misc.c

Packit e18bd3
/******************************************************************************
Packit e18bd3
Packit e18bd3
Packit e18bd3
Copyright 1993, 1998  The Open Group
Packit e18bd3
Packit e18bd3
Permission to use, copy, modify, distribute, and sell this software and its
Packit e18bd3
documentation for any purpose is hereby granted without fee, provided that
Packit e18bd3
the above copyright notice appear in all copies and that both that
Packit e18bd3
copyright notice and this permission notice appear in supporting
Packit e18bd3
documentation.
Packit e18bd3
Packit e18bd3
The above copyright notice and this permission notice shall be included in
Packit e18bd3
all copies or substantial portions of the Software.
Packit e18bd3
Packit e18bd3
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
Packit e18bd3
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
Packit e18bd3
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
Packit e18bd3
OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
Packit e18bd3
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
Packit e18bd3
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Packit e18bd3
Packit e18bd3
Except as contained in this notice, the name of The Open Group shall not be
Packit e18bd3
used in advertising or otherwise to promote the sale, use or other dealings
Packit e18bd3
in this Software without prior written authorization from The Open Group.
Packit e18bd3
Packit e18bd3
Author: Ralph Mor, X Consortium
Packit e18bd3
******************************************************************************/
Packit e18bd3
Packit e18bd3
#ifdef WIN32
Packit e18bd3
#define _WILLWINSOCK_
Packit e18bd3
#endif
Packit e18bd3
#ifdef HAVE_CONFIG_H
Packit e18bd3
#include <config.h>
Packit e18bd3
#endif
Packit e18bd3
#include <X11/ICE/ICElib.h>
Packit e18bd3
#include "ICElibint.h"
Packit e18bd3
#include <X11/Xtrans/Xtrans.h>
Packit e18bd3
#include <stdio.h>
Packit e18bd3
#ifdef WIN32
Packit e18bd3
#include <X11/Xwinsock.h>
Packit e18bd3
#include <X11/Xw32defs.h>
Packit e18bd3
#endif
Packit e18bd3
Packit e18bd3

Packit e18bd3
/*
Packit e18bd3
 * scratch buffer
Packit e18bd3
 */
Packit e18bd3
Packit e18bd3
char *
Packit e18bd3
IceAllocScratch (
Packit e18bd3
	IceConn		iceConn,
Packit e18bd3
	unsigned long	size
Packit e18bd3
)
Packit e18bd3
{
Packit e18bd3
    if (!iceConn->scratch || size > iceConn->scratch_size)
Packit e18bd3
    {
Packit e18bd3
	if (iceConn->scratch)
Packit e18bd3
	    free (iceConn->scratch);
Packit e18bd3
Packit e18bd3
	iceConn->scratch = malloc (size);
Packit e18bd3
	iceConn->scratch_size = size;
Packit e18bd3
    }
Packit e18bd3
Packit e18bd3
    return (iceConn->scratch);
Packit e18bd3
}
Packit e18bd3
Packit e18bd3
Packit e18bd3

Packit e18bd3
/*
Packit e18bd3
 * Output/Input buffer functions
Packit e18bd3
 */
Packit e18bd3
Packit e18bd3
int
Packit e18bd3
IceFlush (
Packit e18bd3
	IceConn iceConn
Packit e18bd3
)
Packit e18bd3
{
Packit e18bd3
    _IceWrite (iceConn,
Packit e18bd3
	(unsigned long) (iceConn->outbufptr - iceConn->outbuf),
Packit e18bd3
	iceConn->outbuf);
Packit e18bd3
Packit e18bd3
    iceConn->outbufptr = iceConn->outbuf;
Packit e18bd3
    return 1;
Packit e18bd3
}
Packit e18bd3
Packit e18bd3
Packit e18bd3
int
Packit e18bd3
IceGetOutBufSize (
Packit e18bd3
	IceConn iceConn
Packit e18bd3
)
Packit e18bd3
{
Packit e18bd3
    return (iceConn->outbufmax - iceConn->outbuf);
Packit e18bd3
}
Packit e18bd3
Packit e18bd3
Packit e18bd3
int
Packit e18bd3
IceGetInBufSize (
Packit e18bd3
	IceConn iceConn
Packit e18bd3
)
Packit e18bd3
{
Packit e18bd3
    return (iceConn->inbufmax - iceConn->inbuf);
Packit e18bd3
}
Packit e18bd3
Packit e18bd3
Packit e18bd3

Packit e18bd3
/*
Packit e18bd3
 * informational functions
Packit e18bd3
 */
Packit e18bd3
Packit e18bd3
IceConnectStatus
Packit e18bd3
IceConnectionStatus (
Packit e18bd3
	IceConn iceConn
Packit e18bd3
)
Packit e18bd3
{
Packit e18bd3
    return (iceConn->connection_status);
Packit e18bd3
}
Packit e18bd3
Packit e18bd3
Packit e18bd3
char *
Packit e18bd3
IceVendor (
Packit e18bd3
	IceConn iceConn
Packit e18bd3
)
Packit e18bd3
{
Packit e18bd3
    return strdup(iceConn->vendor);
Packit e18bd3
}
Packit e18bd3
Packit e18bd3
Packit e18bd3
char *
Packit e18bd3
IceRelease (
Packit e18bd3
	IceConn iceConn
Packit e18bd3
)
Packit e18bd3
{
Packit e18bd3
    return strdup(iceConn->release);
Packit e18bd3
}
Packit e18bd3
Packit e18bd3
Packit e18bd3
int
Packit e18bd3
IceProtocolVersion (
Packit e18bd3
	IceConn iceConn
Packit e18bd3
)
Packit e18bd3
{
Packit e18bd3
    return (_IceVersions[iceConn->my_ice_version_index].major_version);
Packit e18bd3
}
Packit e18bd3
Packit e18bd3
Packit e18bd3
int
Packit e18bd3
IceProtocolRevision (
Packit e18bd3
	IceConn iceConn
Packit e18bd3
)
Packit e18bd3
{
Packit e18bd3
    return (_IceVersions[iceConn->my_ice_version_index].minor_version);
Packit e18bd3
}
Packit e18bd3
Packit e18bd3
Packit e18bd3
int
Packit e18bd3
IceConnectionNumber (
Packit e18bd3
	IceConn iceConn
Packit e18bd3
)
Packit e18bd3
{
Packit e18bd3
    return (_IceTransGetConnectionNumber (iceConn->trans_conn));
Packit e18bd3
}
Packit e18bd3
Packit e18bd3
Packit e18bd3
char *
Packit e18bd3
IceConnectionString (
Packit e18bd3
	IceConn iceConn
Packit e18bd3
)
Packit e18bd3
{
Packit e18bd3
    if (iceConn->connection_string)
Packit e18bd3
    {
Packit e18bd3
	return strdup(iceConn->connection_string);
Packit e18bd3
    }
Packit e18bd3
    else
Packit e18bd3
	return (NULL);
Packit e18bd3
}
Packit e18bd3
Packit e18bd3
Packit e18bd3
unsigned long
Packit e18bd3
IceLastSentSequenceNumber (
Packit e18bd3
	IceConn iceConn
Packit e18bd3
)
Packit e18bd3
{
Packit e18bd3
    return (iceConn->send_sequence);
Packit e18bd3
}
Packit e18bd3
Packit e18bd3
Packit e18bd3
unsigned long
Packit e18bd3
IceLastReceivedSequenceNumber (
Packit e18bd3
	IceConn iceConn
Packit e18bd3
)
Packit e18bd3
{
Packit e18bd3
    return (iceConn->receive_sequence);
Packit e18bd3
}
Packit e18bd3
Packit e18bd3
Packit e18bd3
Bool
Packit e18bd3
IceSwapping (
Packit e18bd3
	IceConn iceConn
Packit e18bd3
)
Packit e18bd3
{
Packit e18bd3
    return (iceConn->swap);
Packit e18bd3
}
Packit e18bd3
Packit e18bd3
Packit e18bd3

Packit e18bd3
/*
Packit e18bd3
 * Read "n" bytes from a connection.
Packit e18bd3
 *
Packit e18bd3
 * Return Status 0 if we detected an EXPECTED closed connection.
Packit e18bd3
 *
Packit e18bd3
 */
Packit e18bd3
Packit e18bd3
Status
Packit e18bd3
_IceRead (
Packit e18bd3
	register IceConn iceConn,
Packit e18bd3
	unsigned long	 nbytes,
Packit e18bd3
	register char	 *ptr
Packit e18bd3
)
Packit e18bd3
{
Packit e18bd3
    register unsigned long nleft;
Packit e18bd3
Packit e18bd3
    nleft = nbytes;
Packit e18bd3
    while (nleft > 0)
Packit e18bd3
    {
Packit e18bd3
	int nread;
Packit e18bd3
Packit e18bd3
	if (iceConn->io_ok)
Packit e18bd3
	    nread = _IceTransRead (iceConn->trans_conn, ptr, (int) nleft);
Packit e18bd3
	else
Packit e18bd3
	    return (1);
Packit e18bd3
Packit e18bd3
	if (nread <= 0)
Packit e18bd3
	{
Packit e18bd3
#ifdef WIN32
Packit e18bd3
	    errno = WSAGetLastError();
Packit e18bd3
#endif
Packit e18bd3
	    if (iceConn->want_to_close)
Packit e18bd3
	    {
Packit e18bd3
		/*
Packit e18bd3
		 * We sent a WantToClose message and now we detected that
Packit e18bd3
		 * the other side closed the connection.
Packit e18bd3
		 */
Packit e18bd3
Packit e18bd3
		_IceConnectionClosed (iceConn);	    /* invoke watch procs */
Packit e18bd3
Packit e18bd3
		return (0);
Packit e18bd3
	    }
Packit e18bd3
	    else
Packit e18bd3
	    {
Packit e18bd3
		/*
Packit e18bd3
		 * Fatal IO error.  First notify each protocol's IceIOErrorProc
Packit e18bd3
		 * callback, then invoke the application IO error handler.
Packit e18bd3
		 */
Packit e18bd3
Packit e18bd3
		iceConn->io_ok = False;
Packit e18bd3
Packit e18bd3
		if (iceConn->connection_status == IceConnectPending)
Packit e18bd3
		{
Packit e18bd3
		    /*
Packit e18bd3
		     * Don't invoke IO error handler if we are in the
Packit e18bd3
		     * middle of a connection setup.
Packit e18bd3
		     */
Packit e18bd3
Packit e18bd3
		    return (1);
Packit e18bd3
		}
Packit e18bd3
Packit e18bd3
		if (iceConn->process_msg_info)
Packit e18bd3
		{
Packit e18bd3
		    int i;
Packit e18bd3
Packit e18bd3
		    for (i = iceConn->his_min_opcode;
Packit e18bd3
			i <= iceConn->his_max_opcode; i++)
Packit e18bd3
		    {
Packit e18bd3
			_IceProcessMsgInfo *process;
Packit e18bd3
Packit e18bd3
			process = &iceConn->process_msg_info[
Packit e18bd3
			    i - iceConn->his_min_opcode];
Packit e18bd3
Packit e18bd3
			if ((process != NULL) && process->in_use)
Packit e18bd3
			{
Packit e18bd3
			    IceIOErrorProc IOErrProc = process->accept_flag ?
Packit e18bd3
			      process->protocol->accept_client->io_error_proc :
Packit e18bd3
			      process->protocol->orig_client->io_error_proc;
Packit e18bd3
Packit e18bd3
			    if (IOErrProc)
Packit e18bd3
				(*IOErrProc) (iceConn);
Packit e18bd3
			}
Packit e18bd3
		    }
Packit e18bd3
		}
Packit e18bd3
Packit e18bd3
		(*_IceIOErrorHandler) (iceConn);
Packit e18bd3
		return (1);
Packit e18bd3
	    }
Packit e18bd3
	}
Packit e18bd3
Packit e18bd3
	nleft -= nread;
Packit e18bd3
	ptr   += nread;
Packit e18bd3
    }
Packit e18bd3
Packit e18bd3
    return (1);
Packit e18bd3
}
Packit e18bd3
Packit e18bd3
Packit e18bd3

Packit e18bd3
/*
Packit e18bd3
 * If we read a message header with a bad major or minor opcode,
Packit e18bd3
 * we need to advance to the end of the message.  This way, the next
Packit e18bd3
 * message can be processed correctly.
Packit e18bd3
 */
Packit e18bd3
Packit e18bd3
void
Packit e18bd3
_IceReadSkip (
Packit e18bd3
	register IceConn	iceConn,
Packit e18bd3
	register unsigned long	nbytes
Packit e18bd3
)
Packit e18bd3
{
Packit e18bd3
    char temp[512];
Packit e18bd3
Packit e18bd3
    while (nbytes > 0)
Packit e18bd3
    {
Packit e18bd3
	unsigned long rbytes = nbytes > 512 ? 512 : nbytes;
Packit e18bd3
Packit e18bd3
	_IceRead (iceConn, rbytes, temp);
Packit e18bd3
	nbytes -= rbytes;
Packit e18bd3
    }
Packit e18bd3
}
Packit e18bd3
Packit e18bd3
Packit e18bd3

Packit e18bd3
/*
Packit e18bd3
 * Write "n" bytes to a connection.
Packit e18bd3
 */
Packit e18bd3
Packit e18bd3
void
Packit e18bd3
_IceWrite (
Packit e18bd3
	register IceConn iceConn,
Packit e18bd3
	unsigned long	 nbytes,
Packit e18bd3
	register char	 *ptr
Packit e18bd3
)
Packit e18bd3
{
Packit e18bd3
    register unsigned long nleft;
Packit e18bd3
Packit e18bd3
    nleft = nbytes;
Packit e18bd3
    while (nleft > 0)
Packit e18bd3
    {
Packit e18bd3
	int nwritten;
Packit e18bd3
Packit e18bd3
	if (iceConn->io_ok)
Packit e18bd3
	    nwritten = _IceTransWrite (iceConn->trans_conn, ptr, (int) nleft);
Packit e18bd3
	else
Packit e18bd3
	    return;
Packit e18bd3
Packit e18bd3
	if (nwritten <= 0)
Packit e18bd3
	{
Packit e18bd3
#ifdef WIN32
Packit e18bd3
	    errno = WSAGetLastError();
Packit e18bd3
#endif
Packit e18bd3
	    /*
Packit e18bd3
	     * Fatal IO error.  First notify each protocol's IceIOErrorProc
Packit e18bd3
	     * callback, then invoke the application IO error handler.
Packit e18bd3
	     */
Packit e18bd3
Packit e18bd3
	    iceConn->io_ok = False;
Packit e18bd3
Packit e18bd3
	    if (iceConn->connection_status == IceConnectPending)
Packit e18bd3
	    {
Packit e18bd3
		/*
Packit e18bd3
		 * Don't invoke IO error handler if we are in the
Packit e18bd3
		 * middle of a connection setup.
Packit e18bd3
		 */
Packit e18bd3
Packit e18bd3
		return;
Packit e18bd3
	    }
Packit e18bd3
Packit e18bd3
	    if (iceConn->process_msg_info)
Packit e18bd3
	    {
Packit e18bd3
		int i;
Packit e18bd3
Packit e18bd3
		for (i = iceConn->his_min_opcode;
Packit e18bd3
		     i <= iceConn->his_max_opcode; i++)
Packit e18bd3
		{
Packit e18bd3
		    _IceProcessMsgInfo *process;
Packit e18bd3
Packit e18bd3
		    process = &iceConn->process_msg_info[
Packit e18bd3
			i - iceConn->his_min_opcode];
Packit e18bd3
Packit e18bd3
		    if (process->in_use)
Packit e18bd3
		    {
Packit e18bd3
			IceIOErrorProc IOErrProc = process->accept_flag ?
Packit e18bd3
			    process->protocol->accept_client->io_error_proc :
Packit e18bd3
			    process->protocol->orig_client->io_error_proc;
Packit e18bd3
Packit e18bd3
			if (IOErrProc)
Packit e18bd3
			    (*IOErrProc) (iceConn);
Packit e18bd3
		    }
Packit e18bd3
		}
Packit e18bd3
	    }
Packit e18bd3
Packit e18bd3
	    (*_IceIOErrorHandler) (iceConn);
Packit e18bd3
	    return;
Packit e18bd3
	}
Packit e18bd3
Packit e18bd3
	nleft -= nwritten;
Packit e18bd3
	ptr   += nwritten;
Packit e18bd3
    }
Packit e18bd3
}
Packit e18bd3
Packit e18bd3
Packit e18bd3

Packit e18bd3
void
Packit e18bd3
_IceAddOpcodeMapping (
Packit e18bd3
	IceConn	iceConn,
Packit e18bd3
	int 	hisOpcode,
Packit e18bd3
	int 	myOpcode
Packit e18bd3
)
Packit e18bd3
{
Packit e18bd3
    if (hisOpcode <= 0 || hisOpcode > 255)
Packit e18bd3
    {
Packit e18bd3
	return;
Packit e18bd3
    }
Packit e18bd3
    else if (iceConn->process_msg_info == NULL)
Packit e18bd3
    {
Packit e18bd3
	iceConn->process_msg_info = malloc (sizeof (_IceProcessMsgInfo));
Packit e18bd3
	iceConn->his_min_opcode = iceConn->his_max_opcode = hisOpcode;
Packit e18bd3
    }
Packit e18bd3
    else if (hisOpcode < iceConn->his_min_opcode)
Packit e18bd3
    {
Packit e18bd3
	_IceProcessMsgInfo *oldVec = iceConn->process_msg_info;
Packit e18bd3
	int oldsize = iceConn->his_max_opcode - iceConn->his_min_opcode + 1;
Packit e18bd3
	int newsize = iceConn->his_max_opcode - hisOpcode + 1;
Packit e18bd3
	int i;
Packit e18bd3
Packit e18bd3
	iceConn->process_msg_info = malloc (
Packit e18bd3
	    newsize * sizeof (_IceProcessMsgInfo));
Packit e18bd3
Packit e18bd3
	memcpy (&iceConn->process_msg_info[
Packit e18bd3
	    iceConn->his_min_opcode - hisOpcode], oldVec,
Packit e18bd3
	    oldsize * sizeof (_IceProcessMsgInfo));
Packit e18bd3
Packit e18bd3
	free (oldVec);
Packit e18bd3
Packit e18bd3
	for (i = hisOpcode + 1; i < iceConn->his_min_opcode; i++)
Packit e18bd3
	{
Packit e18bd3
	    iceConn->process_msg_info[i -
Packit e18bd3
		iceConn->his_min_opcode].in_use = False;
Packit e18bd3
Packit e18bd3
	    iceConn->process_msg_info[i -
Packit e18bd3
		iceConn->his_min_opcode].protocol = NULL;
Packit e18bd3
	}
Packit e18bd3
Packit e18bd3
	iceConn->his_min_opcode = hisOpcode;
Packit e18bd3
    }
Packit e18bd3
    else if (hisOpcode > iceConn->his_max_opcode)
Packit e18bd3
    {
Packit e18bd3
	_IceProcessMsgInfo *oldVec = iceConn->process_msg_info;
Packit e18bd3
	int oldsize = iceConn->his_max_opcode - iceConn->his_min_opcode + 1;
Packit e18bd3
	int newsize = hisOpcode - iceConn->his_min_opcode + 1;
Packit e18bd3
	int i;
Packit e18bd3
Packit e18bd3
	iceConn->process_msg_info = malloc (
Packit e18bd3
	    newsize * sizeof (_IceProcessMsgInfo));
Packit e18bd3
Packit e18bd3
	memcpy (iceConn->process_msg_info, oldVec,
Packit e18bd3
	    oldsize * sizeof (_IceProcessMsgInfo));
Packit e18bd3
Packit e18bd3
	free (oldVec);
Packit e18bd3
Packit e18bd3
	for (i = iceConn->his_max_opcode + 1; i < hisOpcode; i++)
Packit e18bd3
	{
Packit e18bd3
	    iceConn->process_msg_info[i -
Packit e18bd3
		iceConn->his_min_opcode].in_use = False;
Packit e18bd3
Packit e18bd3
	    iceConn->process_msg_info[i -
Packit e18bd3
		iceConn->his_min_opcode].protocol = NULL;
Packit e18bd3
	}
Packit e18bd3
Packit e18bd3
	iceConn->his_max_opcode = hisOpcode;
Packit e18bd3
    }
Packit e18bd3
Packit e18bd3
    iceConn->process_msg_info[hisOpcode -
Packit e18bd3
	iceConn->his_min_opcode].in_use = True;
Packit e18bd3
Packit e18bd3
    iceConn->process_msg_info[hisOpcode -
Packit e18bd3
	iceConn->his_min_opcode].my_opcode = myOpcode;
Packit e18bd3
Packit e18bd3
    iceConn->process_msg_info[hisOpcode -
Packit e18bd3
	iceConn->his_min_opcode].protocol = &_IceProtocols[myOpcode - 1];
Packit e18bd3
}
Packit e18bd3
Packit e18bd3
Packit e18bd3

Packit e18bd3
char *
Packit e18bd3
IceGetPeerName (IceConn iceConn)
Packit e18bd3
{
Packit e18bd3
    return (_IceTransGetPeerNetworkId (iceConn->trans_conn));
Packit e18bd3
}
Packit e18bd3
Packit e18bd3

Packit e18bd3
char *
Packit e18bd3
_IceGetPeerName (IceConn iceConn)
Packit e18bd3
{
Packit e18bd3
    return (IceGetPeerName(iceConn));
Packit e18bd3
}