From 5fd83771641d15c418f747bd343ba6738d3875f7 Mon Sep 17 00:00:00 2001 From: Cameron Katri Date: Sun, 9 May 2021 14:20:58 -0400 Subject: Import macOS userland adv_cmds-176 basic_cmds-55 bootstrap_cmds-116.100.1 developer_cmds-66 diskdev_cmds-667.40.1 doc_cmds-53.60.1 file_cmds-321.40.3 mail_cmds-35 misc_cmds-34 network_cmds-606.40.1 patch_cmds-17 remote_cmds-63 shell_cmds-216.60.1 system_cmds-880.60.2 text_cmds-106 --- remote_cmds/talk.tproj/invite.c | 202 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 202 insertions(+) create mode 100644 remote_cmds/talk.tproj/invite.c (limited to 'remote_cmds/talk.tproj/invite.c') diff --git a/remote_cmds/talk.tproj/invite.c b/remote_cmds/talk.tproj/invite.c new file mode 100644 index 0000000..b8562b2 --- /dev/null +++ b/remote_cmds/talk.tproj/invite.c @@ -0,0 +1,202 @@ +/* + * Copyright (c) 1983, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include + +#ifndef __APPLE__ +__FBSDID("$FreeBSD: src/usr.bin/talk/invite.c,v 1.9 2003/01/01 18:49:00 schweikh Exp $"); + +#ifndef lint +static const char sccsid[] = "@(#)invite.c 8.1 (Berkeley) 6/6/93"; +#endif +#endif /* __APPLE__ */ + +#include +#include +#include + +#include +#include +#include +#include + +#include "talk_ctl.h" +#include "talk.h" + +/* + * There wasn't an invitation waiting, so send a request containing + * our sockt address to the remote talk daemon so it can invite + * him + */ + +/* + * The msg.id's for the invitations + * on the local and remote machines. + * These are used to delete the + * invitations. + */ +int local_id, remote_id; +jmp_buf invitebuf; + +void +invite_remote() +{ + int new_sockt; + struct itimerval itimer; + CTL_RESPONSE response; + + itimer.it_value.tv_sec = RING_WAIT; + itimer.it_value.tv_usec = 0; + itimer.it_interval = itimer.it_value; + if (listen(sockt, 5) != 0) + p_error("Error on attempt to listen for caller"); +#ifdef MSG_EOR + /* copy new style sockaddr to old, swap family (short in old) */ + msg.addr = *(struct osockaddr *)&my_addr; /* XXX new to old style*/ + msg.addr.sa_family = htons(my_addr.sin_family); +#else + msg.addr = *(struct sockaddr *)&my_addr; +#endif + msg.id_num = htonl(-1); /* an impossible id_num */ + invitation_waiting = 1; + announce_invite(); + /* + * Shut off the automatic messages for a while, + * so we can use the interupt timer to resend the invitation + */ + end_msgs(); + setitimer(ITIMER_REAL, &itimer, (struct itimerval *)0); + message("Waiting for your party to respond"); + signal(SIGALRM, re_invite); + (void) setjmp(invitebuf); + while ((new_sockt = accept(sockt, 0, 0)) < 0) { + if (errno == EINTR) + continue; + p_error("Unable to connect with your party"); + } + close(sockt); + sockt = new_sockt; + + /* + * Have the daemons delete the invitations now that we + * have connected. + */ + current_state = "Waiting for your party to respond"; + start_msgs(); + + msg.id_num = htonl(local_id); + ctl_transact(my_machine_addr, msg, DELETE, &response); + msg.id_num = htonl(remote_id); + ctl_transact(his_machine_addr, msg, DELETE, &response); + invitation_waiting = 0; +} + +/* + * Routine called on interupt to re-invite the callee + */ +/* ARGSUSED */ +void +re_invite(signo) + int signo __unused; +{ + + message("Ringing your party again"); + waddch(my_win.x_win, '\n'); + if (current_line < my_win.x_nlines - 1) + current_line++; + /* force a re-announce */ + msg.id_num = htonl(remote_id + 1); + announce_invite(); + longjmp(invitebuf, 1); +} + +static const char *answers[] = { + "answer #0", /* SUCCESS */ + "Your party is not logged on", /* NOT_HERE */ + "Target machine is too confused to talk to us", /* FAILED */ + "Target machine does not recognize us", /* MACHINE_UNKNOWN */ + "Your party is refusing messages", /* PERMISSION_REFUSED */ + "Target machine can not handle remote talk", /* UNKNOWN_REQUEST */ + "Target machine indicates protocol mismatch", /* BADVERSION */ + "Target machine indicates protocol botch (addr)",/* BADADDR */ + "Target machine indicates protocol botch (ctl_addr)",/* BADCTLADDR */ +}; +#define NANSWERS (sizeof (answers) / sizeof (answers[0])) + +/* + * Transmit the invitation and process the response + */ +void +announce_invite() +{ + CTL_RESPONSE response; + + current_state = "Trying to connect to your party's talk daemon"; + ctl_transact(his_machine_addr, msg, ANNOUNCE, &response); + remote_id = response.id_num; + if (response.answer != SUCCESS) { + if (response.answer < NANSWERS) + message(answers[response.answer]); + quit(); + } + /* leave the actual invitation on my talk daemon */ + current_state = "Trying to connect to local talk daemon"; + ctl_transact(my_machine_addr, msg, LEAVE_INVITE, &response); + local_id = response.id_num; +} + +/* + * Tell the daemon to remove your invitation + */ +void +send_delete() +{ + + msg.type = DELETE; + /* + * This is just an extra clean up, so just send it + * and don't wait for an answer + */ + msg.id_num = htonl(remote_id); + daemon_addr.sin_addr = his_machine_addr; + if (sendto(ctl_sockt, &msg, sizeof (msg), 0, + (struct sockaddr *)&daemon_addr, + sizeof (daemon_addr)) != sizeof(msg)) + warn("send_delete (remote)"); + msg.id_num = htonl(local_id); + daemon_addr.sin_addr = my_machine_addr; + if (sendto(ctl_sockt, &msg, sizeof (msg), 0, + (struct sockaddr *)&daemon_addr, + sizeof (daemon_addr)) != sizeof (msg)) + warn("send_delete (local)"); +} -- cgit v1.2.3-56-ge451