look_up.c revision 120550
1139749Simp/*
2117632Sharti * Copyright (c) 1983, 1993
3117632Sharti *	The Regents of the University of California.  All rights reserved.
4117632Sharti *
5117632Sharti * Redistribution and use in source and binary forms, with or without
6117632Sharti * modification, are permitted provided that the following conditions
7117632Sharti * are met:
8117632Sharti * 1. Redistributions of source code must retain the above copyright
9117632Sharti *    notice, this list of conditions and the following disclaimer.
10117632Sharti * 2. Redistributions in binary form must reproduce the above copyright
11117632Sharti *    notice, this list of conditions and the following disclaimer in the
12117632Sharti *    documentation and/or other materials provided with the distribution.
13117632Sharti * 3. All advertising materials mentioning features or use of this software
14117632Sharti *    must display the following acknowledgement:
15117632Sharti *	This product includes software developed by the University of
16117632Sharti *	California, Berkeley and its contributors.
17117632Sharti * 4. Neither the name of the University nor the names of its contributors
18117632Sharti *    may be used to endorse or promote products derived from this software
19117632Sharti *    without specific prior written permission.
20117632Sharti *
21117632Sharti * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22117632Sharti * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23117632Sharti * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24117632Sharti * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25117632Sharti * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26117632Sharti * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27117632Sharti * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28117632Sharti * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29117632Sharti * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30117632Sharti * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31119418Sobrien * SUCH DAMAGE.
32117632Sharti */
33117632Sharti
34117632Sharti#include <sys/cdefs.h>
35117632Sharti
36117632Sharti__FBSDID("$FreeBSD: head/usr.bin/talk/look_up.c 120550 2003-09-28 09:45:56Z tjr $");
37117632Sharti
38117632Sharti#ifndef lint
39117632Shartistatic const char sccsid[] = "@(#)look_up.c	8.1 (Berkeley) 6/6/93";
40117632Sharti#endif
41117632Sharti
42117632Sharti#include <sys/types.h>
43117632Sharti#include <sys/socket.h>
44117632Sharti#include <protocols/talkd.h>
45117632Sharti
46117632Sharti#include <errno.h>
47117632Sharti
48117632Sharti#include "talk_ctl.h"
49117632Sharti#include "talk.h"
50117632Sharti
51117632Sharti/*
52117632Sharti * See if the local daemon has an invitation for us.
53117632Sharti */
54117632Shartiint
55117632Sharticheck_local()
56117632Sharti{
57117632Sharti	CTL_RESPONSE response;
58117632Sharti	CTL_RESPONSE *rp = &response;
59117632Sharti	struct sockaddr addr;
60117632Sharti
61117632Sharti	/* the rest of msg was set up in get_names */
62117632Sharti#ifdef MSG_EOR
63117632Sharti	/* copy new style sockaddr to old, swap family (short in old) */
64117632Sharti	msg.ctl_addr = *(struct osockaddr *)&ctl_addr;
65117632Sharti	msg.ctl_addr.sa_family = htons(ctl_addr.sin_family);
66117632Sharti#else
67117632Sharti	msg.ctl_addr = *(struct sockaddr *)&ctl_addr;
68117632Sharti#endif
69117632Sharti	/* must be initiating a talk */
70117632Sharti	if (!look_for_invite(rp))
71117632Sharti		return (0);
72117632Sharti	/*
73117632Sharti	 * There was an invitation waiting for us,
74117632Sharti	 * so connect with the other (hopefully waiting) party
75117632Sharti	 */
76117632Sharti	current_state = "Waiting to connect with caller";
77117632Sharti	do {
78117632Sharti		if (rp->addr.sa_family != AF_INET)
79117632Sharti			p_error("Response uses invalid network address");
80117632Sharti		(void)memcpy(&addr, &rp->addr.sa_family, sizeof(addr));
81117632Sharti		addr.sa_family = rp->addr.sa_family;
82117632Sharti		addr.sa_len = sizeof(addr);
83117632Sharti		errno = 0;
84117632Sharti		if (connect(sockt, &addr, sizeof(addr)) != -1)
85117632Sharti			return (1);
86117632Sharti	} while (errno == EINTR);
87117632Sharti	if (errno == ECONNREFUSED) {
88117632Sharti		/*
89117632Sharti		 * The caller gave up, but his invitation somehow
90117632Sharti		 * was not cleared. Clear it and initiate an
91117632Sharti		 * invitation. (We know there are no newer invitations,
92117632Sharti		 * the talkd works LIFO.)
93117632Sharti		 */
94117632Sharti		ctl_transact(his_machine_addr, msg, DELETE, rp);
95117632Sharti		close(sockt);
96117632Sharti		open_sockt();
97117632Sharti		return (0);
98117632Sharti	}
99117632Sharti	p_error("Unable to connect with initiator");
100117632Sharti	/*NOTREACHED*/
101117632Sharti	return (0);
102117632Sharti}
103117632Sharti
104117632Sharti/*
105117632Sharti * Look for an invitation on 'machine'
106117632Sharti */
107117632Shartiint
108117632Shartilook_for_invite(rp)
109117632Sharti	CTL_RESPONSE *rp;
110117632Sharti{
111117632Sharti	current_state = "Checking for invitation on caller's machine";
112117632Sharti	ctl_transact(his_machine_addr, msg, LOOK_UP, rp);
113117632Sharti	/* the switch is for later options, such as multiple invitations */
114117632Sharti	switch (rp->answer) {
115117632Sharti
116117632Sharti	case SUCCESS:
117117632Sharti		msg.id_num = htonl(rp->id_num);
118117632Sharti		return (1);
119117632Sharti
120117632Sharti	default:
121117632Sharti		/* there wasn't an invitation waiting for us */
122117632Sharti		return (0);
123117632Sharti	}
124117632Sharti}
125117632Sharti