1 /*
2 * Copyright (c) 1983, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * %sccs.include.redist.c%
6 */
7
8 #ifndef lint
9 static char sccsid[] = "@(#)look_up.c 8.1 (Berkeley) 06/06/93";
10 #endif /* not lint */
11
12 #include <sys/types.h>
13 #include <sys/socket.h>
14 #include <netinet/in.h>
15 #include <protocols/talkd.h>
16 #include <errno.h>
17 #include "talk_ctl.h"
18 #include "talk.h"
19
20 /*
21 * See if the local daemon has an invitation for us.
22 */
check_local()23 check_local()
24 {
25 CTL_RESPONSE response;
26 register CTL_RESPONSE *rp = &response;
27
28 /* the rest of msg was set up in get_names */
29 #ifdef MSG_EOR
30 /* copy new style sockaddr to old, swap family (short in old) */
31 msg.ctl_addr = *(struct osockaddr *)&ctl_addr;
32 msg.ctl_addr.sa_family = htons(ctl_addr.sin_family);
33 #else
34 msg.ctl_addr = *(struct sockaddr *)&ctl_addr;
35 #endif
36 /* must be initiating a talk */
37 if (!look_for_invite(rp))
38 return (0);
39 /*
40 * There was an invitation waiting for us,
41 * so connect with the other (hopefully waiting) party
42 */
43 current_state = "Waiting to connect with caller";
44 do {
45 if (rp->addr.sa_family != AF_INET)
46 p_error("Response uses invalid network address");
47 errno = 0;
48 if (connect(sockt,
49 (struct sockaddr *)&rp->addr, sizeof (rp->addr)) != -1)
50 return (1);
51 } while (errno == EINTR);
52 if (errno == ECONNREFUSED) {
53 /*
54 * The caller gave up, but his invitation somehow
55 * was not cleared. Clear it and initiate an
56 * invitation. (We know there are no newer invitations,
57 * the talkd works LIFO.)
58 */
59 ctl_transact(his_machine_addr, msg, DELETE, rp);
60 close(sockt);
61 open_sockt();
62 return (0);
63 }
64 p_error("Unable to connect with initiator");
65 /*NOTREACHED*/
66 }
67
68 /*
69 * Look for an invitation on 'machine'
70 */
look_for_invite(rp)71 look_for_invite(rp)
72 CTL_RESPONSE *rp;
73 {
74 struct in_addr machine_addr;
75
76 current_state = "Checking for invitation on caller's machine";
77 ctl_transact(his_machine_addr, msg, LOOK_UP, rp);
78 /* the switch is for later options, such as multiple invitations */
79 switch (rp->answer) {
80
81 case SUCCESS:
82 msg.id_num = htonl(rp->id_num);
83 return (1);
84
85 default:
86 /* there wasn't an invitation waiting for us */
87 return (0);
88 }
89 }
90