| 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) %G%"; |
| 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 | } |