xref: /original-bsd/old/talk/talk/look_up.c (revision 0842ddeb)
1 /*-
2  * Copyright (c) 1983, 1985
3  *	The Regents of the University of California.  All rights reserved.
4  *
5  * %sccs.include.redist.c%
6  */
7 
8 /* from "@(#)look_up.c	5.1 (Berkeley) 6/6/85"; */
9 
10 #ifndef lint
11 static char sccsid[] = "@(#)look_up.c	6.5 (Berkeley) 04/29/95";
12 #endif not lint
13 
14 #include "talk_ctl.h"
15 #include <machine/endian.h>
16 #include <string.h>
17 #include <unistd.h>
18 
19 int	look_for_invite __P((CTL_RESPONSE *));
20 void	swapresponse __P((CTL_RESPONSE *));
21 
22 /*
23  * See if the local daemon has a invitation for us
24  */
25 int
26 check_local()
27 {
28 	CTL_RESPONSE response;
29 
30 	/* the rest of msg was set up in get_names */
31 	msg.ctl_addr = ctl_addr;
32 	/* must be initiating a talk */
33 	if (!look_for_invite(&response))
34 		return (0);
35 	/*
36 	 * There was an invitation waiting for us,
37 	 * so connect with the other (hopefully waiting) party
38 	 */
39 	current_state = "Waiting to connect with caller";
40 again:
41 	swapresponse(&response);
42 	response.addr.sin_family = AF_INET;
43 	if (connect(sockt,
44 	    (struct sockaddr *)&response.addr, sizeof(response.addr)) != -1)
45 		return (1);
46 	if (errno == EINTR)
47 		goto again;
48 	if (errno == ECONNREFUSED) {
49 		/*
50 		 * The caller gave up, but his invitation somehow
51 		 * was not cleared. Clear it and initiate an
52 		 * invitation. (We know there are no newer invitations,
53 		 * the talkd works LIFO.)
54 		 */
55 		ctl_transact(his_machine_addr, msg, DELETE, &response);
56 		close(sockt);
57 		open_sockt();
58 		return (0);
59 	}
60 	p_error("Unable to connect with initiator");
61 	/*NOTREACHED*/
62 }
63 
64 /*
65  * Look for an invitation on 'machine'
66  */
67 int
68 look_for_invite(response)
69 	CTL_RESPONSE *response;
70 {
71 
72 	current_state = "Checking for invitation on caller's machine";
73 	ctl_transact(his_machine_addr, msg, LOOK_UP, response);
74 	/* the switch is for later options, such as multiple invitations */
75 	switch (response->answer) {
76 
77 	case SUCCESS:
78 		msg.id_num = response->id_num;
79 		return (1);
80 
81 	default :
82 		/* there wasn't an invitation waiting for us */
83 		return (0);
84 	}
85 }
86 
87 /*
88  * heuristic to detect if need to reshuffle CTL_RESPONSE structure
89  */
90 
91 #define swapshort(a) (((a << 8) | ((unsigned short) a >> 8)) & 0xffff)
92 #define swaplong(a) ((swapshort(a) << 16) | (swapshort(((unsigned)a >> 16))))
93 
94 #if BYTE_ORDER == BIG_ENDIAN
95 struct ctl_response_vax {
96 	char type;
97 	char answer;
98 	short junk;
99 	int id_num;
100 	struct sockaddr_in addr;
101 };
102 
103 void
104 swapresponse(rsp)
105 	CTL_RESPONSE *rsp;
106 {
107 	struct ctl_response_vax swaprsp;
108 
109 	if (rsp->addr.sin_family != AF_INET) {
110 		bcopy(rsp, &swaprsp, sizeof(CTL_RESPONSE));
111 		swaprsp.addr.sin_family = swapshort(swaprsp.addr.sin_family);
112 		if (swaprsp.addr.sin_family == AF_INET) {
113 			rsp->addr = swaprsp.addr;
114 			rsp->type = swaprsp.type;
115 			rsp->answer = swaprsp.answer;
116 			rsp->id_num = swaplong(swaprsp.id_num);
117 		}
118 	}
119 }
120 #endif
121 
122 #if BYTE_ORDER == LITTLE_ENDIAN
123 struct ctl_response_sun {
124 	char type;
125 	char answer;
126 	unsigned short id_num2;
127 	unsigned short id_num1;
128 	short sin_family;
129 	short sin_port;
130 	short sin_addr2;
131 	short sin_addr1;
132 };
133 
134 void
135 swapresponse(rsp)
136 	CTL_RESPONSE *rsp;
137 {
138 	struct ctl_response_sun swaprsp;
139 
140 	if (rsp->addr.sin_family != AF_INET) {
141 		bcopy(rsp, &swaprsp, sizeof(struct ctl_response_sun));
142 		if (swaprsp.sin_family == swapshort(AF_INET)) {
143 			rsp->type = swaprsp.type;
144 			rsp->answer = swaprsp.answer;
145 			rsp->id_num = swapshort(swaprsp.id_num1)
146 			    | (swapshort(swaprsp.id_num2) << 16);
147 			rsp->addr.sin_family = swapshort(swaprsp.sin_family);
148  			rsp->addr.sin_port = swaprsp.sin_port;
149 			rsp->addr.sin_addr.s_addr =
150 			    swaprsp.sin_addr2 | (swaprsp.sin_addr1 << 16);
151 		}
152 	}
153 }
154 #endif
155