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