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