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;
+ }
+ #endifforys@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 */