[net.bugs.4bsd] talk

dg@sun.uucp (David Goldberg) (04/29/84)

	This is ugly, but it works, and is upward compatible
	with the current talk.

Subject: Talk doesn't work betwen sun's and vaxes
Index:	ucb/talk 4.2BSD

Description:
	The Talk(1) command does not work between sun's and vaxes.
Repeat-By:
	Try
		talk name@vax-machine
	from a sun, or vice-versa.
Fix:
	There are changes to look_up.c and talkd.c
	Here is a diff -c:

*** talkd.c	Wed May 11 20:28:19 1983
--- /tmp/talkd.c	Sat Apr 28 22:12:00 1984
***************
*** 30,35
  
  int debug = 0;
  
  main(argc)
  int argc;
  {

--- 30,37 -----
  
  int debug = 0;
  
+ CTL_MSG swapmsg();
+ 
  main(argc)
  int argc;
  {
***************
*** 104,109
  	    if (debug) printf("Request received : \n");
  	    if (debug) print_request(&request);
  
  	    process_request(&request, &response);
  
  	    if (debug) printf("Response sent : \n");

--- 106,112 -----
  	    if (debug) printf("Request received : \n");
  	    if (debug) print_request(&request);
  
+ 	    request = swapmsg(request);
  	    process_request(&request, &response);
  
  	    if (debug) printf("Response sent : \n");
***************
*** 190,193
  	    }
  	} while (val != pid);
      }
  }

--- 193,222 -----
  	    }
  	} while (val != pid);
      }
+ }
+ 
+ #define swapshort(a) (((a << 8) | ((unsigned short) a >> 8)) & 0xffff)
+ #define swaplong(a) ((swapshort(a) << 16) | (swapshort(((unsigned)a >> 16))))
+ 
+ /*  
+  * heuristic to detect if need to swap bytes
+  */
+ 
+ CTL_MSG
+ swapmsg(req)
+ 	CTL_MSG req;
+ {
+ 	CTL_MSG swapreq;
+ 	
+ 	if (req.ctl_addr.sin_family == swapshort(AF_INET)) {
+ 		swapreq = req;
+ 		swapreq.id_num = swaplong(req.id_num);
+ 		swapreq.pid = swaplong(req.pid);
+ 		swapreq.addr.sin_family = swapshort(req.addr.sin_family);
+ 		swapreq.ctl_addr.sin_family =
+ 			swapshort(req.ctl_addr.sin_family);
+ 		return swapreq;
+ 	}
+ 	else
+ 		return req;
  }



*** look_up.c	Wed May 11 20:28:27 1983
--- /tmp/look_up.c	Sat Apr 28 22:12:06 1984
***************
*** 4,9
  
      /* see if the local daemon has a invitation for us */
  
  check_local()
  {
      CTL_RESPONSE response;

--- 4,11 -----
  
      /* see if the local daemon has a invitation for us */
  
+ CTL_RESPONSE swapresponse();
+ 
  check_local()
  {
      CTL_RESPONSE response;
***************
*** 26,31
  
      current_state = "Waiting to connect with caller";
  
      while (connect(sockt, &response.addr, sizeof(response.addr)) != 0) {
  	if (errno == ECONNREFUSED) {
  

--- 28,34 -----
  
      current_state = "Waiting to connect with caller";
  
+     response = swapresponse(response);
      while (connect(sockt, &response.addr, sizeof(response.addr)) != 0) {
  	if (errno == ECONNREFUSED) {
  
***************
*** 76,78
  	    return(0);
      }
  }

--- 79,152 -----
  	    return(0);
      }
  }
+ 
+ /*  
+  * heuristic to detect if need to reshuffle CTL_RESPONSE structure
+  */
+ 
+ #define swapshort(a) (((a << 8) | ((unsigned short) a >> 8)) & 0xffff)
+ #define swaplong(a) ((swapshort(a) << 16) | (swapshort(((unsigned)a >> 16))))
+ 
+ #ifdef sun
+ struct ctl_response_vax {
+ 	char type;
+ 	char answer;
+ 	short junk;
+ 	int id_num;
+ 	struct sockaddr_in addr;
+ };
+ 
+ CTL_RESPONSE
+ swapresponse(rsp)
+ 	CTL_RESPONSE rsp;
+ {
+ 	struct ctl_response_vax swaprsp;
+ 	
+ 	if (rsp.addr.sin_family != AF_INET) {
+ 		bcopy(&rsp, &swaprsp, sizeof(CTL_RESPONSE));
+ 		swaprsp.addr.sin_family = swapshort(swaprsp.addr.sin_family);
+ 		if (swaprsp.addr.sin_family == AF_INET) {
+ 			rsp.addr = swaprsp.addr;
+ 			rsp.type = swaprsp.type;
+ 			rsp.answer = swaprsp.answer;
+ 			rsp.id_num = swaplong(swaprsp.id_num);
+ 		}
+ 	}
+ 	return rsp;
+ }
+ #endif
+ 
+ #ifdef vax
+ struct ctl_response_sun {
+ 	char type;
+ 	char answer;
+ 	unsigned short id_num2;
+ 	unsigned short id_num1;
+ 	short sin_family;
+ 	short sin_port;
+ 	short sin_addr2;
+ 	short sin_addr1;
+ };
+ 
+ CTL_RESPONSE
+ swapresponse(rsp)
+ 	CTL_RESPONSE rsp;
+ {
+ 	struct ctl_response_sun swaprsp;
+ 	
+ 	if (rsp.addr.sin_family != AF_INET) {
+ 		bcopy(&rsp, &swaprsp, sizeof(struct ctl_response_sun));
+ 		if (swaprsp.sin_family == swapshort(AF_INET)) {
+ 			rsp.type = swaprsp.type;
+ 			rsp.answer = swaprsp.answer;
+ 			rsp.id_num = swapshort(swaprsp.id_num1)
+ 			    | (swapshort(swaprsp.id_num2) << 16);
+ 			rsp.addr.sin_family = swapshort(swaprsp.sin_family);
 			rsp.addr.sin_port = swaprsp.sin_port;
+ 			rsp.addr.sin_addr.s_addr =
+ 			    swaprsp.sin_addr2 | (swaprsp.sin_addr1 << 16);
+ 		}
+ 	}
+ 	return rsp;
+ }
+ #endif

forys@sunybcs.UUCP (Jeff Forys) (11/08/86)

Index:	/usr/src/ucb/talk/invite.c 4.3BSD FIX

Description:

	talk(1) returns wrong error message under various circumstances.

Repeat by:

	% talk foo		# where `foo' is someone not logged in
	  [No connection yet]
     >>>  [Target machine does not recognize us]  <<<
	% 

Fix:
	The error messages do not jibe with their respective #define's
	in "/usr/include/protocols/talkd.h".  The solution is to reorder
	the error messages properly as the following diff illustrates...

*** invite.c_old	Sat Nov  8 00:46:33 1986
--- invite.c	Sat Nov  8 00:46:32 1986
***************
*** 92,102 ****
  }
  
  static	char *answers[] = {
  	"Your party is not logged on",			/* NOT_HERE */
- 	"Target machine does not recognize us",		/* MACHINE_UNKNOWN */
- 	"Target machine can not handle remote talk",	/* UNKNOWN_REQUEST */
  	"Target machine is too confused to talk to us",	/* FAILED */
  	"Your party is refusing messages",		/* PERMISSION_REFUSED */
  	"Target machine indicates protocol mismatch",	/* BADVERSION */
  	"Target machine indicates protocol botch (addr)",/* BADADDR */
  	"Target machine indicates protocol botch (ctl_addr)",/* BADCTLADDR */
--- 92,103 ----
  }
  
  static	char *answers[] = {
+ 	"",						/* SUCCESS */
  	"Your party is not logged on",			/* NOT_HERE */
  	"Target machine is too confused to talk to us",	/* FAILED */
+ 	"Target machine does not recognize us",		/* MACHINE_UNKNOWN */
  	"Your party is refusing messages",		/* PERMISSION_REFUSED */
+ 	"Target machine can not handle remote talk",	/* UNKNOWN_REQUEST */
  	"Target machine indicates protocol mismatch",	/* BADVERSION */
  	"Target machine indicates protocol botch (addr)",/* BADADDR */
  	"Target machine indicates protocol botch (ctl_addr)",/* BADCTLADDR */