invite.c revision 108533
1178354Ssam/* 2178354Ssam * Copyright (c) 1983, 1993 3178354Ssam * The Regents of the University of California. All rights reserved. 4178354Ssam * 5178354Ssam * Redistribution and use in source and binary forms, with or without 6178354Ssam * modification, are permitted provided that the following conditions 7178354Ssam * are met: 8178354Ssam * 1. Redistributions of source code must retain the above copyright 9178354Ssam * notice, this list of conditions and the following disclaimer. 10178354Ssam * 2. Redistributions in binary form must reproduce the above copyright 11178354Ssam * notice, this list of conditions and the following disclaimer in the 12178354Ssam * documentation and/or other materials provided with the distribution. 13178354Ssam * 3. All advertising materials mentioning features or use of this software 14178354Ssam * must display the following acknowledgement: 15178354Ssam * This product includes software developed by the University of 16178354Ssam * California, Berkeley and its contributors. 17178354Ssam * 4. Neither the name of the University nor the names of its contributors 18178354Ssam * may be used to endorse or promote products derived from this software 19178354Ssam * without specific prior written permission. 20178354Ssam * 21178354Ssam * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22178354Ssam * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23178354Ssam * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24178354Ssam * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25178354Ssam * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26178354Ssam * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27178354Ssam * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28178354Ssam * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29178354Ssam * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30178354Ssam * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31178354Ssam * SUCH DAMAGE. 32178354Ssam */ 33178354Ssam 34178354Ssam#include <sys/cdefs.h> 35178354Ssam 36178354Ssam__FBSDID("$FreeBSD: head/usr.bin/talk/invite.c 108533 2003-01-01 18:49:04Z schweikh $"); 37178354Ssam 38178354Ssam#ifndef lint 39178354Ssamstatic const char sccsid[] = "@(#)invite.c 8.1 (Berkeley) 6/6/93"; 40178354Ssam#endif 41178354Ssam 42178354Ssam#include <sys/types.h> 43178354Ssam#include <sys/socket.h> 44178354Ssam#include <protocols/talkd.h> 45178354Ssam 46178354Ssam#include <err.h> 47178354Ssam#include <errno.h> 48178354Ssam#include <setjmp.h> 49178354Ssam#include <signal.h> 50178354Ssam 51178354Ssam#include "talk_ctl.h" 52178354Ssam#include "talk.h" 53178354Ssam 54178354Ssam/* 55178354Ssam * There wasn't an invitation waiting, so send a request containing 56178354Ssam * our sockt address to the remote talk daemon so it can invite 57178354Ssam * him 58178354Ssam */ 59178354Ssam 60178354Ssam/* 61178354Ssam * The msg.id's for the invitations 62178354Ssam * on the local and remote machines. 63178354Ssam * These are used to delete the 64178354Ssam * invitations. 65178354Ssam */ 66178354Ssamint local_id, remote_id; 67178354Ssamjmp_buf invitebuf; 68178354Ssam 69178354Ssamvoid 70178354Ssaminvite_remote() 71178354Ssam{ 72178354Ssam int new_sockt; 73178354Ssam struct itimerval itimer; 74178354Ssam CTL_RESPONSE response; 75178354Ssam 76178354Ssam itimer.it_value.tv_sec = RING_WAIT; 77178354Ssam itimer.it_value.tv_usec = 0; 78178354Ssam itimer.it_interval = itimer.it_value; 79178354Ssam if (listen(sockt, 5) != 0) 80178354Ssam p_error("Error on attempt to listen for caller"); 81178354Ssam#ifdef MSG_EOR 82178354Ssam /* copy new style sockaddr to old, swap family (short in old) */ 83178354Ssam msg.addr = *(struct osockaddr *)&my_addr; /* XXX new to old style*/ 84178354Ssam msg.addr.sa_family = htons(my_addr.sin_family); 85178354Ssam#else 86178354Ssam msg.addr = *(struct sockaddr *)&my_addr; 87178354Ssam#endif 88178354Ssam msg.id_num = htonl(-1); /* an impossible id_num */ 89178354Ssam invitation_waiting = 1; 90178354Ssam announce_invite(); 91178354Ssam /* 92178354Ssam * Shut off the automatic messages for a while, 93178354Ssam * so we can use the interupt timer to resend the invitation 94178354Ssam */ 95178354Ssam end_msgs(); 96178354Ssam setitimer(ITIMER_REAL, &itimer, (struct itimerval *)0); 97178354Ssam message("Waiting for your party to respond"); 98178354Ssam signal(SIGALRM, re_invite); 99178354Ssam (void) setjmp(invitebuf); 100178354Ssam while ((new_sockt = accept(sockt, 0, 0)) < 0) { 101178354Ssam if (errno == EINTR) 102178354Ssam continue; 103178354Ssam p_error("Unable to connect with your party"); 104178354Ssam } 105178354Ssam close(sockt); 106178354Ssam sockt = new_sockt; 107178354Ssam 108178354Ssam /* 109178354Ssam * Have the daemons delete the invitations now that we 110178354Ssam * have connected. 111178354Ssam */ 112178354Ssam current_state = "Waiting for your party to respond"; 113178354Ssam start_msgs(); 114178354Ssam 115178354Ssam msg.id_num = htonl(local_id); 116178354Ssam ctl_transact(my_machine_addr, msg, DELETE, &response); 117178354Ssam msg.id_num = htonl(remote_id); 118178354Ssam ctl_transact(his_machine_addr, msg, DELETE, &response); 119178354Ssam invitation_waiting = 0; 120178354Ssam} 121178354Ssam 122178354Ssam/* 123178354Ssam * Routine called on interupt to re-invite the callee 124178354Ssam */ 125178354Ssam/* ARGSUSED */ 126178354Ssamvoid 127178354Ssamre_invite(signo) 128178354Ssam int signo __unused; 129178354Ssam{ 130178354Ssam 131178354Ssam message("Ringing your party again"); 132178354Ssam waddch(my_win.x_win, '\n'); 133178354Ssam if (current_line < my_win.x_nlines - 1) 134178354Ssam current_line++; 135178354Ssam /* force a re-announce */ 136178354Ssam msg.id_num = htonl(remote_id + 1); 137178354Ssam announce_invite(); 138178354Ssam longjmp(invitebuf, 1); 139178354Ssam} 140178354Ssam 141178354Ssamstatic const char *answers[] = { 142178354Ssam "answer #0", /* SUCCESS */ 143178354Ssam "Your party is not logged on", /* NOT_HERE */ 144178354Ssam "Target machine is too confused to talk to us", /* FAILED */ 145178354Ssam "Target machine does not recognize us", /* MACHINE_UNKNOWN */ 146178354Ssam "Your party is refusing messages", /* PERMISSION_REFUSED */ 147178354Ssam "Target machine can not handle remote talk", /* UNKNOWN_REQUEST */ 148178354Ssam "Target machine indicates protocol mismatch", /* BADVERSION */ 149178354Ssam "Target machine indicates protocol botch (addr)",/* BADADDR */ 150178354Ssam "Target machine indicates protocol botch (ctl_addr)",/* BADCTLADDR */ 151178354Ssam}; 152178354Ssam#define NANSWERS (sizeof (answers) / sizeof (answers[0])) 153178354Ssam 154178354Ssam/* 155178354Ssam * Transmit the invitation and process the response 156178354Ssam */ 157178354Ssamvoid 158178354Ssamannounce_invite() 159178354Ssam{ 160178354Ssam CTL_RESPONSE response; 161178354Ssam 162178354Ssam current_state = "Trying to connect to your party's talk daemon"; 163178354Ssam ctl_transact(his_machine_addr, msg, ANNOUNCE, &response); 164178354Ssam remote_id = response.id_num; 165178354Ssam if (response.answer != SUCCESS) { 166178354Ssam if (response.answer < NANSWERS) 167178354Ssam message(answers[response.answer]); 168178354Ssam quit(); 169178354Ssam } 170178354Ssam /* leave the actual invitation on my talk daemon */ 171178354Ssam current_state = "Trying to connect to local talk daemon"; 172178354Ssam ctl_transact(my_machine_addr, msg, LEAVE_INVITE, &response); 173178354Ssam local_id = response.id_num; 174178354Ssam} 175178354Ssam 176178354Ssam/* 177178354Ssam * Tell the daemon to remove your invitation 178178354Ssam */ 179178354Ssamvoid 180178354Ssamsend_delete() 181178354Ssam{ 182178354Ssam 183178354Ssam msg.type = DELETE; 184178354Ssam /* 185178354Ssam * This is just an extra clean up, so just send it 186178354Ssam * and don't wait for an answer 187178354Ssam */ 188178354Ssam msg.id_num = htonl(remote_id); 189178354Ssam daemon_addr.sin_addr = his_machine_addr; 190178354Ssam if (sendto(ctl_sockt, &msg, sizeof (msg), 0, 191178354Ssam (struct sockaddr *)&daemon_addr, 192178354Ssam sizeof (daemon_addr)) != sizeof(msg)) 193178354Ssam warn("send_delete (remote)"); 194178354Ssam msg.id_num = htonl(local_id); 195178354Ssam daemon_addr.sin_addr = my_machine_addr; 196178354Ssam if (sendto(ctl_sockt, &msg, sizeof (msg), 0, 197178354Ssam (struct sockaddr *)&daemon_addr, 198178354Ssam sizeof (daemon_addr)) != sizeof (msg)) 199178354Ssam warn("send_delete (local)"); 200178354Ssam} 201178354Ssam