11590Srgrimes/* 21590Srgrimes * Copyright (c) 1983, 1993 31590Srgrimes * The Regents of the University of California. All rights reserved. 41590Srgrimes * 51590Srgrimes * Redistribution and use in source and binary forms, with or without 61590Srgrimes * modification, are permitted provided that the following conditions 71590Srgrimes * are met: 81590Srgrimes * 1. Redistributions of source code must retain the above copyright 91590Srgrimes * notice, this list of conditions and the following disclaimer. 101590Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 111590Srgrimes * notice, this list of conditions and the following disclaimer in the 121590Srgrimes * documentation and/or other materials provided with the distribution. 131590Srgrimes * 4. Neither the name of the University nor the names of its contributors 141590Srgrimes * may be used to endorse or promote products derived from this software 151590Srgrimes * without specific prior written permission. 161590Srgrimes * 171590Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 181590Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 191590Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 201590Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 211590Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 221590Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 231590Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 241590Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 251590Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 261590Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 271590Srgrimes * SUCH DAMAGE. 281590Srgrimes */ 291590Srgrimes 3087710Smarkm#include <sys/cdefs.h> 3187710Smarkm 3287710Smarkm__FBSDID("$FreeBSD$"); 3387710Smarkm 341590Srgrimes#ifndef lint 3587710Smarkmstatic const char sccsid[] = "@(#)invite.c 8.1 (Berkeley) 6/6/93"; 3632503Scharnier#endif 371590Srgrimes 3887710Smarkm#include <sys/types.h> 3987710Smarkm#include <sys/socket.h> 4087710Smarkm#include <protocols/talkd.h> 4187710Smarkm 4232503Scharnier#include <err.h> 4332503Scharnier#include <errno.h> 4432503Scharnier#include <setjmp.h> 4532503Scharnier#include <signal.h> 46200418Sdelphij#include <unistd.h> 4787710Smarkm 481590Srgrimes#include "talk_ctl.h" 491590Srgrimes#include "talk.h" 501590Srgrimes 511590Srgrimes/* 521590Srgrimes * There wasn't an invitation waiting, so send a request containing 531590Srgrimes * our sockt address to the remote talk daemon so it can invite 548874Srgrimes * him 551590Srgrimes */ 561590Srgrimes 571590Srgrimes/* 581590Srgrimes * The msg.id's for the invitations 591590Srgrimes * on the local and remote machines. 608874Srgrimes * These are used to delete the 611590Srgrimes * invitations. 621590Srgrimes */ 63227185Sedstatic int local_id, remote_id; 64227185Sedstatic jmp_buf invitebuf; 651590Srgrimes 6614443Sjoergvoid 67178642Sdelphijinvite_remote(void) 681590Srgrimes{ 6987710Smarkm int new_sockt; 701590Srgrimes struct itimerval itimer; 711590Srgrimes CTL_RESPONSE response; 721590Srgrimes 731590Srgrimes itimer.it_value.tv_sec = RING_WAIT; 741590Srgrimes itimer.it_value.tv_usec = 0; 751590Srgrimes itimer.it_interval = itimer.it_value; 761590Srgrimes if (listen(sockt, 5) != 0) 771590Srgrimes p_error("Error on attempt to listen for caller"); 781590Srgrimes#ifdef MSG_EOR 791590Srgrimes /* copy new style sockaddr to old, swap family (short in old) */ 801590Srgrimes msg.addr = *(struct osockaddr *)&my_addr; /* XXX new to old style*/ 811590Srgrimes msg.addr.sa_family = htons(my_addr.sin_family); 821590Srgrimes#else 831590Srgrimes msg.addr = *(struct sockaddr *)&my_addr; 841590Srgrimes#endif 851590Srgrimes msg.id_num = htonl(-1); /* an impossible id_num */ 861590Srgrimes invitation_waiting = 1; 871590Srgrimes announce_invite(); 881590Srgrimes /* 891590Srgrimes * Shut off the automatic messages for a while, 90228992Suqs * so we can use the interrupt timer to resend the invitation 911590Srgrimes */ 921590Srgrimes end_msgs(); 931590Srgrimes setitimer(ITIMER_REAL, &itimer, (struct itimerval *)0); 941590Srgrimes message("Waiting for your party to respond"); 951590Srgrimes signal(SIGALRM, re_invite); 961590Srgrimes (void) setjmp(invitebuf); 971590Srgrimes while ((new_sockt = accept(sockt, 0, 0)) < 0) { 981590Srgrimes if (errno == EINTR) 991590Srgrimes continue; 1001590Srgrimes p_error("Unable to connect with your party"); 1011590Srgrimes } 1021590Srgrimes close(sockt); 1031590Srgrimes sockt = new_sockt; 1041590Srgrimes 1051590Srgrimes /* 1061590Srgrimes * Have the daemons delete the invitations now that we 1071590Srgrimes * have connected. 1081590Srgrimes */ 1091590Srgrimes current_state = "Waiting for your party to respond"; 1101590Srgrimes start_msgs(); 1111590Srgrimes 1121590Srgrimes msg.id_num = htonl(local_id); 1131590Srgrimes ctl_transact(my_machine_addr, msg, DELETE, &response); 1141590Srgrimes msg.id_num = htonl(remote_id); 1151590Srgrimes ctl_transact(his_machine_addr, msg, DELETE, &response); 1161590Srgrimes invitation_waiting = 0; 1171590Srgrimes} 1181590Srgrimes 1191590Srgrimes/* 120228992Suqs * Routine called on interrupt to re-invite the callee 1211590Srgrimes */ 12214443Sjoerg/* ARGSUSED */ 1231590Srgrimesvoid 124178642Sdelphijre_invite(int signo __unused) 1251590Srgrimes{ 1261590Srgrimes 1271590Srgrimes message("Ringing your party again"); 1287451Sache waddch(my_win.x_win, '\n'); 1297451Sache if (current_line < my_win.x_nlines - 1) 1307451Sache current_line++; 1311590Srgrimes /* force a re-announce */ 1321590Srgrimes msg.id_num = htonl(remote_id + 1); 1331590Srgrimes announce_invite(); 1341590Srgrimes longjmp(invitebuf, 1); 1351590Srgrimes} 1361590Srgrimes 13787710Smarkmstatic const char *answers[] = { 1381590Srgrimes "answer #0", /* SUCCESS */ 1391590Srgrimes "Your party is not logged on", /* NOT_HERE */ 1401590Srgrimes "Target machine is too confused to talk to us", /* FAILED */ 1411590Srgrimes "Target machine does not recognize us", /* MACHINE_UNKNOWN */ 1421590Srgrimes "Your party is refusing messages", /* PERMISSION_REFUSED */ 1431590Srgrimes "Target machine can not handle remote talk", /* UNKNOWN_REQUEST */ 1441590Srgrimes "Target machine indicates protocol mismatch", /* BADVERSION */ 1451590Srgrimes "Target machine indicates protocol botch (addr)",/* BADADDR */ 1461590Srgrimes "Target machine indicates protocol botch (ctl_addr)",/* BADCTLADDR */ 1471590Srgrimes}; 1481590Srgrimes#define NANSWERS (sizeof (answers) / sizeof (answers[0])) 1491590Srgrimes 1501590Srgrimes/* 1511590Srgrimes * Transmit the invitation and process the response 1521590Srgrimes */ 15314443Sjoergvoid 154178642Sdelphijannounce_invite(void) 1551590Srgrimes{ 1561590Srgrimes CTL_RESPONSE response; 1571590Srgrimes 1581590Srgrimes current_state = "Trying to connect to your party's talk daemon"; 1591590Srgrimes ctl_transact(his_machine_addr, msg, ANNOUNCE, &response); 1601590Srgrimes remote_id = response.id_num; 1611590Srgrimes if (response.answer != SUCCESS) { 1621590Srgrimes if (response.answer < NANSWERS) 1631590Srgrimes message(answers[response.answer]); 1641590Srgrimes quit(); 1651590Srgrimes } 1661590Srgrimes /* leave the actual invitation on my talk daemon */ 16766682Sru current_state = "Trying to connect to local talk daemon"; 1681590Srgrimes ctl_transact(my_machine_addr, msg, LEAVE_INVITE, &response); 1691590Srgrimes local_id = response.id_num; 1701590Srgrimes} 1711590Srgrimes 1721590Srgrimes/* 1731590Srgrimes * Tell the daemon to remove your invitation 1741590Srgrimes */ 17514443Sjoergvoid 176178642Sdelphijsend_delete(void) 1771590Srgrimes{ 1781590Srgrimes 1791590Srgrimes msg.type = DELETE; 1801590Srgrimes /* 181108533Sschweikh * This is just an extra clean up, so just send it 1821590Srgrimes * and don't wait for an answer 1831590Srgrimes */ 1841590Srgrimes msg.id_num = htonl(remote_id); 1851590Srgrimes daemon_addr.sin_addr = his_machine_addr; 1861590Srgrimes if (sendto(ctl_sockt, &msg, sizeof (msg), 0, 1871590Srgrimes (struct sockaddr *)&daemon_addr, 1881590Srgrimes sizeof (daemon_addr)) != sizeof(msg)) 18932503Scharnier warn("send_delete (remote)"); 1901590Srgrimes msg.id_num = htonl(local_id); 1911590Srgrimes daemon_addr.sin_addr = my_machine_addr; 1921590Srgrimes if (sendto(ctl_sockt, &msg, sizeof (msg), 0, 1931590Srgrimes (struct sockaddr *)&daemon_addr, 1941590Srgrimes sizeof (daemon_addr)) != sizeof (msg)) 19532503Scharnier warn("send_delete (local)"); 1961590Srgrimes} 197