look_up.c revision 178642
190075Sobrien/* 290075Sobrien * Copyright (c) 1983, 1993 390075Sobrien * The Regents of the University of California. All rights reserved. 490075Sobrien * 590075Sobrien * Redistribution and use in source and binary forms, with or without 690075Sobrien * modification, are permitted provided that the following conditions 790075Sobrien * are met: 890075Sobrien * 1. Redistributions of source code must retain the above copyright 990075Sobrien * notice, this list of conditions and the following disclaimer. 1090075Sobrien * 2. Redistributions in binary form must reproduce the above copyright 1190075Sobrien * notice, this list of conditions and the following disclaimer in the 1290075Sobrien * documentation and/or other materials provided with the distribution. 1390075Sobrien * 3. All advertising materials mentioning features or use of this software 1490075Sobrien * must display the following acknowledgement: 1590075Sobrien * This product includes software developed by the University of 1690075Sobrien * California, Berkeley and its contributors. 1790075Sobrien * 4. Neither the name of the University nor the names of its contributors 1890075Sobrien * may be used to endorse or promote products derived from this software 1990075Sobrien * without specific prior written permission. 2090075Sobrien * 2190075Sobrien * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 2290075Sobrien * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2390075Sobrien * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2490075Sobrien * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 2590075Sobrien * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2690075Sobrien * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2790075Sobrien * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2890075Sobrien * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2990075Sobrien * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3090075Sobrien * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3190075Sobrien * SUCH DAMAGE. 3290075Sobrien */ 3390075Sobrien 3490075Sobrien#include <sys/cdefs.h> 3590075Sobrien 3690075Sobrien__FBSDID("$FreeBSD: head/usr.bin/talk/look_up.c 178642 2008-04-28 21:08:42Z delphij $"); 3790075Sobrien 3890075Sobrien#ifndef lint 3990075Sobrienstatic const char sccsid[] = "@(#)look_up.c 8.1 (Berkeley) 6/6/93"; 4090075Sobrien#endif 4190075Sobrien 4290075Sobrien#include <sys/types.h> 4390075Sobrien#include <sys/socket.h> 4490075Sobrien#include <protocols/talkd.h> 4590075Sobrien 4690075Sobrien#include <errno.h> 4790075Sobrien#include <string.h> 4890075Sobrien 4990075Sobrien#include "talk_ctl.h" 5090075Sobrien#include "talk.h" 5190075Sobrien 5290075Sobrien/* 5390075Sobrien * See if the local daemon has an invitation for us. 5490075Sobrien */ 5590075Sobrienint 5690075Sobriencheck_local(void) 5790075Sobrien{ 5890075Sobrien CTL_RESPONSE response; 5990075Sobrien CTL_RESPONSE *rp = &response; 6090075Sobrien struct sockaddr addr; 61 62 /* the rest of msg was set up in get_names */ 63#ifdef MSG_EOR 64 /* copy new style sockaddr to old, swap family (short in old) */ 65 msg.ctl_addr = *(struct osockaddr *)&ctl_addr; 66 msg.ctl_addr.sa_family = htons(ctl_addr.sin_family); 67#else 68 msg.ctl_addr = *(struct sockaddr *)&ctl_addr; 69#endif 70 /* must be initiating a talk */ 71 if (!look_for_invite(rp)) 72 return (0); 73 /* 74 * There was an invitation waiting for us, 75 * so connect with the other (hopefully waiting) party 76 */ 77 current_state = "Waiting to connect with caller"; 78 do { 79 if (rp->addr.sa_family != AF_INET) 80 p_error("Response uses invalid network address"); 81 (void)memcpy(&addr, &rp->addr.sa_family, sizeof(addr)); 82 addr.sa_family = rp->addr.sa_family; 83 addr.sa_len = sizeof(addr); 84 errno = 0; 85 if (connect(sockt, &addr, sizeof(addr)) != -1) 86 return (1); 87 } while (errno == EINTR); 88 if (errno == ECONNREFUSED) { 89 /* 90 * The caller gave up, but his invitation somehow 91 * was not cleared. Clear it and initiate an 92 * invitation. (We know there are no newer invitations, 93 * the talkd works LIFO.) 94 */ 95 ctl_transact(his_machine_addr, msg, DELETE, rp); 96 close(sockt); 97 open_sockt(); 98 return (0); 99 } 100 p_error("Unable to connect with initiator"); 101 /*NOTREACHED*/ 102 return (0); 103} 104 105/* 106 * Look for an invitation on 'machine' 107 */ 108int 109look_for_invite(CTL_RESPONSE *rp) 110{ 111 current_state = "Checking for invitation on caller's machine"; 112 ctl_transact(his_machine_addr, msg, LOOK_UP, rp); 113 /* the switch is for later options, such as multiple invitations */ 114 switch (rp->answer) { 115 116 case SUCCESS: 117 msg.id_num = htonl(rp->id_num); 118 return (1); 119 120 default: 121 /* there wasn't an invitation waiting for us */ 122 return (0); 123 } 124} 125