source: trunk/third/talk/talk/invite.c @ 10543

Revision 10543, 6.1 KB checked in by ghudson, 27 years ago (diff)
Remove sa_ in oldsockaddr field names to avoid conflict with IRIX 6.3 macros.
Line 
1/*      $NetBSD: invite.c,v 1.3 1994/12/09 02:14:18 jtc Exp $   */
2
3/*
4 * Copyright (c) 1983, 1993
5 *      The Regents of the University of California.  All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 *    notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 *    notice, this list of conditions and the following disclaimer in the
14 *    documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 *    must display the following acknowledgement:
17 *      This product includes software developed by the University of
18 *      California, Berkeley and its contributors.
19 * 4. Neither the name of the University nor the names of its contributors
20 *    may be used to endorse or promote products derived from this software
21 *    without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
34 */
35
36#ifndef lint
37#if 0
38static char sccsid[] = "@(#)invite.c    8.1 (Berkeley) 6/6/93";
39#endif
40static char rcsid[] = "$NetBSD: invite.c,v 1.3 1994/12/09 02:14:18 jtc Exp $";
41#endif /* not lint */
42
43#include <sys/types.h>
44#include <sys/socket.h>
45#include <sys/time.h>
46#include <signal.h>
47#include <netinet/in.h>
48#include <protocols/talkd.h>
49#include <errno.h>
50#include <setjmp.h>
51#include "talk_ctl.h"
52#include "talk.h"
53
54/*
55 * There wasn't an invitation waiting, so send a request containing
56 * our sockt address to the remote talk daemon so it can invite
57 * him
58 */
59
60/*
61 * The msg.id's for the invitations
62 * on the local and remote machines.
63 * These are used to delete the
64 * invitations.
65 */
66int             local_id, remote_id;
67void            re_invite();
68sigjmp_buf      invitebuf;
69
70invite_remote()
71{
72        int nfd, read_mask, template, new_sockt;
73        struct itimerval itimer;
74        CTL_RESPONSE response;
75        struct sigaction action;
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        /* copy new style sockaddr to old, swap family (short in old) */
83        msg.addr = *(struct oldsockaddr *)&my_addr;  /* XXX new to old  style*/
84        msg.addr.family = htons(my_addr.sin_family);
85        msg.id_num = htonl(-1);         /* an impossible id_num */
86        invitation_waiting = 1;
87        announce_invite();
88        /*
89         * Shut off the automatic messages for a while,
90         * so we can use the interupt timer to resend the invitation
91         */
92        end_msgs();
93        setitimer(ITIMER_REAL, &itimer, (struct itimerval *)0);
94        message("Waiting for your party to respond");
95        sigemptyset(&action.sa_mask);
96        action.sa_handler = re_invite;
97        action.sa_flags = 0;
98        sigaction(SIGALRM, &action, NULL);
99        (void) sigsetjmp(invitebuf, 1);
100        while ((new_sockt = accept(sockt, 0, 0)) < 0) {
101                if (errno == EINTR)
102                        continue;
103                p_error("Unable to connect with your party");
104        }
105        close(sockt);
106        sockt = new_sockt;
107
108        /*
109         * Have the daemons delete the invitations now that we
110         * have connected.
111         */
112        current_state = "Waiting for your party to respond";
113        start_msgs();
114
115        msg.id_num = htonl(local_id);
116        ctl_transact(my_machine_addr, msg, DELETE, &response);
117        msg.id_num = htonl(remote_id);
118        ctl_transact(his_machine_addr, msg, DELETE, &response);
119        invitation_waiting = 0;
120}
121
122/*
123 * Routine called on interupt to re-invite the callee
124 */
125void
126re_invite()
127{
128
129        message("Ringing your party again");
130        current_line++;
131        /* force a re-announce */
132        msg.id_num = htonl(remote_id + 1);
133        announce_invite();
134        siglongjmp(invitebuf, 1);
135}
136
137static  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 */
153announce_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 */
173send_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}
Note: See TracBrowser for help on using the repository browser.