| Commit | Line | Data |
|---|---|---|
| 984263bc MD |
1 | /* |
| 2 | * Copyright (c) 1983, 1993 | |
| 3 | * The Regents of the University of California. All rights reserved. | |
| 4 | * | |
| 5 | * Redistribution and use in source and binary forms, with or without | |
| 6 | * modification, are permitted provided that the following conditions | |
| 7 | * are met: | |
| 8 | * 1. Redistributions of source code must retain the above copyright | |
| 9 | * notice, this list of conditions and the following disclaimer. | |
| 10 | * 2. Redistributions in binary form must reproduce the above copyright | |
| 11 | * notice, this list of conditions and the following disclaimer in the | |
| 12 | * documentation and/or other materials provided with the distribution. | |
| 13 | * 3. All advertising materials mentioning features or use of this software | |
| 14 | * must display the following acknowledgement: | |
| 15 | * This product includes software developed by the University of | |
| 16 | * California, Berkeley and its contributors. | |
| 17 | * 4. Neither the name of the University nor the names of its contributors | |
| 18 | * may be used to endorse or promote products derived from this software | |
| 19 | * without specific prior written permission. | |
| 20 | * | |
| 21 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | |
| 22 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
| 23 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
| 24 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | |
| 25 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
| 26 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
| 27 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
| 28 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
| 29 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
| 30 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
| 31 | * SUCH DAMAGE. | |
| 1de703da MD |
32 | * |
| 33 | * @(#)invite.c 8.1 (Berkeley) 6/6/93 | |
| 34 | * $FreeBSD: src/usr.bin/talk/invite.c,v 1.6.2.1 2000/10/05 17:40:38 ru Exp $ | |
| 984263bc MD |
35 | */ |
| 36 | ||
| 800c4f63 JS |
37 | #include <sys/param.h> |
| 38 | #include <sys/socket.h> | |
| 984263bc MD |
39 | #include <err.h> |
| 40 | #include <errno.h> | |
| 41 | #include <setjmp.h> | |
| 42 | #include <signal.h> | |
| 984263bc MD |
43 | #include <protocols/talkd.h> |
| 44 | #include "talk_ctl.h" | |
| 45 | #include "talk.h" | |
| 46 | ||
| 47 | /* | |
| 48 | * There wasn't an invitation waiting, so send a request containing | |
| 49 | * our sockt address to the remote talk daemon so it can invite | |
| 50 | * him | |
| 51 | */ | |
| 52 | ||
| 53 | /* | |
| 54 | * The msg.id's for the invitations | |
| 55 | * on the local and remote machines. | |
| 56 | * These are used to delete the | |
| 57 | * invitations. | |
| 58 | */ | |
| 59 | int local_id, remote_id; | |
| 60 | jmp_buf invitebuf; | |
| 61 | ||
| 62 | void | |
| 1d1731fa | 63 | invite_remote(void) |
| 984263bc | 64 | { |
| e2daa382 | 65 | int new_sockt; |
| 984263bc MD |
66 | struct itimerval itimer; |
| 67 | CTL_RESPONSE response; | |
| 68 | ||
| 69 | itimer.it_value.tv_sec = RING_WAIT; | |
| 70 | itimer.it_value.tv_usec = 0; | |
| 71 | itimer.it_interval = itimer.it_value; | |
| 72 | if (listen(sockt, 5) != 0) | |
| 73 | p_error("Error on attempt to listen for caller"); | |
| 74 | #ifdef MSG_EOR | |
| 75 | /* copy new style sockaddr to old, swap family (short in old) */ | |
| 76 | msg.addr = *(struct osockaddr *)&my_addr; /* XXX new to old style*/ | |
| 77 | msg.addr.sa_family = htons(my_addr.sin_family); | |
| 78 | #else | |
| 79 | msg.addr = *(struct sockaddr *)&my_addr; | |
| 80 | #endif | |
| 81 | msg.id_num = htonl(-1); /* an impossible id_num */ | |
| 82 | invitation_waiting = 1; | |
| 83 | announce_invite(); | |
| 84 | /* | |
| 85 | * Shut off the automatic messages for a while, | |
| 86 | * so we can use the interupt timer to resend the invitation | |
| 87 | */ | |
| 88 | end_msgs(); | |
| 60233e58 | 89 | setitimer(ITIMER_REAL, &itimer, NULL); |
| 984263bc MD |
90 | message("Waiting for your party to respond"); |
| 91 | signal(SIGALRM, re_invite); | |
| 92 | (void) setjmp(invitebuf); | |
| 93 | while ((new_sockt = accept(sockt, 0, 0)) < 0) { | |
| 94 | if (errno == EINTR) | |
| 95 | continue; | |
| 96 | p_error("Unable to connect with your party"); | |
| 97 | } | |
| 98 | close(sockt); | |
| 99 | sockt = new_sockt; | |
| 100 | ||
| 101 | /* | |
| 102 | * Have the daemons delete the invitations now that we | |
| 103 | * have connected. | |
| 104 | */ | |
| 105 | current_state = "Waiting for your party to respond"; | |
| 106 | start_msgs(); | |
| 107 | ||
| 108 | msg.id_num = htonl(local_id); | |
| 109 | ctl_transact(my_machine_addr, msg, DELETE, &response); | |
| 110 | msg.id_num = htonl(remote_id); | |
| 111 | ctl_transact(his_machine_addr, msg, DELETE, &response); | |
| 112 | invitation_waiting = 0; | |
| 113 | } | |
| 114 | ||
| 115 | /* | |
| 116 | * Routine called on interupt to re-invite the callee | |
| 117 | */ | |
| 118 | /* ARGSUSED */ | |
| 119 | void | |
| e2daa382 | 120 | re_invite(int signo __unused) |
| 984263bc MD |
121 | { |
| 122 | ||
| 123 | message("Ringing your party again"); | |
| 124 | waddch(my_win.x_win, '\n'); | |
| 125 | if (current_line < my_win.x_nlines - 1) | |
| 126 | current_line++; | |
| 127 | /* force a re-announce */ | |
| 128 | msg.id_num = htonl(remote_id + 1); | |
| 129 | announce_invite(); | |
| 130 | longjmp(invitebuf, 1); | |
| 131 | } | |
| 132 | ||
| e2daa382 | 133 | static const char *answers[] = { |
| 984263bc MD |
134 | "answer #0", /* SUCCESS */ |
| 135 | "Your party is not logged on", /* NOT_HERE */ | |
| 136 | "Target machine is too confused to talk to us", /* FAILED */ | |
| 137 | "Target machine does not recognize us", /* MACHINE_UNKNOWN */ | |
| 138 | "Your party is refusing messages", /* PERMISSION_REFUSED */ | |
| 139 | "Target machine can not handle remote talk", /* UNKNOWN_REQUEST */ | |
| 140 | "Target machine indicates protocol mismatch", /* BADVERSION */ | |
| 141 | "Target machine indicates protocol botch (addr)",/* BADADDR */ | |
| 142 | "Target machine indicates protocol botch (ctl_addr)",/* BADCTLADDR */ | |
| 143 | }; | |
| 144 | #define NANSWERS (sizeof (answers) / sizeof (answers[0])) | |
| 145 | ||
| 146 | /* | |
| 147 | * Transmit the invitation and process the response | |
| 148 | */ | |
| 149 | void | |
| 1d1731fa | 150 | announce_invite(void) |
| 984263bc MD |
151 | { |
| 152 | CTL_RESPONSE response; | |
| 153 | ||
| 154 | current_state = "Trying to connect to your party's talk daemon"; | |
| 155 | ctl_transact(his_machine_addr, msg, ANNOUNCE, &response); | |
| 156 | remote_id = response.id_num; | |
| 157 | if (response.answer != SUCCESS) { | |
| 158 | if (response.answer < NANSWERS) | |
| 159 | message(answers[response.answer]); | |
| 160 | quit(); | |
| 161 | } | |
| 162 | /* leave the actual invitation on my talk daemon */ | |
| 163 | current_state = "Trying to connect to local talk daemon"; | |
| 164 | ctl_transact(my_machine_addr, msg, LEAVE_INVITE, &response); | |
| 165 | local_id = response.id_num; | |
| 166 | } | |
| 167 | ||
| 168 | /* | |
| 169 | * Tell the daemon to remove your invitation | |
| 170 | */ | |
| 171 | void | |
| 1d1731fa | 172 | send_delete(void) |
| 984263bc MD |
173 | { |
| 174 | ||
| 175 | msg.type = DELETE; | |
| 176 | /* | |
| 177 | * This is just a extra clean up, so just send it | |
| 178 | * and don't wait for an answer | |
| 179 | */ | |
| 180 | msg.id_num = htonl(remote_id); | |
| 181 | daemon_addr.sin_addr = his_machine_addr; | |
| 182 | if (sendto(ctl_sockt, &msg, sizeof (msg), 0, | |
| 183 | (struct sockaddr *)&daemon_addr, | |
| 184 | sizeof (daemon_addr)) != sizeof(msg)) | |
| 185 | warn("send_delete (remote)"); | |
| 186 | msg.id_num = htonl(local_id); | |
| 187 | daemon_addr.sin_addr = my_machine_addr; | |
| 188 | if (sendto(ctl_sockt, &msg, sizeof (msg), 0, | |
| 189 | (struct sockaddr *)&daemon_addr, | |
| 190 | sizeof (daemon_addr)) != sizeof (msg)) | |
| 191 | warn("send_delete (local)"); | |
| 192 | } |