1 #ifndef lint 2 static char sccsid[] = "@(#)look_up.c 1.3 (Berkeley) 05/11/84"; 3 #endif 4 5 #include "talk_ctl.h" 6 7 8 /* 9 * See if the local daemon has a invitation for us 10 */ 11 check_local() 12 { 13 CTL_RESPONSE response; 14 15 /* the rest of msg was set up in get_names */ 16 msg.ctl_addr = ctl_addr; 17 /* must be initiating a talk */ 18 if (!look_for_invite(&response)) 19 return (0); 20 /* 21 * There was an invitation waiting for us, 22 * so connect with the other (hopefully waiting) party 23 */ 24 current_state = "Waiting to connect with caller"; 25 again: 26 swapresponse(&response); 27 if (connect(sockt, &response.addr, sizeof(response.addr)) != -1) 28 return (1); 29 if (errno == EINTR) 30 goto again; 31 if (errno == ECONNREFUSED) { 32 /* 33 * The caller gave up, but his invitation somehow 34 * was not cleared. Clear it and initiate an 35 * invitation. (We know there are no newer invitations, 36 * the talkd works LIFO.) 37 */ 38 ctl_transact(his_machine_addr, msg, DELETE, &response); 39 close(sockt); 40 open_sockt(); 41 return (0); 42 } 43 p_error("Unable to connect with initiator"); 44 /*NOTREACHED*/ 45 } 46 47 /* 48 * Look for an invitation on 'machine' 49 */ 50 look_for_invite(response) 51 CTL_RESPONSE *response; 52 { 53 struct in_addr machine_addr; 54 55 current_state = "Checking for invitation on caller's machine"; 56 ctl_transact(his_machine_addr, msg, LOOK_UP, response); 57 /* the switch is for later options, such as multiple invitations */ 58 switch (response->answer) { 59 60 case SUCCESS: 61 msg.id_num = response->id_num; 62 return (1); 63 64 default : 65 /* there wasn't an invitation waiting for us */ 66 return (0); 67 } 68 } 69 70 /* 71 * heuristic to detect if need to reshuffle CTL_RESPONSE structure 72 */ 73 74 #define swapshort(a) (((a << 8) | ((unsigned short) a >> 8)) & 0xffff) 75 #define swaplong(a) ((swapshort(a) << 16) | (swapshort(((unsigned)a >> 16)))) 76 77 #ifdef sun 78 struct ctl_response_vax { 79 char type; 80 char answer; 81 short junk; 82 int id_num; 83 struct sockaddr_in addr; 84 }; 85 86 swapresponse(rsp) 87 CTL_RESPONSE *rsp; 88 { 89 struct ctl_response_vax swaprsp; 90 91 if (rsp->addr.sin_family != AF_INET) { 92 bcopy(rsp, &swaprsp, sizeof(CTL_RESPONSE)); 93 swaprsp.addr.sin_family = swapshort(swaprsp.addr.sin_family); 94 if (swaprsp.addr.sin_family == AF_INET) { 95 rsp->addr = swaprsp.addr; 96 rsp->type = swaprsp.type; 97 rsp->answer = swaprsp.answer; 98 rsp->id_num = swaplong(swaprsp.id_num); 99 } 100 } 101 } 102 #endif 103 104 #ifdef vax 105 struct ctl_response_sun { 106 char type; 107 char answer; 108 unsigned short id_num2; 109 unsigned short id_num1; 110 short sin_family; 111 short sin_port; 112 short sin_addr2; 113 short sin_addr1; 114 }; 115 116 swapresponse(rsp) 117 CTL_RESPONSE *rsp; 118 { 119 struct ctl_response_sun swaprsp; 120 121 if (rsp->addr.sin_family != AF_INET) { 122 bcopy(rsp, &swaprsp, sizeof(struct ctl_response_sun)); 123 if (swaprsp.sin_family == swapshort(AF_INET)) { 124 rsp->type = swaprsp.type; 125 rsp->answer = swaprsp.answer; 126 rsp->id_num = swapshort(swaprsp.id_num1) 127 | (swapshort(swaprsp.id_num2) << 16); 128 rsp->addr.sin_family = swapshort(swaprsp.sin_family); 129 rsp->addr.sin_port = swaprsp.sin_port; 130 rsp->addr.sin_addr.s_addr = 131 swaprsp.sin_addr2 | (swaprsp.sin_addr1 << 16); 132 } 133 } 134 } 135 #endif 136