#include "scope.h"
#include "x11.h"
struct TypeDef TD[MaxTypes];
unsigned char RBf[2];
unsigned char SBf[4];
struct ConnState CS[StaticMaxFD];
void
ReportFromClient(
FD fd,
const unsigned char *buf,
long n)
{
if (Verbose > 0)
{
if (ScopeEnabled) {
PrintTime();
fprintf(stdout, "Client%s --> %4ld %s\n",
ClientName(fd), n, (n == 1 ? "byte" : "bytes"));
}
}
ProcessBuffer(fd, buf, n);
}
void
ReportFromServer (
FD fd,
const unsigned char *buf,
long n)
{
if (Verbose > 0) {
if (ScopeEnabled) {
PrintTime();
fprintf(stdout, "\t\t\t\t\t%4ld %s <-- X11 Server%s\n",
n, (n == 1 ? "byte" : "bytes"), ClientName(fd));
}
}
ProcessBuffer(fd, buf, n);
}
static long ZeroTime1 = -1;
static long ZeroTime2 = -1;
static struct timeval tp;
void
PrintTime(void)
{
static long lastsec = 0;
long sec ;
long hsec ;
gettimeofday(&tp, (struct timezone *)NULL);
if (ZeroTime1 == -1 || (tp.tv_sec - lastsec) >= 1000)
{
ZeroTime1 = tp.tv_sec;
ZeroTime2 = tp.tv_usec / 10000;
}
lastsec = tp.tv_sec;
sec = tp.tv_sec - ZeroTime1;
hsec = tp.tv_usec / 10000 - ZeroTime2;
if (hsec < 0)
{
hsec += 100;
sec -= 1;
}
fprintf(stdout, "%2ld.%02ld: ", sec, hsec);
}
long
pad (
long n)
{
return((n + 3) & ~0x3);
}
unsigned long
ILong (
const unsigned char buf[])
{
if (littleEndian)
return((((((buf[3] << 8) | buf[2]) << 8) | buf[1]) << 8) | buf[0]);
return((((((buf[0] << 8) | buf[1]) << 8) | buf[2]) << 8) | buf[3]);
}
unsigned short
IShort (
const unsigned char buf[])
{
if (littleEndian)
return (buf[1] << 8) | buf[0];
return((buf[0] << 8) | buf[1]);
}
unsigned short
IChar2B (
const unsigned char buf[])
{
return((buf[0] << 8) | buf[1]);
}
unsigned short
IByte (
const unsigned char buf[])
{
return(buf[0]);
}
Boolean
IBool (
const unsigned char buf[])
{
if (buf[0] != 0)
return(true);
else
return(false);
}
static void
SaveBytes (
FD fd,
const unsigned char *buf,
long n)
{
if (CS[fd].NumberofSavedBytes + n > CS[fd].SizeofSavedBytes)
{
long SizeofNewBytes = (CS[fd].NumberofSavedBytes + n + 1);
unsigned char *NewBytes = (unsigned char *)Malloc (SizeofNewBytes);
bcopy((char *)CS[fd].SavedBytes,
(char *)NewBytes,
(int)CS[fd].SizeofSavedBytes);
Free((char *)CS[fd].SavedBytes);
CS[fd].SavedBytes = NewBytes;
CS[fd].SizeofSavedBytes = SizeofNewBytes;
}
bcopy((char *)buf,
(char *)(CS[fd].SavedBytes + CS[fd].NumberofSavedBytes),
(int)n);
CS[fd].NumberofSavedBytes += n;
}
static void
RemoveSavedBytes (
FD fd,
long n)
{
if (CS[fd].NumberofSavedBytes <= n)
CS[fd].NumberofSavedBytes = 0;
else if (n == 0)
return;
else
{
register unsigned char *p = CS[fd].SavedBytes;
register unsigned char *q = CS[fd].SavedBytes + n;
register long i = CS[fd].NumberofSavedBytes - n;
while (i-- > 0)
*p++ = *q++;
CS[fd].NumberofSavedBytes -= n;
}
}
static long FinishSetUpMessage(FD fd, const unsigned char *buf, long n);
static long StartRequest(FD fd, const unsigned char *buf, long n);
static long FinishRequest(FD fd, const unsigned char *buf, long n);
static long FinishSetUpReply(FD fd, const unsigned char *buf, long n);
static long ServerPacket(FD fd, const unsigned char *buf, long n);
static long FinishReply(FD fd, const unsigned char *buf, long n);
int littleEndian;
void
ProcessBuffer (
FD fd,
const unsigned char *buf,
long n)
{
const unsigned char *BytesToProcess;
long NumberofUsedBytes;
if (Verbose > 4)
{
fprintf (stdout, "\nRead from fd %d\n", fd);
DumpHexBuffer (buf, n);
}
while (CS[fd].NumberofSavedBytes + n >= CS[fd].NumberofBytesNeeded)
{
if (CS[fd].NumberofSavedBytes == 0)
{
BytesToProcess = buf ;
}
else
{
if (CS[fd].NumberofSavedBytes < CS[fd].NumberofBytesNeeded)
{
long m;
m = CS[fd].NumberofBytesNeeded - CS[fd].NumberofSavedBytes;
SaveBytes(fd, buf, m);
buf += m;
n -= m;
}
BytesToProcess = CS[fd].SavedBytes ;
}
littleEndian = CS[fd].littleEndian;
NumberofUsedBytes = (*CS[fd].ByteProcessing)
(fd, BytesToProcess, CS[fd].NumberofBytesNeeded);
if (NumberofUsedBytes > 0)
{
CS[fd].NumberofBytesProcessed += NumberofUsedBytes;
if (CS[fd].NumberofSavedBytes > 0)
RemoveSavedBytes(fd, NumberofUsedBytes);
else
{
buf += NumberofUsedBytes;
n -= NumberofUsedBytes;
}
}
}
if (Verbose > 3)
fprintf (stdout, "Have %ld need %ld\n",
CS[fd].NumberofSavedBytes + n,
CS[fd].NumberofBytesNeeded);
if (n > 0)
{
SaveBytes(fd, buf, n);
}
return;
}
void
SetBufLimit (
FD fd)
{
int ServerFD = FDPair (fd);
FDinfo[ServerFD].buflimit = (CS[fd].NumberofBytesProcessed +
CS[fd].NumberofBytesNeeded);
}
void
ClearBufLimit (
FD fd)
{
int ServerFD = FDPair (fd);
FDinfo[ServerFD].buflimit = -1;
}
static void
StartStuff (
FD fd)
{
if (BreakPoint)
{
int ServerFD = FDPair (fd);
FDinfo[ServerFD].buflimit = (CS[fd].NumberofBytesProcessed +
CS[fd].NumberofBytesNeeded);
FlushFD (ServerFD);
}
}
static void
FinishStuff (
FD fd,
const unsigned char *buf,
long n)
{
if (BreakPoint)
{
int ServerFD = FDPair (fd);
FlushFD (ServerFD);
if (SingleStep)
ReadCommands ();
else if (BreakPoint)
TestBreakPoints (buf, n);
if (!BreakPoint)
{
FDinfo[ServerFD].buflimit = -1;
FlushFD (ServerFD);
}
}
}
void
StartClientConnection (
FD fd)
{
enterprocedure("StartClientConnection");
CS[fd].SavedBytes = NULL;
CS[fd].SizeofSavedBytes = 0;
CS[fd].NumberofSavedBytes = 0;
CS[fd].NumberofBytesProcessed = 0;
FlushReplyQ(fd);
CS[fd].SequenceNumber = 0;
CS[fd].ByteProcessing = StartSetUpMessage;
CS[fd].NumberofBytesNeeded = 12;
StartStuff (fd);
}
void
StopClientConnection (
FD fd)
{
enterprocedure("StopClientConnection");
if (CS[fd].SizeofSavedBytes > 0)
Free((char*)CS[fd].SavedBytes);
}
long
StartSetUpMessage (
FD fd,
const unsigned char *buf,
long n)
{
unsigned short namelength;
unsigned short datalength;
enterprocedure("StartSetUpMessage");
CS[fd].littleEndian = (buf[0] == 'l');
CS[ServerHalf(fd)].littleEndian = CS[fd].littleEndian;
littleEndian = CS[fd].littleEndian;
namelength = IShort(&buf[6]);
datalength = IShort(&buf[8]);
CS[fd].ByteProcessing = FinishSetUpMessage;
CS[fd].NumberofBytesNeeded = n
+ pad((long)namelength) + pad((long)datalength);
debug(8,(stderr, "need %ld bytes to finish startup\n",
CS[fd].NumberofBytesNeeded - n));
StartStuff (fd);
return(0);
}
static long
FinishSetUpMessage (
FD fd,
const unsigned char *buf,
long n)
{
enterprocedure("FinishSetUpMessage");
if( Raw || (Verbose > 3) )
DumpItem("Client Connect", fd, buf, n) ;
CS[fd].littleEndian = (buf[0] == 'l');
CS[ServerHalf(fd)].littleEndian = CS[fd].littleEndian;
littleEndian = CS[fd].littleEndian;
if (ScopeEnabled)
PrintSetUpMessage(buf);
CS[fd].ByteProcessing = StartRequest;
CS[fd].NumberofBytesNeeded = 4;
FinishStuff (fd, buf, n);
return(n);
}
static long
StartBigRequest (
FD fd,
const unsigned char *buf,
long n)
{
enterprocedure("StartBigRequest");
CS[fd].requestLen = ILong(&buf[4]);
CS[fd].ByteProcessing = FinishRequest;
CS[fd].NumberofBytesNeeded = 4 * CS[fd].requestLen;
debug(8,(stderr, "need %ld more bytes to finish request\n",
CS[fd].NumberofBytesNeeded - n));
StartStuff (fd);
return(0);
}
static long
StartRequest (
FD fd,
const unsigned char *buf,
long n)
{
enterprocedure("StartRequest");
CS[fd].requestLen = IShort(&buf[2]);
if (CS[fd].requestLen == 0 && CS[fd].bigreqEnabled)
{
CS[fd].ByteProcessing = StartBigRequest;
CS[fd].NumberofBytesNeeded = 8;
}
else
{
if (CS[fd].requestLen == 0)
CS[fd].requestLen = 1;
CS[fd].ByteProcessing = FinishRequest;
CS[fd].NumberofBytesNeeded = 4 * CS[fd].requestLen;
debug(8,(stderr, "need %ld more bytes to finish request\n",
CS[fd].NumberofBytesNeeded - n));
}
StartStuff (fd);
return(0);
}
static long
FinishRequest (
FD fd,
const unsigned char *buf,
long n)
{
enterprocedure("FinishRequest");
CS[fd].ByteProcessing = StartRequest;
CS[fd].NumberofBytesNeeded = 4;
if (ScopeEnabled)
DecodeRequest(fd, buf, n);
FinishStuff (fd, buf, n);
return(n);
}
void
StartServerConnection (
FD fd)
{
enterprocedure("StartServerConnection");
CS[fd].SavedBytes = NULL;
CS[fd].SizeofSavedBytes = 0;
CS[fd].NumberofSavedBytes = 0;
CS[fd].NumberofBytesProcessed = 0;
FlushReplyQ(fd);
CS[fd].ByteProcessing = StartSetUpReply;
CS[fd].NumberofBytesNeeded = 8;
}
void
StopServerConnection (
FD fd)
{
enterprocedure("StopServerConnection");
if (CS[fd].SizeofSavedBytes > 0)
Free((char *)CS[fd].SavedBytes);
}
long
StartSetUpReply (
FD fd,
const unsigned char *buf,
long n)
{
unsigned short replylength;
enterprocedure("StartSetUpReply");
replylength = IShort(&buf[6]);
CS[fd].ByteProcessing = FinishSetUpReply;
CS[fd].NumberofBytesNeeded = n + 4 * replylength;
debug(8,(stderr, "need %ld bytes to finish startup reply\n",
CS[fd].NumberofBytesNeeded - n));
return(0);
}
static long
FinishSetUpReply (
FD fd,
const unsigned char *buf,
long n)
{
enterprocedure("FinishSetUpReply");
if( Raw || (Verbose > 3) )
DumpItem("Server Connect", fd, buf, n) ;
if (ScopeEnabled)
PrintSetUpReply(buf);
CS[fd].ByteProcessing = ServerPacket;
CS[fd].NumberofBytesNeeded = 32;
return(n);
}
static long
ErrorPacket (
FD fd,
const unsigned char *buf,
long n)
{
CS[fd].ByteProcessing = ServerPacket;
CS[fd].NumberofBytesNeeded = 32;
DecodeError(fd, buf, n);
return(n);
}
static long
FinishEvent (
FD fd,
const unsigned char *buf,
long n)
{
CS[fd].ByteProcessing = ServerPacket;
CS[fd].NumberofBytesNeeded = 32;
enterprocedure("FinishEvent");
if (ScopeEnabled)
DecodeEvent(fd, buf, n);
return(n);
}
static long
EventPacket (
FD fd,
const unsigned char *buf,
long n)
{
short Event = IByte (&buf[0]);
long eventlength = 0;
CS[fd].ByteProcessing = FinishEvent;
CS[fd].NumberofBytesNeeded = 32;
if (Event == Event_Type_Generic) {
eventlength = ILong(&buf[4]);
CS[fd].NumberofBytesNeeded += (4 * eventlength);
}
debug(8,(stderr, "need %ld bytes to finish reply\n", (4 * eventlength)));
return(0);
}
static long
ReplyPacket (
FD fd,
const unsigned char *buf,
long n)
{
long replylength;
replylength = ILong(&buf[4]);
CS[fd].ByteProcessing = FinishReply;
CS[fd].NumberofBytesNeeded = n + 4 * replylength;
debug(8,(stderr, "need %ld bytes to finish reply\n", (4 * replylength)));
return(0);
}
static long
ServerPacket (
FD fd,
const unsigned char *buf,
long n)
{
short PacketType;
enterprocedure("ServerPacket");
PacketType = IByte(&buf[0]);
if (PacketType == 0)
return(ErrorPacket(fd, buf, n));
if (PacketType == 1)
return(ReplyPacket(fd, buf, n));
return(EventPacket(fd, buf, n));
}
long
FinishReply (
FD fd,
const unsigned char *buf,
long n)
{
CS[fd].ByteProcessing = ServerPacket;
CS[fd].NumberofBytesNeeded = 32;
enterprocedure("FinishReply");
if (ScopeEnabled)
DecodeReply(fd, buf, n);
return(n);
}
long
GetXRequestFromName (
const char *name)
{
long req = GetEValue (REQUEST, name);
if (req < 0)
req = GetEValue (EXTENSION, name);
return req;
}