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