Now works between SUNs and VAXen
[unix-history] / usr / src / usr.bin / talk / invite.c
CommitLineData
963ce42e
MK
1#ifndef lint
2static char sccsid[] = "@(#)invite.c 1.2 (Berkeley) %G%";
3#endif
ec7915a9
MK
4
5#include "talk_ctl.h"
6#include <sys/time.h>
7#include <signal.h>
8#include <setjmp.h>
963ce42e
MK
9
10/*
11 * There wasn't an invitation waiting, so send a request containing
12 * our sockt address to the remote talk daemon so it can invite
13 * him
14 */
15
16/*
17 * The msg.id's for the invitations
18 * on the local and remote machines.
19 * These are used to delete the
20 * invitations.
21 */
22int local_id, remote_id;
23void re_invite();
24jmp_buf invitebuf;
ec7915a9
MK
25
26invite_remote()
27{
963ce42e
MK
28 int nfd, read_mask, template, new_sockt;
29 struct itimerval itimer;
30 CTL_RESPONSE response;
31
32 itimer.it_value.tv_sec = RING_WAIT;
33 itimer.it_value.tv_usec = 0;
34 itimer.it_interval = itimer.it_value;
35 if (listen(sockt, 5) != 0)
36 p_error("Error on attempt to listen for caller");
37 msg.addr = my_addr;
38 msg.id_num = -1; /* an impossible id_num */
39 invitation_waiting = 1;
40 announce_invite();
ec7915a9 41 /*
963ce42e 42 * Shut off the automatic messages for a while,
ec7915a9
MK
43 * so we can use the interupt timer to resend the invitation
44 */
963ce42e
MK
45 end_msgs();
46 setitimer(ITIMER_REAL, &itimer, (struct itimerval *)0);
47 message("Waiting for your party to respond");
48 signal(SIGALRM, re_invite);
49 (void) setjmp(invitebuf);
50 while ((new_sockt = accept(sockt, 0, 0)) < 0) {
51 if (errno == EINTR)
52 continue;
53 p_error("Unable to connect with your party");
ec7915a9 54 }
963ce42e
MK
55 close(sockt);
56 sockt = new_sockt;
ec7915a9 57
963ce42e
MK
58 /*
59 * Have the daemons delete the invitations now that we
60 * have connected.
ec7915a9 61 */
963ce42e
MK
62 current_state = "Waiting for your party to respond";
63 start_msgs();
64
65 msg.id_num = local_id;
66 ctl_transact(my_machine_addr, msg, DELETE, &response);
67 msg.id_num = remote_id;
68 ctl_transact(his_machine_addr, msg, DELETE, &response);
69 invitation_waiting = 0;
ec7915a9
MK
70}
71
963ce42e
MK
72/*
73 * Routine called on interupt to re-invite the callee
74 */
75void
76re_invite()
ec7915a9 77{
963ce42e
MK
78
79 message("Ringing your party again");
80 current_line++;
ec7915a9 81 /* force a re-announce */
963ce42e
MK
82 msg.id_num = remote_id + 1;
83 announce_invite();
84 longjmp(invitebuf, 1);
ec7915a9
MK
85}
86
963ce42e
MK
87/*
88 * Transmit the invitation and process the response
89 */
ec7915a9
MK
90announce_invite()
91{
963ce42e
MK
92 CTL_RESPONSE response;
93
94 current_state = "Trying to connect to your party's talk daemon";
95 ctl_transact(his_machine_addr, msg, ANNOUNCE, &response);
96 remote_id = response.id_num;
97 if (response.answer != SUCCESS) {
98 switch (response.answer) {
99
100 case NOT_HERE :
101 message("Your party is not logged on");
102 break;
103
104 case MACHINE_UNKNOWN :
105 message("Target machine does not recognize us");
106 break;
107
108 case UNKNOWN_REQUEST :
109 message("Target machine can not handle remote talk");
110 break;
111
112 case FAILED :
113 message("Target machine is too confused to talk to us");
114 break;
115
116 case PERMISSION_DENIED :
117 message("Your party is refusing messages");
118 break;
119 }
120 quit();
ec7915a9 121 }
ec7915a9 122 /* leave the actual invitation on my talk daemon */
963ce42e
MK
123 ctl_transact(my_machine_addr, msg, LEAVE_INVITE, &response);
124 local_id = response.id_num;
ec7915a9 125}
963ce42e
MK
126
127/*
128 * Tell the daemon to remove your invitation
129 */
ec7915a9
MK
130send_delete()
131{
963ce42e
MK
132
133 msg.type = DELETE;
134 /*
135 * This is just a extra clean up, so just send it
136 * and don't wait for an answer
137 */
138 msg.id_num = remote_id;
139 daemon_addr.sin_addr = his_machine_addr;
140 if (sendto(ctl_sockt, &msg, sizeof(CTL_MSG), 0, &daemon_addr,
141 sizeof(daemon_addr)) != sizeof(CTL_MSG))
142 perror("send_delete remote");
143 msg.id_num = local_id;
144 daemon_addr.sin_addr = my_machine_addr;
145 if (sendto(ctl_sockt, &msg, sizeof(CTL_MSG), 0, &daemon_addr,
146 sizeof(daemon_addr)) != sizeof(CTL_MSG))
147 perror("send_delete local");
ec7915a9 148}