1 /* 2 * Copyright (c) 1983 Regents of the University of California. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms are permitted 6 * provided that the above copyright notice and this paragraph are 7 * duplicated in all such forms and that any documentation, 8 * advertising materials, and other materials related to such 9 * distribution and use acknowledge that the software was developed 10 * by the University of California, Berkeley. The name of the 11 * University may not be used to endorse or promote products derived 12 * from this software without specific prior written permission. 13 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 14 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 15 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 16 */ 17 18 #ifndef lint 19 static char sccsid[] = "@(#)look_up.c 5.4 (Berkeley) 06/29/88"; 20 #endif /* not lint */ 21 22 #include "talk_ctl.h" 23 24 /* 25 * See if the local daemon has an invitation for us. 26 */ 27 check_local() 28 { 29 CTL_RESPONSE response; 30 register CTL_RESPONSE *rp = &response; 31 32 /* the rest of msg was set up in get_names */ 33 msg.ctl_addr = *(struct sockaddr *)&ctl_addr; 34 msg.ctl_addr.sa_family = htons(msg.ctl_addr.sa_family); 35 /* must be initiating a talk */ 36 if (!look_for_invite(rp)) 37 return (0); 38 /* 39 * There was an invitation waiting for us, 40 * so connect with the other (hopefully waiting) party 41 */ 42 current_state = "Waiting to connect with caller"; 43 do { 44 if (rp->addr.sa_family != AF_INET) 45 p_error("Response uses invalid network address"); 46 errno = 0; 47 if (connect(sockt, &rp->addr, sizeof (rp->addr)) != -1) 48 return (1); 49 } while (errno == EINTR); 50 if (errno == ECONNREFUSED) { 51 /* 52 * The caller gave up, but his invitation somehow 53 * was not cleared. Clear it and initiate an 54 * invitation. (We know there are no newer invitations, 55 * the talkd works LIFO.) 56 */ 57 ctl_transact(his_machine_addr, msg, DELETE, rp); 58 close(sockt); 59 open_sockt(); 60 return (0); 61 } 62 p_error("Unable to connect with initiator"); 63 /*NOTREACHED*/ 64 } 65 66 /* 67 * Look for an invitation on 'machine' 68 */ 69 look_for_invite(rp) 70 CTL_RESPONSE *rp; 71 { 72 struct in_addr machine_addr; 73 74 current_state = "Checking for invitation on caller's machine"; 75 ctl_transact(his_machine_addr, msg, LOOK_UP, rp); 76 /* the switch is for later options, such as multiple invitations */ 77 switch (rp->answer) { 78 79 case SUCCESS: 80 msg.id_num = htonl(rp->id_num); 81 return (1); 82 83 default: 84 /* there wasn't an invitation waiting for us */ 85 return (0); 86 } 87 } 88