122394Sdist /* 222394Sdist * Copyright (c) 1983 Regents of the University of California. 3*34373Sbostic * All rights reserved. 4*34373Sbostic * 5*34373Sbostic * Redistribution and use in source and binary forms are permitted 6*34373Sbostic * provided that this notice is preserved and that due credit is given 7*34373Sbostic * to the University of California at Berkeley. The name of the University 8*34373Sbostic * may not be used to endorse or promote products derived from this 9*34373Sbostic * software without specific prior written permission. This software 10*34373Sbostic * is provided ``as is'' without express or implied warranty. 1122394Sdist */ 1222394Sdist 1316363Skarels #ifndef lint 14*34373Sbostic static char sccsid[] = "@(#)invite.c 5.4 (Berkeley) 05/20/88"; 15*34373Sbostic #endif /* not lint */ 1616350Skarels 1716350Skarels #include "talk_ctl.h" 1816350Skarels #include <sys/time.h> 1916350Skarels #include <signal.h> 2016350Skarels #include <setjmp.h> 2116350Skarels 2216363Skarels /* 2316363Skarels * There wasn't an invitation waiting, so send a request containing 2416363Skarels * our sockt address to the remote talk daemon so it can invite 2516363Skarels * him 2616363Skarels */ 2716350Skarels 2816363Skarels /* 2916363Skarels * The msg.id's for the invitations 3016363Skarels * on the local and remote machines. 3116363Skarels * These are used to delete the 3216363Skarels * invitations. 3316363Skarels */ 3416363Skarels int local_id, remote_id; 3516363Skarels void re_invite(); 3616363Skarels jmp_buf invitebuf; 3716363Skarels 3816350Skarels invite_remote() 3916350Skarels { 4016363Skarels int nfd, read_mask, template, new_sockt; 4116363Skarels struct itimerval itimer; 4216363Skarels CTL_RESPONSE response; 4316350Skarels 4416363Skarels itimer.it_value.tv_sec = RING_WAIT; 4516363Skarels itimer.it_value.tv_usec = 0; 4616363Skarels itimer.it_interval = itimer.it_value; 4716363Skarels if (listen(sockt, 5) != 0) 4816363Skarels p_error("Error on attempt to listen for caller"); 4926848Smckusick msg.addr = *(struct sockaddr *)&my_addr; 5026848Smckusick msg.addr.sa_family = htons(msg.addr.sa_family); 5126848Smckusick msg.id_num = htonl(-1); /* an impossible id_num */ 5216363Skarels invitation_waiting = 1; 5316363Skarels announce_invite(); 5416350Skarels /* 5516363Skarels * Shut off the automatic messages for a while, 5616350Skarels * so we can use the interupt timer to resend the invitation 5716350Skarels */ 5816363Skarels end_msgs(); 5916363Skarels setitimer(ITIMER_REAL, &itimer, (struct itimerval *)0); 6016363Skarels message("Waiting for your party to respond"); 6116363Skarels signal(SIGALRM, re_invite); 6216363Skarels (void) setjmp(invitebuf); 6316363Skarels while ((new_sockt = accept(sockt, 0, 0)) < 0) { 6416363Skarels if (errno == EINTR) 6516363Skarels continue; 6616363Skarels p_error("Unable to connect with your party"); 6716350Skarels } 6816363Skarels close(sockt); 6916363Skarels sockt = new_sockt; 7016350Skarels 7116363Skarels /* 7216363Skarels * Have the daemons delete the invitations now that we 7316363Skarels * have connected. 7416350Skarels */ 7516363Skarels current_state = "Waiting for your party to respond"; 7616363Skarels start_msgs(); 7716350Skarels 7826848Smckusick msg.id_num = htonl(local_id); 7916363Skarels ctl_transact(my_machine_addr, msg, DELETE, &response); 8026848Smckusick msg.id_num = htonl(remote_id); 8116363Skarels ctl_transact(his_machine_addr, msg, DELETE, &response); 8216363Skarels invitation_waiting = 0; 8316350Skarels } 8416350Skarels 8516363Skarels /* 8616363Skarels * Routine called on interupt to re-invite the callee 8716363Skarels */ 8816363Skarels void 8916363Skarels re_invite() 9016363Skarels { 9116350Skarels 9216363Skarels message("Ringing your party again"); 9316363Skarels current_line++; 9416350Skarels /* force a re-announce */ 9526848Smckusick msg.id_num = htonl(remote_id + 1); 9616363Skarels announce_invite(); 9716363Skarels longjmp(invitebuf, 1); 9816350Skarels } 9916350Skarels 10026848Smckusick static char *answers[] = { 10130540Ssam "answer #0", /* SUCCESS */ 10226848Smckusick "Your party is not logged on", /* NOT_HERE */ 10330540Ssam "Target machine is too confused to talk to us", /* FAILED */ 10426848Smckusick "Target machine does not recognize us", /* MACHINE_UNKNOWN */ 10530540Ssam "Your party is refusing messages", /* PERMISSION_REFUSED */ 10626848Smckusick "Target machine can not handle remote talk", /* UNKNOWN_REQUEST */ 10726848Smckusick "Target machine indicates protocol mismatch", /* BADVERSION */ 10826848Smckusick "Target machine indicates protocol botch (addr)",/* BADADDR */ 10926848Smckusick "Target machine indicates protocol botch (ctl_addr)",/* BADCTLADDR */ 11026848Smckusick }; 11126848Smckusick #define NANSWERS (sizeof (answers) / sizeof (answers[0])) 11226848Smckusick 11316363Skarels /* 11416363Skarels * Transmit the invitation and process the response 11516363Skarels */ 11616350Skarels announce_invite() 11716350Skarels { 11816363Skarels CTL_RESPONSE response; 11916350Skarels 12016363Skarels current_state = "Trying to connect to your party's talk daemon"; 12116363Skarels ctl_transact(his_machine_addr, msg, ANNOUNCE, &response); 12216363Skarels remote_id = response.id_num; 12316363Skarels if (response.answer != SUCCESS) { 12426848Smckusick if (response.answer < NANSWERS) 12526848Smckusick message(answers[response.answer]); 12616363Skarels quit(); 12716350Skarels } 12816350Skarels /* leave the actual invitation on my talk daemon */ 12916363Skarels ctl_transact(my_machine_addr, msg, LEAVE_INVITE, &response); 13016363Skarels local_id = response.id_num; 13116350Skarels } 13226848Smckusick 13316363Skarels /* 13416363Skarels * Tell the daemon to remove your invitation 13516363Skarels */ 13616350Skarels send_delete() 13716350Skarels { 13816350Skarels 13916363Skarels msg.type = DELETE; 14016363Skarels /* 14116363Skarels * This is just a extra clean up, so just send it 14216363Skarels * and don't wait for an answer 14316363Skarels */ 14426848Smckusick msg.id_num = htonl(remote_id); 14516363Skarels daemon_addr.sin_addr = his_machine_addr; 14626848Smckusick if (sendto(ctl_sockt, &msg, sizeof (msg), 0, &daemon_addr, 14726848Smckusick sizeof (daemon_addr)) != sizeof(msg)) 14826848Smckusick perror("send_delete (remote)"); 14926848Smckusick msg.id_num = htonl(local_id); 15016363Skarels daemon_addr.sin_addr = my_machine_addr; 15126848Smckusick if (sendto(ctl_sockt, &msg, sizeof (msg), 0, &daemon_addr, 15226848Smckusick sizeof (daemon_addr)) != sizeof (msg)) 15326848Smckusick perror("send_delete (local)"); 15416350Skarels } 155