* Copyright (c) 1983 Regents of the University of California.
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not be used to endorse or promote products derived
* from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
static char sccsid
[] = "@(#)invite.c 5.5 (Berkeley) %G%";
* There wasn't an invitation waiting, so send a request containing
* our sockt address to the remote talk daemon so it can invite
* The msg.id's for the invitations
* on the local and remote machines.
* These are used to delete the
int nfd
, read_mask
, template, new_sockt
;
itimer
.it_value
.tv_sec
= RING_WAIT
;
itimer
.it_value
.tv_usec
= 0;
itimer
.it_interval
= itimer
.it_value
;
if (listen(sockt
, 5) != 0)
p_error("Error on attempt to listen for caller");
msg
.addr
= *(struct sockaddr
*)&my_addr
;
msg
.addr
.sa_family
= htons(msg
.addr
.sa_family
);
msg
.id_num
= htonl(-1); /* an impossible id_num */
* Shut off the automatic messages for a while,
* so we can use the interupt timer to resend the invitation
setitimer(ITIMER_REAL
, &itimer
, (struct itimerval
*)0);
message("Waiting for your party to respond");
signal(SIGALRM
, re_invite
);
(void) setjmp(invitebuf
);
while ((new_sockt
= accept(sockt
, 0, 0)) < 0) {
p_error("Unable to connect with your party");
* Have the daemons delete the invitations now that we
current_state
= "Waiting for your party to respond";
msg
.id_num
= htonl(local_id
);
ctl_transact(my_machine_addr
, msg
, DELETE
, &response
);
msg
.id_num
= htonl(remote_id
);
ctl_transact(his_machine_addr
, msg
, DELETE
, &response
);
* Routine called on interupt to re-invite the callee
message("Ringing your party again");
/* force a re-announce */
msg
.id_num
= htonl(remote_id
+ 1);
static char *answers
[] = {
"answer #0", /* SUCCESS */
"Your party is not logged on", /* NOT_HERE */
"Target machine is too confused to talk to us", /* FAILED */
"Target machine does not recognize us", /* MACHINE_UNKNOWN */
"Your party is refusing messages", /* PERMISSION_REFUSED */
"Target machine can not handle remote talk", /* UNKNOWN_REQUEST */
"Target machine indicates protocol mismatch", /* BADVERSION */
"Target machine indicates protocol botch (addr)",/* BADADDR */
"Target machine indicates protocol botch (ctl_addr)",/* BADCTLADDR */
#define NANSWERS (sizeof (answers) / sizeof (answers[0]))
* Transmit the invitation and process the response
current_state
= "Trying to connect to your party's talk daemon";
ctl_transact(his_machine_addr
, msg
, ANNOUNCE
, &response
);
remote_id
= response
.id_num
;
if (response
.answer
!= SUCCESS
) {
if (response
.answer
< NANSWERS
)
message(answers
[response
.answer
]);
/* leave the actual invitation on my talk daemon */
ctl_transact(my_machine_addr
, msg
, LEAVE_INVITE
, &response
);
local_id
= response
.id_num
;
* Tell the daemon to remove your invitation
* This is just a extra clean up, so just send it
* and don't wait for an answer
msg
.id_num
= htonl(remote_id
);
daemon_addr
.sin_addr
= his_machine_addr
;
if (sendto(ctl_sockt
, &msg
, sizeof (msg
), 0, &daemon_addr
,
sizeof (daemon_addr
)) != sizeof(msg
))
perror("send_delete (remote)");
msg
.id_num
= htonl(local_id
);
daemon_addr
.sin_addr
= my_machine_addr
;
if (sendto(ctl_sockt
, &msg
, sizeof (msg
), 0, &daemon_addr
,
sizeof (daemon_addr
)) != sizeof (msg
))
perror("send_delete (local)");