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