[comp.sources.x] v10i070: Xmon - X protocol monitor, Patch3, Part01/01

gregm@otc.otca.oz.au (Greg McFarlane) (11/16/90)

Submitted-by: Greg McFarlane <gregm@otc.otca.oz.au>
Posting-number: Volume 10, Issue 70
Archive-name: xmon/patch3
Patch-To: xmon: Volume 9, Issue 15-19, 30, 75

This patch brings xmon to patchlevel 3 and makes the following changes:

1. The number of bytes in each network protocol packet can be displayed.
2. Can initialize xmond from a setup file. (Useful for testing clients.)
3. Synthetic events are monitored correctly.
4. The default server is taken from the DISPLAY environment variable.
5. Don't need to use -Bstatic compiler flag on Suns.
6. Xmond doesn't need to link to Xt or Xaw libraries.
7. Will now compile on Sony's RISC based 3710 system under SVR4.
8. Manual page updated to reflect above changes.

First unshar this posting, then run it through patch.
You must be up to patchlevel 2.

---- Cut Here and unpack ----
#!/bin/sh
# This is xmon.patch3, a shell archive (shar 3.32)
# made 11/13/1990 02:39 UTC by gregm@otc.otca.oz.au
# Source directory /u/projects/multi/xmux/xmon/patches
#
# existing files will NOT be overwritten
#
# This shar contains:
# length  mode       name
# ------ ---------- ------------------------------------------
#  28460 -rw-rw-r-- xmon.patch3
#
if touch 2>&1 | fgrep 'amc' > /dev/null
 then TOUCH=touch
 else TOUCH=true
fi
# ============= xmon.patch3 ==============
if test X"$1" != X"-c" -a -f 'xmon.patch3'; then
	echo "File already exists: skipping 'xmon.patch3'"
else
echo "x - extracting xmon.patch3 (Text)"
sed 's/^X//' << 'SHAR_EOF' > xmon.patch3 &&
Xdiff -c version2/CHANGES version3/CHANGES
X*** version2/CHANGES	Tue Nov 13 13:32:01 1990
X--- version3/CHANGES	Tue Nov 13 13:32:50 1990
X***************
X*** 0 ****
X--- 1,13 ----
X+ xmon patch 3
X+ 
X+ This patch brings xmon to patchlevel 3 and makes the following changes:
X+ 
X+ 1. The number of bytes in each network protocol packet can be displayed.
X+ 2. Can initialize xmond from a setup file. (Useful for testing clients.)
X+ 3. Synthetic events are monitored correctly.
X+ 4. The default server is taken from the DISPLAY environment variable.
X+ 5. Don't need to use -Bstatic compiler flag on Suns.
X+ 6. Xmond doesn't need to link to Xt or Xaw libraries.
X+ 7. Will now compile on Sony's RISC based 3710 system under SVR4.
X+ 8. Manual page updated to reflect above changes.
X+ 
Xdiff -c version2/patchlevel.h version3/patchlevel.h
X*** version2/patchlevel.h	Thu Sep 27 17:03:30 1990
X--- version3/patchlevel.h	Fri Nov  2 15:21:18 1990
X***************
X*** 1 ****
X! #define PATCHLEVEL 2
X--- 1 ----
X! #define PATCHLEVEL 3
Xdiff -c version2/Imakefile version3/Imakefile
X*** version2/Imakefile	Thu Sep 27 16:44:45 1990
X--- version3/Imakefile	Fri Oct 12 19:35:05 1990
X***************
X*** 1,4 ****
X! LOCAL_LIBRARIES = -Bstatic -lXaw -lXmu -lXt -lXext -lX11
X  CDEBUGFLAGS = -g
X  
X  SRCS1 = decode11.c linkl.c print11.c server.c fd.c main.c prtype.c table11.c
X--- 1,6 ----
X! LOCAL_LIBRARIES1 = -lXmu -lXext -lX11
X! LOCAL_LIBRARIES2 = -lXaw -lXmu -lXt -lXext -lX11
X! 
X  CDEBUGFLAGS = -g
X  
X  SRCS1 = decode11.c linkl.c print11.c server.c fd.c main.c prtype.c table11.c
X***************
X*** 12,19 ****
X  
X  PROGRAMS = xmond xmonui
X  
X! ComplexProgramTarget_1(xmond, $(LOCAL_LIBRARIES), )
X! ComplexProgramTarget_2(xmonui, $(LOCAL_LIBRARIES), )
X  
X  SHARFILES = README xmon.man Imakefile Makefile $(SRCS1) $(SRCS2) \
X  $(INCLUDE_FILES)
X--- 14,21 ----
X  
X  PROGRAMS = xmond xmonui
X  
X! ComplexProgramTarget_1(xmond, $(LOCAL_LIBRARIES1), )
X! ComplexProgramTarget_2(xmonui, $(LOCAL_LIBRARIES2), )
X  
X  SHARFILES = README xmon.man Imakefile Makefile $(SRCS1) $(SRCS2) \
X  $(INCLUDE_FILES)
Xdiff -c version2/README version3/README
X*** version2/README	Thu Sep 27 16:44:46 1990
X--- version3/README	Fri Nov  2 15:37:47 1990
X***************
X*** 8,17 ****
X  	make Makefile
X  If you don't have imake, then good luck with modifing the Makefile.
X  
X! You may want to delete the -Bstatic flag from the Imakefile (or Makefile
X! if you are not using imake). I need it to get around the infamous
X! 	ld.so: Undefined symbol: __XtInherit
X! error with shared libraries on Suns.
X  
X  When you have finished the Makefile, type
X  	make
X--- 8,15 ----
X  	make Makefile
X  If you don't have imake, then good luck with modifing the Makefile.
X  
X! If you have system five unices, define the appropriate ones of these:
X! 	-DSYSV -DSVR4
X  
X  When you have finished the Makefile, type
X  	make
X***************
X*** 19,24 ****
X--- 17,26 ----
X  
X  Run xmon with the command
X  	xmonui | xmond
X+ 
X+ PS: The source files have tab stops set to 4 characters. If you are using
X+ vi to look at the code use this to set the tab stops:
X+ 	: set tabstop=4
X  
X  Please send any reports to
X  	gregm@otc.otca.oz.au
Xdiff -c version2/decode11.c version3/decode11.c
X*** version2/decode11.c	Fri Oct 12 18:49:03 1990
X--- version3/decode11.c	Fri Oct 12 19:28:32 1990
X***************
X*** 996,1043 ****
X  }
X  
X  Global void
X! DecodeEvent(server, buf, n)
X  	Server					*server;
X  	unsigned char			*buf;
X  	long					n;
X  {
X- 	int						fd = server->fdd->fd;
X  	short					Event = IByte (&buf[0]) & 0x7f;
X  
X! 	if (CountEvents)
X  	{
X! 		if (Event < 0 || Event >= MAX_EVENT)
X! 			fprintf(stdout, "####### Illegal event opcode %d\n", Event);
X! 		else
X! 			EventCount[Event]++;
X! 	}
X  
X! 	if 
X! 	(
X! 		BlockingEvents
X! 		&&
X! 		2 <= Event && Event <= 34
X! 		&&
X! 		BlockEvent[Event]
X! 	)
X! 		ignore_bytes = True;
X  
X! 	if 
X! 	(
X! 		MonitoringEvents
X! 		&&
X! 		2 <= Event && Event <= 34
X! 		&&
X! 		VerboseEvent[Event]
X! 	)
X! 		CurrentVerbose = SelectedEventVerbose;
X! 	else
X! 		CurrentVerbose = EventVerbose;
X! 	if (CurrentVerbose <= 0)
X! 		return;
X! 	SetIndentLevel(PRINTSERVER);
X! 	if (CurrentVerbose > 3)
X! 		DumpItem("Event", fd, buf, n);
X  	if (Event < 2 || Event > 34)
X  		fprintf(stdout, "####### Extended Event opcode %d\n", Event);
X  	else
X--- 996,1046 ----
X  }
X  
X  Global void
X! DecodeEvent(server, buf, n, real_event)
X  	Server					*server;
X  	unsigned char			*buf;
X  	long					n;
X+ 	Bool					real_event;
X  {
X  	short					Event = IByte (&buf[0]) & 0x7f;
X  
X! 	if (real_event)
X  	{
X! 		if (CountEvents)
X! 		{
X! 			if (Event < 0 || Event >= MAX_EVENT)
X! 				fprintf(stdout, "####### Illegal event opcode %d\n", Event);
X! 			else
X! 				EventCount[Event]++;
X! 		}
X  
X! 		if 
X! 		(
X! 			BlockingEvents
X! 			&&
X! 			2 <= Event && Event <= 34
X! 			&&
X! 			BlockEvent[Event]
X! 		)
X! 			ignore_bytes = True;
X  
X! 		if 
X! 		(
X! 			MonitoringEvents
X! 			&&
X! 			2 <= Event && Event <= 34
X! 			&&
X! 			VerboseEvent[Event]
X! 		)
X! 			CurrentVerbose = SelectedEventVerbose;
X! 		else
X! 			CurrentVerbose = EventVerbose;
X! 		if (CurrentVerbose <= 0)
X! 			return;
X! 		SetIndentLevel(PRINTSERVER);
X! 		if (CurrentVerbose > 3)
X! 			DumpItem("Event", server->fdd->fd, buf, n);
X! 	}
X  	if (Event < 2 || Event > 34)
X  		fprintf(stdout, "####### Extended Event opcode %d\n", Event);
X  	else
Xdiff -c version2/fd.c version3/fd.c
X*** version2/fd.c	Thu Sep 27 16:44:46 1990
X--- version3/fd.c	Thu Nov  1 18:53:52 1990
X***************
X*** 15,20 ****
X--- 15,25 ----
X  
X  #include <errno.h>             /* for EINTR, EADDRINUSE, ... */
X  
X+ #ifdef SVR4
X+ #include <sys/time.h>
X+ #include <sys/resource.h>
X+ #endif
X+ 
X  #include "common.h"
X  
X  #include "xmond.h"
X***************
X*** 35,44 ****
X--- 40,61 ----
X  {
X  	register short  i;
X  	short   MaxFD /* maximum number of FD's possible */ ;
X+ #ifdef SVR4
X+ 	struct rlimit rlp;
X+ #endif
X  
X  	enterprocedure("InitializeFD");
X  	/* get the number of file descriptors the system will let us use */
X+ #ifdef SVR4
X+ 	if (getrlimit(RLIMIT_NOFILE, &rlp) < 0)
X+ 	{
X+ 		perror("getrlimit(RLIMIT_NOFILE)");
X+ 		exit(1);
X+ 	}
X+ 	MaxFD = rlp.rlim_cur;
X+ #else
X  	MaxFD = getdtablesize();
X+ #endif
X  
X  	/* allocate space for a File Descriptor Table */
X  	FDD = (FDDescriptor *)malloc((long)(MaxFD * sizeof(FDDescriptor)));
Xdiff -c version2/main.c version3/main.c
X*** version2/main.c	Thu Sep 27 17:00:51 1990
X--- version3/main.c	Wed Nov  7 11:02:33 1990
X***************
X*** 13,19 ****
X--- 13,22 ----
X  #include <sys/ioctl.h>         /* for FIONCLEX, FIONBIO, ... */
X  #ifdef SYSV
X  #include <sys/fcntl.h>
X+ #ifndef FD_CLOEXEC
X+ #define FD_CLOEXEC 1
X  #endif
X+ #endif
X  #include <netinet/in.h>        /* struct sockaddr_in */
X  #include <netdb.h>             /* struct servent * and struct hostent * */
X  #include <errno.h>             /* for EINTR, EADDRINUSE, ... */
X***************
X*** 41,51 ****
X  static short GetScopePort P((void ));
X  static void Usage P((void ));
X  static void ReadStdin P((Pointer private_data ));
X  static void NewConnection P((Pointer private_data ));
X  static void DataFromClient P((Pointer private_data ));
X  static void DataFromServer P((Pointer private_data ));
X  static Bool ReadAndProcessData P((Pointer private_data , FDDescriptor
X! *read_fdd , FDDescriptor *write_fdd ));
X  static void SaveBytes P((Buffer *buffer , char *buf , long n ));
X  static void RemoveSavedBytes P((Buffer *buffer , int n ));
X  static int ConnectToClient P((int ConnectionSocket ));
X--- 44,55 ----
X  static short GetScopePort P((void ));
X  static void Usage P((void ));
X  static void ReadStdin P((Pointer private_data ));
X+ static void do_command P((char *ptr ));
X  static void NewConnection P((Pointer private_data ));
X  static void DataFromClient P((Pointer private_data ));
X  static void DataFromServer P((Pointer private_data ));
X  static Bool ReadAndProcessData P((Pointer private_data , FDDescriptor
X! *read_fdd , FDDescriptor *write_fdd , Bool is_server ));
X  static void SaveBytes P((Buffer *buffer , char *buf , long n ));
X  static void RemoveSavedBytes P((Buffer *buffer , int n ));
X  static int ConnectToClient P((int ConnectionSocket ));
X***************
X*** 63,68 ****
X--- 67,74 ----
X  static Bool ANYSET P((long *src));
X  #endif
X  
X+ extern char *getenv();
X+ 
X  /* end function prototypes */
X  
X  Global Bool    ignore_bytes;
X***************
X*** 95,100 ****
X--- 101,107 ----
X  static long			ClientNumber = 0;
X  static int				ServerPort = 0;
X  static int				ListenForClientsPort = 1;
X+ static Bool     ShowPacketSize = False;     /* show size of net packets? */
X  
X  Global void
X  main(argc, argv)
X***************
X*** 159,164 ****
X--- 166,172 ----
X  {
X  	int i;
X  
X+ 	ServerHostName[0] = '\0';
X  	/* Scan argument list */
X  	for (i = 1; i < argc; i++)
X  		{
X***************
X*** 235,241 ****
X  	LocalHostName = (char *)malloc(255);
X  	(void) gethostname(LocalHostName, 255);
X  	if (ServerHostName[0] == '\0')
X! 		(void) gethostname(ServerHostName, sizeof (ServerHostName));
X  	if (Streq(ServerHostName,LocalHostName) && ListenForClientsPort ==
X  ServerPort)
X  		{
X--- 243,270 ----
X  	LocalHostName = (char *)malloc(255);
X  	(void) gethostname(LocalHostName, 255);
X  	if (ServerHostName[0] == '\0')
X! 	{
X! 		char *display_env_name;
X! 
X! 		if ((display_env_name = getenv("DISPLAY")) == NULL)
X! 			(void) gethostname(ServerHostName, sizeof (ServerHostName));
X! 		else
X! 		{
X! 			char *index;
X! 
X! 			strcpy(ServerHostName, display_env_name);
X! 			index = strchr(ServerHostName, ':');
X! 			if (index != NULL)
X! 			{
X! 				*index = '\0';
X! 				ServerPort = atoi(index + 1);
X! 				if (ServerPort < 0)
X! 					ServerPort = 0;
X! 			}
X! 			if (index == ServerHostName)
X! 				(void) gethostname(ServerHostName, sizeof (ServerHostName));
X! 		}
X! 	}
X  	if (Streq(ServerHostName,LocalHostName) && ListenForClientsPort ==
X  ServerPort)
X  		{
X***************
X*** 325,331 ****
X--- 354,362 ----
X  #else
X  	ioctl(ConnectionSocket, FIOCLEX, 0);
X  #endif
X+ #ifndef SVR4
X  	ioctl(ConnectionSocket, FIONBIO, &ON);
X+ #endif
X  
X  	debug(4,(stderr, "Listening on FD %d\n", ConnectionSocket));
X  	(void)UsingFD(ConnectionSocket, NewConnection, (Pointer)ConnectionSocket);
X***************
X*** 372,379 ****
X  		(
X  			HighestFD + 1, (fd_set *)rfds, (fd_set *)wfds, (fd_set *)xfds, NULL
X  		);
X- 		if (ANYSET(xfds))
X- 			panic("MainLoop: error in select");
X  		if (nfds <= 0)
X  		{
X  			if (errno != EINTR)
X--- 403,408 ----
X***************
X*** 401,406 ****
X--- 430,446 ----
X  						panic("help: which connection do we shut down (TODO?");
X  				}
X  			}
X+ 			for (fd = 0; ANYSET(xfds) && fd <= HighestFD; fd++)
X+ 			{
X+ 				if (GETBIT(xfds, fd))
X+ 				{
X+ 					BITCLEAR(xfds, fd);
X+ 					if (fd == fileno(stdin))
X+ 						NotUsingFD(fd);
X+ 					else
X+ 						fprintf(stderr, "error in select: fd is %d\n", fd);
X+ 				}
X+ 			}
X  		}
X  		client_list.current = client_list.top;
X  		while (client_list.current != (LinkLeaf *)(&client_list))
X***************
X*** 538,576 ****
X  #define REQUEST_BLOCKING_OFF_STR			"request_blocking_off"
X  #define EVENT_BLOCKING_ON_STR				"event_blocking_on"
X  #define EVENT_BLOCKING_OFF_STR				"event_blocking_off"
X  #define QUIT_STR							"quit"
X  #define HELP_STR							"help"
X  
X  #define Strleneq(a,b) Strneq(a, b, strlen(b))
X  
X  static void
X  ReadStdin(private_data)
X  	Pointer				private_data;
X  {
X  	int					fd = (int)private_data;
X! 	char				buf[2048];
X  	char				*ptr;
X  	int					n;
X  
X  	enterprocedure("ReadStdin");
X  	n = read(fd, buf, 2048);
X- 	if (n == 0)
X- 	{
X- 		fprintf(stdout, "EOF on stdin\n");
X- 		exit(0);
X- 	}
X  	if (n < 0)
X  	{
X  		fprintf(stdout, "Error reading stdin\n");
X! 		exit(0);
X  	}
X! 
X! 	buf[n] = '\0';
X  	ptr = buf;
X! 	while (*ptr == ' ' || *ptr == '\t')
X! 		ptr++;
X! 	if (*ptr != '\0')
X  	{
X  		if (Strleneq(ptr, REQUEST_VERBOSE_STR))
X  			RequestVerbose = atoi(ptr + strlen(REQUEST_VERBOSE_STR));
X  		else if (Strleneq(ptr, EVENT_VERBOSE_STR))
X--- 578,654 ----
X  #define REQUEST_BLOCKING_OFF_STR			"request_blocking_off"
X  #define EVENT_BLOCKING_ON_STR				"event_blocking_on"
X  #define EVENT_BLOCKING_OFF_STR				"event_blocking_off"
X+ #define SHOW_PACKET_SIZE_ON_STR				"show_packet_size_on"
X+ #define SHOW_PACKET_SIZE_OFF_STR			"show_packet_size_off"
X  #define QUIT_STR							"quit"
X  #define HELP_STR							"help"
X  
X  #define Strleneq(a,b) Strneq(a, b, strlen(b))
X  
X+ char				save_buf[2048];
X+ int					saved_bytes = 0;
X+ 
X  static void
X  ReadStdin(private_data)
X  	Pointer				private_data;
X  {
X  	int					fd = (int)private_data;
X! 	char				buf[4096];
X  	char				*ptr;
X+ 	char				*end_ptr;
X  	int					n;
X+ 	int					endn;
X  
X  	enterprocedure("ReadStdin");
X  	n = read(fd, buf, 2048);
X  	if (n < 0)
X  	{
X  		fprintf(stdout, "Error reading stdin\n");
X! 		return;
X  	}
X! 	if (n + saved_bytes == 0)
X! 		return;
X! 	if (saved_bytes > 0)
X! 	{
X! 		bcopy(buf, buf + saved_bytes, n);
X! 		bcopy(save_buf, buf, saved_bytes);
X! 		n += saved_bytes;
X! 		saved_bytes = 0;
X! 	}
X  	ptr = buf;
X! 	while(n > 0)
X  	{
X+ 		while (n > 0 && (*ptr == ' ' || *ptr == '\t'))
X+ 		{
X+ 			ptr++;
X+ 			n--;
X+ 		}
X+ 		if (n <= 0)
X+ 			break;
X+ 		end_ptr = ptr;
X+ 		endn = n;
X+ 		while(endn > 0 && *end_ptr != '\n')
X+ 		{
X+ 			end_ptr++;
X+ 			endn--;
X+ 		}
X+ 		if (endn <= 0)
X+ 		{
X+ 			bcopy(ptr, save_buf, n);
X+ 			saved_bytes = n;
X+ 			break;
X+ 		}
X+ 		*end_ptr = '\0';
X+ 		do_command(ptr);
X+ 		ptr = end_ptr + 1;
X+ 		n = endn - 1;
X+ 	}
X+ }
X+ 
X+ static void
X+ do_command(ptr)
X+ 	char				*ptr;
X+ {
X  		if (Strleneq(ptr, REQUEST_VERBOSE_STR))
X  			RequestVerbose = atoi(ptr + strlen(REQUEST_VERBOSE_STR));
X  		else if (Strleneq(ptr, EVENT_VERBOSE_STR))
X***************
X*** 603,608 ****
X--- 681,690 ----
X  			BlockingEvents = True;
X  		else if (Strleneq(ptr, EVENT_BLOCKING_OFF_STR))
X  			BlockingEvents = False;
X+ 		else if (Strleneq(ptr, SHOW_PACKET_SIZE_ON_STR))
X+ 			ShowPacketSize = True;
X+ 		else if (Strleneq(ptr, SHOW_PACKET_SIZE_OFF_STR))
X+ 			ShowPacketSize = False;
X  		else if (Strleneq(ptr, SELECTED_REQUEST_VERBOSE_STR))
X  			SelectedRequestVerbose =
X  				atoi(ptr +strlen(SELECTED_REQUEST_VERBOSE_STR));
X***************
X*** 695,701 ****
X  			(
X  				stdout, "illegal command: %s\n\"help\" to get help\n", ptr
X  			);
X- 	}
X  }
X  
X  /*
X--- 777,782 ----
X***************
X*** 740,746 ****
X  	Server					*server;
X  
X  	server = (Server *)(TopOfList(&client->server_list));
X! 	if (!ReadAndProcessData(private_data, client->fdd, server->fdd))
X  		CloseConnection(client);
X  }
X  
X--- 821,827 ----
X  	Server					*server;
X  
X  	server = (Server *)(TopOfList(&client->server_list));
X! 	if (!ReadAndProcessData(private_data, client->fdd, server->fdd, False))
X  		CloseConnection(client);
X  }
X  
X***************
X*** 751,757 ****
X  	Server					*server = (Server *)private_data;
X  	Client					*client = server->client;
X  
X! 	if (!ReadAndProcessData(private_data, server->fdd, client->fdd))
X  		CloseConnection(client);
X  }
X  
X--- 832,838 ----
X  	Server					*server = (Server *)private_data;
X  	Client					*client = server->client;
X  
X! 	if (!ReadAndProcessData(private_data, server->fdd, client->fdd, True))
X  		CloseConnection(client);
X  }
X  
X***************
X*** 801,815 ****
X   */
X  
X  static Bool
X! ReadAndProcessData(private_data, read_fdd, write_fdd)
X  	Pointer					private_data;
X  	FDDescriptor			*read_fdd;
X  	FDDescriptor			*write_fdd;
X  {
X  	Buffer					*inbuffer = &read_fdd->inBuffer;
X  	Buffer					*outbuffer = &write_fdd->outBuffer;
X  	int						fd = read_fdd->fd;
X! 	char					read_buf_block[2048];
X  	char					*read_buf = read_buf_block;
X  	int						num_read;
X  	char					*process_buf;
X--- 882,897 ----
X   */
X  
X  static Bool
X! ReadAndProcessData(private_data, read_fdd, write_fdd, is_server)
X  	Pointer					private_data;
X  	FDDescriptor			*read_fdd;
X  	FDDescriptor			*write_fdd;
X+ 	Bool					is_server;
X  {
X  	Buffer					*inbuffer = &read_fdd->inBuffer;
X  	Buffer					*outbuffer = &write_fdd->outBuffer;
X  	int						fd = read_fdd->fd;
X! 	char					read_buf_block[16384];
X  	char					*read_buf = read_buf_block;
X  	int						num_read;
X  	char					*process_buf;
X***************
X*** 816,822 ****
X  	int						NumberofUsedBytes;
X  	int						BytesToSave;
X  
X! 	num_read = read(fd, read_buf, 2048);
X  	if (num_read < 0)
X  	{
X  		perror("read error");
X--- 898,916 ----
X  	int						NumberofUsedBytes;
X  	int						BytesToSave;
X  
X! 	num_read = read(fd, read_buf, 16384);
X! 	if (ShowPacketSize)
X! 	{
X! 		if (is_server)
X! 			fprintf(stdout, "\t\t\t\t\t");
X! 		else
X! 			fprintf(stdout, "Client %d --> ", read_fdd->fd);
X! 		fprintf(stdout, "%4d byte%s", num_read, (num_read == 1) ? "" : "s");
X! 		if (is_server)
X! 			fprintf(stdout, "<-- Server %d\n", read_fdd->fd);
X! 		else
X! 			fprintf(stdout, "\n");
X! 	}
X  	if (num_read < 0)
X  	{
X  		perror("read error");
X***************
X*** 950,956 ****
X--- 1044,1052 ----
X  #else
X  	ioctl(ClientFD, FIOCLEX, 0);
X  #endif
X+ #ifndef SVR4
X  	ioctl(ClientFD, FIONBIO, &ON);
X+ #endif
X  	return(ClientFD);
X  }
X  
Xdiff -c version2/prtype.c version3/prtype.c
X*** version2/prtype.c	Thu Sep 27 16:44:52 1990
X--- version3/prtype.c	Fri Oct 12 19:28:48 1990
X***************
X*** 581,588 ****
X  		unsigned char *buf;
X  {
X  	/* print an EVENT_FORM -- event format */
X! 	fprintf(stdout, "PrintEVENTFORM: calling DecodeEvent with NULL server!\n");
X! 	DecodeEvent((Server *)NULL, buf, (long)-1);
X  }
X  
X  Global void
X--- 581,587 ----
X  		unsigned char *buf;
X  {
X  	/* print an EVENT_FORM -- event format */
X! 	DecodeEvent((Server *)NULL, buf, (long)-1, False);
X  }
X  
X  Global void
Xdiff -c version2/server.c version3/server.c
X*** version2/server.c	Thu Sep 27 17:36:46 1990
X--- version3/server.c	Fri Oct 12 19:28:57 1990
X***************
X*** 312,318 ****
X  	unsigned char			*buf;
X  	long					n;
X  {
X! 	DecodeEvent(server, buf, n);
X  	server->fdd->ByteProcessing = ServerPacket;
X  	server->fdd->inBuffer.num_Needed = 32;
X  	return(n);
X--- 312,318 ----
X  	unsigned char			*buf;
X  	long					n;
X  {
X! 	DecodeEvent(server, buf, n, True);
X  	server->fdd->ByteProcessing = ServerPacket;
X  	server->fdd->inBuffer.num_Needed = 32;
X  	return(n);
Xdiff -c version2/widgeti.c version3/widgeti.c
X*** version2/widgeti.c	Thu Sep 27 16:44:53 1990
X--- version3/widgeti.c	Thu Nov  1 18:57:22 1990
X***************
X*** 4,10 ****
X--- 4,14 ----
X   *  Description: Routines to build various widget combinations
X   */
X  #include    <stdio.h>
X+ #ifdef SVR4
X+ #include    <string.h>
X+ #else
X  #include    <strings.h>
X+ #endif
X  #include	<X11/cursorfont.h>
X  #include	<X11/Intrinsic.h>
X  #include	<X11/StringDefs.h>
Xdiff -c version2/xmon.man version3/xmon.man
X*** version2/xmon.man	Thu Sep 27 16:44:53 1990
X--- version3/xmon.man	Fri Nov  2 15:13:49 1990
X***************
X*** 1,4 ****
X! .TH xmon 1 "September, 1990" "X Version 11"
X  .SH NAME
X  xmon \- interactive X protocol monitor
X  .SH SYNOPSIS
X--- 1,4 ----
X! .TH xmon 1 "November, 1990" "X Version 11"
X  .SH NAME
X  xmon \- interactive X protocol monitor
X  .SH SYNOPSIS
X***************
X*** 54,60 ****
X  
X  .PP
X  In the diagram the vertical connections are pipes and the horizontal
X! connections are normal X connections.
X  .PP
X  Xmond sits transparently between the X clients and an X server.
X  To the clients it behaves just like an X server and to the server
X--- 54,60 ----
X  
X  .PP
X  In the diagram the vertical connections are pipes and the horizontal
X! connections are normal X socket connections.
X  .PP
X  Xmond sits transparently between the X clients and an X server.
X  To the clients it behaves just like an X server and to the server
X***************
X*** 63,70 ****
X  .TP
X  .B "-server \fIdisplay_name\fP:\fIdisplay_number\fP"
X  This option sets the X display which xmond connects to.
X! Default for \fIdisplay_name\fP is the local host.
X! Default for \fIdisplay_number\fP is 0.
X  .TP
X  .B "-port \fIdisplay_number\fP"
X  This option sets the 
X--- 63,72 ----
X  .TP
X  .B "-server \fIdisplay_name\fP:\fIdisplay_number\fP"
X  This option sets the X display which xmond connects to.
X! The default for both values is the value of the DISPLAY environment
X! variable. If this is not set, then the
X! default for \fIdisplay_name\fP is the local host and the
X! default for \fIdisplay_number\fP is 0.
X  .TP
X  .B "-port \fIdisplay_number\fP"
X  This option sets the 
X***************
X*** 88,93 ****
X--- 90,123 ----
X  The xmonui user interface will
X  appear on the display \fIlocalhost:0\fP.
X  .PP
X+ When starting up the application that you want to monitor, be sure to set
X+ it's display correctly.
X+ When you normally start up an X application, and if
X+ you have not done anything special, it
X+ will by default start up on display 0 of your local host.
X+ But xmon by default
X+ is listening as if it is display 1 of your local host. Assuming your X
X+ application
X+ is called "myclient" and your local host name is "dolphin" then type the
X+ following to start up your application:
X+ 
X+ myclient -display dolphin:1
X+ 
X+ Another way to do the same thing is to change the DISPLAY environment
X+ variable. If you are using a C shell you can do this:
X+ 
X+ setenv DISPLAY dolphin:1
X+ .br
X+ myclient
X+ 
X+ If you are not using a C shell, you may have to do something
X+ different to change the DISPLAY environment variable.
X+ Also, most clients understand the -display option, but there are those
X+ that do not.
X+ To determine the name of your local host try
X+ the \fIhostname\fP command (although it may not be available
X+ on all machines).
X+ .PP
X  2) If you are on the host \fIsquiggle\fP which has two X servers using
X  the displays \fIsquiggle:0\fP and \fIsquiggle:1\fP, and want to monitor
X  connections made to the server running on the display
X***************
X*** 127,132 ****
X--- 157,174 ----
X  .I hex
X  All fields of the message are output, as well as a hexadecimal dump.
X  .PP
X+ Note that synthetic events (events sent by XSendEvent) are 
X+ monitored in the same way as normal events but are identified as
X+ being "SYNTHETIC".
X+ .PP
X+ Also in this section is the \fIshow packet size\fP toggle. If this is
X+ turned \fIon\fP, xmon will display the size of each packet received from
X+ both clients and servers. The file descriptor of the client or server
X+ which sent the packet is also displayed. The first client file
X+ descriptor is 4. File descriptors 0, 1 and 2 are used by standard
X+ input, standard output and standard error and file descriptor 3 is where
X+ xmon listens for new connections.
X+ .PP
X  In the \fIstatistics\fP section, the counting of requests, events and
X  errors can be controlled as follows.
X  .TP
X***************
X*** 166,176 ****
X  .PP
X  The \fIselected events\fP section is similar to the above section but
X  deals with events received from the server.
X! .SH BUGS
X! Tested only on Sun3 machines. Byte swapping may produce problems on other
X! machines.
X  .PP
X  No provision is included for extensions to the base protocol.
X  .SH SEE ALSO
X  X(1)
X  .PP
X--- 208,278 ----
X  .PP
X  The \fIselected events\fP section is similar to the above section but
X  deals with events received from the server.
X! .SH USING XMOND WITHOUT XMONUI
X! Normally xmonui is used as an interactive interface to xmond. However,
X! for some testing procedures it may be better to run xmond by itself
X! initialising it with some standard setup.
X! The interface between xmonui and xmond is made up of simple ascii
X! strings.
X! Pressing buttons on xmonui causes it to write these strings to
X! standard output which are then usually read by xmond.
X! You can just run xmond by itself
X! and type in the strings, or, even better, use a file as input to xmond.
X! There are too many strings to list here, but
X! if you run xmonui by itself, you will see the strings being printed to
X! standard output.
X! Run
X! 
X! xmonui > command.file
X! 
X! to create a file of strings that can be used as input to xmond.
X! For example, a file which will cause xmond to monitor the Bell request
X! and also print the names of all events would contain the lines:
X! 
X! monitor_request_on 104
X! .br
X! event_verbose 1
X! 
X! Running
X! 
X! xmond < command.file
X! 
X! will then set up xmond in the same way each time. Note that when
X! running xmond by itself, it does not
X! exit on reading end-of-file and so it must be killed. (I use
X! CONTROL-C to kill.
X! Your kill character may be different.)
X  .PP
X+ It is also possible to initialise xmond with a file, and then
X+ take further commands from xmonui by running
X+ 
X+ xmonui | cat command.file - | xmond
X+ 
X+ The cat command first sends the command.file to xmond and then passes the
X+ output of xmonui to xmond. Please note that in this case xmonui will not
X+ show the new state of xmond correctly.
X+ For example, xmonui starts up assuming that
X+ no requests have been selected, even if the command.file has initialised
X+ xmond by selecting some requests.
X+ This inconsistency does not effect the usability of xmon
X+ but may be confusing.
X+ .PP
X+ The string
X+ 
X+ quit
X+ 
X+ will cause xmond to exit, so make sure that this does not occur in
X+ any input file. Also it is meaningless to use the statistics commands
X+ from within an input file because these will be read before any X clients
X+ have connected.
X+ .SH BUGS
X  No provision is included for extensions to the base protocol.
X+ .PP
X+ Xmon only handles TCP socket connections.
X+ UNIX domain sockets and DECnet are not supported.
X+ .PP
X+ There should be a better way of initialising the state of xmond and having
X+ this new state reflected in xmonui.
X  .SH SEE ALSO
X  X(1)
X  .PP
Xdiff -c version2/xmond.h version3/xmond.h
X*** version2/xmond.h	Thu Sep 27 16:44:54 1990
X--- version3/xmond.h	Mon Nov  5 13:13:41 1990
X***************
X*** 98,103 ****
X  Global void DecodeReply P((Server *server , unsigned char *buf , long n ));
X  Global void DecodeError P((Server *server , unsigned char *buf , long n ));
X! Global void DecodeEvent P((Server *server , unsigned char *buf , long n ));
X  Global void KeepLastReplyExpected P((void ));
X  /* print11.c: */
X  Global void PrintSetUpMessage P((unsigned char *buf ));
X--- 98,104 ----
X  Global void DecodeReply P((Server *server , unsigned char *buf , long n ));
X  Global void DecodeError P((Server *server , unsigned char *buf , long n ));
X! Global void DecodeEvent P((Server *server , unsigned char *buf , long n ,
X! Bool real_event ));
X  Global void KeepLastReplyExpected P((void ));
X  /* print11.c: */
X  Global void PrintSetUpMessage P((unsigned char *buf ));
Xdiff -c version2/xmonui.c version3/xmonui.c
X*** version2/xmonui.c	Thu Sep 27 16:44:54 1990
X--- version3/xmonui.c	Fri Nov  2 14:09:18 1990
X***************
X*** 125,130 ****
X--- 125,134 ----
X  		/*"0\n1\n2\n3\n4", "reply_verbose %s\n", "0"*/
X  	},
X  	{
X+ 		"show packet size       ",
X+ 		"off\non", "show_packet_size_%s\n", "off"
X+ 	},
X+ 	{
X  		"detail ",
X  		DETAIL_STR, "selected_request_verbose", "full"
X  		/*"0\n1\n2\n3\n4", "selected_request_verbose %s\n", "3"*/
X***************
X*** 136,153 ****
X  	},
X  	{
X  		" blocking ",
X! 		"on\noff", "request_blocking_%s\n", "on"
X  	},
X  	{
X  		" blocking ",
X! 		"on\noff", "event_blocking_%s\n", "on"
X  	},
X  };
X- #define REQUEST_VERBOSE			4
X- #define EVENT_VERBOSE			5
X- #define REQUEST_BLOCKING		6
X- #define EVENT_BLOCKING			7
X  
X  #define NUM_TOGGLES (sizeof(toggledata) / sizeof(ToggleData))
X  
X  typedef struct
X--- 140,159 ----
X  	},
X  	{
X  		" blocking ",
X! 		"off\non", "request_blocking_%s\n", "on"
X  	},
X  	{
X  		" blocking ",
X! 		"off\non", "event_blocking_%s\n", "on"
X  	},
X  };
X  
X+ #define NUM_FIRST_TOGGLES		5
X+ #define REQUEST_VERBOSE			5
X+ #define EVENT_VERBOSE			6
X+ #define REQUEST_BLOCKING		7
X+ #define EVENT_BLOCKING			8
X+ 
X  #define NUM_TOGGLES (sizeof(toggledata) / sizeof(ToggleData))
X  
X  typedef struct
X***************
X*** 213,219 ****
X  	for (toggle_count = 0; toggle_count < NUM_TOGGLES; toggle_count++)
X  		if (toggledata[toggle_count].widget == XtParent(widget))
X  		{
X! 			if (toggle_count < 6)
X  			{
X  				printf(toggledata[toggle_count].output_string);
X  				if (Streq((char*) client_data, "off"))
X--- 219,225 ----
X  	for (toggle_count = 0; toggle_count < NUM_TOGGLES; toggle_count++)
X  		if (toggledata[toggle_count].widget == XtParent(widget))
X  		{
X! 			if (toggle_count < 4 || toggle_count == 5 || toggle_count == 6)
X  			{
X  				printf(toggledata[toggle_count].output_string);
X  				if (Streq((char*) client_data, "off"))
X***************
X*** 415,421 ****
X  
X  
X  /* verbose level toggles */
X! 	for (toggle_count = 0; toggle_count < 4; toggle_count++)
X  		widget = build_toggle(form, toggle_count, widget);
X  
X  /* counting buttons */
X--- 421,427 ----
X  
X  
X  /* verbose level toggles */
X! 	for (toggle_count = 0; toggle_count < NUM_FIRST_TOGGLES; toggle_count++)
X  		widget = build_toggle(form, toggle_count, widget);
X  
X  /* counting buttons */
SHAR_EOF
$TOUCH -am 1113133890 xmon.patch3 &&
chmod 0664 xmon.patch3 ||
echo "restore of xmon.patch3 failed"
set `wc -c xmon.patch3`;Wc_c=$1
if test "$Wc_c" != "28460"; then
	echo original size 28460, current size $Wc_c
fi
fi
exit 0

dan
----------------------------------------------------
O'Reilly && Associates   argv@sun.com / argv@ora.com
Opinions expressed reflect those of the author only.
--
dan
----------------------------------------------------
O'Reilly && Associates   argv@sun.com / argv@ora.com
Opinions expressed reflect those of the author only.