x3270 v3.0.1 Patch Set #3, 29. November 1993

  This file is in 'patch' format.  To apply, run 'patch <x3270-3.0.1.fix03'.
  If you don't have 'patch', it is readily available on the net.

  New patches and releases are available by anonymous ftp from ftp.x.org.

Fix typo which most compilers let pass.

*** globals.h.orig	Thu Nov  4 12:50:16 1993
--- globals.h	Thu Nov  4 12:50:17 1993
***************
*** 111,117 ****
  #define toggled(ix)		(appres.toggle[ix].value)
  #define toggle_toggle(t)	((t)->value = !(t)->value)
  
! extern enum placement { Center, Bottom, Right };
  extern enum kp_placement { kp_right, kp_bottom, kp_integral } kp_placement;
  
  extern struct trans_list {
--- 111,117 ----
  #define toggled(ix)		(appres.toggle[ix].value)
  #define toggle_toggle(t)	((t)->value = !(t)->value)
  
! enum placement { Center, Bottom, Right };
  extern enum kp_placement { kp_right, kp_bottom, kp_integral } kp_placement;
  
  extern struct trans_list {

Fix can't-ever-happen which apparently did.

*** telnet.c.orig	Thu Nov  4 12:50:22 1993
--- telnet.c	Thu Nov  4 12:50:23 1993
***************
*** 288,293 ****
--- 288,295 ----
  
  	nr = read(sock, (char *) netrbuf, BUFSZ);
  	if (nr < 0) {
+ 		if (errno == EWOULDBLOCK)
+ 			return;
  		if (HALF_CONNECTED && errno == EAGAIN) {
  			if (non_blocking(False) < 0) {
  				x_disconnect();

Fix for error in the response to the READ BUFFER command, which wasn't
properly encoding attribute bytes.

*** ctlr.c.orig	Mon Nov 15 11:35:56 1993
--- ctlr.c	Mon Nov 15 11:35:57 1993
***************
*** 62,68 ****
  static void	do_erase_all_unprotected();
  static void	do_write();
  
! /* code_table is used to translate buffer addresses to the 3270
   * datastream representation
   */
  static unsigned char	code_table[64] = {
--- 62,68 ----
  static void	do_erase_all_unprotected();
  static void	do_write();
  
! /* code_table is used to translate buffer addresses and attributes to the 3270
   * datastream representation
   */
  static unsigned char	code_table[64] = {
***************
*** 595,601 ****
  			if (FA_IS_MODIFIED(screen_buf[baddr]))
  				fa |= 0x01;
  			fa |= ((screen_buf[baddr] & FA_INTENSITY) << 2);
! 			*obptr++ = fa;
  			if (toggled(TRACE3270)) {
  				if (!last_fa)
  					(void) printf("'");
--- 595,601 ----
  			if (FA_IS_MODIFIED(screen_buf[baddr]))
  				fa |= 0x01;
  			fa |= ((screen_buf[baddr] & FA_INTENSITY) << 2);
! 			*obptr++ = code_table[fa];
  			if (toggled(TRACE3270)) {
  				if (!last_fa)
  					(void) printf("'");

Fix OpenWindows font targets in Makefile.aux.

*** Makefile.aux.orig	Wed Nov 17 13:49:46 1993
--- Makefile.aux	Wed Nov 17 13:49:47 1993
***************
*** 62,68 ****
  
  OWFONTOBJS = $(FONTS:%.bdf=%.fb)
  .bdf.fb:
! 	convertfont -d. $<
  .SUFFIXES: .bdf .fb $(SUFFIXES)
  
  LIBS = -lXaw -lXmu -lX11 -lXt -lXext -lX11 -lm
--- 62,68 ----
  
  OWFONTOBJS = $(FONTS:%.bdf=%.fb)
  .bdf.fb:
! 	$(OPENWINHOME)/bin/convertfont -d. -o `basename $@ .fb` $<
  .SUFFIXES: .bdf .fb $(SUFFIXES)
  
  LIBS = -lXaw -lXmu -lX11 -lXt -lXext -lX11 -lm
***************
*** 90,96 ****
  	@$(RM) version.c
  
  # Make x3270 for OpenWindows 3
! ow3: x3270
  
  # Install x3270 under OpenWindows 3: assumes you want to put everything in
  # $OPENWINHOME.
--- 90,96 ----
  	@$(RM) version.c
  
  # Make x3270 for OpenWindows 3
! ow3: x3270 $(OWFONTOBJS)
  
  # Install x3270 under OpenWindows 3: assumes you want to put everything in
  # $OPENWINHOME.
***************
*** 97,103 ****
  ow3.install: ow3
  	install -m 755 x3270 $(OPENWINHOME)/bin
  	cp $(OWFONTOBJS) $(OPENWINHOME)/lib/fonts
! 	mkfontdir $(OPENWINHOME)/lib/fonts
  	cp X3270.ad $(OPENWINHOME)/lib/app-defaults/X3270
  	cp x3270.man $(OPENWINHOME)/man/man1/x3270.1
  	cp ibm_hosts.man $(OPENWINHOME)/man/man5/ibm_hosts.5
--- 97,103 ----
  ow3.install: ow3
  	install -m 755 x3270 $(OPENWINHOME)/bin
  	cp $(OWFONTOBJS) $(OPENWINHOME)/lib/fonts
! 	$(OPENWINHOME)/bin/mkfontdir $(OPENWINHOME)/lib/fonts
  	cp X3270.ad $(OPENWINHOME)/lib/app-defaults/X3270
  	cp x3270.man $(OPENWINHOME)/man/man1/x3270.1
  	cp ibm_hosts.man $(OPENWINHOME)/man/man5/ibm_hosts.5

Fix a typo in X3270.ad.

*** X3270.ad.orig	Wed Nov 17 13:51:25 1993
--- X3270.ad	Wed Nov 17 13:51:25 1993
***************
*** 9,15 ****
  ! easily uncomment and change them.
  !
  !   Fonts
! ! x3270.eumlatorFont:		3270
  !
  !   Colors
  ! x3270.colorBackground:	black
--- 9,15 ----
  ! easily uncomment and change them.
  !
  !   Fonts
! ! x3270.emulatorFont:		3270
  !
  !   Colors
  ! x3270.colorBackground:	black

Fix a spelling error in x3270.man.

*** x3270.man.orig	Wed Nov 17 13:53:41 1993
--- x3270.man	Wed Nov 17 13:53:42 1993
***************
*** 669,675 ****
  .B Note:
  The default keymap defines the "Multi_key" keysym as the "Compose" key.
  If your keyboard lacks such a key, you may set up your own "Compose" key with
! a keymap that maps smoe other keysym onto the "Compose" action.
  .SH "APL SUPPORT"
  .B x3270
  supports an
--- 669,675 ----
  .B Note:
  The default keymap defines the "Multi_key" keysym as the "Compose" key.
  If your keyboard lacks such a key, you may set up your own "Compose" key with
! a keymap that maps some other keysym onto the "Compose" action.
  .SH "APL SUPPORT"
  .B x3270
  supports an

Proper fix for the problem with the nulling-out behavior of PT orders.
Versions 1.2 through 3.0.1.1 did it too often; v3.0.1.2 didn't do it at all.
[Identified by a number of people; primary help from Ilia Levi.]

*** 3270.h.orig	Wed Nov 17 14:04:44 1993
--- 3270.h	Wed Nov 17 14:04:45 1993
***************
*** 45,50 ****
--- 45,60 ----
  #define ORDER_GE	0x08	/* graphic escape */
  #define ORDER_YALE	0x2B	/* Yale sub command */
  
+ #define FCORDER_NULL	0x00	/* format control: null */
+ #define FCORDER_SUB	0x3F	/*		   substitute */
+ #define FCORDER_DUP	0x1C	/*		   duplicate */
+ #define FCORDER_FM	0x1E	/*		   field mark */
+ #define FCORDER_FF	0x0C	/*		   form feed */
+ #define FCORDER_CR	0x0D	/*		   carriage return */
+ #define FCORDER_NL	0x15	/*		   new line */
+ #define FCORDER_EM	0x19	/*		   end of medium */
+ #define FCORDER_EO	0xFF	/*		   eight ones */
+ 
  #define fCHAR_WIDTH(f)	((f)->max_bounds.width)
  #define CHAR_WIDTH	fCHAR_WIDTH(*efontinfo)
  #define fCHAR_HEIGHT(f)	((f)->ascent + (f)->descent)
*** kybd.c.orig	Wed Nov 17 14:04:50 1993
--- kybd.c	Wed Nov 17 14:04:52 1993
***************
*** 85,114 ****
  
  
  /*
-  * Find the next unprotected field.  Returns the address following the
-  * unprotected attribute byte, or 0 if no nonzero-width unprotected field
-  * can be found.
-  */
- static int
- next_unprotected(baddr0)
- int baddr0;
- {
- 	register int baddr, nbaddr;
- 
- 	nbaddr = baddr0;
- 	do {
- 		baddr = nbaddr;
- 		INC_BA(nbaddr);
- 		if (IS_FA(screen_buf[baddr]) &&
- 		    !FA_IS_PROTECTED(screen_buf[baddr]) &&
- 		    !IS_FA(screen_buf[nbaddr]))
- 			return nbaddr;
- 	} while (nbaddr != baddr0);
- 	return 0;
- }
- 
- 
- /*
   * Handle an AID (Attention IDentifier) key.  This is the common stuff that
   * gets executed for all AID keys (PFs, PAs, Clear and etc).
   */
--- 85,90 ----
*** globals.h.orig	Wed Nov 17 14:04:56 1993
--- globals.h	Wed Nov 17 14:04:57 1993
***************
*** 181,186 ****
--- 181,187 ----
  extern unsigned char *get_field_attribute();
  extern void mdt_clear();
  extern void mdt_set();
+ extern int next_unprotected();
  extern int process_ds();
  extern void ps_process();
  extern void ps_set();
*** ctlr.c.orig	Wed Nov 17 14:05:02 1993
--- ctlr.c	Wed Nov 17 14:05:03 1993
***************
*** 166,171 ****
--- 166,191 ----
  {
  	static char buf[8];
  
+ 	switch (ch) {
+ 	    case FCORDER_NULL:
+ 		return "NULL";
+ 	    case FCORDER_SUB:
+ 		return "SUB";
+ 	    case FCORDER_DUP:
+ 		return "DUP";
+ 	    case FCORDER_FM:
+ 		return "FM";
+ 	    case FCORDER_FF:
+ 		return "FF";
+ 	    case FCORDER_CR:
+ 		return "CR";
+ 	    case FCORDER_NL:
+ 		return "NL";
+ 	    case FCORDER_EM:
+ 		return "EM";
+ 	    case FCORDER_EO:
+ 		return "EO";
+ 	}
  	if (ebc2asc[ch])
  		(void) sprintf(buf, "%c", ebc2asc[ch]);
  	else
***************
*** 230,235 ****
--- 250,278 ----
  }
  
  /*
+  * Find the next unprotected field.  Returns the address following the
+  * unprotected attribute byte, or 0 if no nonzero-width unprotected field
+  * can be found.
+  */
+ int
+ next_unprotected(baddr0)
+ int baddr0;
+ {
+ 	register int baddr, nbaddr;
+ 
+ 	nbaddr = baddr0;
+ 	do {
+ 		baddr = nbaddr;
+ 		INC_BA(nbaddr);
+ 		if (IS_FA(screen_buf[baddr]) &&
+ 		    !FA_IS_PROTECTED(screen_buf[baddr]) &&
+ 		    !IS_FA(screen_buf[nbaddr]))
+ 			return nbaddr;
+ 	} while (nbaddr != baddr0);
+ 	return 0;
+ }
+ 
+ /*
   * Perform an erase command, which may include changing the (virtual) screen
   * size.
   */
***************
*** 337,343 ****
  {
  	switch (code) {
  	case AID_NO: 
! 		return "None?";
  	case AID_ENTER: 
  		return "Enter";
  	case AID_PF1: 
--- 380,386 ----
  {
  	switch (code) {
  	case AID_NO: 
! 		return "NoAID";
  	case AID_ENTER: 
  		return "Enter";
  	case AID_PF1: 
***************
*** 601,618 ****
  					(void) printf("'");
  				(void) printf(" SF%s%s", rcba(baddr),
  				    see_attr(fa));
  			}
! 			last_fa = False;
! 		}
! 		else {
  			*obptr++ = cg2ebc[screen_buf[baddr]];
  			if (toggled(TRACE3270)) {
! 				if (last_fa)
! 					(void) printf(" '");
  			}
- 			if (toggled(TRACE3270))
- 				(void) printf("%s", see_ebc(cg2ebc[screen_buf[baddr]]));
- 			last_fa = False;
  		}
  		INC_BA(baddr);
  	} while (baddr != 0);
--- 644,670 ----
  					(void) printf("'");
  				(void) printf(" SF%s%s", rcba(baddr),
  				    see_attr(fa));
+ 				last_fa = True;
  			}
! 		} else {
  			*obptr++ = cg2ebc[screen_buf[baddr]];
  			if (toggled(TRACE3270)) {
! 				if (cg2ebc[screen_buf[baddr]] <= 0x3f ||
! 				    cg2ebc[screen_buf[baddr]] == 0xff) {
! 					if (!last_fa)
! 						(void) printf("'");
! 
! 					(void) printf(" %s",
! 					    see_ebc(cg2ebc[screen_buf[baddr]]));
! 					last_fa = True;
! 				} else {
! 					if (last_fa)
! 						(void) printf(" '");
! 					(void) printf("%s",
! 					    see_ebc(cg2ebc[screen_buf[baddr]]));
! 					last_fa = False;
! 				}
  			}
  		}
  		INC_BA(baddr);
  	} while (baddr != 0);
***************
*** 692,697 ****
--- 744,750 ----
  	unsigned char	*current_fa;
  	unsigned char	new_attr;
  	Boolean		last_cmd;
+ 	Boolean		last_zpt;
  	Boolean		wcc_keyboard_restore, wcc_sound_alarm;
  	unsigned char	temp_aid2;
  	char		paren = '(';
***************
*** 731,744 ****
  		(void) printf(")");
  
  	last_cmd = True;
  	current_fa = get_field_attribute(buffer_addr);
  	for (cp = &buf[2]; cp < (buf + buflen); cp++) {
  		switch (*cp) {
- 		case ORDER_GE:	/* graphic escape - ignore */
- 			if (toggled(TRACE3270))
- 				END_TEXT("GE");
- 			last_cmd = True;
- 			break;
  		case ORDER_SF:	/* start field */
  			if (toggled(TRACE3270)) {
  				END_TEXT("SF");
--- 784,793 ----
  		(void) printf(")");
  
  	last_cmd = True;
+ 	last_zpt = False;
  	current_fa = get_field_attribute(buffer_addr);
  	for (cp = &buf[2]; cp < (buf + buflen); cp++) {
  		switch (*cp) {
  		case ORDER_SF:	/* start field */
  			if (toggled(TRACE3270)) {
  				END_TEXT("SF");
***************
*** 760,765 ****
--- 809,815 ----
  			formatted = True;
  			INC_BA(buffer_addr);
  			last_cmd = True;
+ 			last_zpt = False;
  			break;
  		case ORDER_SBA:	/* set buffer address */
  			cp += 2;	/* skip buffer address */
***************
*** 774,779 ****
--- 824,830 ----
  			}
  			current_fa = get_field_attribute(buffer_addr);
  			last_cmd = True;
+ 			last_zpt = False;
  			break;
  		case ORDER_IC:	/* insert cursor */
  			if (toggled(TRACE3270))
***************
*** 780,820 ****
  				END_TEXT("IC");
  			cursor_move(buffer_addr);
  			last_cmd = True;
  			break;
  		case ORDER_PT:	/* program tab */
  			if (toggled(TRACE3270))
  				END_TEXT("PT");
! 			baddr = buffer_addr;
! 			while (True) {
! 				if (IS_FA(screen_buf[baddr])
! 				    &&  (!FA_IS_PROTECTED(screen_buf[baddr]))) {
! 					current_fa = &screen_buf[baddr];
! 					INC_BA(baddr);
! 					buffer_addr = baddr;
! #ifdef notdef
! 					/*
! 					 * Under certain conditions, PT is
! 					 * supposed to null out the field,
! 					 * but these ain't them.
! 					 */
! 					if (!last_cmd) {
! 						while (!IS_FA(screen_buf[baddr])) {
! 							ctlr_add(baddr, CG_NULLBLANK);
! 							INC_BA(baddr);
! 						}
! 					}
! #endif
! 					break;
  				}
! 				else {
! 					INC_BA(baddr);
! 					if (baddr == 0) {
! 						buffer_addr = baddr;
! 						current_fa = get_field_attribute(baddr);
! 						break;
! 					}
! 				}
! 			}
  			last_cmd = True;
  			break;
  		case ORDER_RA:	/* repeat to address */
--- 831,863 ----
  				END_TEXT("IC");
  			cursor_move(buffer_addr);
  			last_cmd = True;
+ 			last_zpt = False;
  			break;
  		case ORDER_PT:	/* program tab */
  			if (toggled(TRACE3270))
  				END_TEXT("PT");
! 			baddr = next_unprotected(buffer_addr);
! 			if (baddr < buffer_addr)
! 				baddr = 0;
! 			/*
! 			 * Null out the remainder of the current field -- even
! 			 * if protected -- if the PT doesn't follow a command
! 			 * or order, or (honestly) if the last order we saw was
! 			 * a null-filling PT that left the buffer address at 0.
! 			 */
! 			if (!last_cmd || last_zpt) {
! 				if (toggled(TRACE3270))
! 					(void) printf("(nulling)");
! 				while ((buffer_addr != baddr) &&
! 				       (!IS_FA(screen_buf[buffer_addr]))) {
! 					ctlr_add(buffer_addr, CG_NULLBLANK);
! 					INC_BA(buffer_addr);
  				}
! 				if (baddr == 0)
! 					last_zpt = True;
! 			} else
! 				last_zpt = False;
! 			buffer_addr = baddr;
  			last_cmd = True;
  			break;
  		case ORDER_RA:	/* repeat to address */
***************
*** 842,847 ****
--- 885,891 ----
  			}
  			current_fa = get_field_attribute(buffer_addr);
  			last_cmd = True;
+ 			last_zpt = False;
  			break;
  		case ORDER_EUA:	/* erase unprotected to address */
  			cp += 2;	/* skip buffer address */
***************
*** 864,886 ****
  			} while (buffer_addr != baddr);
  			current_fa = get_field_attribute(buffer_addr);
  			last_cmd = True;
  			break;
  		case ORDER_MF:	/* modify field */
  			if (toggled(TRACE3270))
! 				(void) printf(" MF");
! 			/* unsupported 3270 order */
  			break;
  		case ORDER_SFE:	/* start field extended */
  			if (toggled(TRACE3270))
! 				(void) printf(" SFE");
! 			/* unsupported 3270 order */
  			break;
  		case ORDER_SA:	/* set attribute */
  			if (toggled(TRACE3270))
! 				(void) printf(" SA");
! 			/* unsupported 3270 order */
  			break;
  		default:	/* enter character */
  			if (toggled(TRACE3270)) {
  				START_TEXT;
  				(void) printf("%s", see_ebc(*cp));
--- 908,969 ----
  			} while (buffer_addr != baddr);
  			current_fa = get_field_attribute(buffer_addr);
  			last_cmd = True;
+ 			last_zpt = False;
  			break;
+ 		case ORDER_GE:	/* graphic escape */
+ 			if (toggled(TRACE3270))
+ 				END_TEXT("GE[unsupported]");
+ 			cp++;
+ 			last_cmd = True;
+ 			last_zpt = False;
+ 			break;
  		case ORDER_MF:	/* modify field */
  			if (toggled(TRACE3270))
! 				END_TEXT("MF[unsupported]");
! 			cp += *(cp + 1) * 2;
! 			last_cmd = True;
! 			last_zpt = False;
  			break;
  		case ORDER_SFE:	/* start field extended */
  			if (toggled(TRACE3270))
! 				END_TEXT("SFE[unsupported]");
! 			cp += *(cp + 1) * 2;
! 			last_cmd = True;
! 			last_zpt = False;
  			break;
  		case ORDER_SA:	/* set attribute */
  			if (toggled(TRACE3270))
! 				END_TEXT("SA[unsupported]");
! 			cp += 2;
! 			last_cmd = True;
! 			last_zpt = False;
  			break;
+ 		case FCORDER_NULL:	/* format control orders */
+ 		case FCORDER_SUB:
+ 		case FCORDER_DUP:
+ 		case FCORDER_FM:
+ 		case FCORDER_FF:
+ 		case FCORDER_CR:
+ 		case FCORDER_NL:
+ 		case FCORDER_EM:
+ 		case FCORDER_EO:
+ 			if (toggled(TRACE3270))
+ 				END_TEXT(see_ebc(*cp));
+ 			ctlr_add(buffer_addr, ebc2cg[*cp]);
+ 			INC_BA(buffer_addr);
+ 			last_cmd = True;
+ 			last_zpt = False;
+ 			break;
  		default:	/* enter character */
+ 			if (*cp <= 0x3F) {
+ 				if (toggled(TRACE3270)) {
+ 					END_TEXT("ILLEGAL_ORDER");
+ 					(void) printf("%s", see_ebc(*cp));
+ 				}
+ 				last_cmd = True;
+ 				last_zpt = False;
+ 				break;
+ 			}
  			if (toggled(TRACE3270)) {
  				START_TEXT;
  				(void) printf("%s", see_ebc(*cp));
***************
*** 888,893 ****
--- 971,977 ----
  			ctlr_add(buffer_addr, ebc2cg[*cp]);
  			INC_BA(buffer_addr);
  			last_cmd = False;
+ 			last_zpt = False;
  			break;
  		}
  	}

Filter the output of the "Trace 3270 DS" option so it doesn't generate huge
lines.

*** ctlr.c.orig	Wed Nov 17 14:10:20 1993
--- ctlr.c	Wed Nov 17 14:10:21 1993
***************
*** 61,66 ****
--- 61,67 ----
  static void	do_read_buffer();
  static void	do_erase_all_unprotected();
  static void	do_write();
+ static void	trace_ds();
  
  /* code_table is used to translate buffer addresses and attributes to the 3270
   * datastream representation
***************
*** 313,363 ****
  unsigned char	*buf;
  int	buflen;
  {
! 	if (toggled(TRACE3270))
! 		(void) printf("< ");
  
  	switch (buf[0]) {	/* 3270 command */
  	case CMD_EAU:	/* erase all unprotected */
  	case SNA_CMD_EAU:
! 		if (toggled(TRACE3270))
! 			(void) printf("EAU\n");
  		do_erase_all_unprotected();
  		break;
  	case CMD_EWA:	/* erase/write alternate */
  	case SNA_CMD_EWA:
! 		if (toggled(TRACE3270))
! 			(void) printf("EWA");
  		ctlr_erase(True);
  		do_write(buf, buflen);
  		break;
  	case CMD_EW:	/* erase/write */
  	case SNA_CMD_EW:
! 		if (toggled(TRACE3270))
! 			(void) printf("EW");
  		ctlr_erase(False);
  		do_write(buf, buflen);
  		break;
  	case CMD_W:	/* write */
  	case SNA_CMD_W:
! 		if (toggled(TRACE3270))
! 			(void) printf("W");
  		do_write(buf, buflen);
  		break;
  	case CMD_RB:	/* read buffer */
  	case SNA_CMD_RB:
! 		if (toggled(TRACE3270))
! 			(void) printf("RB\n");
  		do_read_buffer();
  		break;
  	case CMD_RM:	/* read modifed */
  	case SNA_CMD_RM:
! 		if (toggled(TRACE3270))
! 			(void) printf("RM\n");
  		ctlr_read_modified();
  		break;
  	case CMD_NOP:	/* no-op */
! 		if (toggled(TRACE3270))
! 			(void) printf("NOP\n");
  		break;
  	default: {
  		/* unknown 3270 command */
--- 314,356 ----
  unsigned char	*buf;
  int	buflen;
  {
! 	trace_ds("< ");
  
  	switch (buf[0]) {	/* 3270 command */
  	case CMD_EAU:	/* erase all unprotected */
  	case SNA_CMD_EAU:
! 		trace_ds("EAU\n");
  		do_erase_all_unprotected();
  		break;
  	case CMD_EWA:	/* erase/write alternate */
  	case SNA_CMD_EWA:
! 		trace_ds("EWA");
  		ctlr_erase(True);
  		do_write(buf, buflen);
  		break;
  	case CMD_EW:	/* erase/write */
  	case SNA_CMD_EW:
! 		trace_ds("EW");
  		ctlr_erase(False);
  		do_write(buf, buflen);
  		break;
  	case CMD_W:	/* write */
  	case SNA_CMD_W:
! 		trace_ds("W");
  		do_write(buf, buflen);
  		break;
  	case CMD_RB:	/* read buffer */
  	case SNA_CMD_RB:
! 		trace_ds("RB\n");
  		do_read_buffer();
  		break;
  	case CMD_RM:	/* read modifed */
  	case SNA_CMD_RM:
! 		trace_ds("RM\n");
  		ctlr_read_modified();
  		break;
  	case CMD_NOP:	/* no-op */
! 		trace_ds("NOP\n");
  		break;
  	default: {
  		/* unknown 3270 command */
***************
*** 461,468 ****
  {
  	register int	baddr, sbaddr;
  
! 	if (toggled(TRACE3270))
! 		(void) printf("> ");
  	obptr = &obuf[0];
  	if (aid != AID_PA1 && aid != AID_PA2
  	    &&  aid != AID_PA3 && aid != AID_CLEAR) {
--- 454,460 ----
  {
  	register int	baddr, sbaddr;
  
! 	trace_ds("> ");
  	obptr = &obuf[0];
  	if (aid != AID_PA1 && aid != AID_PA2
  	    &&  aid != AID_PA3 && aid != AID_CLEAR) {
***************
*** 471,486 ****
  			*obptr++ = 0x5B;	/*  %  */
  			*obptr++ = 0x61;	/*  /  */
  			*obptr++ = 0x02;	/* stx */
! 			if (toggled(TRACE3270))
! 				(void) printf("SYSREQ");
  		}
  		else {
  			*obptr++ = aid;
  			*obptr++ = code_table[(cursor_addr >> 6) & 0x3F];
  			*obptr++ = code_table[cursor_addr & 0x3F];
! 			if (toggled(TRACE3270))
! 				(void) printf("%s%s", see_aid(aid),
! 				    rcba(cursor_addr));
  		}
  		baddr = 0;
  		if (formatted) {
--- 463,476 ----
  			*obptr++ = 0x5B;	/*  %  */
  			*obptr++ = 0x61;	/*  /  */
  			*obptr++ = 0x02;	/* stx */
! 			trace_ds("SYSREQ");
  		}
  		else {
  			*obptr++ = aid;
  			*obptr++ = code_table[(cursor_addr >> 6) & 0x3F];
  			*obptr++ = code_table[cursor_addr & 0x3F];
! 			trace_ds(see_aid(aid));
! 			trace_ds(rcba(cursor_addr));
  		}
  		baddr = 0;
  		if (formatted) {
***************
*** 499,521 ****
  					*obptr++ = ORDER_SBA;
  					*obptr++ = code_table[(baddr >> 6) & 0x3F];
  					*obptr++ = code_table[baddr & 0x3F];
! 					if (toggled(TRACE3270))
! 						(void) printf(" SBA%s",
! 						    rcba(baddr));
  					do {
  						if (screen_buf[baddr]) {
  							*obptr++ = cg2ebc[screen_buf[baddr]];
! 							if (toggled(TRACE3270)) {
! 								if (!any)
! 									(void) printf(" '");
! 								(void) printf("%s", see_ebc(cg2ebc[screen_buf[baddr]]));
! 							}
  							any = True;
  						}
  						INC_BA(baddr);
  					} while (!IS_FA(screen_buf[baddr]));
! 					if (toggled(TRACE3270) && any)
! 						(void) printf("'");
  				}
  				else {	/* not modified - skip */
  					do {
--- 489,508 ----
  					*obptr++ = ORDER_SBA;
  					*obptr++ = code_table[(baddr >> 6) & 0x3F];
  					*obptr++ = code_table[baddr & 0x3F];
! 					trace_ds(" SBA");
! 					trace_ds(rcba(baddr));
  					do {
  						if (screen_buf[baddr]) {
  							*obptr++ = cg2ebc[screen_buf[baddr]];
! 							if (!any)
! 								trace_ds(" '");
! 							trace_ds(see_ebc(cg2ebc[screen_buf[baddr]]));
  							any = True;
  						}
  						INC_BA(baddr);
  					} while (!IS_FA(screen_buf[baddr]));
! 					if (any)
! 						trace_ds("'");
  				}
  				else {	/* not modified - skip */
  					do {
***************
*** 530,555 ****
  			do {
  				if (screen_buf[baddr]) {
  					*obptr++ = cg2ebc[screen_buf[baddr]];
! 					if (toggled(TRACE3270)) {
! 						if (!any)
! 							(void) printf("'");
! 						(void) printf("%s", see_ebc(cg2ebc[screen_buf[baddr]]));
! 					}
  					any = True;
  				}
  				INC_BA(baddr);
  			} while (baddr != 0);
! 			if (toggled(TRACE3270) && any)
! 				(void) printf("'");
  		}
  	}
  	else {
  		*obptr++ = aid;
! 		if (toggled(TRACE3270))
! 			(void) printf("%s", see_aid(aid));
  	}
! 	if (toggled(TRACE3270))
! 		(void) printf("\n");
  	net_output(obuf, obptr - obuf);
  }
  
--- 517,538 ----
  			do {
  				if (screen_buf[baddr]) {
  					*obptr++ = cg2ebc[screen_buf[baddr]];
! 					if (!any)
! 						trace_ds("'");
! 					trace_ds(see_ebc(cg2ebc[screen_buf[baddr]]));
  					any = True;
  				}
  				INC_BA(baddr);
  			} while (baddr != 0);
! 			if (any)
! 				trace_ds("'");
  		}
  	}
  	else {
  		*obptr++ = aid;
! 		trace_ds(see_aid(aid));
  	}
! 	trace_ds("\n");
  	net_output(obuf, obptr - obuf);
  }
  
***************
*** 618,631 ****
  	unsigned char	fa;
  	Boolean		last_fa = True;
  
! 	if (toggled(TRACE3270))
! 		(void) printf("> ");
  	obptr = &obuf[0];
  	*obptr++ = aid;
  	*obptr++ = code_table[(cursor_addr >> 6) & 0x3F];
  	*obptr++ = code_table[cursor_addr & 0x3F];
! 	if (toggled(TRACE3270))
! 		(void) printf("%s%s", see_aid(aid), rcba(cursor_addr));
  	baddr = 0;
  	do {
  		if (IS_FA(screen_buf[baddr])) {
--- 601,613 ----
  	unsigned char	fa;
  	Boolean		last_fa = True;
  
! 	trace_ds("> ");
  	obptr = &obuf[0];
  	*obptr++ = aid;
  	*obptr++ = code_table[(cursor_addr >> 6) & 0x3F];
  	*obptr++ = code_table[cursor_addr & 0x3F];
! 	trace_ds(see_aid(aid));
! 	trace_ds(rcba(cursor_addr));
  	baddr = 0;
  	do {
  		if (IS_FA(screen_buf[baddr])) {
***************
*** 639,678 ****
  				fa |= 0x01;
  			fa |= ((screen_buf[baddr] & FA_INTENSITY) << 2);
  			*obptr++ = code_table[fa];
! 			if (toggled(TRACE3270)) {
! 				if (!last_fa)
! 					(void) printf("'");
! 				(void) printf(" SF%s%s", rcba(baddr),
! 				    see_attr(fa));
! 				last_fa = True;
! 			}
  		} else {
  			*obptr++ = cg2ebc[screen_buf[baddr]];
! 			if (toggled(TRACE3270)) {
! 				if (cg2ebc[screen_buf[baddr]] <= 0x3f ||
! 				    cg2ebc[screen_buf[baddr]] == 0xff) {
! 					if (!last_fa)
! 						(void) printf("'");
  
! 					(void) printf(" %s",
! 					    see_ebc(cg2ebc[screen_buf[baddr]]));
! 					last_fa = True;
! 				} else {
! 					if (last_fa)
! 						(void) printf(" '");
! 					(void) printf("%s",
! 					    see_ebc(cg2ebc[screen_buf[baddr]]));
! 					last_fa = False;
! 				}
  			}
  		}
  		INC_BA(baddr);
  	} while (baddr != 0);
! 	if (toggled(TRACE3270)) {
! 		if (!last_fa)
! 			(void) printf("'");
! 		(void) printf("\n");
! 	}
  	net_output(obuf, obptr - obuf);
  }
  
--- 621,654 ----
  				fa |= 0x01;
  			fa |= ((screen_buf[baddr] & FA_INTENSITY) << 2);
  			*obptr++ = code_table[fa];
! 			if (!last_fa)
! 				trace_ds("'");
! 			trace_ds(" SF");
! 			trace_ds(rcba(baddr));
! 			trace_ds(see_attr(fa));
! 			last_fa = True;
  		} else {
  			*obptr++ = cg2ebc[screen_buf[baddr]];
! 			if (cg2ebc[screen_buf[baddr]] <= 0x3f ||
! 			    cg2ebc[screen_buf[baddr]] == 0xff) {
! 				if (!last_fa)
! 					trace_ds("'");
  
! 				trace_ds(" ");
! 				trace_ds(see_ebc(cg2ebc[screen_buf[baddr]]));
! 				last_fa = True;
! 			} else {
! 				if (last_fa)
! 					trace_ds(" '");
! 				trace_ds(see_ebc(cg2ebc[screen_buf[baddr]]));
! 				last_fa = False;
  			}
  		}
  		INC_BA(baddr);
  	} while (baddr != 0);
! 	if (!last_fa)
! 		trace_ds("'");
! 	trace_ds("\n");
  	net_output(obuf, obptr - obuf);
  }
  
***************
*** 747,776 ****
  	Boolean		last_zpt;
  	Boolean		wcc_keyboard_restore, wcc_sound_alarm;
  	unsigned char	temp_aid2;
! 	char		paren = '(';
  
! #define START_TEXT	{ if (last_cmd) (void) printf(" '"); }
! #define END_TEXT(cmd)	{ if (!last_cmd) (void) printf("'"); if (cmd) (void) printf(" %s", cmd); }
  
  	buffer_addr = cursor_addr;
  	wcc_sound_alarm = WCC_SOUND_ALARM(buf[1]);
! 	if (toggled(TRACE3270) && wcc_sound_alarm) {
! 		(void) printf("%calarm", paren);
! 		paren = ',';
  	}
  	wcc_keyboard_restore = WCC_KEYBOARD_RESTORE(buf[1]);
  	if (wcc_keyboard_restore)
  		ticking_stop();
! 	if (toggled(TRACE3270) && wcc_keyboard_restore) {
! 		(void) printf("%crestore", paren);
! 		paren = ',';
  	}
  
  	if (WCC_RESET_MDT(buf[1])) {
! 		if (toggled(TRACE3270)) {
! 			(void) printf("%cresetMDT", paren);
! 			paren = ',';
! 		}
  		baddr = 0;
  		screen_changed = True;
  		do {
--- 723,754 ----
  	Boolean		last_zpt;
  	Boolean		wcc_keyboard_restore, wcc_sound_alarm;
  	unsigned char	temp_aid2;
! 	char		*paren = "(";
  
! #define START_TEXT	{ if (last_cmd) trace_ds(" '"); }
! #define END_TEXT(cmd)	{ if (!last_cmd) trace_ds("'"); \
! 			  if (cmd) { trace_ds(" "); trace_ds(cmd); } }
  
  	buffer_addr = cursor_addr;
  	wcc_sound_alarm = WCC_SOUND_ALARM(buf[1]);
! 	if (wcc_sound_alarm) {
! 		trace_ds(paren);
! 		trace_ds("alarm");
! 		paren = ",";
  	}
  	wcc_keyboard_restore = WCC_KEYBOARD_RESTORE(buf[1]);
  	if (wcc_keyboard_restore)
  		ticking_stop();
! 	if (wcc_keyboard_restore) {
! 		trace_ds(paren);
! 		trace_ds("restore");
! 		paren = ",";
  	}
  
  	if (WCC_RESET_MDT(buf[1])) {
! 		trace_ds(paren);
! 		trace_ds("resetMDT");
! 		paren = ",";
  		baddr = 0;
  		screen_changed = True;
  		do {
***************
*** 780,787 ****
  			INC_BA(baddr);
  		} while (baddr != 0);
  	}
! 	if (toggled(TRACE3270) && paren != '(')
! 		(void) printf(")");
  
  	last_cmd = True;
  	last_zpt = False;
--- 758,765 ----
  			INC_BA(baddr);
  		} while (baddr != 0);
  	}
! 	if (strcmp(paren, "("))
! 		trace_ds(")");
  
  	last_cmd = True;
  	last_zpt = False;
***************
*** 789,798 ****
  	for (cp = &buf[2]; cp < (buf + buflen); cp++) {
  		switch (*cp) {
  		case ORDER_SF:	/* start field */
! 			if (toggled(TRACE3270)) {
! 				END_TEXT("SF");
! 				(void) printf("%s", rcba(buffer_addr));
! 			}
  			cp++;		/* skip field attribute */
  			new_attr = FA_BASE;
  			if (*cp & 0x20)
--- 767,774 ----
  	for (cp = &buf[2]; cp < (buf + buflen); cp++) {
  		switch (*cp) {
  		case ORDER_SF:	/* start field */
! 			END_TEXT("SF");
! 			trace_ds(rcba(buffer_addr));
  			cp++;		/* skip field attribute */
  			new_attr = FA_BASE;
  			if (*cp & 0x20)
***************
*** 804,811 ****
  			new_attr |= (*cp >> 2) & FA_INTENSITY;
  			current_fa = &(screen_buf[buffer_addr]);
  			ctlr_add(buffer_addr, new_attr);
! 			if (toggled(TRACE3270))
! 				(void) printf("%s", see_attr(new_attr));
  			formatted = True;
  			INC_BA(buffer_addr);
  			last_cmd = True;
--- 780,786 ----
  			new_attr |= (*cp >> 2) & FA_INTENSITY;
  			current_fa = &(screen_buf[buffer_addr]);
  			ctlr_add(buffer_addr, new_attr);
! 			trace_ds(see_attr(new_attr));
  			formatted = True;
  			INC_BA(buffer_addr);
  			last_cmd = True;
***************
*** 818,841 ****
  			else	/* 12-bit coded */
  				buffer_addr = ((*(cp-1) & 0x3F) << 6) | (*cp & 0x3F);
  			buffer_addr %= (COLS * ROWS);
! 			if (toggled(TRACE3270)) {
! 				END_TEXT("SBA");
! 				(void) printf("%s", rcba(buffer_addr));
! 			}
  			current_fa = get_field_attribute(buffer_addr);
  			last_cmd = True;
  			last_zpt = False;
  			break;
  		case ORDER_IC:	/* insert cursor */
! 			if (toggled(TRACE3270))
! 				END_TEXT("IC");
  			cursor_move(buffer_addr);
  			last_cmd = True;
  			last_zpt = False;
  			break;
  		case ORDER_PT:	/* program tab */
! 			if (toggled(TRACE3270))
! 				END_TEXT("PT");
  			baddr = next_unprotected(buffer_addr);
  			if (baddr < buffer_addr)
  				baddr = 0;
--- 793,812 ----
  			else	/* 12-bit coded */
  				buffer_addr = ((*(cp-1) & 0x3F) << 6) | (*cp & 0x3F);
  			buffer_addr %= (COLS * ROWS);
! 			END_TEXT("SBA");
! 			trace_ds(rcba(buffer_addr));
  			current_fa = get_field_attribute(buffer_addr);
  			last_cmd = True;
  			last_zpt = False;
  			break;
  		case ORDER_IC:	/* insert cursor */
! 			END_TEXT("IC");
  			cursor_move(buffer_addr);
  			last_cmd = True;
  			last_zpt = False;
  			break;
  		case ORDER_PT:	/* program tab */
! 			END_TEXT("PT");
  			baddr = next_unprotected(buffer_addr);
  			if (baddr < buffer_addr)
  				baddr = 0;
***************
*** 846,853 ****
  			 * a null-filling PT that left the buffer address at 0.
  			 */
  			if (!last_cmd || last_zpt) {
! 				if (toggled(TRACE3270))
! 					(void) printf("(nulling)");
  				while ((buffer_addr != baddr) &&
  				       (!IS_FA(screen_buf[buffer_addr]))) {
  					ctlr_add(buffer_addr, CG_NULLBLANK);
--- 817,823 ----
  			 * a null-filling PT that left the buffer address at 0.
  			 */
  			if (!last_cmd || last_zpt) {
! 				trace_ds("(nulling)");
  				while ((buffer_addr != baddr) &&
  				       (!IS_FA(screen_buf[buffer_addr]))) {
  					ctlr_add(buffer_addr, CG_NULLBLANK);
***************
*** 870,880 ****
  			cp++;		/* skip char to repeat */
  			if (*cp == ORDER_GE)
  				cp++;
! 			if (toggled(TRACE3270)) {
! 				END_TEXT("RA");
! 				(void) printf("%s'%s'", rcba(baddr),
! 				    see_ebc(*cp));
! 			}
  			if (buffer_addr == baddr) {
  				ctlr_add(buffer_addr, ebc2cg[*cp]);
  				INC_BA(buffer_addr);
--- 840,850 ----
  			cp++;		/* skip char to repeat */
  			if (*cp == ORDER_GE)
  				cp++;
! 			END_TEXT("RA");
! 			trace_ds(rcba(baddr));
! 			trace_ds("'");
! 			trace_ds(see_ebc(*cp));
! 			trace_ds("'");
  			if (buffer_addr == baddr) {
  				ctlr_add(buffer_addr, ebc2cg[*cp]);
  				INC_BA(buffer_addr);
***************
*** 894,903 ****
  			else	/* 12-bit coded */
  				baddr = ((*(cp-1) & 0x3F) << 6) | (*cp & 0x3F);
  			baddr %= (COLS * ROWS);
! 			if (toggled(TRACE3270)) {
! 				END_TEXT("EUA");
! 				(void) printf("%s", rcba(baddr));
! 			}
  			do {
  				if (IS_FA(screen_buf[buffer_addr]))
  					current_fa = &(screen_buf[buffer_addr]);
--- 864,871 ----
  			else	/* 12-bit coded */
  				baddr = ((*(cp-1) & 0x3F) << 6) | (*cp & 0x3F);
  			baddr %= (COLS * ROWS);
! 			END_TEXT("EUA");
! 			trace_ds(rcba(baddr));
  			do {
  				if (IS_FA(screen_buf[buffer_addr]))
  					current_fa = &(screen_buf[buffer_addr]);
***************
*** 911,939 ****
  			last_zpt = False;
  			break;
  		case ORDER_GE:	/* graphic escape */
! 			if (toggled(TRACE3270))
! 				END_TEXT("GE[unsupported]");
  			cp++;
  			last_cmd = True;
  			last_zpt = False;
  			break;
  		case ORDER_MF:	/* modify field */
! 			if (toggled(TRACE3270))
! 				END_TEXT("MF[unsupported]");
  			cp += *(cp + 1) * 2;
  			last_cmd = True;
  			last_zpt = False;
  			break;
  		case ORDER_SFE:	/* start field extended */
! 			if (toggled(TRACE3270))
! 				END_TEXT("SFE[unsupported]");
  			cp += *(cp + 1) * 2;
  			last_cmd = True;
  			last_zpt = False;
  			break;
  		case ORDER_SA:	/* set attribute */
! 			if (toggled(TRACE3270))
! 				END_TEXT("SA[unsupported]");
  			cp += 2;
  			last_cmd = True;
  			last_zpt = False;
--- 879,903 ----
  			last_zpt = False;
  			break;
  		case ORDER_GE:	/* graphic escape */
! 			END_TEXT("GE[unsupported]");
  			cp++;
  			last_cmd = True;
  			last_zpt = False;
  			break;
  		case ORDER_MF:	/* modify field */
! 			END_TEXT("MF[unsupported]");
  			cp += *(cp + 1) * 2;
  			last_cmd = True;
  			last_zpt = False;
  			break;
  		case ORDER_SFE:	/* start field extended */
! 			END_TEXT("SFE[unsupported]");
  			cp += *(cp + 1) * 2;
  			last_cmd = True;
  			last_zpt = False;
  			break;
  		case ORDER_SA:	/* set attribute */
! 			END_TEXT("SA[unsupported]");
  			cp += 2;
  			last_cmd = True;
  			last_zpt = False;
***************
*** 947,954 ****
  		case FCORDER_NL:
  		case FCORDER_EM:
  		case FCORDER_EO:
! 			if (toggled(TRACE3270))
! 				END_TEXT(see_ebc(*cp));
  			ctlr_add(buffer_addr, ebc2cg[*cp]);
  			INC_BA(buffer_addr);
  			last_cmd = True;
--- 911,917 ----
  		case FCORDER_NL:
  		case FCORDER_EM:
  		case FCORDER_EO:
! 			END_TEXT(see_ebc(*cp));
  			ctlr_add(buffer_addr, ebc2cg[*cp]);
  			INC_BA(buffer_addr);
  			last_cmd = True;
***************
*** 956,973 ****
  			break;
  		default:	/* enter character */
  			if (*cp <= 0x3F) {
! 				if (toggled(TRACE3270)) {
! 					END_TEXT("ILLEGAL_ORDER");
! 					(void) printf("%s", see_ebc(*cp));
! 				}
  				last_cmd = True;
  				last_zpt = False;
  				break;
  			}
! 			if (toggled(TRACE3270)) {
! 				START_TEXT;
! 				(void) printf("%s", see_ebc(*cp));
! 			}
  			ctlr_add(buffer_addr, ebc2cg[*cp]);
  			INC_BA(buffer_addr);
  			last_cmd = False;
--- 919,932 ----
  			break;
  		default:	/* enter character */
  			if (*cp <= 0x3F) {
! 				END_TEXT("ILLEGAL_ORDER");
! 				trace_ds(see_ebc(*cp));
  				last_cmd = True;
  				last_zpt = False;
  				break;
  			}
! 			START_TEXT;
! 			trace_ds(see_ebc(*cp));
  			ctlr_add(buffer_addr, ebc2cg[*cp]);
  			INC_BA(buffer_addr);
  			last_cmd = False;
***************
*** 976,985 ****
  		}
  	}
  	set_formatted();
! 	if (toggled(TRACE3270)) {
! 		END_TEXT((char *)0);
! 		(void) printf("\n");
! 	}
  	if (wcc_keyboard_restore) {
  		aid = AID_NO;
  		if (oia_locked) {
--- 935,942 ----
  		}
  	}
  	set_formatted();
! 	END_TEXT((char *)0);
! 	trace_ds("\n");
  	if (wcc_keyboard_restore) {
  		aid = AID_NO;
  		if (oia_locked) {
***************
*** 1285,1288 ****
--- 1242,1283 ----
  void
  toggle_nop()
  {
+ }
+ 
+ 
+ /*
+  * 3270 Data Stream Tracing
+  */
+ static int dscnt = 0;
+ 
+ static void
+ trace_ds(s)
+ char *s;
+ {
+ 	int len = strlen(s);
+ 	Boolean nl = False;
+ 
+ 	if (!toggled(TRACE3270))
+ 		return;
+ 
+ 	if (s && s[len-1] == '\n') {
+ 		len--;
+ 		nl = True;
+ 	}
+ 	while (dscnt + len >= 72) {
+ 		int plen = 72-dscnt;
+ 
+ 		(void) printf("%.*s ...\n... ", plen, s);
+ 		dscnt = 4;
+ 		s += plen;
+ 		len -= plen;
+ 	}
+ 	if (len) {
+ 		(void) printf("%.*s", len, s);
+ 		dscnt += len;
+ 	}
+ 	if (nl) {
+ 		(void) printf("\n");
+ 		dscnt = 0;
+ 	}
  }

Up the program version number to 3.0.1.3, but no need to change the
app-defaults version.

*** x3270.c.orig	Wed Nov 17 14:35:56 1993
--- x3270.c	Wed Nov 17 14:35:57 1993
***************
*** 27,33 ****
  
  /* Externals */
  extern int	n_read;
! extern char	*version;
  
  /* Globals */
  Display		*display;
--- 27,33 ----
  
  /* Externals */
  extern int	n_read;
! extern char	*app_defaults_version;
  
  /* Globals */
  Display		*display;
***************
*** 243,251 ****
  		XtError("Outdated app-defaults file");
  	else if (!strcmp(appres.ad_version, "fallback"))
  		XtError("No app-defaults file");
! 	else if (strcmp(appres.ad_version, version)) {
  		char *msg = xs_buffer2("app-defaults version mismatch: want %s, got %s",
! 		    version, appres.ad_version);
  
  		XtError(msg);
  	}
--- 243,251 ----
  		XtError("Outdated app-defaults file");
  	else if (!strcmp(appres.ad_version, "fallback"))
  		XtError("No app-defaults file");
! 	else if (strcmp(appres.ad_version, app_defaults_version)) {
  		char *msg = xs_buffer2("app-defaults version mismatch: want %s, got %s",
! 		    app_defaults_version, appres.ad_version);
  
  		XtError(msg);
  	}
*** version.txt.orig	Wed Nov 17 14:36:02 1993
--- version.txt	Wed Nov 17 14:36:02 1993
***************
*** 1 ****
! 3.0.1.2
--- 1,2 ----
! char *version = "3.0.1.3";
! char *app_defaults_version = "3.0.1.2";
*** popups.c.orig	Wed Nov 17 14:36:06 1993
--- popups.c	Wed Nov 17 14:36:07 1993
***************
*** 476,481 ****
--- 476,482 ----
  extern int ns_bsent;
  extern int ns_rsent;
  extern int linemode;
+ extern char *version;
  extern char *build;
  extern char ttype_val[];
  extern Pixmap icon;
***************
*** 616,625 ****
  
  	/* Miscellany */
  
  	(void) XtVaCreateManagedWidget(
  	    "build", labelWidgetClass, options_form,
  	    XtNborderWidth, 0,
! 	    XtNlabel, build,
  	    XtNfromHoriz, w,
  	    XtNleft, XtChainLeft,
  	    NULL);
--- 617,627 ----
  
  	/* Miscellany */
  
+ 	sprintf(fbuf, "x3270 v%s, %s", version, build);
  	(void) XtVaCreateManagedWidget(
  	    "build", labelWidgetClass, options_form,
  	    XtNborderWidth, 0,
! 	    XtNlabel, fbuf,
  	    XtNfromHoriz, w,
  	    XtNleft, XtChainLeft,
  	    NULL);
*** Imakefile.orig	Wed Nov 17 14:36:10 1993
--- Imakefile	Wed Nov 17 14:36:11 1993
***************
*** 26,32 ****
  FontTarget(3270ab)
  
  version.o: $(VOBJS) version.txt
! 	@echo "char *build = \"x3270 v`cat version.txt`, `date`\"; char *version = \"`cat version.txt`\";" >version.c
  	@$(CC) -c version.c
  	@$(RM) version.c
  
--- 26,32 ----
  FontTarget(3270ab)
  
  version.o: $(VOBJS) version.txt
! 	@(cat version.txt; echo "char *build = \"`date`\";") >version.c
  	@$(CC) -c version.c
  	@$(RM) version.c
  
*** Makefile.aux.orig	Wed Nov 17 14:36:14 1993
--- Makefile.aux	Wed Nov 17 14:36:15 1993
***************
*** 85,91 ****
  	@$(RM) version.o
  
  version.o: $(OBJECTS) version.txt
! 	@echo "char *build = \"x3270 v`cat version.txt`, `date`\"; char *version = \"`cat version.txt`\";" >version.c
  	@$(CC) -c version.c
  	@$(RM) version.c
  
--- 85,91 ----
  	@$(RM) version.o
  
  version.o: $(OBJECTS) version.txt
! 	@(cat version.txt; echo "char *build = \"`date`\";") >version.c
  	@$(CC) -c version.c
  	@$(RM) version.c
  

Correct the handling of illegal buffer addresses.

*** ctlr.c.orig	Mon Nov 29 16:15:07 1993
--- ctlr.c	Mon Nov 29 16:15:08 1993
***************
*** 792,800 ****
  				buffer_addr = ((*(cp-1) & 0x3F) << 8) | *cp;
  			else	/* 12-bit coded */
  				buffer_addr = ((*(cp-1) & 0x3F) << 6) | (*cp & 0x3F);
- 			buffer_addr %= (COLS * ROWS);
  			END_TEXT("SBA");
  			trace_ds(rcba(buffer_addr));
  			current_fa = get_field_attribute(buffer_addr);
  			last_cmd = True;
  			last_zpt = False;
--- 792,803 ----
  				buffer_addr = ((*(cp-1) & 0x3F) << 8) | *cp;
  			else	/* 12-bit coded */
  				buffer_addr = ((*(cp-1) & 0x3F) << 6) | (*cp & 0x3F);
  			END_TEXT("SBA");
  			trace_ds(rcba(buffer_addr));
+ 			if (buffer_addr >= COLS * ROWS) {
+ 				trace_ds(" [invalid address, write command terminated]\n");
+ 				return;
+ 			}
  			current_fa = get_field_attribute(buffer_addr);
  			last_cmd = True;
  			last_zpt = False;
***************
*** 836,842 ****
  				baddr = ((*(cp-1) & 0x3F) << 8) | *cp;
  			else	/* 12-bit coded */
  				baddr = ((*(cp-1) & 0x3F) << 6) | (*cp & 0x3F);
- 			baddr %= (COLS * ROWS);
  			cp++;		/* skip char to repeat */
  			if (*cp == ORDER_GE)
  				cp++;
--- 839,844 ----
***************
*** 845,858 ****
  			trace_ds("'");
  			trace_ds(see_ebc(*cp));
  			trace_ds("'");
! 			if (buffer_addr == baddr) {
! 				ctlr_add(buffer_addr, ebc2cg[*cp]);
! 				INC_BA(buffer_addr);
  			}
! 			while (buffer_addr != baddr) {
  				ctlr_add(buffer_addr, ebc2cg[*cp]);
  				INC_BA(buffer_addr);
! 			}
  			current_fa = get_field_attribute(buffer_addr);
  			last_cmd = True;
  			last_zpt = False;
--- 847,860 ----
  			trace_ds("'");
  			trace_ds(see_ebc(*cp));
  			trace_ds("'");
! 			if (baddr >= COLS * ROWS) {
! 				trace_ds(" [invalid address, write command terminated]\n");
! 				return;
  			}
! 			do {
  				ctlr_add(buffer_addr, ebc2cg[*cp]);
  				INC_BA(buffer_addr);
! 			} while (buffer_addr != baddr);
  			current_fa = get_field_attribute(buffer_addr);
  			last_cmd = True;
  			last_zpt = False;
***************
*** 863,871 ****
  				baddr = ((*(cp-1) & 0x3F) << 8) | *cp;
  			else	/* 12-bit coded */
  				baddr = ((*(cp-1) & 0x3F) << 6) | (*cp & 0x3F);
- 			baddr %= (COLS * ROWS);
  			END_TEXT("EUA");
  			trace_ds(rcba(baddr));
  			do {
  				if (IS_FA(screen_buf[buffer_addr]))
  					current_fa = &(screen_buf[buffer_addr]);
--- 865,876 ----
  				baddr = ((*(cp-1) & 0x3F) << 8) | *cp;
  			else	/* 12-bit coded */
  				baddr = ((*(cp-1) & 0x3F) << 6) | (*cp & 0x3F);
  			END_TEXT("EUA");
  			trace_ds(rcba(baddr));
+ 			if (baddr >= COLS * ROWS) {
+ 				trace_ds(" [invalid address, write command terminated]\n");
+ 				return;
+ 			}
  			do {
  				if (IS_FA(screen_buf[buffer_addr]))
  					current_fa = &(screen_buf[buffer_addr]);

README changes.

*** README.3.0.orig	Mon Nov 29 16:27:09 1993
--- README.3.0	Mon Nov 29 16:27:10 1993
***************
*** 1,4 ****
! x3270 3.0.1.2 -- (Version 3.0, Update 1, Patch Set 2)
  ===============================================================================
  
  0. Introduction
--- 1,4 ----
! x3270 3.0.1.3 -- (Version 3.0, Update 1, Patch Set 3)
  ===============================================================================
  
  0. Introduction
***************
*** 20,38 ****
  x3270 (cut and paste, hollowing cursor, etc.) and a number of significant
  changes and improvements.
  
! Thanks to --
!     Robert Viduya, for the original SunView 3270tool;
!     Jeff Sparkes, for the original X port and for inspiring so many of us to
!      improve on it;
!     Peter Johnston, for insisting that each new function he wanted was just an
!      itty bitty change, honest;
!     Thomas Vogler, for requesting the original ASCII functionality and helping
!      debug it;
!     Pekka Nikander, for helpful advice in internationalization and X trivia,
!      and yet more porting and debug help;
!     Distinguished bug hunters: David Summers, Ian Daniel, Kevin Murphy, George
!      Pallas;
!     and everyone else who has put up with my naive stumblings through X.
  
  1. Enhancements from Release 1.2
  
--- 20,29 ----
  x3270 (cut and paste, hollowing cursor, etc.) and a number of significant
  changes and improvements.
  
! Despite its name, x3270 3.0 is a separate line of development from other
! versions of x3270, most notably v1.2-cutpaste-iso8859-1, and v2.65.  Patches
! for those versions will not apply to x3270 3.0, and some of the features found
! in those versions may not yet be in v3.0.
  
  1. Enhancements from Release 1.2
  
***************
*** 436,441 ****
--- 427,460 ----
  		xmkmf (or without one that works).
  
      ow3.install	Install x3270 in /usr/openwin.
+ 
+ 5.9 Bug Fixes in Patch Set 3 (v3.0.1.3)
+ 
+ Fixed typo which most compilers let pass.  [Reported by Marc Morin.]
+ 
+ Fixed EWOULDBLOCK can't-ever-happen which apparently did.  [Reported by Marc
+ Morin.]
+ 
+ Fixed an error in the response to the READ BUFFER command, which wasn't
+ properly encoding attribute bytes.  [Reported by Eric M. Boehm.]
+ 
+ Fixed OpenWindows font targets in Makefile.aux.  [Fixed by Raymond A. Wiker.]
+ 
+ Fixed a typo in X3270.ad.  [Found by Eric M. Boehm.]
+ 
+ Fixed a spelling error in x3270.man.
+ 
+ Properly fixed the problem with the nulling-out behavior of PT orders.
+ Versions 1.2 through 3.0.1.1 did it too often; v3.0.1.2 didn't do it at all.
+ [Identified by a number of people; primary help from Ilia Levi.]
+ 
+ Corrected the handling of illegal buffer addresses.  [Reported by Soren B.
+ Poulsen.]
+ 
+ 5.10 Enhancements in Patch Set 3 (v3.0.1.3)
+ 
+ Filter the output of the "Trace 3270 DS" option so it doesn't generate huge
+ lines.
  
  =====