|
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 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 |
|
|
Packit |
e18bd3 |
|
|
Packit |
e18bd3 |
Status
|
|
Packit |
e18bd3 |
IceProtocolShutdown (
|
|
Packit |
e18bd3 |
IceConn iceConn,
|
|
Packit |
e18bd3 |
int majorOpcode
|
|
Packit |
e18bd3 |
)
|
|
Packit |
e18bd3 |
{
|
|
Packit |
e18bd3 |
if (iceConn->proto_ref_count == 0 || iceConn->process_msg_info == NULL ||
|
|
Packit |
e18bd3 |
majorOpcode < 1 || majorOpcode > _IceLastMajorOpcode)
|
|
Packit |
e18bd3 |
{
|
|
Packit |
e18bd3 |
return (0);
|
|
Packit |
e18bd3 |
}
|
|
Packit |
e18bd3 |
else
|
|
Packit |
e18bd3 |
{
|
|
Packit |
e18bd3 |
/*
|
|
Packit |
e18bd3 |
* Make sure this majorOpcode is really being used.
|
|
Packit |
e18bd3 |
*/
|
|
Packit |
e18bd3 |
|
|
Packit |
e18bd3 |
int i;
|
|
Packit |
e18bd3 |
|
|
Packit |
e18bd3 |
for (i = iceConn->his_min_opcode; i <= iceConn->his_max_opcode; i++)
|
|
Packit |
e18bd3 |
{
|
|
Packit |
e18bd3 |
if (iceConn->process_msg_info[
|
|
Packit |
e18bd3 |
i - iceConn->his_min_opcode].in_use &&
|
|
Packit |
e18bd3 |
iceConn->process_msg_info[
|
|
Packit |
e18bd3 |
i - iceConn->his_min_opcode].my_opcode == majorOpcode)
|
|
Packit |
e18bd3 |
break;
|
|
Packit |
e18bd3 |
}
|
|
Packit |
e18bd3 |
|
|
Packit |
e18bd3 |
if (i > iceConn->his_max_opcode)
|
|
Packit |
e18bd3 |
{
|
|
Packit |
e18bd3 |
return (0);
|
|
Packit |
e18bd3 |
}
|
|
Packit |
e18bd3 |
else
|
|
Packit |
e18bd3 |
{
|
|
Packit |
e18bd3 |
/*
|
|
Packit |
e18bd3 |
* OK, we can shut down the protocol.
|
|
Packit |
e18bd3 |
*/
|
|
Packit |
e18bd3 |
|
|
Packit |
e18bd3 |
iceConn->process_msg_info[
|
|
Packit |
e18bd3 |
i - iceConn->his_min_opcode].in_use = False;
|
|
Packit |
e18bd3 |
iceConn->proto_ref_count--;
|
|
Packit |
e18bd3 |
|
|
Packit |
e18bd3 |
return (1);
|
|
Packit |
e18bd3 |
}
|
|
Packit |
e18bd3 |
}
|
|
Packit |
e18bd3 |
}
|
|
Packit |
e18bd3 |
|
|
Packit |
e18bd3 |
|
|
Packit |
e18bd3 |
|
|
Packit |
e18bd3 |
void
|
|
Packit |
e18bd3 |
IceSetShutdownNegotiation (
|
|
Packit |
e18bd3 |
IceConn iceConn,
|
|
Packit |
e18bd3 |
Bool negotiate
|
|
Packit |
e18bd3 |
)
|
|
Packit |
e18bd3 |
{
|
|
Packit |
e18bd3 |
iceConn->skip_want_to_close = negotiate ? False : True;
|
|
Packit |
e18bd3 |
}
|
|
Packit |
e18bd3 |
|
|
Packit |
e18bd3 |
|
|
Packit |
e18bd3 |
|
|
Packit |
e18bd3 |
Bool
|
|
Packit |
e18bd3 |
IceCheckShutdownNegotiation (
|
|
Packit |
e18bd3 |
IceConn iceConn
|
|
Packit |
e18bd3 |
)
|
|
Packit |
e18bd3 |
{
|
|
Packit |
e18bd3 |
return (iceConn->skip_want_to_close ? False : True);
|
|
Packit |
e18bd3 |
}
|
|
Packit |
e18bd3 |
|
|
Packit |
e18bd3 |
|
|
Packit |
e18bd3 |
|
|
Packit |
e18bd3 |
IceCloseStatus
|
|
Packit |
e18bd3 |
IceCloseConnection (
|
|
Packit |
e18bd3 |
IceConn iceConn
|
|
Packit |
e18bd3 |
)
|
|
Packit |
e18bd3 |
{
|
|
Packit |
e18bd3 |
int refCountReachedZero;
|
|
Packit |
e18bd3 |
IceCloseStatus status;
|
|
Packit |
e18bd3 |
|
|
Packit |
e18bd3 |
/*
|
|
Packit |
e18bd3 |
* If this connection object was never valid, we can close
|
|
Packit |
e18bd3 |
* it right now. This happens if IceAcceptConnection was
|
|
Packit |
e18bd3 |
* called, but after calling IceProcessMessages several times
|
|
Packit |
e18bd3 |
* the connection was rejected (because of authentication or
|
|
Packit |
e18bd3 |
* some other reason).
|
|
Packit |
e18bd3 |
*/
|
|
Packit |
e18bd3 |
|
|
Packit |
e18bd3 |
if (iceConn->listen_obj &&
|
|
Packit |
e18bd3 |
iceConn->connection_status != IceConnectAccepted)
|
|
Packit |
e18bd3 |
{
|
|
Packit |
e18bd3 |
_IceConnectionClosed (iceConn); /* invoke watch procs */
|
|
Packit |
e18bd3 |
_IceFreeConnection (iceConn);
|
|
Packit |
e18bd3 |
return (IceClosedNow);
|
|
Packit |
e18bd3 |
}
|
|
Packit |
e18bd3 |
|
|
Packit |
e18bd3 |
|
|
Packit |
e18bd3 |
/*---------------------------------------------------------------
|
|
Packit |
e18bd3 |
|
|
Packit |
e18bd3 |
ACTIONS:
|
|
Packit |
e18bd3 |
|
|
Packit |
e18bd3 |
A = Invoke Watch Procedures
|
|
Packit |
e18bd3 |
B = Set free-asap bit
|
|
Packit |
e18bd3 |
C = Free connection
|
|
Packit |
e18bd3 |
D = Initialize shutdown negotiation
|
|
Packit |
e18bd3 |
N = do nothing
|
|
Packit |
e18bd3 |
|
|
Packit |
e18bd3 |
|
|
Packit |
e18bd3 |
ACTION TABLE:
|
|
Packit |
e18bd3 |
|
|
Packit |
e18bd3 |
IO free- dispatch protocol shutdown
|
|
Packit |
e18bd3 |
error asap bit level refcount negotiation ACTION
|
|
Packit |
e18bd3 |
occured set reached 0 reached 0
|
|
Packit |
e18bd3 |
|
|
Packit |
e18bd3 |
0 0 0 0 0 N
|
|
Packit |
e18bd3 |
0 0 0 0 1 N
|
|
Packit |
e18bd3 |
0 0 0 1 0 AB
|
|
Packit |
e18bd3 |
0 0 0 1 1 N
|
|
Packit |
e18bd3 |
0 0 1 0 0 N
|
|
Packit |
e18bd3 |
0 0 1 0 1 N
|
|
Packit |
e18bd3 |
0 0 1 1 0 AC
|
|
Packit |
e18bd3 |
0 0 1 1 1 D
|
|
Packit |
e18bd3 |
0 1 0 0 0 N
|
|
Packit |
e18bd3 |
0 1 0 0 1 N
|
|
Packit |
e18bd3 |
0 1 0 1 0 N
|
|
Packit |
e18bd3 |
0 1 0 1 1 N
|
|
Packit |
e18bd3 |
0 1 1 0 0 C
|
|
Packit |
e18bd3 |
0 1 1 0 1 D
|
|
Packit |
e18bd3 |
0 1 1 1 0 C
|
|
Packit |
e18bd3 |
0 1 1 1 1 D
|
|
Packit |
e18bd3 |
1 0 0 0 0 AB
|
|
Packit |
e18bd3 |
1 0 0 0 1 AB
|
|
Packit |
e18bd3 |
1 0 0 1 0 AB
|
|
Packit |
e18bd3 |
1 0 0 1 1 AB
|
|
Packit |
e18bd3 |
1 0 1 0 0 AC
|
|
Packit |
e18bd3 |
1 0 1 0 1 AC
|
|
Packit |
e18bd3 |
1 0 1 1 0 AC
|
|
Packit |
e18bd3 |
1 0 1 1 1 AC
|
|
Packit |
e18bd3 |
1 1 0 0 0 N
|
|
Packit |
e18bd3 |
1 1 0 0 1 N
|
|
Packit |
e18bd3 |
1 1 0 1 0 N
|
|
Packit |
e18bd3 |
1 1 0 1 1 N
|
|
Packit |
e18bd3 |
1 1 1 0 0 C
|
|
Packit |
e18bd3 |
1 1 1 0 1 C
|
|
Packit |
e18bd3 |
1 1 1 1 0 C
|
|
Packit |
e18bd3 |
1 1 1 1 1 C
|
|
Packit |
e18bd3 |
|
|
Packit |
e18bd3 |
---------------------------------------------------------------*/
|
|
Packit |
e18bd3 |
|
|
Packit |
e18bd3 |
if (iceConn->open_ref_count > 0)
|
|
Packit |
e18bd3 |
iceConn->open_ref_count--;
|
|
Packit |
e18bd3 |
|
|
Packit |
e18bd3 |
refCountReachedZero = iceConn->open_ref_count == 0 &&
|
|
Packit |
e18bd3 |
iceConn->proto_ref_count == 0;
|
|
Packit |
e18bd3 |
|
|
Packit |
e18bd3 |
status = IceConnectionInUse;
|
|
Packit |
e18bd3 |
|
|
Packit |
e18bd3 |
if (!iceConn->free_asap && (!iceConn->io_ok ||
|
|
Packit |
e18bd3 |
(iceConn->io_ok && refCountReachedZero &&
|
|
Packit |
e18bd3 |
iceConn->skip_want_to_close)))
|
|
Packit |
e18bd3 |
{
|
|
Packit |
e18bd3 |
/*
|
|
Packit |
e18bd3 |
* Invoke the watch procedures now.
|
|
Packit |
e18bd3 |
*/
|
|
Packit |
e18bd3 |
|
|
Packit |
e18bd3 |
_IceConnectionClosed (iceConn);
|
|
Packit |
e18bd3 |
status = IceClosedNow; /* may be overwritten by IceClosedASAP */
|
|
Packit |
e18bd3 |
}
|
|
Packit |
e18bd3 |
|
|
Packit |
e18bd3 |
if (!iceConn->free_asap && iceConn->dispatch_level != 0 &&
|
|
Packit |
e18bd3 |
(!iceConn->io_ok ||
|
|
Packit |
e18bd3 |
(iceConn->io_ok && refCountReachedZero &&
|
|
Packit |
e18bd3 |
iceConn->skip_want_to_close)))
|
|
Packit |
e18bd3 |
{
|
|
Packit |
e18bd3 |
/*
|
|
Packit |
e18bd3 |
* Set flag so we free the connection as soon as possible.
|
|
Packit |
e18bd3 |
*/
|
|
Packit |
e18bd3 |
|
|
Packit |
e18bd3 |
iceConn->free_asap = True;
|
|
Packit |
e18bd3 |
status = IceClosedASAP;
|
|
Packit |
e18bd3 |
}
|
|
Packit |
e18bd3 |
|
|
Packit |
e18bd3 |
if (iceConn->io_ok && iceConn->dispatch_level == 0 &&
|
|
Packit |
e18bd3 |
!iceConn->skip_want_to_close && refCountReachedZero)
|
|
Packit |
e18bd3 |
{
|
|
Packit |
e18bd3 |
/*
|
|
Packit |
e18bd3 |
* Initiate shutdown negotiation.
|
|
Packit |
e18bd3 |
*/
|
|
Packit |
e18bd3 |
|
|
Packit |
e18bd3 |
IceSimpleMessage (iceConn, 0, ICE_WantToClose);
|
|
Packit |
e18bd3 |
IceFlush (iceConn);
|
|
Packit |
e18bd3 |
|
|
Packit |
e18bd3 |
iceConn->want_to_close = 1;
|
|
Packit |
e18bd3 |
|
|
Packit |
e18bd3 |
status = IceStartedShutdownNegotiation;
|
|
Packit |
e18bd3 |
}
|
|
Packit |
e18bd3 |
else if (iceConn->dispatch_level == 0 &&
|
|
Packit |
e18bd3 |
(!iceConn->io_ok || (iceConn->io_ok && iceConn->skip_want_to_close &&
|
|
Packit |
e18bd3 |
(iceConn->free_asap || (!iceConn->free_asap && refCountReachedZero)))))
|
|
Packit |
e18bd3 |
{
|
|
Packit |
e18bd3 |
/*
|
|
Packit |
e18bd3 |
* Free the connection.
|
|
Packit |
e18bd3 |
*/
|
|
Packit |
e18bd3 |
|
|
Packit |
e18bd3 |
_IceFreeConnection (iceConn);
|
|
Packit |
e18bd3 |
|
|
Packit |
e18bd3 |
status = IceClosedNow;
|
|
Packit |
e18bd3 |
}
|
|
Packit |
e18bd3 |
|
|
Packit |
e18bd3 |
return (status);
|
|
Packit |
e18bd3 |
}
|
|
Packit |
e18bd3 |
|
|
Packit |
e18bd3 |
|
|
Packit |
e18bd3 |
|
|
Packit |
e18bd3 |
void
|
|
Packit |
e18bd3 |
_IceFreeConnection (
|
|
Packit |
e18bd3 |
IceConn iceConn
|
|
Packit |
e18bd3 |
)
|
|
Packit |
e18bd3 |
{
|
|
Packit |
e18bd3 |
if (iceConn->listen_obj == NULL)
|
|
Packit |
e18bd3 |
{
|
|
Packit |
e18bd3 |
/*
|
|
Packit |
e18bd3 |
* This iceConn was created with IceOpenConnection.
|
|
Packit |
e18bd3 |
* We keep track of all open IceConn's, so we need
|
|
Packit |
e18bd3 |
* to remove it from the list.
|
|
Packit |
e18bd3 |
*/
|
|
Packit |
e18bd3 |
|
|
Packit |
e18bd3 |
int i;
|
|
Packit |
e18bd3 |
|
|
Packit |
e18bd3 |
for (i = 0; i < _IceConnectionCount; i++)
|
|
Packit |
e18bd3 |
if (_IceConnectionObjs[i] == iceConn)
|
|
Packit |
e18bd3 |
break;
|
|
Packit |
e18bd3 |
|
|
Packit |
e18bd3 |
if (i < _IceConnectionCount)
|
|
Packit |
e18bd3 |
{
|
|
Packit |
e18bd3 |
if (i < _IceConnectionCount - 1)
|
|
Packit |
e18bd3 |
{
|
|
Packit |
e18bd3 |
_IceConnectionObjs[i] =
|
|
Packit |
e18bd3 |
_IceConnectionObjs[_IceConnectionCount - 1];
|
|
Packit |
e18bd3 |
_IceConnectionStrings[i] =
|
|
Packit |
e18bd3 |
_IceConnectionStrings[_IceConnectionCount - 1];
|
|
Packit |
e18bd3 |
}
|
|
Packit |
e18bd3 |
|
|
Packit |
e18bd3 |
_IceConnectionCount--;
|
|
Packit |
e18bd3 |
}
|
|
Packit |
e18bd3 |
}
|
|
Packit |
e18bd3 |
|
|
Packit |
e18bd3 |
if (iceConn->trans_conn)
|
|
Packit |
e18bd3 |
_IceTransClose (iceConn->trans_conn);
|
|
Packit |
e18bd3 |
|
|
Packit |
e18bd3 |
if (iceConn->connection_string)
|
|
Packit |
e18bd3 |
free (iceConn->connection_string);
|
|
Packit |
e18bd3 |
|
|
Packit |
e18bd3 |
if (iceConn->vendor)
|
|
Packit |
e18bd3 |
free (iceConn->vendor);
|
|
Packit |
e18bd3 |
|
|
Packit |
e18bd3 |
if (iceConn->release)
|
|
Packit |
e18bd3 |
free (iceConn->release);
|
|
Packit |
e18bd3 |
|
|
Packit |
e18bd3 |
if (iceConn->inbuf)
|
|
Packit |
e18bd3 |
free (iceConn->inbuf);
|
|
Packit |
e18bd3 |
|
|
Packit |
e18bd3 |
if (iceConn->outbuf)
|
|
Packit |
e18bd3 |
free (iceConn->outbuf);
|
|
Packit |
e18bd3 |
|
|
Packit |
e18bd3 |
if (iceConn->scratch)
|
|
Packit |
e18bd3 |
free (iceConn->scratch);
|
|
Packit |
e18bd3 |
|
|
Packit |
e18bd3 |
if (iceConn->process_msg_info)
|
|
Packit |
e18bd3 |
free (iceConn->process_msg_info);
|
|
Packit |
e18bd3 |
|
|
Packit |
e18bd3 |
if (iceConn->connect_to_you)
|
|
Packit |
e18bd3 |
free (iceConn->connect_to_you);
|
|
Packit |
e18bd3 |
|
|
Packit |
e18bd3 |
if (iceConn->protosetup_to_you)
|
|
Packit |
e18bd3 |
free (iceConn->protosetup_to_you);
|
|
Packit |
e18bd3 |
|
|
Packit |
e18bd3 |
if (iceConn->connect_to_me)
|
|
Packit |
e18bd3 |
free (iceConn->connect_to_me);
|
|
Packit |
e18bd3 |
|
|
Packit |
e18bd3 |
if (iceConn->protosetup_to_me)
|
|
Packit |
e18bd3 |
free (iceConn->protosetup_to_me);
|
|
Packit |
e18bd3 |
|
|
Packit |
e18bd3 |
free (iceConn);
|
|
Packit |
e18bd3 |
}
|
|
Packit |
e18bd3 |
|
|
Packit |
e18bd3 |
|
|
Packit |
e18bd3 |
|
|
Packit |
e18bd3 |
|