1 /* 2 * Copyright (c) 1983 Regents of the University of California. 3 * All rights reserved. 4 * 5 * %sccs.include.redist.c% 6 */ 7 8 #ifndef lint 9 static char sccsid[] = "@(#)look_up.c 5.7 (Berkeley) 03/01/91"; 10 #endif /* not lint */ 11 12 #include <sys/types.h> 13 #include <sys/socket.h> 14 #include <netinet/in.h> 15 #include <protocols/talkd.h> 16 #include <errno.h> 17 #include "talk_ctl.h" 18 #include "talk.h" 19 20 /* 21 * See if the local daemon has an invitation for us. 22 */ 23 check_local() 24 { 25 CTL_RESPONSE response; 26 register CTL_RESPONSE *rp = &response; 27 28 /* the rest of msg was set up in get_names */ 29 #ifdef MSG_EOR 30 /* copy new style sockaddr to old, swap family (short in old) */ 31 msg.ctl_addr = *(struct osockaddr *)&ctl_addr; 32 msg.ctl_addr.sa_family = htons(ctl_addr.sin_family); 33 #else 34 msg.ctl_addr = *(struct sockaddr *)&ctl_addr; 35 #endif 36 /* must be initiating a talk */ 37 if (!look_for_invite(rp)) 38 return (0); 39 /* 40 * There was an invitation waiting for us, 41 * so connect with the other (hopefully waiting) party 42 */ 43 current_state = "Waiting to connect with caller"; 44 do { 45 if (rp->addr.sa_family != AF_INET) 46 p_error("Response uses invalid network address"); 47 errno = 0; 48 if (connect(sockt, 49 (struct sockaddr *)&rp->addr, sizeof (rp->addr)) != -1) 50 return (1); 51 } while (errno == EINTR); 52 if (errno == ECONNREFUSED) { 53 /* 54 * The caller gave up, but his invitation somehow 55 * was not cleared. Clear it and initiate an 56 * invitation. (We know there are no newer invitations, 57 * the talkd works LIFO.) 58 */ 59 ctl_transact(his_machine_addr, msg, DELETE, rp); 60 close(sockt); 61 open_sockt(); 62 return (0); 63 } 64 p_error("Unable to connect with initiator"); 65 /*NOTREACHED*/ 66 } 67 68 /* 69 * Look for an invitation on 'machine' 70 */ 71 look_for_invite(rp) 72 CTL_RESPONSE *rp; 73 { 74 struct in_addr machine_addr; 75 76 current_state = "Checking for invitation on caller's machine"; 77 ctl_transact(his_machine_addr, msg, LOOK_UP, rp); 78 /* the switch is for later options, such as multiple invitations */ 79 switch (rp->answer) { 80 81 case SUCCESS: 82 msg.id_num = htonl(rp->id_num); 83 return (1); 84 85 default: 86 /* there wasn't an invitation waiting for us */ 87 return (0); 88 } 89 } 90