1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 2000 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */ 28 /* All Rights Reserved */ 29 30 /* 31 * University Copyright- Copyright (c) 1982, 1986, 1988 32 * The Regents of the University of California 33 * All Rights Reserved 34 * 35 * University Acknowledgment- Portions of this document are derived from 36 * software developed by the University of California, Berkeley, and its 37 * contributors. 38 */ 39 40 #include "talk_ctl.h" 41 #include <libintl.h> 42 #include <sys/isa_defs.h> 43 44 #ifdef SYSV 45 #define bcopy(a, b, c) memcpy((b), (a), (c)) 46 #endif /* SYSV */ 47 48 static int look_for_invite(CTL_RESPONSE *); 49 static CTL_RESPONSE swapresponse(); 50 51 52 /* see if the local daemon has a invitation for us */ 53 54 int 55 check_local() 56 { 57 CTL_RESPONSE response; 58 59 /* the rest of msg was set up in get_names */ 60 61 msg.ctl_addr = ctl_addr; 62 63 if (!look_for_invite(&response)) { 64 65 /* we must be initiating a talk */ 66 67 return (0); 68 } 69 70 /* 71 * there was an invitation waiting for us, 72 * so connect with the other (hopefully waiting) party 73 */ 74 75 current_state = gettext("Waiting to connect with caller"); 76 77 response = swapresponse(response); 78 while (connect(sockt, (struct sockaddr *)&response.addr, 79 sizeof (response.addr)) != 0) { 80 if (errno == ECONNREFUSED) { 81 82 /* 83 * the caller gave up, but the invitation somehow 84 * was not cleared. Clear it and initiate an 85 * invitation. (We know there are no newer invitations, 86 * the talkd works LIFO.) 87 */ 88 89 ctl_transact(rem_machine_addr, msg, DELETE, &response); 90 close(sockt); 91 open_sockt(); 92 return (0); 93 } else if (errno == EINTR) { 94 95 /* we have returned from an interupt handler */ 96 continue; 97 } else { 98 p_error(gettext("Unable to connect with initiator")); 99 } 100 } 101 102 return (1); 103 } 104 105 /* look for an invitation on 'machine' */ 106 107 static int 108 look_for_invite(response) 109 CTL_RESPONSE *response; 110 { 111 current_state = gettext("Checking for invitation on caller's machine"); 112 113 ctl_transact(rem_machine_addr, msg, LOOK_UP, response); 114 115 /* 116 * switch is for later options, such as multiple invitations 117 */ 118 119 switch (response->answer) { 120 121 case SUCCESS: 122 123 msg.id_num = response->id_num; 124 return (1); 125 126 default : 127 /* there wasn't an invitation waiting for us */ 128 return (0); 129 } 130 } 131 132 /* 133 * heuristic to detect if need to reshuffle CTL_RESPONSE structure 134 */ 135 136 #if defined(_LITTLE_ENDIAN) 137 struct ctl_response_runrise { 138 char type; 139 char answer; 140 short junk; 141 int id_num; 142 struct sockaddr_in addr; 143 }; 144 145 static CTL_RESPONSE 146 swapresponse(rsp) 147 CTL_RESPONSE rsp; 148 { 149 struct ctl_response_runrise swaprsp; 150 151 if (rsp.addr.sin_family != AF_INET) { 152 bcopy(&rsp, &swaprsp, sizeof (CTL_RESPONSE)); 153 if (swaprsp.addr.sin_family == AF_INET) { 154 rsp.addr = swaprsp.addr; 155 rsp.type = swaprsp.type; 156 rsp.answer = swaprsp.answer; 157 rsp.id_num = swaprsp.id_num; 158 } 159 } 160 return (rsp); 161 } 162 #endif 163 164 #if defined(_BIG_ENDIAN) 165 struct ctl_response_sun3 { 166 char type; 167 char answer; 168 unsigned short id_num2; 169 unsigned short id_num1; 170 short sin_family; 171 short sin_port; 172 short sin_addr2; 173 short sin_addr1; 174 }; 175 176 static CTL_RESPONSE 177 swapresponse(rsp) 178 CTL_RESPONSE rsp; 179 { 180 struct ctl_response_sun3 swaprsp; 181 182 if (rsp.addr.sin_family != AF_INET) { 183 bcopy(&rsp, &swaprsp, sizeof (struct ctl_response_sun3)); 184 if (swaprsp.sin_family == AF_INET) { 185 rsp.type = swaprsp.type; 186 rsp.answer = swaprsp.answer; 187 rsp.id_num = swaprsp.id_num1 188 | (swaprsp.id_num2 << 16); 189 rsp.addr.sin_family = swaprsp.sin_family; 190 rsp.addr.sin_port = swaprsp.sin_port; 191 rsp.addr.sin_addr.s_addr = 192 (swaprsp.sin_addr2 << 16)| swaprsp.sin_addr1; 193 } 194 } 195 return (rsp); 196 } 197 #endif 198